juju-solutions / bundle-cwr-ci

Deploy the Juju Charm CI system
Other
2 stars 6 forks source link

Overview

This bundle deploys a reference platform for building, testing, and releasing Juju Charms and Bundles into the Juju Charm Store. The CI used in this bundle is Jenkins, paired with the following charm-specific tools:

The cornerstone of this bundle is Cloud Weather Report (CWR). The cwr charm handles CI requests (e.g. from from a webhook), manages the necessary models on your controller(s), dispatches jobs to Jenkins, provides job status to the requester, and can automatically release charms to your namespace in the charm store.

Note: We have a variation of this bundle called cwr-rq that includes all of the same components plus the Review Queue. If you are interested in a charm/bundle CI system that includes a source review application, we recommend you have a look at cwr-rq.

Bundle Composition

The charms that comprise this bundle are colocated on 1 machine. Additional information about these charms can by found in the following linked READMEs:

Getting Started

Note: This bundle requires Juju 2.1.0 (or higher) and a bootstrapped Juju controller. If Juju is not yet set up, please follow the getting-started instructions prior to deploying this bundle.

Deploy this bundle from the charm store:

juju deploy cs:~juju-solutions/cwr-ci

Charms in this bundle provide status messages to indicate their readiness. Monitor the progress of the deployment with:

watch -c juju status --color

Note: Once the charms indicate they are ready, use Ctrl-c to terminate the watch command and proceed with the following instructions.

Set a password for Jenkins:

juju config jenkins password=<yourpassword>

CWR needs access to your controller(s) to create models and allocate resources needed to run charm/bundle tests. Grant this by creating a user on your bootstrapped controller(s) with appropriate permissions:

juju add-user ciuser
juju grant ciuser add-model

Now register your controller with CWR by calling the register-controller action. Provide the controller name and the registration token from the above juju add-user command:

juju run-action cwr/0 register-controller name=<controller-name> \
    token=<registration-token>

Clouds require credentials to allow the jenkins user to allocate resources on your behalf. In the future, Juju should provide a way to share access to the credentials without having to share the credentials themselves. Until then, inform CWR of your controller credentials with the set-credentials action:

juju run-action cwr/0 set-credentials cloud=<cloud-name> \
    credentials="$(base64 ~/.local/share/juju/credentials.yaml)"

Finally, you may setup a session with the charm store that allows CWR to release charms to your namespace. To do this, call the store-login action and provide the base64 representation of an existing auth token:

charm login
.........
juju run-action cwr/0 store-login \
    charmstore-usso-token="$(base64 ~/.local/share/juju/store-usso-token)"

The charm store session will remain active while the CI system is online. To terminate the session, run the store-logout action:

juju run-action cwr/0 store-logout

At this point, you have the foundation for a powerful charm/bundle CI system. Workflows that leverage this system are described in the next section.

Workflows

Test Charm when the Repository Changes

Objective

Build and test a charm every time code is committed, tagged as a release, or has a pull request opened in the charm source repository. In light of a successful test, the resulting charm may optionally be pushed to the store and released to a configured channel.

The rationale of this workflow is that you want charm updates released to an appropriate channel as soon as you are confident that things are working as expected. With good tests, the CWR/CI system can give you that confidence and automatically handle the release process from a source repo to a channel in the charm store.

Prerequisites

Procedure

To include awesome-charm in a commit-based CI pipeline (i.e.: tests are triggered any time a commit is made to a charm source repo), call the cwr-charm-commit action:

juju run-action cwr/0 cwr-charm-commit \
    repo=http://github.com/myself/my-awesome-charm \
    charm-name=awesome-charm \
    reference-bundle=~awesome-team/awesome-bundle

To include awesome-charm in a release-based CI pipeline (i.e.: tests are triggered any time a release is created in a Github charm source repo), call the cwr-charm-release action:

juju run-action cwr/0 cwr-charm-release \
    repo=http://github.com/myself/my-awesome-charm \
    charm-name=awesome-charm \
    reference-bundle=~awesome-team/awesome-bundle

To include awesome-charm in a PR-based CI pipeline (i.e.: tests are triggered any time a pull request is created in a Github charm source repo), call the cwr-charm-pr action:

juju run-action cwr/0 cwr-charm-pr \
    repo=http://github.com/myself/my-awesome-charm \
    charm-name=awesome-charm \
    reference-bundle=~awesome-team/awesome-bundle \
    oauth-token=<token string>

Each of these actions will instruct CWR to setup a Jenkins job that will test awesome-charm on all registered controllers. This works by cloning the given repo, building a local copy of charm-name, deploying the given reference-bundle with the locally built charm, and executing the charm/bundle tests using CWR.

By default, these actions will generate a webhook url. You will need to add this url under Settings->Webhooks in your Github charm source repo. Example action output showing this url:

$ juju show-action-output <action id>
results:
  hook:
    url: http://<cwr-ip>:5000/ci/v1.0/pr-trigger/<job>/<uuid>
status: completed

Replace cwr-ip with the public address of the cwr unit. If your cwr unit is in a restricted network environment and not accessible to Github, the cwr-charm-commit and cwr-charm-release actions can be configured to poll your repository periodically (every 5 minutes) and trigger jobs when a change is detected. See the repo-access parameter below for more details.

Note: the cwr-charm-pr action must be triggered from a webhook; polling is not currently supported for this action.

Except where noted, the above actions support the following parameters:

Test Bundle when the Store Changes

Objective

Test a bundle every time an included charm is updated in the Charm Store. In light of a successful test, the resulting bundle may optionally be pushed to the store and released to a configured channel.

The rationale of this workflow is that you want your bundle updated with the most recent charms from the store, and you want to release a new bundle to the appropriate channel as soon as you are confident that things are working as expected.

Prerequisites

The CWR/CI system needs to know what parts of the bundle are important to you to trigger meaningful tests. To do this, the bundle must include a ci-info.yaml file. An example ci-info.yaml follows:

bundle:
  name: awesome-bundle
  namespace: awesome-team
  release: true
  to-channel: beta
charm-upgrade:
  awesome-charm:
    from-channel: edge
    release: true
    to-channel: beta
  not-my-charm:
    from-channel: edge
    release: false

Under the bundle key, set the bundle name. If you wish to release the bundle upon a successful update and test cycle, set release to true and provide the desired namespace and to-channel where you want to release the bundle.

Under the charm-upgrade key, specify the charm(s) you want CWR/CI to monitor. For each charm, specify the channel to watch for new revisions (from-channel) and optionally the channel to release any upgraded charms (to-channel).

Procedure

To include awesome-bundle in a charm store-based CI pipeline, call the cwr-bundle action:

juju run-action cwr/0 cwr-bundle \
  repo=http://github.com/myself/my-awesome-bundle \
  bundle-name=awesome-bundle

This action will create a Jenkins job that will clone your bundle source repository, inspect the bundle.yaml, and determine if there are any charms that can be updated. If an update is possible, a local bundle.yaml will be created with updated charm revisions and the bundle tests will be executed. If the tests are successful, this job can also release the bundle and updated charms to the specified channels in the store.

The job will run periodically (every 10 minutes), but it can also be triggered via a webhook. The webhook URL is shown in the action output and requires you to perform a POST request with at least an empty payload (compatible with the GitHub Push Event Webhook).

This action supports the following parameters:

Job Status and Logs

Jenkins

As mentioned earlier, running any of the above actions will result in a Jenkins job being created. When triggered, these jobs can be monitored from the Jenkins web UI:

http://<jenkins-ip>:8080

Login with admin and the password configured in the Getting Started section. You will find commit, release, pr, and/or bundle jobs related to the actions that have been run in the main workspace.

CWR

Cloud Weather Report stores detailed information about tests in the /srv/artifacts directory on the cwr/0 unit. CWR provides an interface to view this information at:

http://<cwr-ip>:5000

Note: CWR is subordinate to Jenkins, so the IP address of both applications will be the same.

Build Badges

CWR/CI offers an SVG badge showing the current test status of a charm/bundle. An example use of this badge would be for reporting CI status in README files. Each Jenkins job has its own build badge URL shown as part of the action output used to set up the job. To view the badge URL, run:

$ juju show-action-output <action-id>
results:
  build:
    badge: http://<cwr-ip>:5000/<job>/build-badge.svg
  hook:
    url: http://<cwr-ip>:5000/ci/v1.0/trigger/<job>/<uuid>
status: completed

Replace cwr-ip with the public address of the cwr unit. Given your README is using a markup language, using the badge should be as easy as:

[![Build Status](http://<cwr-ip>:5000/<job>/build-badge.svg)](http://<cwr-ip>:5000/)

A build badge will report the results of Cloud Weather Report for all clouds on which the job was run. An example looks like this:

alt text

Green indicates tests passed on a particular cloud; red indicates failing tests; yellow/orange indicates an infrastructure error (e.g., deployment failure).

Note: the build badge is currently not supported for the cwr-charm-pr action.

Summary

We have described a few example workflows that can leverage the charm/bundle CI system provided by this bundle. Do you have questions, ideas, or other workflows related to charm/bundle CI? Join us in the community or find more technical information from the resources below.

Resources

Community

Technical

The CWR/CI system leverages a plethora of tooling from the Juju ecosystem. Details can be found at the following project links: