Writing Policies¶
When you ask Greenwave for a decision, it checks all the configured policies to find which ones are applicable to the subject of the decision. It then evaluates all the rules in each applicable policy and makes a decision based on whether they are all satisfied.
Policies are YAML files, loaded from the directory given by the
POLICIES_DIR
configuration setting (by default,
/etc/greenwave/policies
).
The YAML format allows you to write one or more “documents” in a file. Greenwave considers each YAML document to be a policy.
Here is an example policy:
1 2 3 4 5 6 7 8 9 10 11 12 | --- !Policy
id: taskotron_release_critical_tasks
decision_context: bodhi_update_push_stable
product_versions:
- fedora-26
- fedora-27
rules:
- !PassingTestCaseRule {test_case_name: dist.rpmdeplint}
- !PassingTestCaseRule {test_case_name: dist.upgradepath}
blacklist:
- qt
- mariadb
|
On line 1, the ---
YAML document header marks the beginning of a new
document.
The top-level document has the YAML tag !Policy
to indicate that this is a
Greenwave policy. Greenwave expects each YAML document to be tagged this way.
The document is a map (dictionary) with the following keys:
id
- This is an arbitrary string identifying this policy. Each policy in the configuration must have a distinct id. Greenwave does not assign any meaning to this identifier, but it appears in Greenwave’s decision API responses so that you can map it back to the configuration where it is defined.
decision_context
This is an arbitrary string identifying the “context” of the decisions where this policy is applicable. In other words, if Greenwave is making decisions at gating points in a pipeline, this is how we identify which gate we are talking about.
Greenwave does not enforce anything about this identifier. It should be chosen in coordination with the tool asking Greenwave for a decision. In this example, the identifier is
bodhi_update_push_stable
. Bodhi passes this value when it asks Greenwave to decide whether a Bodhi update is ready to be pushed to the stable repositories.product_versions
A policy applies to one or more “product versions”. When you ask Greenwave for a decision, you must tell it which product version you are working with, and it only selects policies which are applicable for that product version.
This mechanism makes it possible to enforce different rules across different versions of a product. For example, the policy for Fedora could become increasingly stricter across versions as the quality and coverage of tests improves.
The “product version” strings used here (and in the Greenwave decision API) are expected to match the product version identifiers used in Product Definition Center (see the /product-versions endpoint), although Greenwave does not enforce this.
You can match many product versions by using a wildcard like
fedora-*
.rules
A list of rules which this policy enforces. Each item in the list is a YAML map, tagged with the rule type.
Currently there are a few rule types,
PassingTestCaseRule
being one of them. See the section of Rule Types, below for a full list.blacklist
A list of binary RPM package names which are exempted from this policy.
The blacklist only takes effect when Greenwave is making a decision about subjects with
"item": "koji_build"
.
Rule Types¶
PassingTestCaseRule¶
For this rule to be satisfied, there must be a result in ResultsDB for the giventest_case_name
with an outcome ofPASS
, or there must be a corresponding waiver in WaiverDB for the given test case.
PackageSpecificBuild¶
Just like the
PassingTestCaseRule
, thePackageSpecificBuild
rule requires that a giventest_case_name
is passing, but only for certain packages (listed in therepos
argument). The configured package names in therepos
list may contain wildcards to, for instance, write a rule requiring a certain test must pass for all python-* packages.At query time, the package name is parsed from an assumed nvr in the
item
of the subject.
FedoraAtomicCi¶
This rule is nearly identical to thePackageSpecificBuild
rule, except that at query time, the package name is parsed from an assumed nvr in theoriginal_spec_nvr
of the subject.
RemoteOriginalSpecNvrRule¶
This rule allows the packager to configure some additional policies in a gating.yaml file configured in the repo. Greenwave checks if the file exists, and, if it does it pulls it down, loads it, and uses it to additionally evaluate the subject of the decision.
This feature is available for an nvr that is
original_spec_nvr
. To use this feature it is required to configureKOJI_BASE_URL
,DIST_GIT_BASE_URL
andDIST_GIT_URL_TEMPLATE
.Examples:
DIST_GIT_BASE_URL = 'https://src.fedoraproject.org' DIST_GIT_URL_TEMPLATE = '{DIST_GIT_BASE_URL}/{pkg_name}/{rev}/gating.yaml' KOJI_BASE_URL = 'https://koji.fedoraproject.org/kojihub'
Testing your policy changes¶
If you’re writing a new policy, you can use the Greenwave dev server to try it out and experiment with how if affects Greenwave’s decisions.
First, follow the steps in the Development Guide to get the dev server running locally.
Then, add your new or modified policy in the conf/policies/
directory
of your source tree. Note that Greenwave currently loads policies once at
startup, it doesn’t reload them at runtime. Therefore you should restart the
dev server whenever you make a change to the policies.
Now, you can use curl or your favourite HTTP client to ask Greenwave for a decision:
$ curl http://localhost:5005/api/v1.0/decision \
--header 'Content-Type: application/json' \
--data '{"product_version": "fedora-27",
> "decision_context": "bodhi_update_push_stable",
> "subject": [{"item": "akonadi-calendar-tools-17.12.1-1.fc27",
> "type": "koji_build"}]}'