This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Contribution Guidelines

How to contribute and get started

How to contribute

We’re excited to have you consider contributing to our chaos! Contributions are always appreciated.

Krkn

Contributing to Krkn

If you would like to contribute to Krkn, but are not sure exactly what to work on, you can find a number of open issues that are awaiting contributions in issues.

Adding New Scenarios and Configurations

New Scenarios

We are always looking for new scenarios to make krkn better and more usable for our chaos community. If you have any ideas, please first open an issue to explain the new scenario you are wanting to add. We will review and respond with ideas of how to get started.

If adding a new scenario or tweaking the main config, be sure to add in updates into the CI to be sure the CI is up to date. Please read this file for more information on updates.

Scenario Plugin Development

If you’re gearing up to develop new scenarios, take a moment to review our Scenario Plugin API Documentation. It’s the perfect starting point to tap into your chaotic creativity!

New Configuration to Scenarios

If you are currently using a scenario but want more configuration options, please open a github issue describing your use case and what fields and functionality you would like to see added. We will review the sugguestion and give pointers on how to add the functionality. If you feel inclined, you can start working on the feature and we’ll help if you get stuck along the way.

Work in Progress PR’s

If you are working on a contribution in any capacity and would like to get a new set of eyes on your work, go ahead and open a PR with ‘[WIP]’ at the start of the tite in your PR and tag the maintainers for review. We will review your changes and give you sugguestions to keep you moving!

Office Hours

If you have any questions that you think could be better discussed on a meeting we have monthly office hours zoom link. Please add items to agenda before so we can best prepare to help you.

Good PR Checklist

Here’s a quick checklist for a good PR, more details below:

  • One feature/change per PR
  • One commit per PR squash your commits
  • PR rebased on main (git rebase, not git pull)
  • Good descriptive commit message, with link to issue
  • No changes to code not directly related to your PR
  • Includes functional/integration test (more applicable to krkn-lib)
  • Includes link to documentation PR (documentation hosted in https://github.com/krkn-chaos/website)

Helpful Documents

Refer to the docs below to be able to test your own images with any changes and be able to contribute them to the repository

1 - Testing your changes

This page gives details about how you can get a kind cluster configured to be able to run on krkn-lib (the lowest level of krkn-chaos repos) up through krkn-hub

Testing Changes in Krkn-lib

Create a kind cluster if needed

  1. Install kind

  2. Create cluster using kind-config.yml under krkn-lib base folder

kind create cluster --wait 300s --config=kind-config.yml

Elasticsearch and Prometheus

To be able to run the full test suite of tests you need to have elasticsearch and promethues properly configured on the cluster

curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo add stable https://charts.helm.sh/stable
helm repo update

Prometheus

Configuring prometheus

ElasticSearch

Set enviornment variables of elasticsearch variables

export ELASTIC_URL="https://localhost"
export ELASTIC_PORT="9091"
export ELASTIC_USER="elastic"
export ELASTIC_PASSWORD="test"

Configuring elasticsearch

Install poetry

Using a virtual enviornment install poetry and install krkn-lib requirmenets

$ pip install poetry
$ poetry install --no-interaction

Run tests

poetry run python3 -m coverage run -a -m unittest discover -v src/krkn_lib/tests/

Testing Changes for Krkn-hub

Install Podman/Docker Compose

You can use either podman-compose or docker-compose for this step

NOTE: Podman might not work on Mac’s

pip3 install docker-compose

OR

To get latest podman-compose features we need, use this installation command

pip3 install https://github.com/containers/podman-compose/archive/devel.tar.gz

Build Your Changes

  1. Run build.sh to get Dockerfiles for each scenario
  2. Edit the docker-compose.yaml file to point to your quay.io repository (optional; required if you want to push)
ex.) 
image: containers.krkn-chaos.dev/krkn-chaos/krkn-hub:chaos-recommender 

change to >

image: quay.io/<user>/krkn-hub:chaos-recommender
  1. Build your image(s) from base krkn-hub directory

Builds all images in docker-compose file

docker-compose build

Builds single image defined by service/scenario name

docker-compose build <scenario_type>

OR

Builds all images in podman-compose file

podman-compose build

Builds single image defined by service/scenario name

podman-compose build <scenario_type>`

Push Images to your quay.io

All Images

docker-compose push

Single image

docker-compose push <scenario_type>

OR

Single Image (have to go one by one to push images through podman)

podman-compose push <scenario_type>

Run your new scenario

docker run -d -v <kube_config_path>:/root/.kube/config:Z quay.io/<username>/kraken-hub:<scenario_type>

OR

podman run -d -v <kube_config_path>:/root/.kube/config:Z quay.io/<username>/kraken-hub:<scenario_type>

See krkn-hub files for each scenario

Adding a New Scenario to Krknctl

Add KrknCtl Input Json

This file adds every enviornment variable that is set up for krkn-hub to be defined as a flag to the krknctl cli commanfd. There are

Enum Type Required Key/Values

{
    "name": "<name>",
    "short_description":"<short-description>",
    "description":"<longer-description>",
    "variable":"<variable_name>", //this needs to match enviornment variable in krkn-hub
    "type": "enum",
    "allowed_values": "<value>,<value>",
    "separator": ",",
    "default":"", // any default value
    "required":"<true_or_false>" // true or false if required to set when running
}

String Type Required Key/Values

{
    "name": "<name>",
    "short_description":"<short-description>",
    "description":"<longer-description>",
    "variable":"<variable_name>", //this needs to match enviornment variable in krkn-hub
    "type": "string",
    "default": "", // any default value
    "required":"<true_or_false>" // true or false if required to set when running
}

Number Type Required Key/Values

{
    "name": "<name>",
    "short_description": "<short-description>",
    "description": "<longer-description>",
    "variable": "<variable_name>", //this needs to match enviornment variable in krkn-hub
    "type": "number",  // options: string, number, file, file64
    "default": "", // any default value
    "required": "<true_or_false>" // true or false if required to set when running
}

File Type Required Key/Values

{
    "name": "<name>",
    "short_description":"<short-description>",
    "description":"<longer-description>",
    "variable":"<variable_name>", //this needs to match enviornment variable in krkn-hub
    "type":"file",  
    "mount_path": "/home/krkn/<file_loc>", // file location to mount to, using /home/krkn as the base has correct read/write locations
    "required":"<true_or_false>" // true or false if required to set when running
}

File Base 64 Type Required Key/Values

{
    "name": "<name>",
    "short_description":"<short-description>",
    "description":"<longer-description>",
    "variable":"<variable_name>", //this needs to match enviornment variable in krkn-hub
    "type":"file_base64",  
    "required":"<true_or_false>" // true or false if required to set when running
}

Push to personal Quay

See build your own changes on how to build and push changes to your own quay repository for testing

Run Krknctl with Personal Image

Once you have your images in quay, you are all set to configure krknctl to look for these new images. You’ll edit the quay_org (your quay username), quay_scenario_registry (krkn-hub), quay_base_image_registry variables here

With these updates to your config, you’ll re-build your personal krknctl binary and you’l be all set to start testing your new scenario and config options.

If any krknctl code changes are required, you’ll have to make changes and rebuild the the krknctl binary.

Follow Contribution Guide

Once all you’re happy with your changes, follow the contribution guide on how to create your own branch and squash your commits

2 - Adding scenarios via plugin api

Scenario Plugin API:

This API enables seamless integration of Scenario Plugins for Krkn. Plugins are automatically detected and loaded by the plugin loader, provided they extend the AbstractPluginScenario abstract class, implement the required methods, and adhere to the specified naming conventions.

Plugin folder:

The plugin loader automatically loads plugins found in the krkn/scenario_plugins directory, relative to the Krkn root folder. Each plugin must reside in its own directory and can consist of one or more Python files. The entry point for each plugin is a Python class that extends the AbstractPluginScenario abstract class and implements its required methods.

AbstractPluginScenario abstract class:

This abstract class defines the contract between the plugin and krkn. It consists of two methods:

  • run(...)
  • get_scenario_type()

Most IDEs can automatically suggest and implement the abstract methods defined in AbstractPluginScenario: pycharm (IntelliJ PyCharm)

run(...)

    def run(
        self,
        run_uuid: str,
        scenario: str,
        krkn_config: dict[str, any],
        lib_telemetry: KrknTelemetryOpenshift,
        scenario_telemetry: ScenarioTelemetry,
    ) -> int:

This method represents the entry point of the plugin and the first method that will be executed.

Parameters:

  • run_uuid:
    • the uuid of the chaos run generated by krkn for every single run.
  • scenario:
    • the config file of the scenario that is currently executed
  • krkn_config:
    • the full dictionary representation of the config.yaml
  • lib_telemetry
    • it is a composite object of all the krkn-lib objects and methods needed by a krkn plugin to run.
  • scenario_telemetry
    • the ScenarioTelemetry object of the scenario that is currently executed

Return value:

Returns 0 if the scenario succeeds and 1 if it fails.

[!WARNING] All the exception must be handled inside the run method and not propagated.

get_scenario_types():

python def get_scenario_types(self) -> list[str]:

Indicates the scenario types specified in the config.yaml. For the plugin to be properly loaded, recognized and executed, it must be implemented and must return one or more strings matching scenario_type strings set in the config.

[!WARNING] Multiple strings can map to a single ScenarioPlugin but the same string cannot map to different plugins, an exception will be thrown for scenario_type redefinition.

[!Note]
The scenario_type strings must be unique across all plugins; otherwise, an exception will be thrown.

Naming conventions:

A key requirement for developing a plugin that will be properly loaded by the plugin loader is following the established naming conventions. These conventions are enforced to maintain a uniform and readable codebase, making it easier to onboard new developers from the community.

plugin folder:

  • the plugin folder must be placed in the krkn/scenario_plugin folder starting from the krkn root folder
  • the plugin folder cannot contain the words
    • plugin
    • scenario

plugin file name and class name:

  • the plugin file containing the main plugin class must be named in snake case and must have the suffix _scenario_plugin:
    • example_scenario_plugin.py
  • the main plugin class must named in capital camel case and must have the suffix ScenarioPlugin :
    • ExampleScenarioPlugin
  • the file name must match the class name in the respective syntax:
    • example_scenario_plugin.py -> ExampleScenarioPlugin

scenario type:

  • the scenario type must be unique between all the scenarios.

logging:

If your new scenario does not adhere to the naming conventions, an error log will be generated in the Krkn standard output, providing details about the issue:

2024-10-03 18:06:31,136 [INFO] 📣 `ScenarioPluginFactory`: types from config.yaml mapped to respective classes for execution:
2024-10-03 18:06:31,136 [INFO]   ✅ type: application_outages_scenarios ➡️ `ApplicationOutageScenarioPlugin` 
2024-10-03 18:06:31,136 [INFO]   ✅ types: [hog_scenarios, arcaflow_scenario] ➡️ `ArcaflowScenarioPlugin` 
2024-10-03 18:06:31,136 [INFO]   ✅ type: container_scenarios ➡️ `ContainerScenarioPlugin` 
2024-10-03 18:06:31,136 [INFO]   ✅ type: managedcluster_scenarios ➡️ `ManagedClusterScenarioPlugin` 
2024-10-03 18:06:31,137 [INFO]   ✅ types: [pod_disruption_scenarios, pod_network_scenario, vmware_node_scenarios, ibmcloud_node_scenarios] ➡️ `NativeScenarioPlugin` 
2024-10-03 18:06:31,137 [INFO]   ✅ type: network_chaos_scenarios ➡️ `NetworkChaosScenarioPlugin` 
2024-10-03 18:06:31,137 [INFO]   ✅ type: node_scenarios ➡️ `NodeActionsScenarioPlugin` 
2024-10-03 18:06:31,137 [INFO]   ✅ type: pvc_scenarios ➡️ `PvcScenarioPlugin` 
2024-10-03 18:06:31,137 [INFO]   ✅ type: service_disruption_scenarios ➡️ `ServiceDisruptionScenarioPlugin` 
2024-10-03 18:06:31,137 [INFO]   ✅ type: service_hijacking_scenarios ➡️ `ServiceHijackingScenarioPlugin` 
2024-10-03 18:06:31,137 [INFO]   ✅ type: cluster_shut_down_scenarios ➡️ `ShutDownScenarioPlugin` 
2024-10-03 18:06:31,137 [INFO]   ✅ type: syn_flood_scenarios ➡️ `SynFloodScenarioPlugin` 
2024-10-03 18:06:31,137 [INFO]   ✅ type: time_scenarios ➡️ `TimeActionsScenarioPlugin` 
2024-10-03 18:06:31,137 [INFO]   ✅ type: zone_outages_scenarios ➡️ `ZoneOutageScenarioPlugin`

2024-09-18 14:48:41,735 [INFO] Failed to load Scenario Plugins:

2024-09-18 14:48:41,735 [ERROR] ⛔ Class: ExamplePluginScenario Module: krkn.scenario_plugins.example.example_scenario_plugin
2024-09-18 14:48:41,735 [ERROR] ⚠️ scenario plugin class name must start with a capital letter, end with `ScenarioPlugin`, and cannot be just `ScenarioPlugin`.

[!NOTE] If you’re trying to understand how the scenario types in the config.yaml are mapped to their corresponding plugins, this log will guide you! Each scenario plugin class mentioned can be found in the krkn/scenario_plugin folder simply convert the camel case notation and remove the ScenarioPlugin suffix from the class name e.g ShutDownScenarioPlugin class can be found in the krkn/scenario_plugin/shut_down folder.

ExampleScenarioPlugin

The ExampleScenarioPlugin class included in the tests folder can be used as a scaffolding for new plugins and it is considered part of the documentation.

For any questions or further guidance, feel free to reach out to us on the Kubernetes workspace in the #krkn channel. We’re happy to assist. Now, release the Krkn!

3 - Git Help For Contributions

How to contribute

Contributions are always appreciated.

How to:

Pull request

In order to submit a change or a PR, please fork the project and follow instructions:

$ git clone http://github.com/<me>/krkn-hub
$ cd krkn-hub
$ git checkout -b <branch_name>
$ <make change>
$ git add <changes>
$ git commit -a
$ <insert good message>
$ git push

Squash Commits

If there are mutliple commits, please rebase/squash multiple commits before creating the PR by following:

$ git checkout <my-working-branch>
$ git rebase -i HEAD~<num_of_commits_to_merge>
   -OR-
$ git rebase -i <commit_id_of_first_change_commit>

In the interactive rebase screen, set the first commit to pick and all others to squash (or whatever else you may need to do).

Push your rebased commits (you may need to force), then issue your PR.

$ git push origin <my-working-branch> --force

Rebase with Upstream

If new commits were merged while you were working you’ll need to rebase with upstream before creating the PR by following:

$ git checkout <my-working-branch>
$ git remote add upstream https://github.com/krkn-chaos/krkn (or krkn-hub)
$ git fetch upstream
$ git rebase upstream/<branch_in_upstream_to_rebase> (most likely `main`)

If any errors occur:

  1. It’ll list off any files that have merge issues
  2. Edit the files with the code blocks you want to keep
  3. Add and continue rebase
$ git add .
$ git rebase --continue
  1. Might need to repeat steps 1-3 until you see Successfully rebased and updated refs/heads/<my-working-branch>.

Push your rebased commits (you may need to force), then issue your PR.

$ git push origin <my-working-branch> --force

Developer’s Certificate of Origin

Any contributions to Krkn must only contain code that can legally be contributed to Krkn, and which the Krkn project can distribute under its license.

Prior to contributing to Krkn please read the Developer’s Certificate of Origin and sign-off all commits with the –signoff option provided by git commit. For example:

git rebase HEAD~1 --signoff
git push origin <branch_name> --force

This option adds a Signed-off-by trailer at the end of the commit log message.