├── .ansible-lint ├── .github └── workflows │ ├── ansible-lint.yml │ ├── dockerfile-lint.yml │ └── markdown-lint.yml ├── .gitignore ├── .hadolint.yaml ├── .mdl_style.rb ├── .mdlrc ├── .stickler.yml ├── LICENSE ├── README.md ├── cleanup.yaml ├── deploy.yaml ├── docs ├── Fedora32.md └── dockerhub.md ├── group_vars └── all.yaml ├── inventory-example.ini ├── koji-base ├── Dockerfile ├── bin │ ├── add-koji-profile.sh │ ├── copy-kcb-plugin.sh │ ├── moshimoshi.sh │ └── pick-koji-profile.sh └── etc │ ├── koji.conf.d │ └── template │ └── pki │ └── koji │ └── README.txt ├── koji-builder ├── Dockerfile ├── bin │ ├── entrypoint.sh │ └── koji-setup.sh └── etc │ ├── kojid │ └── kojid.conf │ └── osbs.conf ├── koji-client ├── Dockerfile └── bin │ └── entrypoint.sh ├── koji-db ├── Dockerfile └── sql-init │ ├── 10-kojiadmin.sql │ └── 20-atomic-reactor.sql ├── koji-hub ├── Dockerfile ├── bin │ ├── entrypoint.sh │ └── koji-steal-build └── etc │ ├── httpd │ └── conf.d │ │ ├── kojihub.conf │ │ ├── kojiweb.conf │ │ ├── servername.conf │ │ ├── ssl.conf │ │ └── test-accessories.conf │ ├── koji-hub │ └── hub.conf │ └── kojiweb │ └── web.conf ├── openshift ├── configs │ ├── client-config-secret.conf.j2 │ ├── koji-builder-osbs.conf.j2 │ ├── koji-hub-web.conf.j2 │ └── reactor-config-map.yaml.j2 ├── params │ └── osbs-box.env.j2 └── templates │ ├── koji-base.yaml │ ├── koji-builder.yaml │ ├── koji-client.yaml │ ├── koji-db.yaml │ ├── koji-hub.yaml │ ├── koji-volumes.yaml │ ├── osbs-buildroot.yaml │ └── osbs-registry.yaml ├── osbs-buildroot └── Dockerfile ├── prerequisite-playbooks └── Fedora32-prerequisites.yaml ├── skopeo-lite └── Dockerfile └── tasks ├── generate-certs.yaml └── generate-ownca-cert.yaml /.ansible-lint: -------------------------------------------------------------------------------- 1 | skip_list: 2 | - experimental 3 | 4 | -------------------------------------------------------------------------------- /.github/workflows/ansible-lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint ansible playbooks 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | ansible-lint: 7 | runs-on: ubuntu-latest 8 | 9 | container: 10 | image: fedora:30 11 | 12 | steps: 13 | - uses: actions/checkout@v1 14 | 15 | - name: Install ansible-lint 16 | run: pip3 install "ansible-lint[yamllint]" "ansible>=2.9" 17 | 18 | - name: Lint playbooks 19 | run: ansible-lint deploy.yaml cleanup.yaml --force-color 20 | -------------------------------------------------------------------------------- /.github/workflows/dockerfile-lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint Dockerfiles 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | dockerfile-lint: 7 | runs-on: ubuntu-latest 8 | 9 | container: 10 | image: hadolint/hadolint:latest-debian 11 | 12 | steps: 13 | - uses: actions/checkout@v1 14 | 15 | - name: Lint Dockerfiles with hadolint 16 | run: hadolint **/Dockerfile 17 | -------------------------------------------------------------------------------- /.github/workflows/markdown-lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint Markdown files 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | markdown-lint: 7 | runs-on: ubuntu-latest 8 | 9 | container: 10 | image: pipelinecomponents/markdownlint:latest 11 | 12 | steps: 13 | - uses: actions/checkout@v1 14 | 15 | - name: Lint Markdown files 16 | # We have to update to latest mdl 17 | run: gem install mdl; /usr/local/bundle/bin/mdl -g . 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | overrides.yaml 2 | inventory.ini 3 | -------------------------------------------------------------------------------- /.hadolint.yaml: -------------------------------------------------------------------------------- 1 | ignored: 2 | - DL3006 # Always tag FROM images (OpenShift replaces those) 3 | - DL3013 # Install specific package versions with pip 4 | - DL3041 # Specify version with dnf install -y - 5 | -------------------------------------------------------------------------------- /.mdl_style.rb: -------------------------------------------------------------------------------- 1 | all 2 | rule 'MD013', :code_blocks => false, :tables => false 3 | exclude_rule 'MD033' 4 | -------------------------------------------------------------------------------- /.mdlrc: -------------------------------------------------------------------------------- 1 | style '.mdl_style.rb' 2 | -------------------------------------------------------------------------------- /.stickler.yml: -------------------------------------------------------------------------------- 1 | linters: 2 | shellcheck: 3 | shell: bash 4 | flake8: 5 | python: 3 6 | max-line-length: 100 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Luiz Carvalho 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OSBS-Box 2 | 3 | An OpenShift based project that provides an environment for testing OSBS 4 | components; it can be deployed locally using the [example inventory][]. 5 | 6 | ## Basic usage 7 | 8 | Run a simple container build on your OSBS-Box: 9 | 10 | ```shell 11 | $ # If running remotely, first log in to the OpenShift server or ssh into the remote machine 12 | $ oc login --server https://:8443 -u osbs -p osbs 13 | 14 | $ # Get URL of container registry 15 | $ OSBS_REGISTRY=$(oc -n osbs-registry get route osbs-registry --output jsonpath='{ .spec.host }') 16 | 17 | $ # Copy base image for container build to registry 18 | $ skopeo copy docker://registry.fedoraproject.org/fedora:30 \ 19 | docker://${OSBS_REGISTRY}/fedora:30 \ 20 | --all \ 21 | --dest-tls-verify=false 22 | 23 | $ # Run koji container-build 24 | $ oc -n osbs-koji rsh dc/koji-client \ 25 | koji container-build candidate \ 26 | git://github.com/chmeliik/docker-hello-world#origin/osbs-box-basic \ 27 | --git-branch osbs-box-basic 28 | ``` 29 | 30 | When logging into the server, you will likely need to use the 31 | `--insecure-skip-tls-verify` flag. 32 | 33 | If your version of `skopeo` does not support the `--all` flag, you might want to 34 | use `skopeo-lite` instead ([more on that][]). 35 | 36 | ## Deployment 37 | 38 | OSBS-Box is primarily intended for use with OpenShift clusters created using 39 | `oc cluster up`. 40 | 41 | Setting one up should be as simple as: 42 | 43 | ```shell 44 | dnf install origin-clients 45 | oc cluster up 46 | ``` 47 | 48 | For more details, refer to [cluster_up_down.md][]. 49 | 50 | ### Prerequisites 51 | 52 | - **On the target machine** 53 | - ansible >= 2.8 54 | - pyOpenSSL >= 0.15 (for the `openssl_*` ansible modules) 55 | - an OpenShift cluster, as described above 56 | 57 | - **Detailed prerequisites on a Fedora 32 target machine** 58 | 59 | - see [Fedora32.md][] 60 | 61 | - **Note about Docker Hub (docker.io image registry)** 62 | 63 | - You *must* have a [Docker Hub] account of some kind for pulling necessary 64 | images. Depending on how you use OSBS Box, you *might* require a paid account, 65 | as you *might* hit the free account's hourly limit on image pulls. 66 | - Consult [dockerhub.md][] for more details. 67 | 68 | ### Deployment steps 69 | 70 | 1. If you haven't already, `git clone` this repository 71 | 1. Take a look at [group_vars/all.yaml][][1](#f1) 72 | 1. You **MUST** override the 'docker_*' group vars in a YAML file, and provide 73 | that file to the ansible-playbook command via (e.g.) `-e @overrides.yaml`. 74 | Consult [dockerhub.md][] for more details. (Note that the '@' *is a necessary 75 | part of the command*) 76 | 1. Provide an inventory file, or use the example one 77 | 1. Run `ansible-playbook deploy.yaml -i ` 78 | 79 | If you are sure that you do not need to re-generate certificates, use 80 | `--tags=openshift` 81 | 82 | **NOTE**: [deploy.yaml][] only starts the build, it does not wait for the entire 83 | deployment to finish. You can check the deployment status in the web console or 84 | with `oc status`. 85 | 86 | ## Using OSBS-Box 87 | 88 | During deployment, the OpenShift user specified in [group_vars/all.yaml][] 89 | will be given cluster admin privileges. This is the user you are going to want 90 | to log in as from the web console / CLI. 91 | 92 | ### OpenShift console 93 | 94 | Located at by default (if running locally). 95 | 96 | You will see all the OSBS-Box namespaces here (by default, they are called 97 | `osbs-*`). After entering a namespace, you will see all the running pods, you 98 | can view their logs, open terminals in them etc. 99 | 100 | ### OpenShift CLI 101 | 102 | Generally, anything you can do in the console, you can do with `oc`. Just make 103 | sure you are logged into the server and in the right project. 104 | 105 | To run a command in a container from the command line (for example, `koji hello` 106 | on the client): 107 | 108 | ```shell 109 | oc login --server -u osbs -p osbs # If not yet logged in 110 | oc rsh dc/koji-client koji hello # dc is short for deploymentconfig 111 | oc -n osbs-koji rsh dc/koji-client koji hello # From a project other than osbs-koji 112 | ``` 113 | 114 | Use 115 | 116 | `oc rsh ` 117 | 118 | or 119 | 120 | `oc rsh bash` 121 | 122 | to open a remote shell in the specified pod. 123 | 124 | ### Koji website 125 | 126 | The koji-hub OpenShift app provides an external route where you can access the 127 | koji website. You can find the URL in the console or with 128 | `oc get route koji-hub`. Here, you can view information about your Koji instance. 129 | 130 | To log in to the website, you will first need to import a client certificate 131 | into your browser. These certificates are generated during deployment and can be 132 | found in the koji certificates directory on the target machine 133 | (`~/.local/share/osbs-box/certificates/koji/` by default). There is one for 134 | each koji user (by default, only `kojiadmin` and `kojiosbs` are users, but 135 | logging in creates a user automatically). 136 | 137 | ### Koji CLI (local) 138 | 139 | Coming soon ^TM^ 140 | 141 | ### Container registry 142 | 143 | OSBS-Box deploys a container registry for you. It is used both as the source 144 | registry for base images and the output registry for built images. 145 | 146 | You can access it just like any other container registry using its external 147 | route. You can find the URL in the console or with `oc get route osbs-registry`. 148 | 149 | Since the certificate used for the registry is signed by our own, untrusted CA, 150 | the registry is considered insecure. 151 | 152 | Use the following to access the registry, depending on your tool 153 | 154 | - `docker` 155 | - Add the registry URL to `insecure-registries` in '/etc/docker/daemon.json' 156 | and restart docker 157 | - `podman` 158 | - Use the `--tls-verify=false` option 159 | - `skopeo` 160 | - Use the `--tls-verify=false` option (or `--(src|dest)-tls-verify=false` for 161 | copying) 162 | 163 | ### Skopeo-lite 164 | 165 | **NOTE**: Starting with `skopeo` release `v0.1.40`, the `copy` command comes 166 | with an `--all` flag, which makes skopeo also copy manifest lists. That renders 167 | `skopeo-lite` obsolete. 168 | 169 | Prior to `v0.1.40`, `skopeo` would not copy manifest lists. Builds may work even 170 | with base images missing manifest lists, but they will not use the related OSBS 171 | features. 172 | 173 | For this purpose, OSBS-Box provides a `skopeo-lite` image. 174 | 175 | Use it with `podman`: 176 | 177 | ```shell 178 | $ podman build skopeo-lite/ --tag skopeo-lite 179 | 180 | $ # Get URL of container registry 181 | $ OSBS_REGISTRY=$(oc -n osbs-registry get route osbs-registry --output jsonpath='{ .spec.host }') 182 | 183 | $ # Copy image to container registry 184 | $ podman run --rm -ti \ 185 | skopeo-lite copy docker://registry.fedoraproject.org/fedora:30 \ 186 | docker://${OSBS_REGISTRY}/fedora:30 \ 187 | --dest-tls-verify=false 188 | ``` 189 | 190 | Or `docker`: 191 | 192 | ```shell 193 | $ docker build skopeo-lite/ --tag skopeo-lite 194 | 195 | $ # If you are on the target machine, you might need to use the registry IP instead 196 | $ OSBS_REGISTRY=$(oc -n osbs-registry get svc osbs-registry --output jsonpath='{ .spec.clusterIP }') 197 | 198 | $ # Otherwise, use the URL 199 | $ OSBS_REGISTRY=$(oc -n osbs-registry get route osbs-registry --output jsonpath='{ .spec.host }') 200 | 201 | $ # Copy image to container registry 202 | $ docker run --rm -ti \ 203 | skopeo-lite copy docker://registry.fedoraproject.org/fedora:30 \ 204 | docker://${OSBS_REGISTRY}:5000/fedora:30 \ 205 | --dest-tls-verify=false 206 | ``` 207 | 208 | ## Updating OSBS-Box 209 | 210 | In general, there are two reasons why you might want to update your OSBS-Box 211 | instance: 212 | 213 | 1. Changes in OSBS-Box itself 214 | 1. Changes in other OSBS components 215 | 216 | For case 1, your best bet is to rerun the entire deployment 217 | 218 | ```shell 219 | ansible-playbook deploy.yaml -i -e 220 | ``` 221 | 222 | For case 2, usually you will only need 223 | 224 | ```shell 225 | ansible-playbook deploy.yaml -i -e --tags=koji,buildroot 226 | ``` 227 | 228 | In fact, it might be desirable to run the update like this to avoid having any 229 | potential manual changes to the reactor config map overwritten. But if you are 230 | not sure, running the full playbook or at least `--tags=openshift` will work. 231 | 232 | **NOTE**: When working on OSBS-Box code, to test changes concerning any of the 233 | pieces used to build Docker images, you will need to **push the changes first** 234 | before running the playbook, because OpenShift gets the code for builds from 235 | git. Alternatively, instead of using the playbook, you can just `oc start-build 236 | {the component you changed} --from-dir .`. 237 | 238 | ## Cleaning up 239 | 240 | There are multiple reasons why you might want to clean up OSBS-Box data: 241 | 242 | - You need to reset your koji/registry instances to a clean state 243 | - For some reason, updating your OSBS-Box failed (and it is not because of the 244 | code) 245 | - You are done with OSBS-Box (forever) 246 | 247 | OSBS-Box provides the **cleanup.yaml** playbook, which does parts of the cleanup 248 | for you based on what `--tags` you specify. In addition to tags related to 249 | OpenShift namespaces/applications, there are extra tags (not run by default) 250 | related to local data: 251 | 252 | - `openshift_files` 253 | - OpenShift files (templates, configs) created during deployment 254 | - `certificates` 255 | - Certificates created during deployment 256 | - `pvs` (uses `sudo`; run playbook with `--ask-become-pass`) 257 | - `registry_pv` 258 | - PV for the container registry 259 | - `koji_pvs` 260 | - `koji_db_pv` 261 | - koji database PV 262 | - `koji_files_pv` 263 | - PV used by koji-hub and koji-builder for `/mnt/koji/` 264 | 265 | When you run the playbook without any tags, all OSBS-Box OpenShift namespaces 266 | are deleted, this also kills the containers running in them. All other data is 267 | kept, including persistent volume directories. If you need to reset your 268 | instance to a clean state, you will likely want to use the `pvs` tag. To get rid 269 | of everything, use `everything`. 270 | 271 | You may also want to 272 | 273 | - Remove the docker images built/pulled by OpenShift 274 | 275 | You will find them in your local registry, like normal docker images 276 | - Run `oc cluster down` and remove the data left behind by `oc cluster up` 277 | - Volumes that were mounted by OpenShift and never unmounted 278 | 279 | ```shell 280 | findmnt -r -n -o TARGET | grep "openshift.local.clusterup" | xargs -r umount 281 | ``` 282 | 283 | - The `openshift.local.clusterup` directory created when you ran 284 | `oc cluster up` (or whatever you passed as the `--base-dir` param to 285 | `oc cluster up`) 286 | 287 | ## Project structure 288 | 289 | Coming soon ^TM^ 290 | 291 | ## Known issues 292 | 293 | - Koji website login bug 294 | - Problem 295 | 296 | ```text 297 | An error has occurred in the web interface code. This could be due to a bug 298 | or a configuration issue. 299 | koji.AuthError: could not get user for principal: 300 | ``` 301 | 302 | - Reproduce 303 | 1. Log in to the koji website as a user that is neither `kojiadmin` nor 304 | `kojiosbs` 305 | 1. Bring koji down without logging out of the website 306 | 1. Remove koji database persistent data 307 | 1. Bring koji back up, go to the website 308 | 1. Congratulations, koji now thinks a non-existent user is logged in 309 | - Solution 310 | - Clear cookies, reload website 311 | - Running deployment playbook triggers multiple deployments in OpenShift 312 | - Problem 313 | - For some reason, even though the DeploymentConfigs are configured to only 314 | trigger deployments on imageChange, running the deployment playbook 315 | against a running OSBS-Box instance triggers multiple re-deployments of 316 | koji components 317 | - Solution 318 | - This is not a major issue, just do not be surprised when you see your koji 319 | containers getting restarted 2 or 3 times after each deployment (except 320 | for the initial deployment, that works fine) 321 | 322 | --- 323 | 324 | 1. It's better to override group vars via `overrides.yaml` than 325 | to change the global configuration in [group_vars/all.yaml][] [↩](#a1) 326 | 327 | [example inventory]: ./inventory-example.ini 328 | [Docker Hub]: https://hub.docker.com 329 | [dockerhub.md]: ./docs/dockerhub.md 330 | [more on that]: #Skopeo-lite 331 | [cluster_up_down.md]: https://github.com/openshift/origin/blob/release-3.11/docs/cluster_up_down.md 332 | [Fedora32.md]: ./docs/Fedora32.md 333 | [group_vars/all.yaml]: ./group_vars/all.yaml 334 | [deploy.yaml]: ./deploy.yaml 335 | -------------------------------------------------------------------------------- /cleanup.yaml: -------------------------------------------------------------------------------- 1 | - name: Prepare for cleanup 2 | hosts: osbs_box_host 3 | tags: 4 | - always 5 | 6 | tasks: 7 | - name: Try to log in as openshift admin 8 | command: oc login -u system:admin 9 | register: oc_login 10 | changed_when: oc_login.rc == 0 11 | # If login failed, cluster is probably down - that means steps which use 12 | # `oc` must be skipped, but otherwise, cleanup can proceed as usual 13 | ignore_errors: true 14 | 15 | 16 | - name: Delete koji 17 | hosts: osbs_box_host 18 | gather_facts: false 19 | tags: 20 | - koji 21 | # All tags related to koji PVs (deleting PVs while in use is a bad idea) 22 | - pvs 23 | - koji_pvs 24 | - koji_db_pv 25 | - koji_files_pv 26 | # One tag to rule them all 27 | - everything 28 | 29 | tasks: 30 | - name: Delete koji namespace from openshift 31 | command: oc delete namespace "{{ koji_namespace }}" 32 | register: delete_koji_namespace 33 | changed_when: delete_koji_namespace.rc == 0 34 | failed_when: delete_koji_namespace.rc != 0 and 35 | 'not found' not in delete_koji_namespace.stderr 36 | when: not oc_login.failed 37 | 38 | - name: Delete koji PVs from openshift 39 | command: oc delete pv --selector volume=koji-volume 40 | register: delete_koji_pvs 41 | changed_when: delete_koji_pvs.rc == 0 and 42 | delete_koji_pvs.stdout != 'No resources found' 43 | failed_when: delete_koji_pvs.rc != 0 44 | when: not oc_login.failed 45 | 46 | 47 | - name: Delete docker registry 48 | hosts: osbs_box_host 49 | gather_facts: false 50 | tags: 51 | - registry 52 | - pvs 53 | - registry_pv 54 | - everything 55 | 56 | tasks: 57 | - name: Delete registry namespace from openshift 58 | command: oc delete namespace "{{ registry_namespace }}" 59 | register: delete_registry_namespace 60 | changed_when: delete_registry_namespace.rc == 0 61 | failed_when: delete_registry_namespace.rc != 0 and 62 | 'not found' not in delete_registry_namespace.stderr 63 | when: not oc_login.failed 64 | 65 | - name: Delete registry PV from openshift 66 | command: oc delete pv registry-data 67 | register: delete_registry_pv 68 | changed_when: delete_registry_pv.rc == 0 69 | failed_when: delete_registry_pv.rc != 0 and 70 | 'not found' not in delete_registry_pv.stderr 71 | when: not oc_login.failed 72 | 73 | 74 | - name: Delete OSBS orchestrator and worker namespaces 75 | hosts: osbs_box_host 76 | gather_facts: false 77 | tags: 78 | - namespaces 79 | - everything 80 | 81 | tasks: 82 | - name: Delete orchestrator and worker namespaces from openshift 83 | command: oc delete namespace "{{ item }}" 84 | register: delete_osbs_namespace 85 | changed_when: delete_osbs_namespace.rc == 0 86 | failed_when: delete_osbs_namespace.rc != 0 and 87 | 'not found' not in delete_osbs_namespace.stderr 88 | loop: 89 | - "{{ orchestrator_namespace }}" 90 | - "{{ worker_namespace }}" 91 | when: not oc_login.failed 92 | 93 | 94 | - name: Delete persistent volume data 95 | hosts: osbs_box_host 96 | gather_facts: false 97 | become: true 98 | tags: 99 | - never 100 | - pvs 101 | - everything 102 | 103 | tasks: 104 | - name: Delete koji-db-data PV directory 105 | file: 106 | path: "{{ koji_db_data_dir }}" 107 | state: absent 108 | tags: 109 | - koji_pvs 110 | - koji_db_pv 111 | 112 | - name: Delete koji-files PV directory 113 | file: 114 | path: "{{ koji_files_dir }}" 115 | state: absent 116 | tags: 117 | - koji_pvs 118 | - koji_files_pv 119 | 120 | - name: Delete registry-data PV directory 121 | file: 122 | path: "{{ registry_data_dir }}" 123 | state: absent 124 | tags: 125 | - registry_pv 126 | 127 | 128 | - name: Delete remaining OSBS-Box data 129 | hosts: osbs_box_host 130 | gather_facts: false 131 | tags: 132 | - never 133 | - everything 134 | 135 | tasks: 136 | - name: Delete certificate directories 137 | file: 138 | path: "{{ item }}" 139 | state: absent 140 | loop: 141 | - "{{ koji_certs_dir }}" 142 | - "{{ registry_certs_dir }}" 143 | - "{{ certificates_dir }}" 144 | tags: 145 | - certificates 146 | 147 | - name: Delete openshift files directory 148 | file: 149 | path: "{{ openshift_files }}" 150 | state: absent 151 | tags: 152 | - openshift_files 153 | 154 | - name: Delete OSBS-Box data directory 155 | # At this point, it should only contain empty directories (if anything) 156 | file: 157 | path: "{{ osbs_box_data_dir }}" 158 | state: absent 159 | -------------------------------------------------------------------------------- /deploy.yaml: -------------------------------------------------------------------------------- 1 | - name: Generate certificates for OSBS-Box 2 | hosts: osbs_box_host 3 | tags: 4 | - certificates 5 | 6 | tasks: 7 | - name: Make sure certificate directories exist 8 | file: 9 | path: "{{ item }}" 10 | state: directory 11 | loop: 12 | - "{{ certificates_dir }}" 13 | - "{{ koji_certs_dir }}" 14 | - "{{ registry_certs_dir }}" 15 | 16 | - name: Generate certificates 17 | include_tasks: tasks/generate-certs.yaml 18 | 19 | 20 | - name: Prepare for deployment of openshift applications 21 | hosts: osbs_box_host 22 | tags: 23 | - koji 24 | - registry 25 | - namespaces 26 | - buildroot 27 | # One tag for all openshift applications 28 | - openshift 29 | 30 | tasks: 31 | - name: Login as openshift admin 32 | command: oc login -u system:admin 33 | changed_when: true 34 | 35 | - name: Make "{{ openshift_user }}" an openshift cluster admin 36 | command: oc adm policy add-cluster-role-to-user 37 | cluster-admin "{{ openshift_user }}" 38 | changed_when: true 39 | 40 | - name: Make sure directory for openshift files exists 41 | file: 42 | path: "{{ openshift_files }}" 43 | state: directory 44 | 45 | - name: Process parameters file and put it in openshift files dir 46 | template: 47 | src: openshift/params/osbs-box.env.j2 48 | dest: "{{ openshift_files }}/osbs-box.env" 49 | 50 | 51 | - name: Create all projects (namespaces) 52 | hosts: osbs_box_host 53 | gather_facts: false 54 | tags: 55 | - namespaces 56 | - openshift 57 | tasks: 58 | - name: Create the project 59 | command: oc create namespace "{{ item }}" 60 | register: create_namespace 61 | failed_when: create_namespace.rc != 0 62 | and "already exists" not in create_namespace.stderr 63 | changed_when: create_namespace.rc == 0 64 | loop: 65 | - "{{ koji_namespace }}" 66 | - "{{ registry_namespace }}" 67 | - "{{ orchestrator_namespace }}" 68 | - "{{ worker_namespace }}" 69 | 70 | 71 | - name: Set up dockerhub pull secret 72 | hosts: osbs_box_host 73 | gather_facts: false 74 | tags: 75 | - pull_secret 76 | 77 | tasks: 78 | - name: Create dockerhub pull secret 79 | no_log: true 80 | shell: 81 | set -o pipefail; 82 | oc create secret docker-registry dockerhub 83 | --docker-server=docker.io 84 | --docker-username="{{ docker_id }}" 85 | --docker-password="{{ docker_password }}" 86 | --docker-email="{{ docker_email }}" 87 | --dry-run 88 | --output json | 89 | oc --namespace "{{ item }}" replace --force -f - 90 | loop: 91 | - "{{ registry_namespace }}" 92 | - "{{ koji_namespace }}" 93 | - "{{ orchestrator_namespace }}" 94 | - "{{ worker_namespace }}" 95 | changed_when: true 96 | 97 | - name: Link dockerhub pull secret to builder service account 98 | tags: link_pull_secret 99 | command: oc --namespace "{{ item }}" secrets link builder dockerhub --for=pull 100 | loop: 101 | - "{{ registry_namespace }}" 102 | - "{{ koji_namespace }}" 103 | - "{{ orchestrator_namespace }}" 104 | - "{{ worker_namespace }}" 105 | changed_when: true 106 | 107 | 108 | - name: Run koji containers on openshift 109 | hosts: osbs_box_host 110 | gather_facts: false 111 | vars: 112 | # This is a constant, please do not override 113 | koji_components: 114 | - koji-volumes 115 | - koji-base 116 | - koji-client 117 | - koji-builder 118 | - koji-db 119 | - koji-hub 120 | tags: 121 | - koji 122 | - openshift 123 | 124 | tasks: 125 | - name: Create koji-certs secret in koji namespace 126 | shell: 127 | set -o pipefail; 128 | oc create secret generic koji-certs 129 | --from-file "{{ certificates_dir }}/osbs-box-ca.crt" 130 | --from-file "{{ koji_certs_dir }}/koji-hub.crt" 131 | --from-file "{{ koji_certs_dir }}/koji-hub.key" 132 | --from-file "{{ koji_certs_dir }}/kojiweb.pem" 133 | --from-file "{{ koji_certs_dir }}/kojibuilder.pem" 134 | --from-file "{{ koji_certs_dir }}/kojiadmin.pem" 135 | --from-file "{{ koji_certs_dir }}/kojiosbs.pem" 136 | --dry-run 137 | --output json | 138 | oc --namespace "{{ koji_namespace }}" replace --force -f - 139 | changed_when: true 140 | 141 | - name: Process koji config templates, output in openshift files dir 142 | template: 143 | src: "openshift/configs/{{ item }}.j2" 144 | dest: "{{ openshift_files }}/{{ item }}" 145 | loop: 146 | - koji-builder-osbs.conf 147 | - koji-hub-web.conf 148 | 149 | - name: Create kojiweb and osbs-client configmaps in koji namespace 150 | shell: 151 | set -o pipefail; 152 | oc create configmap "{{ item.name }}" 153 | --from-file "{{ item.dest }}={{ openshift_files }}/{{ item.src }}" 154 | --dry-run 155 | --output json | 156 | oc --namespace "{{ koji_namespace }}" replace --force -f - 157 | changed_when: true 158 | loop: 159 | - name: koji-builder-osbs 160 | src: koji-builder-osbs.conf 161 | dest: osbs.conf 162 | 163 | - name: koji-hub-web 164 | src: koji-hub-web.conf 165 | dest: web.conf 166 | 167 | - name: Copy openshift templates for koji components to openshift files dir 168 | copy: 169 | src: "openshift/templates/{{ item }}.yaml" 170 | dest: "{{ openshift_files }}/{{ item }}.yaml" 171 | loop: 172 | "{{ koji_components }}" 173 | 174 | - name: Create openshift resources for all koji components 175 | shell: 176 | set -o pipefail; 177 | oc process -f "{{ openshift_files }}/{{ item }}.yaml" 178 | --param-file "{{ openshift_files }}/osbs-box.env" 179 | --ignore-unknown-parameters | 180 | oc --namespace "{{ koji_namespace }}" apply -f - 181 | changed_when: true 182 | loop: 183 | "{{ koji_components }}" 184 | 185 | - name: Set up directories that will serve as backing storage for koji PVs 186 | file: 187 | path: "{{ item }}" 188 | state: directory 189 | setype: container_file_t 190 | loop: 191 | - "{{ koji_files_dir }}" 192 | - "{{ koji_db_data_dir }}" 193 | 194 | - name: Allow koji containers to run as any user 195 | command: 196 | oc --namespace "{{ koji_namespace }}" adm policy add-scc-to-user anyuid 197 | --serviceaccount default 198 | changed_when: true 199 | 200 | - name: Build (and automatically deploy) koji components 201 | command: oc --namespace "{{ koji_namespace }}" start-build koji-base 202 | changed_when: true 203 | 204 | 205 | - name: Run registry container on openshift 206 | hosts: osbs_box_host 207 | gather_facts: false 208 | tags: 209 | - registry 210 | - openshift 211 | 212 | tasks: 213 | - name: Create registry-cert secret in openshift 214 | shell: 215 | set -o pipefail; 216 | oc create secret generic registry-cert 217 | --from-file "{{ registry_certs_dir }}/osbs-registry.crt" 218 | --from-file "{{ registry_certs_dir }}/osbs-registry.key" 219 | --dry-run 220 | --output json | 221 | oc --namespace "{{ registry_namespace }}" replace --force -f - 222 | changed_when: true 223 | 224 | - name: Set up directory for registry PV storage 225 | file: 226 | path: "{{ registry_data_dir }}" 227 | state: directory 228 | setype: container_file_t 229 | 230 | - name: Allow registry container to run as any user 231 | command: 232 | oc --namespace "{{ registry_namespace }}" adm policy add-scc-to-user 233 | anyuid --serviceaccount default 234 | changed_when: true 235 | 236 | - name: Copy osbs-registry template to openshift files dir 237 | copy: 238 | src: openshift/templates/osbs-registry.yaml 239 | dest: "{{ openshift_files }}/osbs-registry.yaml" 240 | 241 | - name: Deploy osbs-registry 242 | shell: 243 | set -o pipefail; 244 | oc process -f "{{ openshift_files }}/osbs-registry.yaml" 245 | --param-file "{{ openshift_files }}/osbs-box.env" 246 | --ignore-unknown-parameters | 247 | oc --namespace "{{ registry_namespace }}" apply -f -; 248 | oc --namespace "{{ registry_namespace }}" rollout status dc/osbs-registry --watch=true 249 | changed_when: true 250 | 251 | - name: Completely remove dockerhub pull secret from osbs-registry project 252 | shell: 253 | set -o pipefail; 254 | oc --namespace "{{ registry_namespace }}" secrets unlink builder dockerhub; 255 | oc --namespace "{{ registry_namespace }}" delete secret dockerhub; 256 | oc --namespace "{{ registry_namespace }}" patch dc osbs-registry --type json -p '[{ "op":"remove", "path":"/spec/template/spec/imagePullSecrets" }]' 257 | changed_when: true 258 | 259 | 260 | - name: Set up OSBS orchestrator and worker projects 261 | hosts: osbs_box_host 262 | gather_facts: false 263 | vars: 264 | # This is a constant, please do not override 265 | projects: 266 | - "{{ orchestrator_namespace }}" 267 | - "{{ worker_namespace }}" 268 | tags: 269 | - osbs 270 | - openshift 271 | 272 | tasks: 273 | - name: Create kojisecret in orchestrator and worker projects 274 | shell: 275 | set -o pipefail; 276 | oc create secret generic kojisecret 277 | --from-file "cert={{ koji_certs_dir }}/kojiosbs.pem" 278 | --from-file "ca={{ certificates_dir }}/osbs-box-ca.crt" 279 | --from-file "serverca={{ certificates_dir }}/osbs-box-ca.crt" 280 | --dry-run 281 | --output json | 282 | oc --namespace "{{ item }}" replace --force -f - 283 | changed_when: true 284 | loop: 285 | "{{ projects }}" 286 | 287 | - name: Query openshift for osbs-registry IP 288 | command: oc --namespace "{{ registry_namespace }}" get svc osbs-registry 289 | --output 'jsonpath={ .spec.clusterIP }' 290 | register: registry_ip_query 291 | changed_when: false 292 | 293 | - name: Set registry_ip fact (needed for orchestrator config templates) 294 | set_fact: 295 | registry_ip: "{{ registry_ip_query.stdout }}" 296 | 297 | - name: Process orchestrator config templates, output in openshift files dir 298 | template: 299 | src: "openshift/configs/{{ item }}.j2" 300 | dest: "{{ openshift_files }}/{{ item }}" 301 | loop: 302 | - reactor-config-map.yaml 303 | - client-config-secret.conf 304 | 305 | - name: Create reactor-config-map in orchestrator namespace 306 | shell: 307 | set -o pipefail; 308 | oc create configmap reactor-config-map 309 | --from-file "config.yaml={{ openshift_files }}/reactor-config-map.yaml" 310 | --dry-run 311 | --output json | 312 | oc --namespace "{{ orchestrator_namespace }}" replace --force -f - 313 | changed_when: true 314 | 315 | - name: Create client-config-secret in orchestrator namespace 316 | shell: 317 | set -o pipefail; 318 | oc create secret generic client-config-secret 319 | --from-file "osbs.conf={{ openshift_files }}/client-config-secret.conf" 320 | --dry-run 321 | --output json | 322 | oc --namespace "{{ orchestrator_namespace }}" replace --force -f - 323 | changed_when: true 324 | 325 | - name: Add necessary roles to builder serviceaccounts 326 | command: oc --namespace "{{ item.0 }}" adm policy 327 | add-role-to-user "{{ item.1 }}" -z builder 328 | changed_when: true 329 | loop: 330 | "{{ projects | product(roles) | list }}" 331 | vars: 332 | roles: 333 | - "edit" 334 | - "system:build-strategy-custom" 335 | 336 | 337 | - name: Build OSBS buildroot 338 | hosts: osbs_box_host 339 | gather_facts: false 340 | tags: 341 | - buildroot 342 | - openshift 343 | 344 | tasks: 345 | - name: Copy osbs-buildroot template to openshift files dir 346 | copy: 347 | src: openshift/templates/osbs-buildroot.yaml 348 | dest: "{{ openshift_files }}/osbs-buildroot.yaml" 349 | 350 | - name: Create openshift resources for osbs-buildroot 351 | shell: 352 | set -o pipefail; 353 | oc process -f "{{ openshift_files }}/osbs-buildroot.yaml" 354 | --param-file "{{ openshift_files }}/osbs-box.env" 355 | --ignore-unknown-parameters | 356 | oc --namespace "{{ orchestrator_namespace }}" apply -f - 357 | changed_when: true 358 | 359 | - name: Build osbs-buildroot 360 | command: oc --namespace "{{ orchestrator_namespace }}" 361 | start-build osbs-buildroot 362 | changed_when: true 363 | -------------------------------------------------------------------------------- /docs/Fedora32.md: -------------------------------------------------------------------------------- 1 | # Fedora 32 Workstation Prerequisites 2 | 3 | ## Packages 4 | 5 | - docker 6 | - origin-clients 7 | - python-devel 8 | 9 | ## Other tweaks 10 | 11 | - Adding insecure registry setting to `/etc/sysconfig/docker` 12 | - Adding `systemd.unified_cgroup_hierarchy=0` to `/boot/efi/EFI/fedora/grubenv` 13 | 14 | *This is required due to a limitation of the docker engine (moby) available 15 | to Fedora 32 Workstation* 16 | - Rebooting after the above setting changes are made. 17 | 18 | ## Ansible Playbook 19 | 20 | `prequisite-playbooks/Fedora32-prerequisites.yaml` installs the required 21 | packages and tweaks. 22 | 23 | ### Example 24 | 25 | `> sudo ansible-playbook prequisite-playbooks/Fedora32-prerequisites.yaml 26 | -i inventory-example.yaml` 27 | 28 | ```text 29 | PLAY [Install Tools] ********************************************************* 30 | 31 | TASK [Gathering Facts] ******************************************************* 32 | ok: [localhost] 33 | 34 | TASK [enable ssh] ************************************************************ 35 | ok: [localhost] 36 | . 37 | . 38 | . 39 | ``` 40 | -------------------------------------------------------------------------------- /docs/dockerhub.md: -------------------------------------------------------------------------------- 1 | # Docker Hub README 2 | 3 | After creating an account (browse to [Docker Hub][]), you will need to add your 4 | account credentials to 'overrides.yaml'[^1] (check [group vars][] for the key names; 5 | they are 'docker_*'). 6 | 7 | *Please* do not use your actual password; instead, go to your Docker Hub 8 | [Security][] settings page, and click the "New Access Token" button to create a 9 | new token to use in place of your password. 10 | 11 | You should end up with something like 12 | 13 | ```yaml 14 | docker_id: myname 15 | docker_password: 2daf3987-fa45-4cab-365d-a454bcd365ef 16 | docker_email: me@work.ez 17 | ``` 18 | 19 | in 'overrides.yaml'. From there, proceed with 20 | `ansible-playbook deploy.yaml -i -e @overrides.yaml` 21 | 22 | --- 23 | 24 | [^1]: Create it if it doesn't exist 25 | 26 | [Docker Hub]: https://hub.docker.com 27 | [group vars]: ./group_vars/all.yaml 28 | [Security]: https://hub.docker.com/settings/security 29 | -------------------------------------------------------------------------------- /group_vars/all.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ### General settings 3 | 4 | # OSBS-Box repository and version (branch, tag or commit ID) 5 | # Used by openshift when building images 6 | osbs_box_repo: https://github.com/containerbuildsystem/osbs-box 7 | osbs_box_version: master 8 | 9 | # Directory for keeping miscellanous osbs-box data 10 | osbs_box_data_dir: "{{ ansible_env.HOME }}/.local/share/osbs-box" 11 | 12 | # URL of the host running OSBS-Box, see https://nip.io/. 13 | # External routes for OSBS-Box components will use the following scheme: 14 | # .$osbs_box_host 15 | # NOTE: 16 | # You *can* use localhost here if you are using OSBS-Box locally, however, 17 | # doing so will make external URLs unreachable from inside containers. 18 | osbs_box_host: "{{ ansible_default_ipv4.address }}.nip.io" 19 | 20 | 21 | ### Openshift settings 22 | 23 | # URL of your openshift cluster, needs to be reachable from inside containers 24 | openshift_url: "https://{{ ansible_default_ipv4.address }}:8443" 25 | 26 | # Openshift user that will be used to trigger builds (does not have to exist) 27 | # This user will be given cluster-admin privileges 28 | openshift_user: osbs 29 | openshift_password: osbs 30 | 31 | # Namespaces for various OSBS-Box pieces 32 | koji_namespace: osbs-koji 33 | orchestrator_namespace: osbs-orchestrator 34 | worker_namespace: osbs-worker 35 | registry_namespace: osbs-registry 36 | 37 | 38 | ### Repositories and versions for OSBS components 39 | atomic_reactor_repo: https://github.com/containerbuildsystem/atomic-reactor 40 | atomic_reactor_version: master 41 | 42 | osbs_client_repo: https://github.com/containerbuildsystem/osbs-client 43 | osbs_client_version: master 44 | 45 | koji_containerbuild_repo: https://github.com/containerbuildsystem/koji-containerbuild 46 | koji_containerbuild_version: master 47 | 48 | dockerfile_parse_repo: https://github.com/containerbuildsystem/dockerfile-parse 49 | dockerfile_parse_version: master 50 | 51 | dockpulp_repo: https://github.com/release-engineering/dockpulp 52 | dockpulp_version: master 53 | 54 | 55 | ### Data directories 56 | 57 | # Directory for openshift files (templates, params, configs) 58 | openshift_files: "{{ osbs_box_data_dir }}/openshift" 59 | 60 | # Directories for certificates created by OSBS-Box 61 | certificates_dir: "{{ osbs_box_data_dir }}/certificates" 62 | koji_certs_dir: "{{ certificates_dir }}/koji" 63 | registry_certs_dir: "{{ certificates_dir }}/registry" 64 | 65 | # Directories that will serve as the backing storage for persistent volumes 66 | koji_files_dir: "{{ osbs_box_data_dir }}/pv/koji-files" 67 | koji_db_data_dir: "{{ osbs_box_data_dir }}/pv/koji-db-data" 68 | registry_data_dir: "{{ osbs_box_data_dir }}/pv/registry-data" 69 | 70 | docker_id: mylogin 71 | docker_password: password-me 72 | docker_email: foo@bar.com 73 | -------------------------------------------------------------------------------- /inventory-example.ini: -------------------------------------------------------------------------------- 1 | [osbs_box_host] 2 | # OSBS-Box is intended for use with only a single host 3 | localhost ansible_connection=local 4 | -------------------------------------------------------------------------------- /koji-base/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM registry.fedoraproject.org/fedora:33 2 | 3 | # The `python` symlink is not installed by default -_- 4 | RUN dnf -y install python "python3-pip" \ 5 | && dnf clean all 6 | 7 | # Install koji, make sure docs are not excluded by unsetting tsflags 8 | # (docs include the SQL schema needed to initialize the DB) 9 | RUN dnf --setopt tsflags="" -y install "koji" \ 10 | && dnf clean all 11 | 12 | # Install git-core, it will be needed when pip-installing packages from git 13 | RUN dnf -y install "git-core" && \ 14 | dnf clean all 15 | 16 | COPY bin/ /usr/local/bin/ 17 | COPY etc/ /etc/ 18 | 19 | # By default, pip3 installs stuff in /usr/local/ 20 | ENV PIP_PREFIX="/usr" 21 | 22 | # Pip URLs for osbs-client and koji-containerbuild (git+[@]) 23 | ARG OSBS_CLIENT_PIP_REF 24 | ARG KOJI_CONTAINERBUILD_PIP_REF 25 | 26 | ENV OSBS_CLIENT_PIP_REF="$OSBS_CLIENT_PIP_REF" \ 27 | KOJI_CONTAINERBUILD_PIP_REF="$KOJI_CONTAINERBUILD_PIP_REF" 28 | -------------------------------------------------------------------------------- /koji-base/bin/add-koji-profile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # Generate a koji profile for the specified user. 5 | # 6 | # If this container cannot access koji-hub at the default hostname (koji-hub), 7 | # you should set the HUB_HOST environmental variable before running this script. 8 | # 9 | # You can also choose the list of koji cli plugins by setting the CLI_PLUGINS 10 | # environment variable (should be a space-separated list). 11 | # 12 | # After generating a profile, you can: 13 | # * `ln -s /usr/bin/koji /` and use 14 | # the symlinked binary instead of 'koji' 15 | # * `pick-koji-profile.sh ` and use the 'koji' binary as usual 16 | 17 | KOJI_USER=${1:-''} 18 | 19 | if [ ! "$KOJI_USER" ]; then 20 | echo "Please supply a username as the 1st argument" >&2 21 | exit 1 22 | fi 23 | 24 | if [ ! -e "/etc/pki/koji/$KOJI_USER.pem" ]; then 25 | echo "Client certificate for $KOJI_USER not found" >&2 26 | exit 1 27 | fi 28 | 29 | HUB_HOST=${HUB_HOST:-koji-hub} 30 | CLI_PLUGINS=${CLI_PLUGINS:-runroot} 31 | 32 | CONF_DIR=~/.koji/config.d 33 | 34 | mkdir -p "$CONF_DIR" 35 | 36 | sed -e "s;\\\$KOJI_USER;$KOJI_USER;" \ 37 | -e "s;\\\$HUB_HOST;$HUB_HOST;" \ 38 | -e "s;\\\$CLI_PLUGINS;$CLI_PLUGINS;" \ 39 | /etc/koji.conf.d/template > "$CONF_DIR/$KOJI_USER.conf" 40 | -------------------------------------------------------------------------------- /koji-base/bin/copy-kcb-plugin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | purelib=$(python -c "import sysconfig; print(sysconfig.get_path('purelib'))") 5 | 6 | # After pip-installing koji-containerbuild from git, use this script to copy 7 | # the specified plugin (cli, hub or builder) to the correct location. 8 | 9 | KCB=${purelib}"/koji_containerbuild" 10 | 11 | plugin=${1:-''} 12 | 13 | if [ ! "$plugin" ]; then 14 | echo 'Please supply name of plugin as the 1st argument' >&2 15 | exit 1 16 | fi 17 | 18 | case "$plugin" in 19 | cli) 20 | src="$KCB/plugins/cli_containerbuild.py" 21 | dest_dir=${purelib}"/koji_cli_plugins/" 22 | ;; 23 | hub|builder) 24 | src="$KCB/plugins/${plugin}_containerbuild.py" 25 | dest_dir="/usr/lib/koji-$plugin-plugins/" 26 | ;; 27 | *) 28 | echo "ERROR: unkown plugin: $plugin" >&2 29 | echo "Available plugins: cli, hub, builder" >&2 30 | exit 1 31 | ;; 32 | esac 33 | 34 | if [ ! -e "$src" ]; then 35 | echo "ERROR: could not find $plugin plugin in $KCB" >&2 36 | exit 1 37 | fi 38 | 39 | mkdir -p "$dest_dir" 40 | cp "$src" "$dest_dir" 41 | echo "Succesfully copied $src to $dest_dir" 42 | -------------------------------------------------------------------------------- /koji-base/bin/moshimoshi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # Call koji hello in a loop until it succeeds. 5 | # 6 | # Use in containers that depend on koji-hub and koji-db being ready. 7 | 8 | attempts=0 9 | 10 | while true; do 11 | (( attempts+=1 )) 12 | echo "koji hello attempt #$attempts" 13 | 14 | if timeout 2 koji hello; then 15 | echo "Success!" 16 | break 17 | elif [ $? = 124 ]; then 18 | echo "Timed out, the hub or database pods are likely still starting." 19 | fi 20 | 21 | sleep 3 22 | done 23 | -------------------------------------------------------------------------------- /koji-base/bin/pick-koji-profile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # Pick a koji profile to be used by the default koji command. 5 | 6 | KOJI_USER=${1:-''} 7 | 8 | if [ ! "$KOJI_USER" ]; then 9 | echo "Please supply a username as the 1st argument" >&2 10 | exit 1 11 | fi 12 | 13 | CONF_DIR=~/.koji/config.d 14 | 15 | if [ ! -e "$CONF_DIR/$KOJI_USER.conf" ]; then 16 | echo "The $KOJI_USER koji profile does not seem to exist" >&2 17 | echo "Please run add-koji-profile.sh '$KOJI_USER' and try again" >&2 18 | exit 1 19 | fi 20 | 21 | sed "s/\\[$KOJI_USER\\]/[koji]/" \ 22 | "$CONF_DIR/$KOJI_USER.conf" > ~/.koji/config 23 | -------------------------------------------------------------------------------- /koji-base/etc/koji.conf.d/template: -------------------------------------------------------------------------------- 1 | [$KOJI_USER] 2 | 3 | ;configuration for koji cli tool 4 | 5 | ;url of XMLRPC server 6 | server = https://$HUB_HOST/kojihub 7 | 8 | ;url of web interface 9 | weburl = https://$HUB_HOST/koji 10 | 11 | ;url of package download site 12 | topurl = https://$HUB_HOST/kojifiles 13 | 14 | ;configuration for SSL authentication 15 | authtype = ssl 16 | 17 | ;client certificate 18 | cert = /etc/pki/koji/$KOJI_USER.pem 19 | 20 | ;certificate of the CA that issued the HTTP server certificate 21 | serverca = /etc/pki/koji/osbs-box-ca.crt 22 | 23 | ;plugin paths, separated by ':' as the same as the shell's PATH 24 | ;koji_cli_plugins module and ~/.koji/plugins are always loaded in advance, 25 | ;and then be overridden by this option 26 | ;plugin_paths = ~/.koji/plugins 27 | 28 | ;[not_implemented_yet] 29 | ;enabled plugins for CLI, runroot and save_failed_tree are available 30 | ;runroot plugin is enabled by default in fedora 31 | plugins = $CLI_PLUGINS 32 | 33 | ;timeout of XMLRPC requests by seconds, default: 60 * 60 * 12 = 43200 34 | ;timeout = 43200 35 | 36 | ;timeout of GSSAPI/SSL authentication by seconds, default: 60 37 | ;auth_timeout = 60 38 | 39 | ;use the fast upload feature of koji by default 40 | use_fast_upload = yes 41 | -------------------------------------------------------------------------------- /koji-base/etc/pki/koji/README.txt: -------------------------------------------------------------------------------- 1 | This directory will be populated by openshift during build. 2 | -------------------------------------------------------------------------------- /koji-builder/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM osbs-box/koji-base 2 | 3 | # Install koji builder components including 4 | # the containerbuild plugin and osbs-client 5 | RUN dnf -y install "koji-builder" \ 6 | "koji-containerbuild-builder" \ 7 | "osbs-client" && \ 8 | dnf clean all 9 | 10 | # Update osbs-client and koji-containerbuild, 11 | # copy the builder plugin to the right location 12 | RUN pip3 --no-cache-dir install -U "$OSBS_CLIENT_PIP_REF" && \ 13 | pip3 --no-cache-dir install -U "$KOJI_CONTAINERBUILD_PIP_REF" && \ 14 | copy-kcb-plugin.sh "builder" 15 | 16 | COPY bin/ /usr/local/bin/ 17 | COPY etc/ /etc/ 18 | 19 | RUN add-koji-profile.sh "kojiadmin" && \ 20 | pick-koji-profile.sh "kojiadmin" 21 | 22 | ENTRYPOINT ["entrypoint.sh"] 23 | CMD ["kojid", "--fg", "--force-lock", "--verbose"] 24 | -------------------------------------------------------------------------------- /koji-builder/bin/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # Wait for up to a minute until koji is ready 5 | if ! timeout 60 moshimoshi.sh; then 6 | echo "Koji still not ready after 60s, something might be wrong." >&2 7 | exit 124 8 | fi 9 | 10 | # Set up koji 11 | koji-setup.sh 12 | 13 | exec "$@" 14 | -------------------------------------------------------------------------------- /koji-builder/bin/koji-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # All of the koji setup necessary for running basic container builds. 5 | 6 | check_result() { 7 | expected_err_msg=$1 8 | shift 9 | 10 | set +e 11 | output=$("$@" 2>&1) 12 | rv=$? 13 | set -e 14 | 15 | if [ $rv == 0 ]; then 16 | echo "$output" 17 | return 0 18 | elif grep -q -- "$expected_err_msg" <<< "$output"; then 19 | echo "$expected_err_msg" 20 | return 0 21 | else 22 | echo "$output" >&2 23 | return $rv 24 | fi 25 | } 26 | 27 | check_result 'kojibuilder is already in the database' \ 28 | koji add-host kojibuilder x86_64 29 | 30 | check_result 'host kojibuilder is already subscribed to the container channel' \ 31 | koji add-host-to-channel kojibuilder container --new 32 | 33 | check_result "A tag with the name 'build' already exists" \ 34 | koji add-tag build --arches=x86_64 35 | check_result "A tag with the name 'dest' already exists" \ 36 | koji add-tag dest --arches=x86_64 37 | 38 | check_result "A build target with the name 'candidate' already exists" \ 39 | koji add-target candidate build dest 40 | 41 | check_result 'Package osbs-buildroot-docker already exists in tag dest' \ 42 | koji add-pkg dest osbs-buildroot-docker --owner kojiadmin 43 | check_result 'Package docker-hello-world already exists in tag dest' \ 44 | koji add-pkg dest docker-hello-world --owner kojiadmin 45 | 46 | check_result 'Package docker-hello-world-source already exists in tag dest' \ 47 | koji add-pkg dest docker-hello-world-source --owner kojiadmin 48 | 49 | check_result 'btype already exists' \ 50 | koji call addBType operator-manifests 51 | 52 | check_result 'btype already exists' \ 53 | koji call addBType remote-sources 54 | 55 | check_result "user already exists: kojiosbs" \ 56 | koji add-user kojiosbs 57 | 58 | check_result 'User already has access to content generator atomic-reactor' \ 59 | koji grant_cg_access kojiosbs atomic-reactor 60 | 61 | check_result 'User already has access to content generator atomic-reactor' \ 62 | koji grant_cg_access kojiadmin atomic-reactor 63 | -------------------------------------------------------------------------------- /koji-builder/etc/kojid/kojid.conf: -------------------------------------------------------------------------------- 1 | [kojid] 2 | ; The number of seconds to sleep between tasks 3 | ; sleeptime=15 4 | 5 | ; The maximum number of jobs that kojid will handle at a time 6 | ; maxjobs=10 7 | 8 | ; The minimum amount of free space (in MBs) required for each build root 9 | minspace=256 10 | 11 | ; The directory root where work data can be found from the koji hub 12 | ; topdir=/mnt/koji 13 | 14 | ; The user to run as when doing builds 15 | ; mockuser=kojibuilder 16 | 17 | ; Timeout for build duration (24 hours) 18 | ; rpmbuild_timeout=86400 19 | 20 | ; The URL for the xmlrpc server 21 | server=https://koji-hub/kojihub 22 | 23 | ; The URL for the file access 24 | topurl=https://koji-hub/kojifiles 25 | 26 | ; A space-separated list of tuples from which kojid is allowed to checkout. 27 | ; The format of those tuples is: 28 | ; 29 | ; host:repository[:use_common[:source_cmd]] 30 | ; 31 | ; Incorrectly-formatted tuples will be ignored. 32 | ; 33 | ; If use_common is not present, kojid will attempt to checkout a common/ 34 | ; directory from the repository. If use_common is set to no, off, false, or 0, 35 | ; it will not attempt to checkout a common/ directory. 36 | ; 37 | ; source_cmd is a shell command (args separated with commas instead of spaces) 38 | ; to run before building the srpm. It is generally used to retrieve source 39 | ; files from a remote location. If no source_cmd is specified, "make sources" 40 | ; is run by default. 41 | allowed_scms= 42 | pkgs.fedoraproject.org:/*:no:--enable-network,fedpkg,sources 43 | *:/*:no 44 | 45 | ; Configuration for SSL authentication 46 | 47 | ; Client certificate 48 | cert = /etc/pki/koji/kojibuilder.pem 49 | 50 | ; Certificate of the CA that issued the HTTP server certificate 51 | serverca = /etc/pki/koji/osbs-box-ca.crt 52 | 53 | ; Space-separated list of builder plugins which should be enabled. 54 | plugins=builder_containerbuild 55 | 56 | ; If set to True, failing subtask will not automatically cancel other siblings 57 | ; build_arch_can_fail = False 58 | 59 | ; If set to True additional logs with timestamps will get created and uploaded 60 | ; to hub. It could be useful for debugging purposes, but creates twice as many 61 | ; log files 62 | ; log_timestamps = False 63 | -------------------------------------------------------------------------------- /koji-builder/etc/osbs.conf: -------------------------------------------------------------------------------- 1 | # This is a placeholder, it will be replaced by OpenShift during build 2 | -------------------------------------------------------------------------------- /koji-client/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM osbs-box/koji-base 2 | 3 | # Install koji-containerbuild cli plugin 4 | RUN dnf install -y "python3-koji-containerbuild-cli" && \ 5 | dnf clean all 6 | 7 | # Update koji-containerbuild and copy the cli plugin to the right location 8 | RUN pip3 --no-cache-dir install -U "$KOJI_CONTAINERBUILD_PIP_REF" && \ 9 | copy-kcb-plugin.sh "cli" 10 | 11 | COPY bin/ /usr/local/bin/ 12 | 13 | ENV CLI_PLUGINS="runroot cli_containerbuild" 14 | 15 | RUN add-koji-profile.sh "kojiadmin" && \ 16 | pick-koji-profile.sh "kojiadmin" 17 | 18 | ENTRYPOINT ["entrypoint.sh"] 19 | CMD ["sleep", "infinity"] 20 | -------------------------------------------------------------------------------- /koji-client/bin/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # Wait for up to a minute until koji is ready 5 | if ! timeout 60 moshimoshi.sh; then 6 | echo "Koji still not ready after 60s, something might be wrong." >&2 7 | exit 124 8 | fi 9 | 10 | exec "$@" 11 | -------------------------------------------------------------------------------- /koji-db/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker.io/postgres:12 2 | 3 | EXPOSE 5432 4 | 5 | ENV POSTGRES_DB="koji" \ 6 | POSTGRES_USER="koji" \ 7 | POSTGRES_PASSWORD="mypassword" 8 | 9 | # Add database initialization scripts 10 | # They will be executed automatically, in alphabetical order 11 | COPY sql-init/ /docker-entrypoint-initdb.d/ 12 | 13 | # The base schema is taken from koji-base and injected during build by openshift 14 | RUN mv /docker-entrypoint-initdb.d/schema.sql \ 15 | /docker-entrypoint-initdb.d/00-schema.sql 16 | -------------------------------------------------------------------------------- /koji-db/sql-init/10-kojiadmin.sql: -------------------------------------------------------------------------------- 1 | 2 | -- Create 'kojiadmin' account 3 | INSERT INTO users (name, usertype, status) VALUES ('kojiadmin', 0, 0); 4 | 5 | -- Make kojiadmin an actual admin 6 | INSERT INTO user_perms (user_id, perm_id, creator_id) 7 | SELECT users.id, permissions.id, users.id FROM users, permissions 8 | WHERE users.name = 'kojiadmin' 9 | AND permissions.name = 'admin'; 10 | -------------------------------------------------------------------------------- /koji-db/sql-init/20-atomic-reactor.sql: -------------------------------------------------------------------------------- 1 | 2 | INSERT INTO content_generator (id, name) VALUES (1, 'atomic-reactor') 3 | -------------------------------------------------------------------------------- /koji-hub/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM osbs-box/koji-base 2 | 3 | EXPOSE 80 443 4 | 5 | # Install koji-hub components including the containerbuild plugin 6 | RUN dnf -y install "httpd" \ 7 | "mod_ssl" \ 8 | "koji-hub" \ 9 | "koji-web" \ 10 | "koji-containerbuild-hub" && \ 11 | dnf clean all 12 | 13 | # Update koji-containerbuild and copy the hub plugin to the right location 14 | RUN pip3 --no-cache-dir install -U "$KOJI_CONTAINERBUILD_PIP_REF" && \ 15 | copy-kcb-plugin.sh "hub" 16 | 17 | # Certificates are mode 0600 and owned by root, apache needs read access too 18 | RUN chown -R :apache /etc/pki/koji/ && \ 19 | chmod -R g+r /etc/pki/koji/ 20 | 21 | COPY bin/ /usr/local/bin/ 22 | COPY etc/ /etc/ 23 | 24 | ENV HUB_HOST="localhost" 25 | 26 | RUN add-koji-profile.sh "kojiadmin" && \ 27 | pick-koji-profile.sh "kojiadmin" 28 | 29 | ENTRYPOINT ["entrypoint.sh"] 30 | CMD ["httpd", "-D", "FOREGROUND"] 31 | -------------------------------------------------------------------------------- /koji-hub/bin/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # Create basic directory structure for koji and change the owner to apache 5 | # Has to be done at runtime because the /mnt/koji/ directory is mounted 6 | mkdir -p /mnt/koji/{packages,repos,work,scratch} 7 | chown -R apache:apache /mnt/koji 8 | 9 | exec "$@" 10 | -------------------------------------------------------------------------------- /koji-hub/bin/koji-steal-build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import argparse 3 | import json 4 | import koji 5 | import os 6 | import requests 7 | import subprocess 8 | import hashlib 9 | 10 | 11 | DEFAULT_DOWNLOAD_BLOCK_SIZE = 10 * 1024 * 1024 # 10Mb 12 | 13 | DEFAULT_OUTPUT_DIR = '/mnt/koji/work/build-stealer' 14 | 15 | 16 | class BuildStealer(): 17 | 18 | def __init__(self, nvr, kojihub, kojiroot): 19 | self.nvr = nvr 20 | self.pathinfo = koji.PathInfo(topdir=kojiroot) 21 | self.session = koji.ClientSession(kojihub) 22 | 23 | self.output_dir = os.path.join(DEFAULT_OUTPUT_DIR, nvr) 24 | 25 | self.build_info = None 26 | self.build_metadata = None 27 | self.build_metadata_url = None 28 | 29 | def start(self): 30 | self.get_build_info() 31 | self.get_build_metadata() 32 | self.download_build_files() 33 | self.import_build() 34 | 35 | def get_build_info(self): 36 | self.build_info = self.session.getBuild(self.nvr, strict=True) 37 | 38 | def get_build_metadata(self): 39 | self.build_metadata_url = os.path.join(self.pathinfo.build(self.build_info), 40 | 'metadata.json') 41 | response = requests.get(self.build_metadata_url) 42 | response.raise_for_status() 43 | self.build_metadata = response.json() 44 | self.build_metadata['build']['build_id'] = '' 45 | 46 | def download_build_files(self): 47 | if not os.path.exists(self.output_dir): 48 | os.makedirs(self.output_dir) 49 | 50 | for output in self.build_metadata['output']: 51 | url, dest = self._resolve_file_download(output) 52 | print('Downloading {}'.format(output['filename'])) 53 | self._download_file(url, dest, output['checksum']) 54 | 55 | def _resolve_file_download(self, output): 56 | dest_path = os.path.join(self.output_dir, output['filename']) 57 | 58 | url_bases = { 59 | 'log': self.pathinfo.build_logs, 60 | 'docker-image': self.pathinfo.imagebuild, 61 | } 62 | url_base = url_bases[output['type']](self.build_info) 63 | url = os.path.join(url_base, output['filename']) 64 | 65 | return (url, dest_path) 66 | 67 | def import_build(self): 68 | metadata_filename = 'metadata-{}.json'.format(self.nvr) 69 | metadata_path = os.path.join(self.output_dir, metadata_filename) 70 | with open(metadata_path, mode='w') as metajsonfile: 71 | metajsonfile.write(json.dumps(self.build_metadata)) 72 | 73 | # We should probably create a new koji session with local defaults 74 | # instead of calling the koji process 75 | # FYI: For unknown reasons, the logs don't appear in final build 76 | print('Importing build {}'.format(metadata_filename)) 77 | subprocess.call([ 78 | '/usr/bin/koji', 'import-cg', '--link', metadata_path, self.output_dir 79 | ]) 80 | 81 | def _download_file(self, url, dest, expected_checksum=None): 82 | # Upstream koji stores an MD5 hash, so that's what we're required to compare to 83 | checksum = hashlib.md5() # noqa: DUO130, S303 84 | request = requests.get(url, stream=True) 85 | request.raise_for_status() 86 | 87 | with open(dest, 'wb') as f: 88 | for chunk in request.iter_content(chunk_size=DEFAULT_DOWNLOAD_BLOCK_SIZE): 89 | f.write(chunk) 90 | checksum.update(chunk) 91 | 92 | if expected_checksum and checksum.hexdigest() != expected_checksum: 93 | raise ValueError( 94 | 'Computed md5 checksum, {}, does not match expected checksum, {}' 95 | .format(checksum.hexdigest(), expected_checksum)) 96 | 97 | 98 | def parse_args(): 99 | parser = argparse.ArgumentParser( 100 | description="Take a build from another Koji instance and load it here.") 101 | 102 | parser.add_argument('nvr', help='Name-Version-Release of build to be moved') 103 | parser.add_argument('--kojihub', required=True, help='Koji Hub API to pull build from') 104 | parser.add_argument('--kojiroot', required=True, help='Koji Top Dir to pull build from') 105 | 106 | return parser.parse_args() 107 | 108 | 109 | if __name__ == '__main__': 110 | args = parse_args() 111 | BuildStealer(args.nvr, args.kojihub, args.kojiroot).start() 112 | -------------------------------------------------------------------------------- /koji-hub/etc/httpd/conf.d/kojihub.conf: -------------------------------------------------------------------------------- 1 | # 2 | # koji-hub is an xmlrpc interface to the Koji database 3 | # 4 | 5 | Alias /kojihub /usr/share/koji-hub/kojixmlrpc.py 6 | 7 | 8 | Options ExecCGI 9 | SetHandler wsgi-script 10 | WSGIApplicationGroup %{GLOBAL} 11 | # ^ works around a hub issue with OpenSSL 12 | # see: https://cryptography.io/en/latest/faq/#starting-cryptography-using-mod-wsgi-produces-an-internalerror-during-a-call-in-register-osrandom-engine 13 | WSGIScriptReloading Off 14 | # ^ reloading breaks hub "firstcall" check 15 | # see: https://pagure.io/koji/issue/875 16 | 17 | Order allow,deny 18 | Allow from all 19 | 20 | = 2.4> 21 | Require all granted 22 | 23 | 24 | 25 | # Also serve /mnt/koji 26 | Alias /kojifiles "/mnt/koji/" 27 | 28 | 29 | Options Indexes SymLinksIfOwnerMatch 30 | # If your top /mnt/koji directory is not owned by the httpd user, then 31 | # you will need to follow all symlinks instead, e.g. 32 | # Options Indexes FollowSymLinks 33 | AllowOverride None 34 | IndexOptions +NameWidth=* 35 | 36 | Order allow,deny 37 | Allow from all 38 | 39 | = 2.4> 40 | Require all granted 41 | 42 | 43 | 44 | # Enable authentication via SSL client certificates 45 | 46 | SSLVerifyClient require 47 | SSLVerifyDepth 10 48 | SSLOptions +StdEnvVars 49 | 50 | -------------------------------------------------------------------------------- /koji-hub/etc/httpd/conf.d/kojiweb.conf: -------------------------------------------------------------------------------- 1 | # We use wsgi by default 2 | Alias /koji "/usr/share/koji-web/scripts/wsgi_publisher.py" 3 | # (configuration goes in /etc/kojiweb/web.conf) 4 | 5 | # Do not show the default welcome page, instead redirect to /koji 6 | RedirectMatch "^/+$" /koji 7 | 8 | # Python 3 Cheetah expectes unicode everywhere, apache's default lang is C 9 | # which is not sufficient to open our templates 10 | WSGIDaemonProcess koji lang=C.UTF-8 11 | WSGIProcessGroup koji 12 | 13 | 14 | Options ExecCGI 15 | SetHandler wsgi-script 16 | WSGIApplicationGroup %{GLOBAL} 17 | # ^ works around an OpenSSL issue 18 | # see: https://cryptography.io/en/latest/faq/#starting-cryptography-using-mod-wsgi-produces-an-internalerror-during-a-call-in-register-osrandom-engine 19 | 20 | Order allow,deny 21 | Allow from all 22 | 23 | = 2.4> 24 | Require all granted 25 | 26 | 27 | 28 | # Enable authentication via SSL client certificates 29 | 30 | SSLVerifyClient require 31 | SSLVerifyDepth 10 32 | SSLOptions +StdEnvVars 33 | 34 | 35 | Alias /koji-static/ "/usr/share/koji-web/static/" 36 | 37 | 38 | Options None 39 | AllowOverride None 40 | 41 | Order allow,deny 42 | Allow from all 43 | 44 | = 2.4> 45 | Require all granted 46 | 47 | 48 | -------------------------------------------------------------------------------- /koji-hub/etc/httpd/conf.d/servername.conf: -------------------------------------------------------------------------------- 1 | ServerName koji-hub:80 2 | -------------------------------------------------------------------------------- /koji-hub/etc/httpd/conf.d/ssl.conf: -------------------------------------------------------------------------------- 1 | # 2 | # When we also provide SSL we have to listen to the 3 | # standard HTTPS port in addition. 4 | # 5 | Listen 443 https 6 | 7 | ## 8 | ## SSL Global Context 9 | ## 10 | ## All SSL configuration in this context applies both to 11 | ## the main server and all SSL-enabled virtual hosts. 12 | ## 13 | 14 | # Pass Phrase Dialog: 15 | # Configure the pass phrase gathering process. 16 | # The filtering dialog program (`builtin' is a internal 17 | # terminal dialog) has to provide the pass phrase on stdout. 18 | SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog 19 | 20 | # Inter-Process Session Cache: 21 | # Configure the SSL Session Cache: First the mechanism 22 | # to use and second the expiring timeout (in seconds). 23 | SSLSessionCache shmcb:/run/httpd/sslcache(512000) 24 | SSLSessionCacheTimeout 300 25 | 26 | # Pseudo Random Number Generator (PRNG): 27 | # Configure one or more sources to seed the PRNG of the 28 | # SSL library. The seed data should be of good random quality. 29 | # WARNING! On some platforms /dev/random blocks if not enough entropy 30 | # is available. This means you then cannot use the /dev/random device 31 | # because it would lead to very long connection times (as long as 32 | # it requires to make more entropy available). But usually those 33 | # platforms additionally provide a /dev/urandom device which doesn't 34 | # block. So, if available, use this one instead. Read the mod_ssl User 35 | # Manual for more details. 36 | SSLRandomSeed startup file:/dev/urandom 256 37 | SSLRandomSeed connect builtin 38 | #SSLRandomSeed startup file:/dev/random 512 39 | #SSLRandomSeed connect file:/dev/random 512 40 | #SSLRandomSeed connect file:/dev/urandom 512 41 | 42 | # 43 | # Use "SSLCryptoDevice" to enable any supported hardware 44 | # accelerators. Use "openssl engine -v" to list supported 45 | # engine names. NOTE: If you enable an accelerator and the 46 | # server does not start, consult the error logs and ensure 47 | # your accelerator is functioning properly. 48 | # 49 | SSLCryptoDevice builtin 50 | #SSLCryptoDevice ubsec 51 | 52 | ## 53 | ## SSL Virtual Host Context 54 | ## 55 | 56 | 57 | 58 | # General setup for the virtual host, inherited from global configuration 59 | #DocumentRoot "/var/www/html" 60 | ### OSBS-Box 61 | ServerName koji-hub:443 62 | 63 | # Use separate log files for the SSL virtual host; note that LogLevel 64 | # is not inherited from httpd.conf. 65 | ErrorLog logs/ssl_error_log 66 | TransferLog logs/ssl_access_log 67 | ### OSBS-Box (more logs, always useful for debugging) 68 | LogLevel debug 69 | 70 | # SSL Engine Switch: 71 | # Enable/Disable SSL for this virtual host. 72 | SSLEngine on 73 | 74 | # List the protocol versions which clients are allowed to connect with. 75 | # The OpenSSL system profile is configured by default. See 76 | # update-crypto-policies(8) for more details. 77 | ### OSBS-Box (force TLSv1.2 because Python is not fully compatible with TLSv1.3) 78 | SSLProtocol TLSv1.2 79 | 80 | # User agents such as web browsers are not configured for the user's 81 | # own preference of either security or performance, therefore this 82 | # must be the prerogative of the web server administrator who manages 83 | # cpu load versus confidentiality, so enforce the server's cipher order. 84 | SSLHonorCipherOrder on 85 | 86 | # SSL Cipher Suite: 87 | # List the ciphers that the client is permitted to negotiate. 88 | # See the mod_ssl documentation for a complete list. 89 | # The OpenSSL system profile is configured by default. See 90 | # update-crypto-policies(8) for more details. 91 | SSLCipherSuite PROFILE=SYSTEM 92 | SSLProxyCipherSuite PROFILE=SYSTEM 93 | 94 | # Point SSLCertificateFile at a PEM encoded certificate. If 95 | # the certificate is encrypted, then you will be prompted for a 96 | # pass phrase. Note that restarting httpd will prompt again. Keep 97 | # in mind that if you have both an RSA and a DSA certificate you 98 | # can configure both in parallel (to also allow the use of DSA 99 | # ciphers, etc.) 100 | # Some ECC cipher suites (http://www.ietf.org/rfc/rfc4492.txt) 101 | # require an ECC certificate which can also be configured in 102 | # parallel. 103 | ### OSBS-Box 104 | SSLCertificateFile /etc/pki/koji/koji-hub.crt 105 | 106 | # Server Private Key: 107 | # If the key is not combined with the certificate, use this 108 | # directive to point at the key file. Keep in mind that if 109 | # you've both a RSA and a DSA private key you can configure 110 | # both in parallel (to also allow the use of DSA ciphers, etc.) 111 | # ECC keys, when in use, can also be configured in parallel 112 | ### OSBS-Box 113 | SSLCertificateKeyFile /etc/pki/koji/koji-hub.key 114 | 115 | # Server Certificate Chain: 116 | # Point SSLCertificateChainFile at a file containing the 117 | # concatenation of PEM encoded CA certificates which form the 118 | # certificate chain for the server certificate. Alternatively 119 | # the referenced file can be the same as SSLCertificateFile 120 | # when the CA certificates are directly appended to the server 121 | # certificate for convenience. 122 | ### OSBS-Box 123 | SSLCertificateChainFile /etc/pki/koji/osbs-box-ca.crt 124 | 125 | # Certificate Authority (CA): 126 | # Set the CA certificate verification path where to find CA 127 | # certificates for client authentication or alternatively one 128 | # huge file containing all of them (file must be PEM encoded) 129 | ### OSBS-Box 130 | SSLCACertificateFile /etc/pki/koji/osbs-box-ca.crt 131 | 132 | # Client Authentication (Type): 133 | # Client certificate verification type and depth. Types are 134 | # none, optional, require and optional_no_ca. Depth is a 135 | # number which specifies how deeply to verify the certificate 136 | # issuer chain before deciding the certificate is not valid. 137 | #SSLVerifyClient require 138 | #SSLVerifyDepth 10 139 | 140 | # Access Control: 141 | # With SSLRequire you can do per-directory access control based 142 | # on arbitrary complex boolean expressions containing server 143 | # variable checks and other lookup directives. The syntax is a 144 | # mixture between C and Perl. See the mod_ssl documentation 145 | # for more details. 146 | # 147 | #SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \ 148 | # and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \ 149 | # and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \ 150 | # and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \ 151 | # and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \ 152 | # or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/ 153 | # 154 | 155 | # SSL Engine Options: 156 | # Set various options for the SSL engine. 157 | # o FakeBasicAuth: 158 | # Translate the client X.509 into a Basic Authorisation. This means that 159 | # the standard Auth/DBMAuth methods can be used for access control. The 160 | # user name is the `one line' version of the client's X.509 certificate. 161 | # Note that no password is obtained from the user. Every entry in the user 162 | # file needs this password: `xxj31ZMTZzkVA'. 163 | # o ExportCertData: 164 | # This exports two additional environment variables: SSL_CLIENT_CERT and 165 | # SSL_SERVER_CERT. These contain the PEM-encoded certificates of the 166 | # server (always existing) and the client (only existing when client 167 | # authentication is used). This can be used to import the certificates 168 | # into CGI scripts. 169 | # o StdEnvVars: 170 | # This exports the standard SSL/TLS related `SSL_*' environment variables. 171 | # Per default this exportation is switched off for performance reasons, 172 | # because the extraction step is an expensive operation and is usually 173 | # useless for serving static content. So one usually enables the 174 | # exportation for CGI and SSI requests only. 175 | # o StrictRequire: 176 | # This denies access when "SSLRequireSSL" or "SSLRequire" applied even 177 | # under a "Satisfy any" situation, i.e. when it applies access is denied 178 | # and no other module can change it. 179 | # o OptRenegotiate: 180 | # This enables optimized SSL connection renegotiation handling when SSL 181 | # directives are used in per-directory context. 182 | #SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire 183 | 184 | SSLOptions +StdEnvVars 185 | 186 | 187 | SSLOptions +StdEnvVars 188 | 189 | 190 | # SSL Protocol Adjustments: 191 | # The safe and default but still SSL/TLS standard compliant shutdown 192 | # approach is that mod_ssl sends the close notify alert but doesn't wait for 193 | # the close notify alert from client. When you need a different shutdown 194 | # approach you can use one of the following variables: 195 | # o ssl-unclean-shutdown: 196 | # This forces an unclean shutdown when the connection is closed, i.e. no 197 | # SSL close notify alert is sent or allowed to be received. This violates 198 | # the SSL/TLS standard but is needed for some brain-dead browsers. Use 199 | # this when you receive I/O errors because of the standard approach where 200 | # mod_ssl sends the close notify alert. 201 | # o ssl-accurate-shutdown: 202 | # This forces an accurate shutdown when the connection is closed, i.e. a 203 | # SSL close notify alert is sent and mod_ssl waits for the close notify 204 | # alert of the client. This is 100% SSL/TLS standard compliant, but in 205 | # practice often causes hanging connections with brain-dead browsers. Use 206 | # this only for browsers where you know that their SSL implementation 207 | # works correctly. 208 | # Notice: Most problems of broken clients are also related to the HTTP 209 | # keep-alive facility, so you usually additionally want to disable 210 | # keep-alive for those clients, too. Use variable "nokeepalive" for this. 211 | # Similarly, one has to force some clients to use HTTP/1.0 to workaround 212 | # their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and 213 | # "force-response-1.0" for this. 214 | BrowserMatch "MSIE [2-5]" \ 215 | nokeepalive ssl-unclean-shutdown \ 216 | downgrade-1.0 force-response-1.0 217 | 218 | # Per-Server Logging: 219 | # The home of a custom SSL log file. Use this when you want a 220 | # compact non-error SSL logfile on a virtual host basis. 221 | CustomLog logs/ssl_request_log \ 222 | "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" 223 | 224 | 225 | -------------------------------------------------------------------------------- /koji-hub/etc/httpd/conf.d/test-accessories.conf: -------------------------------------------------------------------------------- 1 | # This location currently does not exist, that may change in the future. 2 | Alias /clients /opt/koji-clients 3 | 4 | 5 | Options Indexes 6 | 7 | Order allow,deny 8 | Allow from all 9 | 10 | = 2.4> 11 | Require all granted 12 | 13 | 14 | 15 | Alias /httpd /etc/httpd 16 | 17 | 18 | Options Indexes 19 | 20 | Order allow,deny 21 | Allow from all 22 | 23 | = 2.4> 24 | Require all granted 25 | 26 | 27 | 28 | Alias /logs /var/log 29 | 30 | 31 | Options Indexes 32 | 33 | Order allow,deny 34 | Allow from all 35 | 36 | = 2.4> 37 | Require all granted 38 | 39 | 40 | -------------------------------------------------------------------------------- /koji-hub/etc/koji-hub/hub.conf: -------------------------------------------------------------------------------- 1 | [hub] 2 | 3 | ## ConfigParser style config file, similar to ini files 4 | ## https://docs.python.org/library/configparser.html 5 | ## 6 | ## Note that multiline values can be set by indenting subsequent lines 7 | ## (which means you should not indent regular lines) 8 | 9 | ## Basic options ## 10 | DBName = koji 11 | DBUser = koji 12 | DBHost = koji-db 13 | DBPort = 5432 14 | DBPass = mypassword 15 | KojiDir = /mnt/koji 16 | 17 | 18 | ## SSL client certificate auth configuration ## 19 | # note: ssl auth may also require editing the httpd config (conf.d/kojihub.conf) 20 | 21 | ## the client username is the common name of the subject of their client certificate 22 | DNUsernameComponent = CN 23 | ## separate multiple DNs with | 24 | ProxyDNs = CN=kojiweb 25 | 26 | ## end SSL client certificate auth configuration 27 | 28 | 29 | ## Other options ## 30 | LoginCreatesUser = On 31 | KojiWebURL = http://localhost/koji 32 | ## The domain name that will be appended to Koji usernames 33 | ## when creating email notifications 34 | # EmailDomain = example.com 35 | ## whether to send the task owner and package owner email or not on success. this still goes to watchers 36 | NotifyOnSuccess = False 37 | ## Disables all notifications 38 | DisableNotifications = True 39 | 40 | ## Extended features 41 | ## Support Maven builds 42 | # EnableMaven = False 43 | ## Support Windows builds 44 | # EnableWin = False 45 | ## TODO: These were True in the old Box, was there a reason for that? 46 | 47 | ## Koji hub plugins 48 | ## The path where plugins are found 49 | # PluginPath = /usr/lib/koji-hub-plugins 50 | ## A space-separated list of plugins to load 51 | Plugins = hub_containerbuild 52 | 53 | ## If KojiDebug is on, the hub will be /very/ verbose and will report exception 54 | ## details to clients for anticipated errors (i.e. koji's own exceptions -- 55 | ## subclasses of koji.GenericError). 56 | KojiDebug = On 57 | 58 | ## Determines how much detail about exceptions is reported to the client (via faults) 59 | ## Meaningful values: 60 | ## normal - a basic traceback (format_exception) 61 | ## extended - an extended traceback (format_exc_plus) 62 | ## anything else - no traceback, just the error message 63 | ## The extended traceback is intended for debugging only and should NOT be 64 | ## used in production, since it may contain sensitive information. 65 | KojiTraceback = extended 66 | -------------------------------------------------------------------------------- /koji-hub/etc/kojiweb/web.conf: -------------------------------------------------------------------------------- 1 | # This is a placeholder, it will be replaced by OpenShift during build 2 | -------------------------------------------------------------------------------- /openshift/configs/client-config-secret.conf.j2: -------------------------------------------------------------------------------- 1 | [general] 2 | build_json_dir = /usr/share/osbs/ 3 | 4 | [worker] 5 | openshift_url = {{ openshift_url }} 6 | namespace = {{ worker_namespace }} 7 | use_auth = true 8 | use_kerberos = false 9 | verify_ssl = false 10 | username = {{ openshift_user }} 11 | password = {{ openshift_password }} 12 | -------------------------------------------------------------------------------- /openshift/configs/koji-builder-osbs.conf.j2: -------------------------------------------------------------------------------- 1 | [general] 2 | build_json_dir = /usr/share/osbs/ 3 | verbose = 1 4 | openshift_required_version = 3.6.0 5 | 6 | [default] 7 | openshift_url = {{ openshift_url }} 8 | namespace = {{ orchestrator_namespace }} 9 | build_from = imagestream:osbs-buildroot:latest 10 | reactor_config_map = reactor-config-map 11 | build_type = prod 12 | can_orchestrate = true 13 | use_auth = true 14 | use_kerberos = false 15 | verify_ssl = false 16 | username = {{ openshift_user }} 17 | password = {{ openshift_password }} 18 | 19 | [scratch] 20 | openshift_url = {{ openshift_url }} 21 | namespace = {{ orchestrator_namespace }} 22 | build_from = imagestream:osbs-buildroot:latest 23 | reactor_config_map = reactor-config-map 24 | build_type = prod 25 | can_orchestrate = true 26 | use_auth = true 27 | use_kerberos = false 28 | verify_ssl = false 29 | username = {{ openshift_user }} 30 | password = {{ openshift_password }} 31 | scratch = true 32 | -------------------------------------------------------------------------------- /openshift/configs/koji-hub-web.conf.j2: -------------------------------------------------------------------------------- 1 | [web] 2 | SiteName = koji 3 | # KojiTheme = mytheme 4 | 5 | # Key urls 6 | KojiHubURL = http://localhost/kojihub 7 | KojiFilesURL = https://koji-hub.{{ osbs_box_host }}/kojifiles 8 | 9 | # SSL authentication options 10 | WebCert = /etc/pki/koji/kojiweb.pem 11 | KojiHubCA = /etc/pki/koji/osbs-box-ca.crt 12 | 13 | LoginTimeout = 72 14 | 15 | # This must be changed and uncommented before deployment 16 | Secret = OK_BUT_WHY_THOUGH 17 | 18 | LibPath = /usr/share/koji-web/lib 19 | 20 | # This can be a space-delimited list of the numeric IDs of users that you want 21 | # to hide from tasks listed on the front page. You might want to, for instance, 22 | # hide the activity of an account used for continuous integration. 23 | # HiddenUsers = 5372 1234 24 | 25 | # Task types visible in pulldown menu on tasks page. 26 | # Tasks = 27 | # runroot plugin provided via main package could be listed as: 28 | # Tasks = runroot 29 | # Tasks that can exist without a parent 30 | # ToplevelTasks = 31 | # Tasks that can have children 32 | # ParentTasks = 33 | 34 | # Uncommenting this will show python tracebacks in the webUI, but they are the 35 | # same as what you will see in apache's error_log. 36 | # Not for production use 37 | PythonDebug = True 38 | -------------------------------------------------------------------------------- /openshift/configs/reactor-config-map.yaml.j2: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1 3 | 4 | clusters: 5 | x86_64: 6 | - name: worker 7 | max_concurrent_builds: 4 8 | enabled: true 9 | 10 | clusters_client_config_dir: /var/run/secrets/atomic-reactor/client-config-secret 11 | 12 | koji: 13 | hub_url: https://koji-hub.{{ koji_namespace }}/kojihub 14 | root_url: https://koji-hub.{{ koji_namespace }}/kojifiles 15 | auth: 16 | ssl_certs_dir: /var/run/secrets/atomic-reactor/kojisecret 17 | 18 | image_labels: 19 | vendor: "Red Hat, Inc." 20 | authoritative-source-url: osbs-box.example.com 21 | distribution-scope: public 22 | 23 | openshift: 24 | url: {{ openshift_url }} 25 | build_json_dir: /usr/share/osbs/ 26 | auth: 27 | enable: true 28 | 29 | platform_descriptors: 30 | - platform: x86_64 31 | architecture: amd64 32 | 33 | content_versions: 34 | - v2 35 | 36 | registries: 37 | - url: https://{{ registry_ip }}:5000/v2 38 | insecure: true 39 | 40 | source_registry: 41 | url: https://{{ registry_ip }}:5000/ 42 | insecure: true 43 | 44 | sources_command: fedpkg sources 45 | 46 | required_secrets: 47 | - kojisecret 48 | 49 | worker_token_secrets: 50 | - client-config-secret 51 | 52 | skip_koji_check_for_base_image: true 53 | 54 | source_containers: 55 | source_builder_image: "quay.io/ctrs/bsi" 56 | -------------------------------------------------------------------------------- /openshift/params/osbs-box.env.j2: -------------------------------------------------------------------------------- 1 | OSBS_BOX_REPO="{{ osbs_box_repo }}" 2 | OSBS_BOX_VERSION="{{ osbs_box_version }}" 3 | 4 | OSBS_BOX_HOST="{{ osbs_box_host }}" 5 | 6 | KOJI_FILES_DIR="{{ koji_files_dir }}" 7 | KOJI_DB_DATA_DIR="{{ koji_db_data_dir }}" 8 | REGISTRY_DATA_DIR="{{ registry_data_dir }}" 9 | 10 | ATOMIC_REACTOR_PIP_REF="git+{{ atomic_reactor_repo }}@{{ atomic_reactor_version }}" 11 | OSBS_CLIENT_PIP_REF="git+{{ osbs_client_repo }}@{{ osbs_client_version }}" 12 | KOJI_CONTAINERBUILD_PIP_REF="git+{{ koji_containerbuild_repo }}@{{ koji_containerbuild_version }}" 13 | DOCKERFILE_PARSE_PIP_REF="git+{{ dockerfile_parse_repo }}@{{ dockerfile_parse_version }}" 14 | DOCKPULP_PIP_REF="git+{{ dockpulp_repo }}@{{ dockpulp_version }}" 15 | -------------------------------------------------------------------------------- /openshift/templates/koji-base.yaml: -------------------------------------------------------------------------------- 1 | kind: Template 2 | apiVersion: v1 3 | metadata: 4 | name: koji-base 5 | description: > 6 | Koji-base serves as a base image for the other koji components. It is not 7 | meant to be run as a container, only built from. 8 | 9 | To successfully build koji-base using this template, you need a koji-certs 10 | secret containing all the SSL certificates that will later be needed by the 11 | images built from koji-base. 12 | 13 | labels: 14 | build: koji-base 15 | 16 | parameters: 17 | - name: OSBS_BOX_REPO 18 | description: Repository to build the image from 19 | value: https://github.com/containerbuildsystem/osbs-box 20 | required: true 21 | 22 | - name: OSBS_BOX_VERSION 23 | description: Branch/tag/commit within the repository specified above 24 | value: master 25 | required: true 26 | 27 | - name: OSBS_CLIENT_PIP_REF 28 | description: > 29 | Pip URL to install osbs-client from (git+[@]) 30 | value: git+https://github.com/containerbuildsystem/osbs-client 31 | required: true 32 | 33 | - name: KOJI_CONTAINERBUILD_PIP_REF 34 | description: > 35 | Pip URL to install koji-containerbuild from (git+[@]) 36 | value: git+https://github.com/containerbuildsystem/koji-containerbuild 37 | required: true 38 | 39 | objects: 40 | - kind: ImageStream 41 | apiVersion: v1 42 | metadata: 43 | name: koji-base 44 | spec: {} 45 | 46 | - kind: BuildConfig 47 | apiVersion: v1 48 | metadata: 49 | name: koji-base 50 | spec: 51 | source: 52 | type: Git 53 | git: 54 | uri: ${OSBS_BOX_REPO} 55 | ref: ${OSBS_BOX_VERSION} 56 | contextDir: koji-base 57 | secrets: 58 | - secret: 59 | name: koji-certs 60 | destinationDir: etc/pki/koji 61 | strategy: 62 | type: Docker 63 | dockerStrategy: 64 | noCache: true 65 | buildArgs: 66 | - name: OSBS_CLIENT_PIP_REF 67 | value: ${OSBS_CLIENT_PIP_REF} 68 | - name: KOJI_CONTAINERBUILD_PIP_REF 69 | value: ${KOJI_CONTAINERBUILD_PIP_REF} 70 | output: 71 | to: 72 | kind: ImageStreamTag 73 | name: koji-base:latest 74 | -------------------------------------------------------------------------------- /openshift/templates/koji-builder.yaml: -------------------------------------------------------------------------------- 1 | kind: Template 2 | apiVersion: v1 3 | metadata: 4 | name: koji-builder 5 | description: > 6 | Koji-builder runs the kojid daemon, which polls koji hub for incoming build 7 | requests and handles them accordingly. 8 | 9 | Expects no user interaction, but is capable of calling koji commands like 10 | the client (only the containerbuild plugin is missing). 11 | 12 | parameters: 13 | - name: OSBS_BOX_REPO 14 | description: Repository to build the image from 15 | value: https://github.com/containerbuildsystem/osbs-box 16 | required: true 17 | 18 | - name: OSBS_BOX_VERSION 19 | description: Branch/tag/commit within the repository specified above 20 | value: master 21 | required: true 22 | 23 | labels: 24 | app: koji-builder 25 | 26 | objects: 27 | - kind: ImageStream 28 | apiVersion: v1 29 | metadata: 30 | name: koji-builder 31 | spec: {} 32 | 33 | - kind: BuildConfig 34 | apiVersion: v1 35 | metadata: 36 | name: koji-builder 37 | spec: 38 | source: 39 | type: Git 40 | git: 41 | uri: ${OSBS_BOX_REPO} 42 | ref: ${OSBS_BOX_VERSION} 43 | contextDir: koji-builder 44 | configMaps: 45 | - configMap: 46 | name: koji-builder-osbs 47 | destinationDir: etc/ 48 | strategy: 49 | type: Docker 50 | dockerStrategy: 51 | noCache: true 52 | from: 53 | kind: ImageStreamTag 54 | name: koji-base:latest 55 | output: 56 | to: 57 | kind: ImageStreamTag 58 | name: koji-builder:latest 59 | triggers: 60 | - type: ImageChange 61 | 62 | - kind: DeploymentConfig 63 | apiVersion: v1 64 | metadata: 65 | name: koji-builder 66 | spec: 67 | replicas: 1 68 | selector: 69 | app: koji-builder 70 | strategy: 71 | type: Recreate 72 | template: 73 | metadata: 74 | name: koji-builder 75 | labels: 76 | app: koji-builder 77 | spec: 78 | containers: 79 | - name: koji-builder 80 | image: koji-builder:latest 81 | volumeMounts: 82 | - name: koji-files 83 | mountPath: /mnt/koji 84 | volumes: 85 | - name: koji-files 86 | persistentVolumeClaim: 87 | claimName: koji-files 88 | triggers: 89 | - type: ImageChange 90 | imageChangeParams: 91 | automatic: true 92 | containerNames: 93 | - koji-builder 94 | from: 95 | kind: ImageStreamTag 96 | name: koji-builder:latest 97 | -------------------------------------------------------------------------------- /openshift/templates/koji-client.yaml: -------------------------------------------------------------------------------- 1 | kind: Template 2 | apiVersion: v1 3 | metadata: 4 | name: koji-client 5 | description: > 6 | Koji-client provides everything that is necessary to communicate with Koji 7 | using the CLI, including the containerbuild CLI plugin. 8 | 9 | Does not do anything on its own (other than `sleep infinity`), is meant to 10 | be used with `oc rsh` to trigger koji commands. 11 | 12 | parameters: 13 | - name: OSBS_BOX_REPO 14 | description: Repository to build the image from 15 | value: https://github.com/containerbuildsystem/osbs-box 16 | required: true 17 | 18 | - name: OSBS_BOX_VERSION 19 | description: Branch/tag/commit within the repository specified above 20 | value: master 21 | required: true 22 | 23 | labels: 24 | app: koji-client 25 | 26 | objects: 27 | - kind: ImageStream 28 | apiVersion: v1 29 | metadata: 30 | name: koji-client 31 | spec: {} 32 | 33 | - kind: BuildConfig 34 | apiVersion: v1 35 | metadata: 36 | name: koji-client 37 | spec: 38 | source: 39 | type: Git 40 | git: 41 | uri: ${OSBS_BOX_REPO} 42 | ref: ${OSBS_BOX_VERSION} 43 | contextDir: koji-client 44 | strategy: 45 | type: Docker 46 | dockerStrategy: 47 | noCache: true 48 | from: 49 | kind: ImageStreamTag 50 | name: koji-base:latest 51 | output: 52 | to: 53 | kind: ImageStreamTag 54 | name: koji-client:latest 55 | triggers: 56 | - type: ImageChange 57 | 58 | - kind: DeploymentConfig 59 | apiVersion: v1 60 | metadata: 61 | name: koji-client 62 | spec: 63 | replicas: 1 64 | selector: 65 | app: koji-client 66 | strategy: 67 | type: Recreate 68 | template: 69 | metadata: 70 | name: koji-client 71 | labels: 72 | app: koji-client 73 | spec: 74 | containers: 75 | - name: koji-client 76 | image: koji-client:latest 77 | triggers: 78 | - type: ImageChange 79 | imageChangeParams: 80 | automatic: true 81 | containerNames: 82 | - koji-client 83 | from: 84 | kind: ImageStreamTag 85 | name: koji-client:latest 86 | -------------------------------------------------------------------------------- /openshift/templates/koji-db.yaml: -------------------------------------------------------------------------------- 1 | kind: Template 2 | apiVersion: v1 3 | metadata: 4 | name: koji-db 5 | description: > 6 | Koji-db provides the PostgreSQL database where koji stores its data. 7 | 8 | Exposes port 5432, where koji-hub can access the data it needs to serve 9 | the koji webpage and handle client requests. 10 | 11 | parameters: 12 | - name: OSBS_BOX_REPO 13 | description: Repository to build the image from 14 | value: https://github.com/containerbuildsystem/osbs-box 15 | required: true 16 | 17 | - name: OSBS_BOX_VERSION 18 | description: Branch/tag/commit within the repository specified above 19 | value: master 20 | required: true 21 | 22 | labels: 23 | app: koji-db 24 | 25 | objects: 26 | - kind: ImageStream 27 | apiVersion: v1 28 | metadata: 29 | name: koji-db 30 | spec: {} 31 | 32 | - kind: BuildConfig 33 | apiVersion: v1 34 | metadata: 35 | name: koji-db 36 | spec: 37 | source: 38 | type: Git 39 | git: 40 | uri: ${OSBS_BOX_REPO} 41 | ref: ${OSBS_BOX_VERSION} 42 | contextDir: koji-db 43 | images: 44 | - from: 45 | kind: ImageStreamTag 46 | name: koji-base:latest 47 | paths: 48 | - sourcePath: /usr/share/doc/koji/docs/schema.sql 49 | destinationDir: koji-db/sql-init 50 | strategy: 51 | type: Docker 52 | dockerStrategy: 53 | noCache: true 54 | pullSecret: 55 | name: dockerhub 56 | output: 57 | to: 58 | kind: ImageStreamTag 59 | name: koji-db:latest 60 | triggers: 61 | - type: ImageChange 62 | imageChange: 63 | from: 64 | kind: ImageStreamTag 65 | name: koji-base:latest 66 | 67 | - kind: DeploymentConfig 68 | apiVersion: v1 69 | metadata: 70 | name: koji-db 71 | spec: 72 | replicas: 1 73 | selector: 74 | app: koji-db 75 | strategy: 76 | type: Recreate 77 | template: 78 | metadata: 79 | name: koji-db 80 | labels: 81 | app: koji-db 82 | spec: 83 | containers: 84 | - name: koji-db 85 | image: koji-db:latest 86 | ports: 87 | - containerPort: 5432 88 | volumeMounts: 89 | - name: koji-db-data 90 | mountPath: /var/lib/postgresql/data 91 | volumes: 92 | - name: koji-db-data 93 | persistentVolumeClaim: 94 | claimName: koji-db-data 95 | triggers: 96 | - type: ImageChange 97 | imageChangeParams: 98 | automatic: true 99 | containerNames: 100 | - koji-db 101 | from: 102 | kind: ImageStreamTag 103 | name: koji-db:latest 104 | 105 | - kind: Service 106 | apiVersion: v1 107 | metadata: 108 | name: koji-db 109 | spec: 110 | selector: 111 | app: koji-db 112 | ports: 113 | - name: "5432" 114 | port: 5432 115 | targetPort: 5432 116 | -------------------------------------------------------------------------------- /openshift/templates/koji-hub.yaml: -------------------------------------------------------------------------------- 1 | kind: Template 2 | apiVersion: v1 3 | metadata: 4 | name: koji-hub 5 | description: > 6 | Koji-hub serves as the interface between clients and the database. It serves 7 | the koji webpage and handles requests made from the CLI. 8 | 9 | Exposes ports 80 and 443 internally. Port 443 is also exposed externally, 10 | using a Route. Users can access the koji website there. 11 | 12 | parameters: 13 | - name: OSBS_BOX_REPO 14 | description: Repository to build the image from 15 | value: https://github.com/containerbuildsystem/osbs-box 16 | required: true 17 | 18 | - name: OSBS_BOX_VERSION 19 | description: Branch/tag/commit within the repository specified above 20 | value: master 21 | required: true 22 | 23 | - name: OSBS_BOX_HOST 24 | description: Hostname of the machine running OSBS-Box 25 | value: localhost 26 | required: true 27 | 28 | labels: 29 | app: koji-hub 30 | 31 | objects: 32 | - kind: ImageStream 33 | apiVersion: v1 34 | metadata: 35 | name: koji-hub 36 | labels: 37 | app: koji-hub 38 | spec: {} 39 | 40 | - kind: BuildConfig 41 | apiVersion: v1 42 | metadata: 43 | name: koji-hub 44 | spec: 45 | source: 46 | type: Git 47 | git: 48 | uri: ${OSBS_BOX_REPO} 49 | ref: ${OSBS_BOX_VERSION} 50 | contextDir: koji-hub 51 | configMaps: 52 | - configMap: 53 | name: koji-hub-web 54 | destinationDir: etc/kojiweb/ 55 | strategy: 56 | type: Docker 57 | dockerStrategy: 58 | noCache: true 59 | from: 60 | kind: ImageStreamTag 61 | name: koji-base:latest 62 | output: 63 | to: 64 | kind: ImageStreamTag 65 | name: koji-hub:latest 66 | triggers: 67 | - type: ImageChange 68 | 69 | - kind: DeploymentConfig 70 | apiVersion: v1 71 | metadata: 72 | name: koji-hub 73 | spec: 74 | replicas: 1 75 | selector: 76 | app: koji-hub 77 | strategy: 78 | type: Recreate 79 | template: 80 | metadata: 81 | name: koji-hub 82 | labels: 83 | app: koji-hub 84 | spec: 85 | containers: 86 | - name: koji-hub 87 | image: koji-hub:latest 88 | ports: 89 | - containerPort: 80 90 | - containerPort: 443 91 | volumeMounts: 92 | - name: koji-files 93 | mountPath: /mnt/koji 94 | volumes: 95 | - name: koji-files 96 | persistentVolumeClaim: 97 | claimName: koji-files 98 | triggers: 99 | - type: ImageChange 100 | imageChangeParams: 101 | automatic: true 102 | containerNames: 103 | - koji-hub 104 | from: 105 | kind: ImageStreamTag 106 | name: koji-hub:latest 107 | 108 | - kind: Service 109 | apiVersion: v1 110 | metadata: 111 | name: koji-hub 112 | spec: 113 | selector: 114 | app: koji-hub 115 | ports: 116 | - name: "80" 117 | port: 80 118 | targetPort: 80 119 | - name: "443" 120 | port: 443 121 | targetPort: 443 122 | 123 | - kind: Route 124 | apiVersion: v1 125 | metadata: 126 | name: koji-hub 127 | spec: 128 | host: koji-hub.${OSBS_BOX_HOST} 129 | to: 130 | kind: Service 131 | name: koji-hub 132 | port: 133 | targetPort: "443" 134 | tls: 135 | termination: passthrough 136 | insecureEdgeTerminationPolicy: Redirect 137 | -------------------------------------------------------------------------------- /openshift/templates/koji-volumes.yaml: -------------------------------------------------------------------------------- 1 | kind: Template 2 | apiVersion: v1 3 | metadata: 4 | name: koji-volumes 5 | description: > 6 | Persistent volumes for koji data. There is one volume for koji-db data 7 | and one for the /mnt/koji/ file hierarchy. They are HostPath volumes. 8 | 9 | The reclaim policy for these volumes is Retain, meaning the data is never 10 | removed (not by openshift, anyway). 11 | 12 | The persistent volume claims that bind to these PVs are also defined here. 13 | 14 | parameters: 15 | - name: KOJI_FILES_DIR 16 | description: Local directory for koji files (the /mnt/koji/ structure) 17 | required: true 18 | 19 | - name: KOJI_DB_DATA_DIR 20 | description: Local directory for koji-db postgresql data 21 | required: true 22 | 23 | labels: 24 | volume: koji-volume 25 | 26 | objects: 27 | - kind: PersistentVolume 28 | apiVersion: v1 29 | metadata: 30 | name: koji-files 31 | spec: 32 | hostPath: 33 | path: ${KOJI_FILES_DIR} 34 | accessModes: 35 | # Can be mounted R/W by one node (node as in machine) 36 | # The only supported access mode for HostPaths PVs 37 | - ReadWriteOnce 38 | capacity: 39 | storage: 100Gi 40 | persistentVolumeReclaimPolicy: Retain 41 | 42 | - kind: PersistentVolume 43 | apiVersion: v1 44 | metadata: 45 | name: koji-db-data 46 | spec: 47 | hostPath: 48 | path: ${KOJI_DB_DATA_DIR} 49 | accessModes: 50 | - ReadWriteOnce 51 | capacity: 52 | storage: 100Gi 53 | persistentVolumeReclaimPolicy: Retain 54 | 55 | - kind: PersistentVolumeClaim 56 | apiVersion: v1 57 | metadata: 58 | name: koji-files 59 | spec: 60 | volumeName: koji-files 61 | accessModes: 62 | - ReadWriteOnce 63 | resources: 64 | requests: 65 | storage: 100Gi 66 | 67 | - kind: PersistentVolumeClaim 68 | apiVersion: v1 69 | metadata: 70 | name: koji-db-data 71 | spec: 72 | volumeName: koji-db-data 73 | accessModes: 74 | - ReadWriteOnce 75 | resources: 76 | requests: 77 | storage: 100Gi 78 | -------------------------------------------------------------------------------- /openshift/templates/osbs-buildroot.yaml: -------------------------------------------------------------------------------- 1 | kind: Template 2 | apiVersion: v1 3 | metadata: 4 | name: osbs-buildroot 5 | description: > 6 | Buildroot is the image which is pulled and run by orchestrator to do 7 | an image build. It should live in the orchestrator namespace. 8 | 9 | labels: 10 | build: osbs-buildroot 11 | 12 | parameters: 13 | - name: OSBS_BOX_REPO 14 | description: Repository to build the image from 15 | value: https://github.com/containerbuildsystem/osbs-box 16 | required: true 17 | 18 | - name: OSBS_BOX_VERSION 19 | description: Branch/tag/commit within the repository specified above 20 | value: master 21 | required: true 22 | 23 | - name: ATOMIC_REACTOR_PIP_REF 24 | description: > 25 | Pip URL to install atomic-reactor from (git+[@]) 26 | value: git+https://github.com/containerbuildsystem/atomic-reactor 27 | required: true 28 | 29 | - name: OSBS_CLIENT_PIP_REF 30 | description: > 31 | Pip URL to install osbs-client from (git+[@]) 32 | value: git+https://github.com/containerbuildsystem/osbs-client 33 | required: true 34 | 35 | - name: DOCKERFILE_PARSE_PIP_REF 36 | description: > 37 | Pip URL to install dockerfile-parse from (git+[@]) 38 | value: git+https://github.com/containerbuildsystem/dockerfile-parse 39 | required: true 40 | 41 | - name: DOCKPULP_PIP_REF 42 | description: > 43 | Pip URL to install dockpulp from (git+[@]) 44 | value: git+https://github.com/release-engineering/dockpulp 45 | required: true 46 | 47 | objects: 48 | - kind: ImageStream 49 | apiVersion: v1 50 | metadata: 51 | name: osbs-buildroot 52 | spec: {} 53 | 54 | - kind: BuildConfig 55 | apiVersion: v1 56 | metadata: 57 | name: osbs-buildroot 58 | spec: 59 | source: 60 | type: Git 61 | git: 62 | uri: ${OSBS_BOX_REPO} 63 | ref: ${OSBS_BOX_VERSION} 64 | contextDir: osbs-buildroot 65 | strategy: 66 | type: Docker 67 | dockerStrategy: 68 | noCache: true 69 | buildArgs: 70 | - name: ATOMIC_REACTOR_PIP_REF 71 | value: ${ATOMIC_REACTOR_PIP_REF} 72 | - name: OSBS_CLIENT_PIP_REF 73 | value: ${OSBS_CLIENT_PIP_REF} 74 | - name: DOCKERFILE_PARSE_PIP_REF 75 | value: ${DOCKERFILE_PARSE_PIP_REF} 76 | - name: DOCKPULP_PIP_REF 77 | value: ${DOCKPULP_PIP_REF} 78 | pullSecret: 79 | name: dockerhub 80 | output: 81 | to: 82 | kind: ImageStreamTag 83 | name: osbs-buildroot:latest 84 | -------------------------------------------------------------------------------- /openshift/templates/osbs-registry.yaml: -------------------------------------------------------------------------------- 1 | kind: Template 2 | apiVersion: v1 3 | metadata: 4 | name: osbs-registry 5 | description: > 6 | Container image registry for OSBS-Box. It can be used both as the source for 7 | pulling base images and as the destination for pushing built images. 8 | 9 | It is simply the registry:2 docker image using a HostPath PV for its data. 10 | 11 | parameters: 12 | - name: REGISTRY_DATA_DIR 13 | description: Local directory for registry data 14 | required: true 15 | 16 | - name: OSBS_BOX_HOST 17 | description: Hostname of the machine running OSBS-Box 18 | value: localhost 19 | required: true 20 | 21 | labels: 22 | app: osbs-registry 23 | 24 | objects: 25 | - kind: PersistentVolume 26 | apiVersion: v1 27 | metadata: 28 | name: registry-data 29 | spec: 30 | hostPath: 31 | path: ${REGISTRY_DATA_DIR} 32 | accessModes: 33 | - ReadWriteOnce 34 | capacity: 35 | storage: 100Gi 36 | persistentVolumeReclaimPolicy: Retain 37 | 38 | - kind: PersistentVolumeClaim 39 | apiVersion: v1 40 | metadata: 41 | name: registry-data 42 | spec: 43 | volumeName: registry-data 44 | accessModes: 45 | - ReadWriteOnce 46 | resources: 47 | requests: 48 | storage: 100Gi 49 | 50 | - kind: DeploymentConfig 51 | apiVersion: v1 52 | metadata: 53 | name: osbs-registry 54 | spec: 55 | replicas: 1 56 | strategy: 57 | type: Recreate 58 | template: 59 | metadata: 60 | name: osbs-registry 61 | labels: 62 | app: osbs-registry 63 | spec: 64 | containers: 65 | - name: osbs-registry 66 | image: docker.io/registry:2 67 | ports: 68 | - containerPort: 5000 69 | env: 70 | - name: REGISTRY_STORAGE_DELETE_ENABLED 71 | value: "true" 72 | - name: REGISTRY_HTTP_TLS_CERTIFICATE 73 | value: /etc/pki/registry/osbs-registry.crt 74 | - name: REGISTRY_HTTP_TLS_KEY 75 | value: /etc/pki/registry/osbs-registry.key 76 | volumeMounts: 77 | - name: registry-data 78 | mountPath: /var/lib/registry 79 | - name: registry-cert 80 | mountPath: /etc/pki/registry 81 | imagePullSecrets: 82 | - name: dockerhub 83 | volumes: 84 | - name: registry-data 85 | persistentVolumeClaim: 86 | claimName: registry-data 87 | - name: registry-cert 88 | secret: 89 | secretName: registry-cert 90 | 91 | - kind: Service 92 | apiVersion: v1 93 | metadata: 94 | name: osbs-registry 95 | spec: 96 | selector: 97 | app: osbs-registry 98 | ports: 99 | - name: "5000" 100 | port: 5000 101 | targetPort: 5000 102 | 103 | - kind: Route 104 | apiVersion: v1 105 | metadata: 106 | name: osbs-registry 107 | spec: 108 | host: osbs-registry.${OSBS_BOX_HOST} 109 | to: 110 | kind: Service 111 | name: osbs-registry 112 | port: 113 | targetPort: "5000" 114 | tls: 115 | termination: passthrough 116 | insecureEdgeTerminationPolicy: Redirect 117 | -------------------------------------------------------------------------------- /osbs-buildroot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker.io/golang:buster AS build 2 | 3 | RUN go get -v "github.com/openshift/imagebuilder/cmd/imagebuilder" 4 | 5 | FROM registry.fedoraproject.org/fedora:30 6 | 7 | # Install non-OSBS buildroot components 8 | COPY --from=build "/go/bin/imagebuilder" "/usr/bin/imagebuilder" 9 | RUN dnf -y install "fedpkg-minimal" \ 10 | "file" \ 11 | "findutils" \ 12 | "jq" \ 13 | "libmodulemd" \ 14 | "python3-docker" \ 15 | "python3-docker-squash" \ 16 | "python3-gobject-base" \ 17 | "python3-koji" \ 18 | "python3-rpm" \ 19 | "python3-ruamel-yaml" \ 20 | "python3-setuptools" \ 21 | "python3-simplejson" \ 22 | "skopeo" \ 23 | && dnf clean all 24 | 25 | # Install stuff that will be needed for pip-installing OSBS components from git 26 | RUN dnf -y install "git-core" \ 27 | "python3-devel" \ 28 | "krb5-devel" \ 29 | "xz-devel" \ 30 | "gcc" \ 31 | && dnf clean all 32 | 33 | # Pip URLs for OSBS components (git+[@]) 34 | ARG ATOMIC_REACTOR_PIP_REF 35 | ARG OSBS_CLIENT_PIP_REF 36 | ARG DOCKERFILE_PARSE_PIP_REF 37 | ARG DOCKPULP_PIP_REF 38 | 39 | # Install OSBS components from git 40 | ENV PIP_PREFIX="/usr" 41 | RUN pip3 --no-cache-dir install "$ATOMIC_REACTOR_PIP_REF" \ 42 | "$OSBS_CLIENT_PIP_REF" \ 43 | "$DOCKERFILE_PARSE_PIP_REF" \ 44 | "$DOCKPULP_PIP_REF" 45 | 46 | # Add script for building source container images 47 | RUN curl "https://raw.githubusercontent.com/containers/BuildSourceImage/master/BuildSourceImage.sh" \ 48 | -o /usr/bin/bsi \ 49 | && chmod +x /usr/bin/bsi 50 | 51 | CMD ["atomic-reactor", "--verbose", "inside-build"] 52 | -------------------------------------------------------------------------------- /prerequisite-playbooks/Fedora32-prerequisites.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # 3 | # Install required prerequisites for Fedora 32 Workstation for OSBS-Box to be successful. 4 | # 5 | - name: Install Tools 6 | hosts: all 7 | 8 | tasks: 9 | - name: enable ssh 10 | service: 11 | name: sshd 12 | state: started 13 | enabled: yes 14 | - name: install docker 15 | yum: 16 | name: docker 17 | state: latest 18 | - name: Add insecure-registry 19 | lineinfile: 20 | path: /etc/sysconfig/docker 21 | insertbefore: "^\"" 22 | line: " --insecure-registry \"172.30.0.0/16\"" 23 | notify: restart docker 24 | - name: start docker 25 | service: 26 | name: docker 27 | state: started 28 | enabled: yes 29 | - name: install origin-clients 30 | yum: 31 | name: origin-clients 32 | state: latest 33 | - name: install python-devel 34 | yum: 35 | name: python-devel 36 | state: latest 37 | - name: add root to docker 38 | user: 39 | name: root 40 | groups: docker 41 | append: yes 42 | # Need a message to reboot at the end. 43 | - name: modify cgroup 44 | replace: 45 | path: /boot/efi/EFI/fedora/grubenv 46 | regexp: '(^kernelopts.+)(?