├── LICENSE ├── README.md ├── Vagrantfile ├── collections └── requirements.yml ├── docs ├── LICENSE ├── README.md ├── compile-docs.sh └── topics │ ├── about-ExpectationsOfOelaBox.md │ ├── about-ExpectationsOfTheUser.md │ ├── about-PurposeOfOelaBox.md │ ├── about-TechnicalAspectsOfOelaBox.md │ ├── operation-KojiServer.md │ ├── operation-Preparation.md │ ├── operation-StartStopDestroyandReset.md │ └── operation-Tools.md ├── files ├── oelabox-dns │ ├── 121.168.192.in-addr.arpa.zone │ ├── named.conf │ ├── oelabox.local.zone │ └── resolv.conf └── oelabox-koji │ └── getsrc │ ├── SOURCES │ └── getsrc.sh │ └── SPECS │ └── getsrc.spec ├── handlers ├── oelabox-dns │ └── main.yml ├── oelabox-ipa │ └── main.yml └── oelabox-koji │ └── main.yml ├── init-oelabox-ipa-team.yml ├── init-oelabox-koji-ecosystem.yml ├── init-oelabox-koji-keytabs.yml ├── init-oelabox-koji-services.yml ├── inventory.ini ├── provision-oelabox-dns-client.yml ├── provision-oelabox-dns.yml ├── provision-oelabox-ipa-client.yml ├── provision-oelabox-ipa.yml ├── provision-oelabox-koji-builder.yml ├── roles ├── oelabox.geerlingguy.postgresql │ ├── .ansible-lint │ ├── .github │ │ ├── FUNDING.yml │ │ ├── stale.yml │ │ └── workflows │ │ │ ├── ci.yml │ │ │ └── release.yml │ ├── .gitignore │ ├── .yamllint │ ├── LICENSE │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── molecule │ │ └── default │ │ │ ├── converge.yml │ │ │ └── molecule.yml │ ├── tasks │ │ ├── configure.yml │ │ ├── databases.yml │ │ ├── initialize.yml │ │ ├── main.yml │ │ ├── setup-Debian.yml │ │ ├── setup-RedHat.yml │ │ ├── users.yml │ │ ├── users_props.yml │ │ └── variables.yml │ ├── templates │ │ ├── pg_hba.conf.j2 │ │ └── postgres.sh.j2 │ └── vars │ │ ├── Amazon-2.yml │ │ ├── Debian-10.yml │ │ ├── Debian-11.yml │ │ ├── Debian-7.yml │ │ ├── Debian-8.yml │ │ ├── Debian-9.yml │ │ ├── Fedora-29.yml │ │ ├── Fedora-30.yml │ │ ├── Fedora-31.yml │ │ ├── Fedora-32.yml │ │ ├── Fedora-34.yml │ │ ├── Fedora-35.yml │ │ ├── Fedora-36.yml │ │ ├── RedHat-7.yml │ │ ├── RedHat-8.yml │ │ ├── RedHat-9.yml │ │ ├── Ubuntu-16.yml │ │ ├── Ubuntu-18.yml │ │ ├── Ubuntu-20.yml │ │ └── Ubuntu-22.yml ├── oelabox.ipagetcert │ ├── .ansible-lint │ ├── .pre-commit-config.yaml │ ├── .yamllint │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── github │ │ └── workflows │ │ │ ├── ansible-lint.yml │ │ │ ├── main.yml │ │ │ └── yaml-lint.yml │ ├── meta │ │ └── main.yml │ ├── molecule │ │ ├── default │ │ │ ├── converge.yml │ │ │ └── molecule.yml │ │ └── requirements.yml │ ├── tasks │ │ └── main.yml │ ├── templates │ │ └── get_cert.sh.j2 │ └── vars │ │ └── main.yml ├── oelabox.kojid │ ├── .ansible-lint │ ├── .pre-commit-config.yaml │ ├── .yamllint │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── github │ │ └── workflows │ │ │ ├── ansible-lint.yml │ │ │ ├── main.yml │ │ │ └── yaml-lint.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── molecule │ │ ├── default │ │ │ ├── converge.yml │ │ │ └── molecule.yml │ │ └── requirements.yml │ ├── tasks │ │ ├── config.yml │ │ ├── main.yml │ │ ├── packages.yml │ │ ├── selinux_boolean.yml │ │ ├── shared │ │ │ ├── config_shared.yml │ │ │ └── storage_shared.yml │ │ ├── storage.yml │ │ └── users.yml │ ├── templates │ │ ├── 00-limit.conf.j2 │ │ ├── buildtools.repo.j2 │ │ ├── koji.conf.j2 │ │ ├── kojid.conf.j2 │ │ ├── kojid.service.j2 │ │ ├── old.site-defaults.cfg │ │ ├── oz.cfg.j2 │ │ ├── production │ │ │ ├── koji.conf.j2 │ │ │ ├── kojid.conf.j2 │ │ │ └── runroot.conf.j2 │ │ ├── runroot.conf.j2 │ │ ├── site-defaults.cfg.j2 │ │ └── staging │ │ │ ├── koji.conf.j2 │ │ │ ├── kojid.conf.j2 │ │ │ └── runroot.conf.j2 │ └── vars │ │ └── main.yml └── oelabox.kojihub │ ├── .ansible-lint │ ├── .pre-commit-config.yaml │ ├── .yamllint │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── defaults │ └── main.yml │ ├── files │ ├── etc │ │ ├── cron.d │ │ │ ├── koji-directory-cleanup │ │ │ ├── koji-gc │ │ │ └── koji-prune-signed-copies │ │ └── koji-hub │ │ │ └── plugins │ │ │ └── sidetag.conf │ ├── plugins │ │ └── rockymsg.py │ ├── usr │ │ └── lib │ │ │ └── koji-hub-plugins │ │ │ └── key_signing.py │ └── var │ │ └── www │ │ └── html │ │ └── robots.txt │ ├── github │ └── workflows │ │ ├── ansible-lint.yml │ │ ├── main.yml │ │ └── yaml-lint.yml │ ├── handlers │ └── main.yml │ ├── meta │ └── main.yml │ ├── molecule │ ├── default │ │ ├── converge.yml │ │ └── molecule.yml │ └── requirements.yml │ ├── tasks │ ├── db.yml │ ├── koji-admin-ipa.yml │ ├── koji-admin-local.yml │ ├── koji-gc.yml │ ├── kojira.yml │ ├── main.yml │ ├── plugins.yml │ ├── selinux_boolean.yml │ ├── selinux_fcontexts.yml │ ├── storage.yml │ └── user-sync.yml │ ├── templates │ ├── etc │ │ ├── httpd │ │ │ └── conf.d │ │ │ │ ├── kojihub.conf.j2 │ │ │ │ └── kojiweb.conf.j2 │ │ ├── koji-gc │ │ │ └── koji-gc.conf.j2 │ │ ├── koji-hub │ │ │ ├── hub.conf.j2 │ │ │ └── plugins │ │ │ │ ├── key_signing.conf.j2 │ │ │ │ └── rockymsg.conf.j2 │ │ ├── kojira │ │ │ └── kojira.conf.j2 │ │ └── kojiweb │ │ │ └── web.conf.j2 │ ├── koji-client-config.j2 │ ├── koji-pgsql-kojira.sql.j2 │ ├── koji-pgsql.sql.j2 │ ├── opt │ │ └── rocky-tools │ │ │ ├── regen-buildrepos.sh │ │ │ ├── regen-buildroots.sh │ │ │ └── who.sh │ └── ssl.conf.j2 │ └── vars │ └── main.yml ├── setup-oelabox-tools.yml ├── setup.sh ├── setup.yml ├── tasks ├── oelabox-dns │ ├── client-setup.yml │ ├── custom-resolv-conf.yml │ ├── disable-nm-dns-processing.yml │ └── server-setup.yml ├── oelabox-ipa │ ├── dns-ext.yml │ ├── domain-prework.yml │ ├── import-ipakeytab.yml │ ├── import-ipaservice.yml │ ├── import-oelagroups.yml │ ├── import-oelaipaprivs.yml │ ├── import-oelasudo.yml │ └── import-oelausers.yml └── oelabox-koji │ └── init-koji.yml ├── templates ├── oelabox-dns │ └── resolv.conf.j2 └── oelabox-ipa │ ├── etc │ └── named │ │ ├── ipa-ext.conf │ │ └── ipa-options-ext.conf │ └── tmp │ └── binder.update.j2 ├── tools └── oelabox-koji │ └── oelaimporter │ ├── install.yml │ └── oelaimporter.py └── vars ├── oelabox-dns ├── common.yml └── main.yml ├── oelabox-ipa ├── ipa │ ├── adminusers.yml │ ├── agreements.yml │ ├── common.yml │ ├── fdns.yml │ ├── groups.yml │ ├── ipaclient.yml │ ├── ipaprivs.yml │ ├── ipareplica.yml │ ├── ipaserver.yml │ ├── rdns.yml │ ├── sudorules.yml │ ├── svcusers.yml │ └── users.yml ├── ipaserver.yml └── main.yml └── oelabox-koji ├── common.yml ├── ipa-keytabs.yml ├── ipa-services.yml ├── main.yml └── production ├── koji-common.yml ├── kojid.yml └── kojihub.yml /README.md: -------------------------------------------------------------------------------- 1 | # Oela Box 2 | 3 | Oela Box is a infrstructure in a box designed for Enterprise Linux development. Oela Box utilizes Vagrant and Ansible for virtual machine provisioning. Oela Box specifically targets OpenELA development and is configured for OpenELA development. Theoretically any Enterprise Linux can be developed using Oela Box. 4 | 5 | If you would like to learn more about Oela Box documentation can be found in the "docs" directory. As of right now the documentation is incomplete, but complete enough to help you understand how Oela Box works. 6 | 7 | # Getting Started 8 | To Get started with Oela Box I recommend having either a dedicated machine or virtual machine running either Rocky Linux 9.3 Minimal or Oracle Linux 9.3 Minimal. 9 | 10 | ## Recommended Specs 11 | Recommended specs are based on my workstation specs. 12 | The recommended specs are as follows: 13 | - An 8 core 16 thread CPU (Ryzen 5800x) 14 | - 16 GB of DDR4 memory 15 | - Atleast 200 GB of storage space (For wiggle room, but you can get away with less) 16 | 17 | For a virtual machine: 18 | - 8 cores dedicated 19 | - 10 GB dedicated memory 20 | - 200 GB dediated storage space (For wiggle room, but you can get away with less) 21 | 22 | ## Run The Setup Script 23 | A shell script is provided called "setup.sh". It bootstraps the system to be able to run the Ansible playbook. Once it has completed it will then run the setup.yml Ansible playbook. Setup is estimated to take about 10 - 20 minutes. 24 | 25 | ``` 26 | sudo sh setup.sh 27 | ``` 28 | 29 | ## Start Oela Box 30 | Starting Oela Box is pretty simple. Provisioning is estimated to take about 30 minutes. 31 | 32 | ``` 33 | vagrant up 34 | ``` 35 | 36 | ## Stop Oela Box 37 | 38 | ``` 39 | vagrant halt 40 | ``` 41 | 42 | ## Resetting Oela Box 43 | If you want to reset Oela Box for any reason it's required to handle this carefully. Vagrant gets a little quirky when the vms are destroyed and recreated too quickly. 44 | 45 | This will cause Vagrant to become unpredictable and may also result in the provisioning playbooks failing. 46 | ``` 47 | vagrant destroy -f && vagrant up 48 | ``` 49 | 50 | This will also make vagrant and provisioning unpredictable. 51 | ``` 52 | vagrant destroy -f && sleep 600 && vagrant up 53 | ``` 54 | 55 | The most predictable way to reset Oela Box is to vagrant destroy, get coffee and vagrant up. 56 | ``` 57 | vagrant destroy -f 58 | ``` 59 | 60 | Wait 10 minutes 61 | 62 | ``` 63 | vagrant up 64 | ``` 65 | 66 | This is weird and I know it's weird, but trust me. I discovered this quirk from rapidly resetting Oela Box during development. It caused a lot of headache. Once I actually timed it and found vagrant destroy, wait 10 minutes, and vagrant up was the way I had to do it. 67 | 68 | ## Local Web Interfaces. 69 | The Free IPA and Koji web interfaces can be found at https://ipa.oelabox.local and https://koji.oelabox.local/koji. They're only accessible locally. 70 | 71 | ## Login To Koji Server and Start A Build 72 | 73 | Login through ssh. (I usually use a VNC viewer since it's more stable.) 74 | ``` 75 | vagrant ssh kojiserver 76 | ``` 77 | 78 | Login to Kerberos as oelakoji. (Password: ThisIsNotMyPassword1!) 79 | ``` 80 | kinit oelakoji 81 | ``` 82 | 83 | Test Koji authentication. (Should say "Hello, oelakoji!" in a randomly chosen language) 84 | ``` 85 | koji moshimoshi 86 | ``` 87 | 88 | Add bash package to dist-oela8. 89 | ``` 90 | koji add-pkg dist-oela8 bash --owner oelakoji 91 | ``` 92 | 93 | Start build of Bash from openela-main SCM. 94 | ``` 95 | koji build dist-oela8 'git+https://github.com/openela-main/bash#el8' 96 | ``` 97 | 98 | You can now watch the task at https://koji.oelabox.local/koji or on the command line. 99 | 100 | 101 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | 3 | ENV['VAGRANT_DEFAULT_PROVIDER'] = 'libvirt' 4 | ENV['VAGRANT_NO_PARALLEL'] = 'yes' 5 | 6 | Vagrant.configure("2") do |config| 7 | config.vm.box = "rockylinux/9" 8 | config.vm.box_check_update = false 9 | config.vm.synced_folder '.', '/vagrant', disabled: true 10 | #config.vm.provider :libvirt do |v| 11 | # v.memorybacking :access, :mode => "shared" 12 | #end 13 | #config.vm.synced_folder "./", "/vagrant", type: "virtiofs" 14 | #config.vm.network "forwarded_port", guest: 22, host: 22 15 | config.ssh.forward_agent = true 16 | 17 | # DNS Server 18 | config.vm.define :dnsserver do |dns| 19 | dns.vm.hostname = 'dns.oelabox.local' 20 | dns.vm.network :private_network, ip: "192.168.121.10" 21 | 22 | dns.vm.provider :libvirt do |v| 23 | v.memory = 512 24 | v.cpus = 2 25 | end 26 | 27 | dns.vm.provision "ansible" do |ansible| 28 | ansible.playbook = "provision-oelabox-dns.yml" 29 | ansible.inventory_path = "inventory.ini" 30 | end 31 | end 32 | 33 | # IPA Server 34 | config.vm.define :ipaserver do |ipa| 35 | ipa.vm.hostname = 'ipa.oelabox.local' 36 | ipa.vm.network :private_network, ip: "192.168.121.11" 37 | 38 | ipa.vm.provider :libvirt do |v| 39 | v.memory = 4096 40 | v.cpus = 2 41 | end 42 | 43 | ipa.vm.provision "ansible" do |ansible| 44 | ansible.playbook = "provision-oelabox-dns-client.yml" 45 | ansible.inventory_path = "inventory.ini" 46 | ansible.extra_vars = { host: "dnsclient" } 47 | end 48 | 49 | ipa.vm.provision "ansible" do |ansible| 50 | ansible.playbook = "provision-oelabox-ipa.yml" 51 | ansible.inventory_path = "inventory.ini" 52 | end 53 | 54 | ipa.vm.provision "ansible" do |ansible| 55 | ansible.playbook = "init-oelabox-ipa-team.yml" 56 | ansible.inventory_path = "inventory.ini" 57 | end 58 | end 59 | 60 | # Koji Server 61 | config.vm.define :kojiserver do |koji| 62 | koji.vm.box = "centos/stream8" 63 | 64 | koji.vm.hostname = 'koji.oelabox.local' 65 | koji.vm.network :private_network, ip: "192.168.121.12" 66 | 67 | koji.vm.provider :libvirt do |v| 68 | v.storage :file, :size => '70G', :device => 'vdb' 69 | v.memory = 4096 70 | v.cpus = 2 71 | end 72 | 73 | # Add IPA builtin DNS server to resolv.conf, so the IPA client can be provisioned 74 | koji.vm.provision "ansible" do |ansible| 75 | ansible.playbook = "provision-oelabox-dns-client.yml" 76 | ansible.inventory_path = "inventory.ini" 77 | ansible.extra_vars = { 78 | host: "ipaclient", 79 | resolv_entries: [ 80 | nameserver: "192.168.121.11", 81 | search: [ "oelabox.local" ], 82 | ], 83 | } 84 | end 85 | 86 | koji.vm.provision "ansible" do |ansible| 87 | ansible.playbook = "provision-oelabox-ipa-client.yml" 88 | ansible.inventory_path = "inventory.ini" 89 | ansible.extra_vars = { host: "ipaclient" } 90 | end 91 | 92 | koji.vm.provision "ansible" do |ansible| 93 | ansible.playbook = "provision-oelabox-koji-builder.yml" 94 | ansible.inventory_path = "inventory.ini" 95 | end 96 | 97 | koji.vm.provision "ansible" do |ansible| 98 | ansible.playbook = "init-oelabox-koji-ecosystem.yml" 99 | ansible.inventory_path = "inventory.ini" 100 | end 101 | end 102 | 103 | config.vm.provision "tools", type: "ansible" do |t| 104 | t.playbook = "setup-oelabox-tools.yml" 105 | t.inventory_path = "inventory.ini" 106 | end 107 | end 108 | -------------------------------------------------------------------------------- /collections/requirements.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxbyte9p/oelabox/b765823161c5ccb650c102a572bc66c44edf6b0e/collections/requirements.yml -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | 5 | # Oela Box 6 | 7 | - About Oela Box 8 | - [Purpose of Oela Box](topics/about-PurposeOfOelaBox.md#purpose) 9 | - [Expectations of Oela Box](topics/about-ExpectationsOfOelaBox.md#expectations) 10 | - [Expectations of The User](topics/about-ExpectationsOfTheUser.md#userexpectations) 11 | - [Learning Resources](topics/about-ExpectationsOfTheUser.md#learning) 12 | - [Technical Aspects of Oela Box](topics/about-TechnicalAspectsOfOelaBox.md#technical) 13 | - [Vagrant](topics/about-TechnicalAspectsOfOelaBox.md#vagrant) 14 | - [Virtual Machines](topics/about-TechnicalAspectsOfOelaBox.md#virtualmachines) 15 | - [DNS Server](topics/about-TechnicalAspectsOfOelaBox.md#dnsserver) 16 | - [IPA Server](topics/about-TechnicalAspectsOfOelaBox.md#ipaserver) 17 | - [Koji Server](topics/about-TechnicalAspectsOfOelaBox.md#kojiserver) 18 | - [Koji Builder](topics/about-TechnicalAspectsOfOelaBox.md#kojibuilder) 19 | - [Koji Hub](topics/about-TechnicalAspectsOfOelaBox.md#kojihub) 20 | - [Koji Web](topics/about-TechnicalAspectsOfOelaBox.md#kojiweb) 21 | - [Kojira](topics/about-TechnicalAspectsOfOelaBox.md#kojira) 22 | - [Koji-gc](topics/about-TechnicalAspectsOfOelaBox.md#kojigc) 23 | - [Apache2](topics/about-TechnicalAspectsOfOelaBox.md#apache2) 24 | - [IPA Client](topics/about-TechnicalAspectsOfOelaBox.md#ipaclient) 25 | - [Ansible](topics/about-TechnicalAspectsOfOelaBox.md#ansible) 26 | - [Types of Playbooks and Task Files](topics/about-TechnicalAspectsOfOelaBox.md#playbooksandtaskfiletypes) 27 | - [Provisioning Playbooks](topics/about-TechnicalAspectsOfOelaBox.md#provisioningplaybooks) 28 | - [Initializer Playbooks](topics/about-TechnicalAspectsOfOelaBox.md#initializerplaybooks) 29 | - [Import Task Files](topics/about-TechnicalAspectsOfOelaBox.md#importtaskfiles) 30 | - [Roles Included With Oela Box](topics/about-TechnicalAspectsOfOelaBox.md#rolesincluded) 31 | - [Role Naming Scheme Examples](topics/about-TechnicalAspectsOfOelaBox.md#rolenaming) 32 | - [oelabox.kojid](topics/about-TechnicalAspectsOfOelaBox.md#oelabox.kojid) 33 | - [oelabox.geerlingguy.postgresql](topics/about-TechnicalAspectsOfOelaBox.md#oelabox.geerlingguy.postgresql) 34 | - [Bash](topics/about-TechnicalAspectsOfOelaBox.md#bash) 35 | - [Python](topics/about-TechnicalAspectsOfOelaBox.md#python) 36 | - [Koji Error Example](topics/about-TechnicalAspectsOfOelaBox.md#kojierrorexample) 37 | - [Enterprise Linux](topics/about-technicalAspectsOfOelaBox.md#enterpriselinux) 38 | 39 | - Operation of Oela Box 40 | - [Preparation](topics/operation-Preparation.md#preparation) 41 | - [Recommended Hardware Specs](topics/operation-Preparation.md#hardwarespecs) 42 | - [Recommended Virtual Machine Specs](topics/operation-Preparation.md#virtualmachinespecs) 43 | - [OS Compatibility](topics/operation-Preparation.md#oscompat) 44 | - [Automated Setup](topics/operation-Preparation.md#setup) 45 | - [Start, Stop, Destroy, and Reset](topics/operation-StartStopDestroyandReset.md#ssdr) 46 | - [Start](topics/operation-StartStopDestroyandReset.md#start) 47 | - [Stop](topics/operation-StartStopDestroyandReset.md#stop) 48 | - [Destroy](topics/operation-StartStopDestroyandReset.md#destroy) 49 | - [Reset](topics/operation-StartStopDestroyandReset.md#reset) 50 | - [Koji Server](topics/operation-KojiServer.md#kojiserver) 51 | - [Login Through SSH](topics/operation-KojiServer.md#loginssh) 52 | - [Login To The oelakoji User With Kerberos](topics/operation-KojiServer.md#loginoelakoji) 53 | - [Test Koji Kerberos Authentication](topics/operation-KojiServer.md#testkerbauth) 54 | - [About Package Building](topics/operation-KojiServer.md#aboutpkgbuilding) 55 | - [Basic Information About Tags](topics/operation-KojiServer.md#basictaginfo) 56 | - [Dist Tags](topics/operation-KojiServer.md#disttags) 57 | - [Build Tags](topics/operation-KojiServer.md#buildtags) 58 | - [SCM](topics/operation-KojiServer.md#scm) 59 | - [Building A Package](topics/operation-KojiServer.md#buildingapkg) 60 | - [Tools](topics/operation-Tools.md#tools) 61 | - [Oela Box Koji](topics/operation-Tools.md#oelabox-koji) 62 | - [Oela Importer](topics/operation-Tools.md#oelaimporter) 63 | - [Basic Usage](topics/operation-Tools.md#basicusage) 64 | - [Regex Mode](topics/operation-Tools.md#regmod) 65 | - [Machine Readable Mode](topics/operation-Tools.md#machmod) 66 | - [Chunking](topics/operation-Tools.md#chunking) 67 | - [Only](topics/operation-Tools.md#only) 68 | 69 | - DNS Server 70 | 71 | - IPA Server 72 | 73 | - Koji Server 74 | -------------------------------------------------------------------------------- /docs/compile-docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | compile() { 4 | pandoc -s $1 -o ${2}/$(basename ${1%.*}).html --toc --metadata title="$(basename ${1%.*})" 5 | } 6 | 7 | [ ! -d /tmp/oeladoc ] && mkdir -pv /tmp/oeladoc/topics 8 | 9 | compile README.md /tmp/oeladoc 10 | for i in $(ls -1 topics/*); do echo "Compiling: $i"; compile $i /tmp/oeladoc/topics; done 11 | -------------------------------------------------------------------------------- /docs/topics/about-ExpectationsOfOelaBox.md: -------------------------------------------------------------------------------- 1 | 5 | # Expectations of Oela Box 6 | Oela Box strives to be a high quality, easy to use, well documented development environment for Enterprise Linux. More specifically OpenELA. Lack of documentation is considered a serious bug. If a user has trouble understanding how to use Oela Box or how Oela Box works that is also considered a serious bug. A user should be able to take a glance at the moving parts and be able to immediately understand how they work. 7 | -------------------------------------------------------------------------------- /docs/topics/about-ExpectationsOfTheUser.md: -------------------------------------------------------------------------------- 1 | 5 | # Expectations of The User 6 | Oela Box expects that the end user has a basic understanding of Ansible, Vagrant, Bash, Python and Enterprise Linux. While I have a disdain for the idea of assumed knowledge I cannot teach you everything. I will however try my best to make sure you are able to understand and use Oela Box. 7 | 8 | ## Learning Resources 9 | To ensure that you are on the right track and to eliminate the issue of assumed knowledge I am providing you a list of resources that I have used myself. The resources I have linked to I believe go over the most important aspects and tools you will see in Oela Box. 10 | 11 | - [Ansible for DevOps By Jeff Geerling](https://www.jeffgeerling.com/project/ansible-devops) 12 | - [Vagrant Documentation](https://developer.hashicorp.com/vagrant/docs) 13 | - [Bash Reference Manual](https://www.gnu.org/software/bash/manual/bash.html) 14 | - [Functional Python Programming By Steven F. Lott](https://www.packtpub.com/product/functional-python-programming-third-edition/9781803232577) 15 | - [Python Data Structures and Algorithms By Benjamin Baka](https://www.packtpub.com/product/python-data-structures-and-algorithms/9781786467355) 16 | - [Serious Python By Julien Danjou](https://nostarch.com/seriouspython) 17 | - [Koji Documentation](https://docs.pagure.org/koji/HOWTO/) 18 | - [Mock Documentation](https://rpm-software-management.github.io/mock/) 19 | - [Skip's Blog on Rocky Linux](https://skip.linuxdn.org/blog.html#000_Rocky0_Intro) 20 | -------------------------------------------------------------------------------- /docs/topics/about-PurposeOfOelaBox.md: -------------------------------------------------------------------------------- 1 | 5 | # Purpose of Oela Box 6 | The purpose of Oela Box is to have a primarily self-contained Enterprise Linux development environment. Oela Box is designed to be easy to use for anyone familiar with Ansible, Vagrant, and Enterprise Linux. Portability between Enterprise Linux distributions is also taken into consideration. 7 | -------------------------------------------------------------------------------- /docs/topics/operation-Preparation.md: -------------------------------------------------------------------------------- 1 | 5 | # Preparation 6 | 7 | ## Recommended Hardware Specs 8 | Recommended hardware specs are based on my workstation specs. 9 | 10 | The recommended specs are as follows: 11 | - An 8 core 16 thread CPU (Ryzen 5800x) 12 | - 16 GB of DDR4 memory 13 | - Atleast 200 GB of storage space 14 | 15 | I recommend a CPU like the Ryzen 5800x specifically due to it being a great processor with enough cores which can be dedicated to the Oela Box virtual machines. It is important to ensure we have enough cores in order to get the best performance out of Oela Box. This processor also gives us enough wiggle room to dedicate more cores if we choose to do so. 16 | 17 | I recommend at least 16 GB of memory due to the fact Oela Box eats a lot of memory. It often uses up to 10 GB of memory on my workstation. It has been difficult to run Oela Box alongside other applications. I had many times where I would run entirely out of both memory and swap causing my system to freeze. 18 | 19 | I recommend at least 200 GB of storage space as that gives us wiggle room for the Koji server. Package builds in Koji can use up a lot of disk space and it's best for us to have more than we need rather than not enough. As of right now the Koji server defined in the Vagrant file is hard coded to create a 70 GB disk. This is good for testing, but I recommend upping it to much more than that. 20 | 21 | Lastly, I recommend running Oela Box on a dedicated machine, so you don't run into any similar memory related issues mentioned before. 22 | 23 | ## Recommended Virtual Machine Specs 24 | Recommended virtual machine specs are based on my QA testing virtual machine. 25 | 26 | The recommended specs are as follows: 27 | - 8 cores dedicated 28 | - 10 GB dedicated memory 29 | - 200 GB dedicated storage space 30 | 31 | I recommend dedicating 8 cores in order to ensure the Oela Box virtual machines which will be nested can also have dedicated cores. 32 | 33 | I recommend 10 GB of dedicated memory as that is the absolute bare minimum for running Oela Box inside of a virtual machine running Rocky 9.3 Minimal. 34 | 35 | I recommend 200 GB of dedicated storage space for the same reason as before in Recommended Hardware Specs. 36 | 37 | ## OS Compatibility 38 | A Rocky Linux 9.3 or Oracle Linux 9.3 install is recommended. 39 | 40 | Oela Box has been thoroughly tested on Rocky Linux 9.3 minimal and Oracle Linux 9.3 minimal. All parts of Oela Box are ensured to work on Rocky Linux 9.3 and Oracle Linux 9.3. 41 | 42 | Oela Box is likely to work on other Enterprise Linux distributions with minimal modification, but this is not guaranteed and has not been thoroughly tested. However I still want to support the entire Enterprise Linux ecosystem. 43 | 44 | ## Automated Setup 45 | Setup of Oela Box is automated using a shell script called "setup.sh" and an Ansible playbook called "setup.yml". 46 | 47 | The "setup.sh" shell script bootstraps a Rocky Linux 9.3 or Oracle Linux 9.3 install to be able to run the "setup.yml" Ansible playbook. Once the system is capable of running the playbook the script then runs the playbook for us. 48 | 49 | The "setup.yml" playbook installs all the required dependencies and configures the system for Oela Box. 50 | 51 | To run the "setup.sh" script: 52 | ``` 53 | sudo sh setup.sh 54 | ``` 55 | 56 | Setup is estimated to take about 10 - 20 minutes. 57 | -------------------------------------------------------------------------------- /docs/topics/operation-StartStopDestroyandReset.md: -------------------------------------------------------------------------------- 1 | 5 | # Start, Stop, Destroy, and Reset 6 | 7 | ## Start 8 | Starting Oela Box is pretty simple. Provisioning is estimated to take about 30 minutes. 9 | 10 | ``` 11 | vagrant up 12 | ``` 13 | 14 | ## Stop 15 | ``` 16 | vagrant halt 17 | ``` 18 | 19 | ## Destroy 20 | ``` 21 | vagrant destroy -f 22 | ``` 23 | 24 | ## Reset 25 | If you want to reset Oela Box for any reason it's required to handle this carefully. Vagrant gets a little quirky when the vms are destroyed and recreated too quickly. 26 | 27 | This will cause Vagrant to become unpredictable and may also result in the provisioning playbooks failing. 28 | ``` 29 | vagrant destroy -f && vagrant up 30 | ``` 31 | 32 | This will also make vagrant and provisioning unpredictable. 33 | ``` 34 | vagrant destroy -f && sleep 600 && vagrant up 35 | ``` 36 | 37 | The most predictable way to reset Oela Box is to vagrant destroy, get coffee and vagrant up. 38 | ``` 39 | vagrant destroy -f 40 | ``` 41 | 42 | Wait 10 minutes 43 | 44 | ``` 45 | vagrant up 46 | ``` 47 | 48 | This is weird and I know it's weird, but trust me. I discovered this quirk from rapidly resetting Oela Box during development. It caused a lot of headache. Once I actually timed it. I found vagrant destroy, wait 10 minutes, and vagrant up to be the most predictable way to reset Oela Box. 49 | -------------------------------------------------------------------------------- /files/oelabox-dns/121.168.192.in-addr.arpa.zone: -------------------------------------------------------------------------------- 1 | $TTL 8h 2 | @ IN SOA ns1.oelabox.local. hostmaster.oelabox.local. ( 3 | 1 ; serial number 4 | 1d ; refresh period 5 | 3h ; retry period 6 | 3d ; expire time 7 | 3h ) ; minimum TTL 8 | 9 | IN NS ns1.oelabox.local. 10 | 11 | 1 IN PTR ns1.oelabox.local. 12 | 30 IN PTR www.oelabox.local. 13 | -------------------------------------------------------------------------------- /files/oelabox-dns/named.conf: -------------------------------------------------------------------------------- 1 | // 2 | // named.conf 3 | // 4 | // Provided by Red Hat bind package to configure the ISC BIND named(8) DNS 5 | // server as a caching only nameserver (as a localhost DNS resolver only). 6 | // 7 | // See /usr/share/doc/bind*/sample/ for example named configuration files. 8 | // 9 | 10 | options { 11 | listen-on port 53 { 127.0.0.1; 192.168.121.10; }; 12 | listen-on-v6 port 53 { ::1; }; 13 | directory "/var/named"; 14 | dump-file "/var/named/data/cache_dump.db"; 15 | statistics-file "/var/named/data/named_stats.txt"; 16 | memstatistics-file "/var/named/data/named_mem_stats.txt"; 17 | secroots-file "/var/named/data/named.secroots"; 18 | recursing-file "/var/named/data/named.recursing"; 19 | allow-query { localhost; 192.168.121.0/24; }; 20 | 21 | /* 22 | - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion. 23 | - If you are building a RECURSIVE (caching) DNS server, you need to enable 24 | recursion. 25 | - If your recursive DNS server has a public IP address, you MUST enable access 26 | control to limit queries to your legitimate users. Failing to do so will 27 | cause your server to become part of large scale DNS amplification 28 | attacks. Implementing BCP38 within your network would greatly 29 | reduce such attack surface 30 | */ 31 | recursion yes; 32 | 33 | dnssec-enable yes; 34 | dnssec-validation yes; 35 | 36 | managed-keys-directory "/var/named/dynamic"; 37 | 38 | pid-file "/run/named/named.pid"; 39 | session-keyfile "/run/named/session.key"; 40 | 41 | /* https://fedoraproject.org/wiki/Changes/CryptoPolicy */ 42 | include "/etc/crypto-policies/back-ends/bind.config"; 43 | }; 44 | 45 | logging { 46 | channel default_debug { 47 | file "data/named.run"; 48 | severity dynamic; 49 | }; 50 | }; 51 | 52 | zone "." IN { 53 | type hint; 54 | file "named.ca"; 55 | }; 56 | 57 | zone "121.168.192.in-addr.arpa" { 58 | type master; 59 | file "121.168.192.in-addr.arpa.zone"; 60 | allow-query { any; }; 61 | allow-transfer { none; }; 62 | }; 63 | 64 | 65 | zone "oelabox.local" { 66 | type master; 67 | file "oelabox.local.zone"; 68 | allow-query { any; }; 69 | allow-transfer { none; }; 70 | }; 71 | 72 | 73 | include "/etc/named.rfc1912.zones"; 74 | include "/etc/named.root.key"; 75 | 76 | -------------------------------------------------------------------------------- /files/oelabox-dns/oelabox.local.zone: -------------------------------------------------------------------------------- 1 | $TTL 8h 2 | @ IN SOA ns1.oelabox.local. hostmaster.oelabox.local. ( 3 | 1 ; serial number 4 | 1d ; refresh period 5 | 3h ; retry period 6 | 3d ; expire time 7 | 3h ) ; minimum TTL 8 | 9 | IN NS ns1.oelabox.local. 10 | 11 | dns IN A 192.168.121.10 12 | ns1 IN A 192.168.121.10 13 | @ IN A 192.168.121.10 14 | ipa IN A 192.168.121.11 15 | koji IN A 192.168.121.12 16 | 17 | _kerberos-master._tcp.oelabox.local. 3600 IN SRV 0 100 88 ipa.oelabox.local. 18 | _kerberos-master._udp.oelabox.local. 3600 IN SRV 0 100 88 ipa.oelabox.local. 19 | _kerberos._tcp.oelabox.local. 3600 IN SRV 0 100 88 ipa.oelabox.local. 20 | _kerberos._udp.oelabox.local. 3600 IN SRV 0 100 88 ipa.oelabox.local. 21 | _kerberos.oelabox.local. 3600 IN TXT "OELABOX.LOCAL" 22 | _kerberos.oelabox.local. 3600 IN URI 0 100 "krb5srv:m:tcp:ipa.oelabox.local." 23 | _kerberos.oelabox.local. 3600 IN URI 0 100 "krb5srv:m:udp:ipa.oelabox.local." 24 | _kpasswd._tcp.oelabox.local. 3600 IN SRV 0 100 464 ipa.oelabox.local. 25 | _kpasswd._udp.oelabox.local. 3600 IN SRV 0 100 464 ipa.oelabox.local. 26 | _kpasswd.oelabox.local. 3600 IN URI 0 100 "krb5srv:m:tcp:ipa.oelabox.local." 27 | _kpasswd.oelabox.local. 3600 IN URI 0 100 "krb5srv:m:udp:ipa.oelabox.local." 28 | _ldap._tcp.oelabox.local. 3600 IN SRV 0 100 389 ipa.oelabox.local. 29 | ipa-ca.oelabox.local. 3600 IN A 192.168.121.11 30 | -------------------------------------------------------------------------------- /files/oelabox-dns/resolv.conf: -------------------------------------------------------------------------------- 1 | search oelabox.local 2 | nameserver 127.0.0.1 3 | 4 | nameserver 192.168.121.1 5 | -------------------------------------------------------------------------------- /files/oelabox-koji/getsrc/SPECS/getsrc.spec: -------------------------------------------------------------------------------- 1 | Name: getsrc 2 | Version: 1.0.0 3 | Release: 1%{?dist} 4 | Summary: Simple lookaside grabber 5 | BuildArch: noarch 6 | 7 | License: MIT 8 | URL: https://github.com/rocky-linux/rocky-tools/tree/main/getsrc 9 | Source0: %{name}-%{version}.tar.gz 10 | 11 | Requires: bash 12 | Requires: git 13 | Requires: curl 14 | Requires: rpm-build 15 | 16 | %description 17 | Simple lookaside grabber from rocky-tools 18 | 19 | 20 | %prep 21 | %setup -q 22 | 23 | 24 | %install 25 | rm -rf $RPM_BUILD_ROOT 26 | mkdir -p $RPM_BUILD_ROOT/%{_bindir} 27 | install -m 755 %{name}.sh $RPM_BUILD_ROOT/%{_bindir} 28 | 29 | 30 | %files 31 | %{_bindir}/%{name}.sh 32 | 33 | 34 | 35 | %changelog 36 | * Mon Feb 12 2024 maxbyte9p 37 | - 38 | -------------------------------------------------------------------------------- /handlers/oelabox-dns/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart_named 3 | ansible.builtin.service: 4 | name: named 5 | state: restarted 6 | 7 | - name: restart_networkmanager 8 | ansible.builtin.service: 9 | name: NetworkManager 10 | state: restarted 11 | -------------------------------------------------------------------------------- /handlers/oelabox-ipa/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Handlers 3 | - name: reload_networkmanager 4 | ansible.builtin.service: 5 | name: NetworkManager 6 | state: reloaded 7 | 8 | - name: restart_named 9 | ansible.builtin.service: 10 | name: named 11 | state: restarted 12 | 13 | - name: enable_firewalld 14 | ansible.builtin.service: 15 | name: firewalld 16 | state: started 17 | enabled: true 18 | 19 | - name: enable_crb 20 | ansible.builtin.shell: "set -o pipefail && /usr/bin/crb enable" 21 | changed_when: "1 != 1" 22 | 23 | - name: enable_core_infra 24 | ansible.builtin.shell: "set -o pipefail && /usr/bin/dnf config-manager --enable core-infra" 25 | changed_when: "1 != 1" 26 | ... 27 | -------------------------------------------------------------------------------- /handlers/oelabox-koji/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: enable_crb 3 | ansible.builtin.shell: "set -o pipefail && /usr/bin/crb enable" 4 | changed_when: "1 != 1" 5 | -------------------------------------------------------------------------------- /init-oelabox-ipa-team.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create our initial users 3 | hosts: ipaserver 4 | become: true 5 | gather_facts: false 6 | 7 | vars_files: 8 | - vars/oelabox-ipa/ipa/users.yml 9 | - vars/oelabox-ipa/ipa/adminusers.yml 10 | - vars/oelabox-ipa/ipa/svcusers.yml 11 | - vars/oelabox-ipa/ipa/groups.yml 12 | - vars/oelabox-ipa/ipa/ipaprivs.yml 13 | 14 | tasks: 15 | - name: "Checking for user variables" 16 | ansible.builtin.assert: 17 | that: 18 | - ipaadmin_password | mandatory 19 | - users | mandatory 20 | - ipagroups | mandatory 21 | success_msg: "Requires variables provided" 22 | fail_msg: "We are missing users or ipa admin password" 23 | 24 | - name: "Start users" 25 | import_tasks: tasks/oelabox-ipa/import-oelausers.yml 26 | 27 | - name: "Start groups" 28 | import_tasks: tasks/oelabox-ipa/import-oelagroups.yml 29 | 30 | - name: "Start sudo for admins" 31 | import_tasks: tasks/oelabox-ipa/import-oelasudo.yml 32 | 33 | - name: "Start privileges for services" 34 | import_tasks: tasks/oelabox-ipa/import-oelaipaprivs.yml 35 | -------------------------------------------------------------------------------- /init-oelabox-koji-ecosystem.yml: -------------------------------------------------------------------------------- 1 | - name: Initialize Koji ecosystem 2 | hosts: "kojihub" 3 | become: true 4 | 5 | tasks: 6 | - name: Build out relevent accounts and components 7 | import_tasks: tasks/oelabox-koji/init-koji.yml 8 | -------------------------------------------------------------------------------- /init-oelabox-koji-keytabs.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create Koji keytabs 3 | hosts: kojihub 4 | become: yes 5 | 6 | vars: 7 | ipa_admin: admin 8 | host: koji.oelabox.local 9 | ipa_server: ipa.oelabox.local 10 | ipa_owner: root 11 | ipa_keytab_file_perms: '0644' 12 | 13 | keytabs: 14 | - keytab: 15 | service: compile/koji.oelabox.local 16 | path: /etc/kojid.keytab 17 | - keytab: 18 | service: HTTP/koji.oelabox.local 19 | path: /etc/keytabs/koji-web.keytab 20 | - keytab: 21 | service: kojira/koji.oelabox.local 22 | path: /etc/keytabs/kojira.keytab 23 | - keytab: 24 | service: koji-gc/koji.oelabox.local 25 | path: /etc/keytabs/koji-gc.keytab 26 | 27 | tasks: 28 | - name: '/etc/keytabs' 29 | ansible.builtin.file: 30 | path: /etc/keytabs 31 | state: directory 32 | owner: root 33 | group: root 34 | mode: '0755' 35 | 36 | - name: '/etc/keytabs/host.keytab' 37 | ansible.builtin.file: 38 | src: /etc/krb5.keytab 39 | dest: /etc/keytabs/host.keytab 40 | state: link 41 | 42 | - name: Fetch Keytabs 43 | include_tasks: tasks/oelabox-ipa/import-ipakeytab.yml 44 | vars: 45 | ipa_service: '{{ item.service }}' 46 | ipa_keytab_fullpath: '{{ item.path }}' 47 | loop: '{{ keytabs }}' 48 | -------------------------------------------------------------------------------- /init-oelabox-koji-services.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create Koji services 3 | hosts: kojihub 4 | 5 | vars: 6 | ipa_admin: admin 7 | ipaadmin_password: freeloader 8 | services: 9 | - compile/koji.oelabox.local 10 | - HTTP/koji.oelabox.local 11 | - kojira/koji.oelabox.local 12 | - koji-gc/koji.oelabox.local 13 | 14 | tasks: 15 | - name: Create services 16 | include_tasks: tasks/oelabox-ipa/import-ipaservice.yml 17 | vars: 18 | ipa_service: "{{ item }}" 19 | loop: "{{ services }}" 20 | -------------------------------------------------------------------------------- /inventory.ini: -------------------------------------------------------------------------------- 1 | [dnsserver] 2 | dns.oelabox.local 3 | 4 | [dnsclient] 5 | dns.oelabox.local 6 | ipa.oelabox.local 7 | 8 | [ipaserver] 9 | ipa.oelabox.local 10 | 11 | [ipaserver:vars] 12 | ipaadmin_password=freeloader 13 | ipadm_password=freeloader 14 | ipa_binder_name=binder 15 | ipa_binder_password=freeloader 16 | 17 | [ipaclient] 18 | koji.oelabox.local 19 | 20 | [ipaclient:vars] 21 | ipaadmin_password=freeloader 22 | ipaclient_force_join=yes 23 | 24 | [kojiserver] 25 | koji.oelabox.local 26 | 27 | [kojihub] 28 | koji.oelabox.local 29 | 30 | [kojihub:vars] 31 | ipaadmin_password=freeloader 32 | oelakoji_password=ThisIsNotMyPassword1! 33 | 34 | -------------------------------------------------------------------------------- /provision-oelabox-dns-client.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Configure Oela Box DNS client. 3 | hosts: "{{ host | default(dnsclient) }}" 4 | become: true 5 | 6 | handlers: 7 | - import_tasks: handlers/oelabox-dns/main.yml 8 | 9 | tasks: 10 | - name: Use default resolv_entries 11 | ansible.builtin.include_vars: 12 | file: vars/oelabox-dns/common.yml 13 | when: resolv_entries is undefined 14 | 15 | - name: "Checking for user variables" 16 | ansible.builtin.assert: 17 | that: 18 | - resolv_entries | mandatory 19 | success_msg: "Required variables provided" 20 | fail_msg: "We are missing required information" 21 | 22 | - import_tasks: tasks/oelabox-dns/client-setup.yml 23 | -------------------------------------------------------------------------------- /provision-oelabox-dns.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Configure Oela Box DNS Server 3 | hosts: dnsserver 4 | become: yes 5 | 6 | vars_files: 7 | - vars/oelabox-dns/common.yml 8 | 9 | handlers: 10 | - import_tasks: handlers/oelabox-dns/main.yml 11 | 12 | tasks: 13 | - import_tasks: tasks/oelabox-dns/server-setup.yml 14 | -------------------------------------------------------------------------------- /provision-oelabox-ipa-client.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Configure IPA client 3 | hosts: "{{ host | default(ipaclient) }}" 4 | become: true 5 | 6 | vars_files: 7 | - vars/oelabox-ipa/ipa/common.yml 8 | - vars/oelabox-ipa/ipa/ipaclient.yml 9 | 10 | pre_tasks: 11 | - name: Apply hostname based on inventory name 12 | hostname: 13 | name: "{{ inventory_hostname }}" 14 | use: systemd 15 | when: ansible_fqdn != inventory_hostname 16 | 17 | roles: 18 | - role: freeipa.ansible_freeipa.ipaclient 19 | state: present 20 | -------------------------------------------------------------------------------- /provision-oelabox-ipa.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: IPA server pre-work 3 | hosts: ipaserver 4 | become: yes 5 | 6 | handlers: 7 | - import_tasks: handlers/oelabox-dns/main.yml 8 | 9 | tasks: 10 | - name: /etc/hosts 11 | ansible.builtin.copy: 12 | dest: /etc/hosts 13 | content: | 14 | 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 15 | ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 16 | 192.168.121.11 ipa.oelabox.local ipa 17 | notify: restart_networkmanager 18 | 19 | - name: Provision Oela Box IPA server 20 | hosts: ipaserver 21 | become: true 22 | 23 | vars_files: 24 | - vars/oelabox-ipa/ipa/common.yml 25 | - vars/oelabox-ipa/ipa/ipaserver.yml 26 | 27 | handlers: 28 | - import_tasks: handlers/oelabox-ipa/main.yml 29 | 30 | pre_tasks: 31 | - name: Perform domain pre-work 32 | ansible.builtin.import_tasks: tasks/oelabox-ipa/domain-prework.yml 33 | 34 | roles: 35 | - role: freeipa.ansible_freeipa.ipaserver 36 | state: present 37 | 38 | post_tasks: 39 | - name: Turn on reverse zone syncing 40 | freeipa.ansible_freeipa.ipadnsconfig: 41 | ipaadmin_password: '{{ ipaadmin_password }}' 42 | allow_sync_ptr: true 43 | 44 | - name: Configure recursion for private nets 45 | ansible.builtin.import_tasks: tasks/oelabox-ipa/dns-ext.yml 46 | ... 47 | -------------------------------------------------------------------------------- /provision-oelabox-koji-builder.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Koji server pre-work 3 | hosts: kojihub 4 | become: yes 5 | 6 | handlers: 7 | - import_tasks: handlers/oelabox-dns/main.yml 8 | 9 | tasks: 10 | - name: /etc/hosts 11 | ansible.builtin.copy: 12 | dest: /etc/hosts 13 | content: | 14 | 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 15 | ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 16 | 192.168.121.12 koji.oelabox.local koji 17 | notify: restart_networkmanager 18 | 19 | - name: Create ext4 filesystem on /dev/vdb 20 | ansible.builtin.filesystem: 21 | fstype: ext4 22 | dev: /dev/vdb 23 | 24 | - name: Mount /dev/vdb 25 | ansible.builtin.mount: 26 | fstype: ext4 27 | src: /dev/vdb 28 | path: /mnt 29 | state: mounted 30 | 31 | - name: Create /mnt/mock 32 | ansible.builtin.file: 33 | path: /mnt/mock 34 | state: directory 35 | mode: '0755' 36 | 37 | - name: Symlink /var/lib/mock to /mnt/mock 38 | ansible.builtin.file: 39 | src: /mnt/mock 40 | dest: /var/lib/mock 41 | state: link 42 | 43 | - name: Create Koji Services 44 | ansible.builtin.import_playbook: init-oelabox-koji-services.yml 45 | 46 | - name: Create Koji Keytabs 47 | ansible.builtin.import_playbook: init-oelabox-koji-keytabs.yml 48 | 49 | - name: Configure Koji hub and web server 50 | hosts: kojihub 51 | become: true 52 | 53 | vars_files: 54 | - vars/oelabox-koji/common.yml 55 | - vars/oelabox-koji/production/kojihub.yml 56 | - vars/oelabox-koji/production/koji-common.yml 57 | 58 | # This is to try to avoid the handler issue in pre/post tasks 59 | handlers: 60 | - ansible.builtin.import_tasks: handlers/oelabox-koji/main.yml 61 | 62 | pre_tasks: 63 | - name: Check for keytabs - web 64 | ansible.builtin.stat: 65 | path: /etc/keytabs/koji-web.keytab 66 | register: koji_keytab 67 | changed_when: "1 != 1" 68 | 69 | - name: Check for keytabs - kojira 70 | ansible.builtin.stat: 71 | path: /etc/keytabs/kojira.keytab 72 | register: kojira_keytab 73 | changed_when: "1 != 1" 74 | 75 | - name: Check for keytabs - gc 76 | ansible.builtin.stat: 77 | path: /etc/keytabs/koji-gc.keytab 78 | register: gc_keytab 79 | changed_when: "1 != 1" 80 | 81 | - name: Check for keytabs - host 82 | ansible.builtin.stat: 83 | path: /etc/keytabs/host.keytab 84 | register: host_keytab 85 | changed_when: "1 != 1" 86 | 87 | - name: Verify keytab 88 | ansible.builtin.assert: 89 | that: 90 | - "koji_keytab.stat.exists" 91 | - "kojira_keytab.stat.exists" 92 | - "gc_keytab.stat.exists" 93 | - "host_keytab.stat.exists" 94 | success_msg: "It is likely we have all keytabs" 95 | fail_msg: "There are no keytabs. Please build the keytabs." 96 | 97 | - name: Enable the PowerTools repository 98 | community.general.ini_file: 99 | dest: /etc/yum.repos.d/CentOS-Stream-PowerTools.repo 100 | section: powertools 101 | option: enabled 102 | value: 1 103 | owner: root 104 | group: root 105 | mode: '0644' 106 | 107 | - name: Enable the EPEL repository 108 | ansible.builtin.dnf: 109 | name: epel-release 110 | state: present 111 | tags: 112 | - packages 113 | 114 | - name: Install rocky-tools copr 115 | ansible.builtin.yum_repository: 116 | name: copr:copr.fedorainfracloud.org:nalika:rockylinux-tool 117 | description: Copr repo for rockylinux-tools owned by nalika 118 | file: copr_repos 119 | baseurl: https://download.copr.fedorainfracloud.org/results/nalika/rockylinux-tools/epel-8-$basearch/ 120 | gpgcheck: true 121 | gpgkey: https://download.copr.fedorainfracloud.org/results/nalika/rockylinux-tools/pubkey.gpg 122 | enabled: true 123 | 124 | roles: 125 | - role: oelabox.ipagetcert 126 | state: present 127 | 128 | - role: oelabox.geerlingguy.postgresql 129 | state: present 130 | 131 | - role: oelabox.kojihub 132 | state: present 133 | 134 | post_tasks: 135 | - name: kinit as koji admin using password 136 | ansible.builtin.shell: "set -o pipefail && echo \"{{ oelakoji_password }}\" | kinit oelakoji@OELABOX.LOCAL" 137 | check_mode: false 138 | changed_when: "1 != 1" 139 | become: true 140 | become_user: koji 141 | 142 | - name: "Configure Koji builder for hub" 143 | ktdreyer.koji_ansible.koji_host: 144 | koji: koji 145 | name: koji.oelabox.local 146 | arches: [x86_64,i386] 147 | state: enabled 148 | channels: 149 | - default 150 | - createrepo 151 | become: true 152 | become_user: koji 153 | 154 | - name: "Make sure kojira has repo permision" 155 | ktdreyer.koji_ansible.koji_user: 156 | koji: koji 157 | name: kojira 158 | state: enabled 159 | permissions: [sign, repo] 160 | become: true 161 | become_user: koji 162 | 163 | - name: Configure Koji builder 164 | hosts: kojihub 165 | become: true 166 | 167 | vars_files: 168 | - vars/oelabox-koji/common.yml 169 | - vars/oelabox-koji/production/kojid.yml 170 | - vars/oelabox-koji/production/koji-common.yml 171 | 172 | handlers: 173 | - ansible.builtin.import_tasks: handlers/oelabox-koji/main.yml 174 | 175 | pre_tasks: 176 | - name: Check for keytabs - kojid 177 | ansible.builtin.stat: 178 | path: /etc/kojid.keytab 179 | register: kojid_keytab_check 180 | changed_when: "1 != 1" 181 | 182 | - name: Verify keytab 183 | ansible.builtin.assert: 184 | that: 185 | - "kojid_keytab_check.stat.exists" 186 | success_msg: "It is likely we have all keytabs" 187 | fail_msg: "There are no keytabs. Please build the keytabs." 188 | 189 | roles: 190 | - role: oelabox.kojid 191 | state: present 192 | ... 193 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/.ansible-lint: -------------------------------------------------------------------------------- 1 | skip_list: 2 | - 'yaml' 3 | - 'no-handler' 4 | - 'role-name' 5 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | --- 3 | github: geerlingguy 4 | patreon: geerlingguy 5 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-stale - https://github.com/probot/stale 2 | 3 | # Number of days of inactivity before an Issue or Pull Request becomes stale 4 | daysUntilStale: 90 5 | 6 | # Number of days of inactivity before an Issue or Pull Request with the stale label is closed. 7 | # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. 8 | daysUntilClose: 30 9 | 10 | # Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) 11 | onlyLabels: [] 12 | 13 | # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable 14 | exemptLabels: 15 | - bug 16 | - pinned 17 | - security 18 | - planned 19 | 20 | # Set to true to ignore issues in a project (defaults to false) 21 | exemptProjects: false 22 | 23 | # Set to true to ignore issues in a milestone (defaults to false) 24 | exemptMilestones: false 25 | 26 | # Set to true to ignore issues with an assignee (defaults to false) 27 | exemptAssignees: false 28 | 29 | # Label to use when marking as stale 30 | staleLabel: stale 31 | 32 | # Limit the number of actions per hour, from 1-30. Default is 30 33 | limitPerRun: 30 34 | 35 | pulls: 36 | markComment: |- 37 | This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! 38 | 39 | Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. 40 | 41 | unmarkComment: >- 42 | This pull request is no longer marked for closure. 43 | 44 | closeComment: >- 45 | This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. 46 | 47 | issues: 48 | markComment: |- 49 | This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! 50 | 51 | Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. 52 | 53 | unmarkComment: >- 54 | This issue is no longer marked for closure. 55 | 56 | closeComment: >- 57 | This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. 58 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: CI 3 | 'on': 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | schedule: 9 | - cron: "0 3 * * 5" 10 | 11 | defaults: 12 | run: 13 | working-directory: 'geerlingguy.postgresql' 14 | 15 | jobs: 16 | 17 | lint: 18 | name: Lint 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Check out the codebase. 22 | uses: actions/checkout@v2 23 | with: 24 | path: 'geerlingguy.postgresql' 25 | 26 | - name: Set up Python 3. 27 | uses: actions/setup-python@v2 28 | with: 29 | python-version: '3.x' 30 | 31 | - name: Install test dependencies. 32 | run: pip3 install yamllint 33 | 34 | - name: Lint code. 35 | run: | 36 | yamllint . 37 | 38 | molecule: 39 | name: Molecule 40 | runs-on: ubuntu-latest 41 | strategy: 42 | fail-fast: ${{ !contains(github.event_name, 'pull_request') }} 43 | matrix: 44 | distro: 45 | - rockylinux8 46 | - centos7 47 | - fedora36 48 | - ubuntu2204 49 | - ubuntu2004 50 | - ubuntu1804 51 | - debian10 52 | - debian11 53 | # - amazonlinux2 54 | 55 | steps: 56 | - name: Check out the codebase. 57 | uses: actions/checkout@v2 58 | with: 59 | path: 'geerlingguy.postgresql' 60 | 61 | - name: Set up Python 3. 62 | uses: actions/setup-python@v2 63 | with: 64 | python-version: '3.x' 65 | 66 | - name: Install test dependencies. 67 | run: pip3 install ansible molecule[docker] docker 68 | 69 | - name: Run Molecule tests. 70 | run: molecule test 71 | env: 72 | PY_COLORS: '1' 73 | ANSIBLE_FORCE_COLOR: '1' 74 | MOLECULE_DISTRO: ${{ matrix.distro }} 75 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # This workflow requires a GALAXY_API_KEY secret present in the GitHub 3 | # repository or organization. 4 | # 5 | # See: https://github.com/marketplace/actions/publish-ansible-role-to-galaxy 6 | # See: https://github.com/ansible/galaxy/issues/46 7 | 8 | name: Release 9 | 'on': 10 | push: 11 | tags: 12 | - '*' 13 | 14 | defaults: 15 | run: 16 | working-directory: 'geerlingguy.postgresql' 17 | 18 | jobs: 19 | 20 | release: 21 | name: Release 22 | runs-on: ubuntu-latest 23 | steps: 24 | - name: Check out the codebase. 25 | uses: actions/checkout@v2 26 | with: 27 | path: 'geerlingguy.postgresql' 28 | 29 | - name: Set up Python 3. 30 | uses: actions/setup-python@v2 31 | with: 32 | python-version: '3.x' 33 | 34 | - name: Install Ansible. 35 | run: pip3 install ansible-core 36 | 37 | - name: Trigger a new import on Galaxy. 38 | run: >- 39 | ansible-galaxy role import --api-key ${{ secrets.GALAXY_API_KEY }} 40 | $(echo ${{ github.repository }} | cut -d/ -f1) $(echo ${{ github.repository }} | cut -d/ -f2) 41 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/.gitignore: -------------------------------------------------------------------------------- 1 | *.retry 2 | */__pycache__ 3 | *.pyc 4 | .cache 5 | 6 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | 4 | rules: 5 | line-length: 6 | max: 120 7 | level: warning 8 | 9 | ignore: | 10 | .github/stale.yml 11 | .travis.yml 12 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Jeff Geerling 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # RHEL/CentOS only. Set a repository to use for PostgreSQL installation. 3 | postgresql_enablerepo: "" 4 | 5 | # Set postgresql state when configuration changes are made. Recommended values: 6 | # `restarted` or `reloaded` 7 | postgresql_restarted_state: "restarted" 8 | 9 | postgresql_python_library: python-psycopg2 10 | postgresql_user: postgres 11 | postgresql_group: postgres 12 | 13 | # `md5` or `scram-sha-256` (https://www.postgresql.org/docs/10/auth-methods.html) 14 | postgresql_auth_method: "{{ ansible_fips | ternary('scram-sha-256', 'md5') }}" 15 | 16 | postgresql_unix_socket_directories: 17 | - /var/run/postgresql 18 | 19 | postgresql_service_state: started 20 | postgresql_service_enabled: true 21 | 22 | # Global configuration options that will be set in postgresql.conf. 23 | postgresql_global_config_options: 24 | - option: unix_socket_directories 25 | value: '{{ postgresql_unix_socket_directories | join(",") }}' 26 | 27 | # Host based authentication (hba) entries to be added to the pg_hba.conf. This 28 | # variable's defaults reflect the defaults that come with a fresh installation. 29 | postgresql_hba_entries: 30 | - {type: local, database: all, user: postgres, auth_method: peer} 31 | - {type: local, database: all, user: all, auth_method: peer} 32 | - {type: host, database: all, user: all, address: '127.0.0.1/32', auth_method: "{{ postgresql_auth_method }}"} 33 | - {type: host, database: all, user: all, address: '::1/128', auth_method: "{{ postgresql_auth_method }}"} 34 | 35 | # Debian only. Used to generate the locales used by PostgreSQL databases. 36 | postgresql_locales: 37 | - 'en_US.UTF-8' 38 | 39 | # Databases to ensure exist. 40 | postgresql_databases: [] 41 | # - name: exampledb # required; the rest are optional 42 | # lc_collate: # defaults to 'en_US.UTF-8' 43 | # lc_ctype: # defaults to 'en_US.UTF-8' 44 | # encoding: # defaults to 'UTF-8' 45 | # template: # defaults to 'template0' 46 | # login_host: # defaults to 'localhost' 47 | # login_password: # defaults to not set 48 | # login_user: # defaults to '{{ postgresql_user }}' 49 | # login_unix_socket: # defaults to 1st of postgresql_unix_socket_directories 50 | # port: # defaults to not set 51 | # owner: # defaults to postgresql_user 52 | # state: # defaults to 'present' 53 | 54 | # Users to ensure exist. 55 | postgresql_users: [] 56 | # - name: jdoe #required; the rest are optional 57 | # password: # defaults to not set 58 | # encrypted: # defaults to not set 59 | # priv: # defaults to not set 60 | # role_attr_flags: # defaults to not set 61 | # db: # defaults to not set 62 | # login_host: # defaults to 'localhost' 63 | # login_password: # defaults to not set 64 | # login_user: # defaults to '{{ postgresql_user }}' 65 | # login_unix_socket: # defaults to 1st of postgresql_unix_socket_directories 66 | # port: # defaults to not set 67 | # state: # defaults to 'present' 68 | 69 | # Whether to output user data when managing users. 70 | postgres_users_no_log: true 71 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart postgresql 3 | service: 4 | name: "{{ postgresql_daemon }}" 5 | state: "{{ postgresql_restarted_state }}" 6 | sleep: 5 7 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependencies: [] 3 | 4 | galaxy_info: 5 | role_name: postgresql 6 | author: geerlingguy 7 | description: PostgreSQL server for Linux. 8 | company: "Midwestern Mac, LLC" 9 | license: "license (BSD, MIT)" 10 | min_ansible_version: 2.8 11 | platforms: 12 | - name: EL 13 | versions: 14 | - 7 15 | - 8 16 | - name: Fedora 17 | versions: 18 | - 30 19 | - 31 20 | - 32 21 | - 33 22 | - 34 23 | - 35 24 | - 36 25 | - name: Ubuntu 26 | versions: 27 | - xenial 28 | - bionic 29 | - focal 30 | - jammy 31 | - name: Debian 32 | versions: 33 | - wheezy 34 | - jessie 35 | - stretch 36 | - buster 37 | - bullseye 38 | galaxy_tags: 39 | - database 40 | - postgresql 41 | - postgres 42 | - rdbms 43 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/molecule/default/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | become: true 5 | 6 | vars: 7 | postgresql_databases: 8 | - name: example 9 | postgresql_users: 10 | - name: jdoe 11 | 12 | pre_tasks: 13 | # The Fedora 30+ container images have only C.UTF-8 installed 14 | - name: Set database locale if using Fedora 30+ or RedHat 8+ 15 | set_fact: 16 | postgresql_databases: 17 | - name: example 18 | lc_collate: 'C.UTF-8' 19 | lc_ctype: 'C.UTF-8' 20 | when: 21 | - ( ansible_distribution == 'Fedora' and ansible_distribution_major_version >= '30') or 22 | ( ansible_os_family == 'RedHat' and ansible_distribution_major_version == '8') 23 | 24 | - name: Update apt cache. 25 | apt: update_cache=true cache_valid_time=600 26 | changed_when: false 27 | when: ansible_os_family == 'Debian' 28 | 29 | roles: 30 | - role: geerlingguy.postgresql 31 | 32 | post_tasks: 33 | - name: Verify postgres is running. 34 | command: "{{ postgresql_bin_path }}/pg_ctl -D {{ postgresql_data_dir }} status" 35 | changed_when: false 36 | become: true 37 | become_user: postgres 38 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/molecule/default/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | role_name_check: 1 3 | dependency: 4 | name: galaxy 5 | driver: 6 | name: docker 7 | platforms: 8 | - name: instance 9 | image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" 10 | command: ${MOLECULE_DOCKER_COMMAND:-""} 11 | volumes: 12 | - /sys/fs/cgroup:/sys/fs/cgroup:ro 13 | privileged: true 14 | pre_build_image: true 15 | provisioner: 16 | name: ansible 17 | playbooks: 18 | converge: ${MOLECULE_PLAYBOOK:-converge.yml} 19 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/tasks/configure.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Configure global settings. 3 | lineinfile: 4 | dest: "{{ postgresql_config_path }}/postgresql.conf" 5 | regexp: "^#?{{ item.option }}.+$" 6 | line: "{{ item.option }} = '{{ item.value }}'" 7 | state: "{{ item.state | default('present') }}" 8 | mode: 0644 9 | with_items: "{{ postgresql_global_config_options }}" 10 | notify: restart postgresql 11 | 12 | - name: Configure host based authentication (if entries are configured). 13 | template: 14 | src: "pg_hba.conf.j2" 15 | dest: "{{ postgresql_config_path }}/pg_hba.conf" 16 | owner: "{{ postgresql_user }}" 17 | group: "{{ postgresql_group }}" 18 | mode: 0600 19 | notify: restart postgresql 20 | when: postgresql_hba_entries | length > 0 21 | 22 | - name: Ensure PostgreSQL unix socket dirs exist. 23 | file: 24 | path: "{{ item }}" 25 | state: directory 26 | owner: "{{ postgresql_user }}" 27 | group: "{{ postgresql_group }}" 28 | mode: "{{ postgresql_unix_socket_directories_mode }}" 29 | with_items: "{{ postgresql_unix_socket_directories }}" 30 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/tasks/databases.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure PostgreSQL databases are present. 3 | postgresql_db: 4 | name: "{{ item.name }}" 5 | lc_collate: "{{ item.lc_collate | default('en_US.UTF-8') }}" 6 | lc_ctype: "{{ item.lc_ctype | default('en_US.UTF-8') }}" 7 | encoding: "{{ item.encoding | default('UTF-8') }}" 8 | template: "{{ item.template | default('template0') }}" 9 | login_host: "{{ item.login_host | default('localhost') }}" 10 | login_password: "{{ item.login_password | default(omit) }}" 11 | login_user: "{{ item.login_user | default(postgresql_user) }}" 12 | login_unix_socket: "{{ item.login_unix_socket | default(postgresql_unix_socket_directories[0]) }}" 13 | port: "{{ item.port | default(omit) }}" 14 | owner: "{{ item.owner | default(postgresql_user) }}" 15 | state: "{{ item.state | default('present') }}" 16 | with_items: "{{ postgresql_databases }}" 17 | become: true 18 | become_user: "{{ postgresql_user }}" 19 | # See: https://github.com/ansible/ansible/issues/16048#issuecomment-229012509 20 | vars: 21 | ansible_ssh_pipelining: true 22 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/tasks/initialize.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set PostgreSQL environment variables. 3 | template: 4 | src: postgres.sh.j2 5 | dest: /etc/profile.d/postgres.sh 6 | mode: 0644 7 | notify: restart postgresql 8 | 9 | - name: Ensure PostgreSQL data directory exists. 10 | file: 11 | path: "{{ postgresql_data_dir }}" 12 | owner: "{{ postgresql_user }}" 13 | group: "{{ postgresql_group }}" 14 | state: directory 15 | mode: 0700 16 | 17 | - name: Check if PostgreSQL database is initialized. 18 | stat: 19 | path: "{{ postgresql_data_dir }}/PG_VERSION" 20 | register: pgdata_dir_version 21 | 22 | - name: Ensure PostgreSQL database is initialized. 23 | command: "{{ postgresql_bin_path }}/initdb -D {{ postgresql_data_dir }}" 24 | when: not pgdata_dir_version.stat.exists 25 | become: true 26 | become_user: "{{ postgresql_user }}" 27 | # See: https://github.com/ansible/ansible/issues/16048#issuecomment-229012509 28 | vars: 29 | ansible_ssh_pipelining: true 30 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Variable configuration. 3 | - include_tasks: variables.yml 4 | 5 | # Setup/install tasks. 6 | - include_tasks: setup-RedHat.yml 7 | when: ansible_os_family == 'RedHat' 8 | 9 | - include_tasks: setup-Debian.yml 10 | when: ansible_os_family == 'Debian' 11 | 12 | - include_tasks: initialize.yml 13 | - include_tasks: configure.yml 14 | 15 | - name: Ensure PostgreSQL is started and enabled on boot. 16 | service: 17 | name: "{{ postgresql_daemon }}" 18 | state: "{{ postgresql_service_state }}" 19 | enabled: "{{ postgresql_service_enabled }}" 20 | 21 | # Configure PostgreSQL. 22 | - import_tasks: users.yml 23 | - import_tasks: databases.yml 24 | - import_tasks: users_props.yml 25 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/tasks/setup-Debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure PostgreSQL Python libraries are installed. 3 | apt: 4 | name: "{{ postgresql_python_library }}" 5 | state: present 6 | 7 | - name: Ensure PostgreSQL packages are installed. 8 | apt: 9 | name: "{{ postgresql_packages }}" 10 | state: present 11 | 12 | - name: Ensure all configured locales are present. 13 | locale_gen: "name={{ item }} state=present" 14 | with_items: "{{ postgresql_locales }}" 15 | register: locale_gen_result 16 | 17 | - name: Force-restart PostgreSQL after new locales are generated. 18 | service: 19 | name: "{{ postgresql_daemon }}" 20 | state: restarted 21 | when: locale_gen_result.changed 22 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/tasks/setup-RedHat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure PostgreSQL packages are installed. 3 | yum: 4 | name: "{{ postgresql_packages }}" 5 | state: present 6 | enablerepo: "{{ postgresql_enablerepo | default(omit, true) }}" 7 | # Don't let postgresql-contrib cause the /usr/bin/python symlink 8 | # to be installed, which breaks later Ansible runs on Fedora 30, 9 | # and affects system behavior in multiple ways. 10 | exclude: python-unversioned-command 11 | 12 | - name: Ensure PostgreSQL Python libraries are installed. 13 | yum: 14 | name: "{{ postgresql_python_library }}" 15 | state: present 16 | enablerepo: "{{ postgresql_enablerepo | default(omit, true) }}" 17 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/tasks/users.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure PostgreSQL users are present. 3 | postgresql_user: 4 | name: "{{ item.name }}" 5 | password: "{{ item.password | default(omit) }}" 6 | login_host: "{{ item.login_host | default('localhost') }}" 7 | login_password: "{{ item.login_password | default(omit) }}" 8 | login_user: "{{ item.login_user | default(postgresql_user) }}" 9 | login_unix_socket: "{{ item.login_unix_socket | default(postgresql_unix_socket_directories[0]) }}" 10 | port: "{{ item.port | default(omit) }}" 11 | with_items: "{{ postgresql_users }}" 12 | no_log: "{{ postgres_users_no_log }}" 13 | become: true 14 | become_user: "{{ postgresql_user }}" 15 | # See: https://github.com/ansible/ansible/issues/16048#issuecomment-229012509 16 | vars: 17 | ansible_ssh_pipelining: true 18 | environment: 19 | PGOPTIONS: "{{ (postgresql_auth_method == 'scram-sha-256') | ternary('-c password_encryption=scram-sha-256', '') }}" 20 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/tasks/users_props.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure PostgreSQL users are configured correctly. 3 | postgresql_user: 4 | name: "{{ item.name }}" 5 | password: "{{ item.password | default(omit) }}" 6 | encrypted: "{{ item.encrypted | default(omit) }}" 7 | priv: "{{ item.priv | default(omit) }}" 8 | role_attr_flags: "{{ item.role_attr_flags | default(omit) }}" 9 | db: "{{ item.db | default(omit) }}" 10 | login_host: "{{ item.login_host | default('localhost') }}" 11 | login_password: "{{ item.login_password | default(omit) }}" 12 | login_user: "{{ item.login_user | default(postgresql_user) }}" 13 | login_unix_socket: "{{ item.login_unix_socket | default(postgresql_unix_socket_directories[0]) }}" 14 | port: "{{ item.port | default(omit) }}" 15 | state: "{{ item.state | default('present') }}" 16 | with_items: "{{ postgresql_users }}" 17 | no_log: "{{ postgres_users_no_log }}" 18 | become: true 19 | become_user: "{{ postgresql_user }}" 20 | # See: https://github.com/ansible/ansible/issues/16048#issuecomment-229012509 21 | vars: 22 | ansible_ssh_pipelining: true 23 | environment: 24 | PGOPTIONS: "{{ (postgresql_auth_method == 'scram-sha-256') | ternary('-c password_encryption=scram-sha-256', '') }}" 25 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/tasks/variables.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Variable configuration. 3 | - name: Include OS-specific variables (Debian). 4 | include_vars: "{{ ansible_distribution }}-{{ ansible_distribution_version.split('.')[0] }}.yml" 5 | when: ansible_os_family == 'Debian' 6 | 7 | - name: Include OS-specific variables (RedHat). 8 | include_vars: "{{ ansible_os_family }}-{{ ansible_distribution_version.split('.')[0] }}.yml" 9 | when: 10 | - ansible_os_family == 'RedHat' 11 | - ansible_distribution != 'Fedora' 12 | - ansible_distribution != 'Amazon' 13 | 14 | - name: Include OS-specific variables (Amazon). 15 | include_vars: "{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml" 16 | when: ansible_distribution == 'Amazon' 17 | 18 | - name: Include OS-specific variables (Fedora). 19 | include_vars: "{{ ansible_distribution }}-{{ ansible_distribution_version.split('.')[0] }}.yml" 20 | when: ansible_distribution == 'Fedora' 21 | 22 | - name: Define postgresql_packages. 23 | set_fact: 24 | postgresql_packages: "{{ __postgresql_packages | list }}" 25 | when: postgresql_packages is not defined 26 | 27 | - name: Define postgresql_version. 28 | set_fact: 29 | postgresql_version: "{{ __postgresql_version }}" 30 | when: postgresql_version is not defined 31 | 32 | - name: Define postgresql_daemon. 33 | set_fact: 34 | postgresql_daemon: "{{ __postgresql_daemon }}" 35 | when: postgresql_daemon is not defined 36 | 37 | - name: Define postgresql_data_dir. 38 | set_fact: 39 | postgresql_data_dir: "{{ __postgresql_data_dir }}" 40 | when: postgresql_data_dir is not defined 41 | 42 | - name: Define postgresql_bin_path. 43 | set_fact: 44 | postgresql_bin_path: "{{ __postgresql_bin_path }}" 45 | when: postgresql_bin_path is not defined 46 | 47 | - name: Define postgresql_config_path. 48 | set_fact: 49 | postgresql_config_path: "{{ __postgresql_config_path }}" 50 | when: postgresql_config_path is not defined 51 | 52 | - name: Define postgresql_unix_socket_directories_mode. 53 | set_fact: 54 | postgresql_unix_socket_directories_mode: >- 55 | {{ __postgresql_unix_socket_directories_mode | default('02775') }} 56 | when: postgresql_unix_socket_directories_mode is not defined 57 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/templates/pg_hba.conf.j2: -------------------------------------------------------------------------------- 1 | {{ ansible_managed | comment }} 2 | # PostgreSQL Client Authentication Configuration File 3 | # =================================================== 4 | # 5 | # See: https://www.postgresql.org/docs/current/static/auth-pg-hba-conf.html 6 | 7 | {% for client in postgresql_hba_entries %} 8 | {{ client.type }} {{ client.database }} {{ client.user }} {{ client.address|default('') }} {{ client.ip_address|default('') }} {{ client.ip_mask|default('') }} {{ client.auth_method }} {{ client.auth_options|default("") }} 9 | {% endfor %} 10 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/templates/postgres.sh.j2: -------------------------------------------------------------------------------- 1 | export PGDATA={{ postgresql_data_dir }} 2 | export PATH=$PATH:{{ postgresql_bin_path }} 3 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/Amazon-2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "9.2" 3 | __postgresql_data_dir: "/var/lib/pgsql/data" 4 | __postgresql_bin_path: "/usr/bin" 5 | __postgresql_config_path: "/var/lib/pgsql/data" 6 | __postgresql_daemon: postgresql 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-server 10 | - postgresql-contrib 11 | - postgresql-libs 12 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/Debian-10.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "11" 3 | __postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main" 4 | __postgresql_bin_path: "/usr/lib/postgresql/{{ __postgresql_version }}/bin" 5 | __postgresql_config_path: "/etc/postgresql/{{ __postgresql_version }}/main" 6 | __postgresql_daemon: "postgresql@{{ postgresql_version }}-main" 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-contrib 10 | - libpq-dev 11 | # Debian 10 uses Python 3 by default. 12 | postgresql_python_library: python3-psycopg2 13 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/Debian-11.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "13" 3 | __postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main" 4 | __postgresql_bin_path: "/usr/lib/postgresql/{{ __postgresql_version }}/bin" 5 | __postgresql_config_path: "/etc/postgresql/{{ __postgresql_version }}/main" 6 | __postgresql_daemon: "postgresql@{{ postgresql_version }}-main" 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-contrib 10 | - libpq-dev 11 | postgresql_python_library: python3-psycopg2 12 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/Debian-7.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "9.1" 3 | __postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main" 4 | __postgresql_bin_path: "/usr/lib/postgresql/{{ __postgresql_version }}/bin" 5 | __postgresql_config_path: "/etc/postgresql/{{ __postgresql_version }}/main" 6 | __postgresql_daemon: postgresql 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-contrib 10 | - libpq-dev 11 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/Debian-8.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "9.4" 3 | __postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main" 4 | __postgresql_bin_path: "/usr/lib/postgresql/{{ __postgresql_version }}/bin" 5 | __postgresql_config_path: "/etc/postgresql/{{ __postgresql_version }}/main" 6 | __postgresql_daemon: "postgresql@{{ postgresql_version }}-main" 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-contrib 10 | - libpq-dev 11 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/Debian-9.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "9.6" 3 | __postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main" 4 | __postgresql_bin_path: "/usr/lib/postgresql/{{ __postgresql_version }}/bin" 5 | __postgresql_config_path: "/etc/postgresql/{{ __postgresql_version }}/main" 6 | __postgresql_daemon: "postgresql@{{ postgresql_version }}-main" 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-contrib 10 | - libpq-dev 11 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/Fedora-29.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "10.5" 3 | __postgresql_data_dir: "/var/lib/pgsql/data" 4 | __postgresql_bin_path: "/usr/bin" 5 | __postgresql_config_path: "/var/lib/pgsql/data" 6 | __postgresql_daemon: postgresql 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-server 10 | - postgresql-contrib 11 | - postgresql-libs 12 | postgresql_python_library: python2-psycopg2 13 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/Fedora-30.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "11.2" 3 | __postgresql_data_dir: "/var/lib/pgsql/data" 4 | __postgresql_bin_path: "/usr/bin" 5 | __postgresql_config_path: "/var/lib/pgsql/data" 6 | __postgresql_daemon: postgresql 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-server 10 | - postgresql-contrib 11 | - postgresql-libs 12 | # Fedora 30 containers only have python3 by default 13 | postgresql_python_library: python3-psycopg2 14 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/Fedora-31.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "11.5" 3 | __postgresql_data_dir: "/var/lib/pgsql/data" 4 | __postgresql_bin_path: "/usr/bin" 5 | __postgresql_config_path: "/var/lib/pgsql/data" 6 | __postgresql_daemon: postgresql 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-server 10 | - postgresql-contrib 11 | - postgresql-libs 12 | __postgresql_unix_socket_directories_mode: '0755' 13 | # Fedora 31 containers only have python3 by default 14 | postgresql_python_library: python3-psycopg2 15 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/Fedora-32.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "12.2" 3 | __postgresql_data_dir: "/var/lib/pgsql/data" 4 | __postgresql_bin_path: "/usr/bin" 5 | __postgresql_config_path: "/var/lib/pgsql/data" 6 | __postgresql_daemon: postgresql 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-server 10 | - postgresql-contrib 11 | - postgresql-libs 12 | __postgresql_unix_socket_directories_mode: '0755' 13 | # Fedora 32 containers only have python3 by default 14 | postgresql_python_library: python3-psycopg2 15 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/Fedora-34.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "13.4" 3 | __postgresql_data_dir: "/var/lib/pgsql/data" 4 | __postgresql_bin_path: "/usr/bin" 5 | __postgresql_config_path: "/var/lib/pgsql/data" 6 | __postgresql_daemon: postgresql 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-server 10 | - postgresql-contrib 11 | - postgresql-libs 12 | __postgresql_unix_socket_directories_mode: '0755' 13 | # Fedora 32 containers only have python3 by default 14 | postgresql_python_library: python3-psycopg2 15 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/Fedora-35.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "13.4" 3 | __postgresql_data_dir: "/var/lib/pgsql/data" 4 | __postgresql_bin_path: "/usr/bin" 5 | __postgresql_config_path: "/var/lib/pgsql/data" 6 | __postgresql_daemon: postgresql 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-server 10 | - postgresql-contrib 11 | - postgresql-libs 12 | __postgresql_unix_socket_directories_mode: '0755' 13 | # Fedora 32 containers only have python3 by default 14 | postgresql_python_library: python3-psycopg2 15 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/Fedora-36.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "14.1" 3 | __postgresql_data_dir: "/var/lib/pgsql/data" 4 | __postgresql_bin_path: "/usr/bin" 5 | __postgresql_config_path: "/var/lib/pgsql/data" 6 | __postgresql_daemon: postgresql 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-server 10 | - postgresql-contrib 11 | - postgresql-libs 12 | __postgresql_unix_socket_directories_mode: '0755' 13 | # Fedora 32 containers only have python3 by default 14 | postgresql_python_library: python3-psycopg2 15 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/RedHat-7.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "9.2" 3 | __postgresql_data_dir: "/var/lib/pgsql/data" 4 | __postgresql_bin_path: "/usr/bin" 5 | __postgresql_config_path: "/var/lib/pgsql/data" 6 | __postgresql_daemon: postgresql 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-server 10 | - postgresql-contrib 11 | - postgresql-libs 12 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/RedHat-8.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "10" 3 | __postgresql_data_dir: "/var/lib/pgsql/data" 4 | __postgresql_bin_path: "/usr/bin" 5 | __postgresql_config_path: "/var/lib/pgsql/data" 6 | __postgresql_daemon: postgresql 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-server 10 | - postgresql-contrib 11 | __postgresql_unix_socket_directories_mode: '0755' 12 | postgresql_python_library: python3-psycopg2 13 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/RedHat-9.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "10" 3 | __postgresql_data_dir: "/var/lib/pgsql/data" 4 | __postgresql_bin_path: "/usr/bin" 5 | __postgresql_config_path: "/var/lib/pgsql/data" 6 | __postgresql_daemon: postgresql 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-server 10 | - postgresql-contrib 11 | __postgresql_unix_socket_directories_mode: '0755' 12 | postgresql_python_library: python3-psycopg2 13 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/Ubuntu-16.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "9.5" 3 | __postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main" 4 | __postgresql_bin_path: "/usr/lib/postgresql/{{ __postgresql_version }}/bin" 5 | __postgresql_config_path: "/etc/postgresql/{{ __postgresql_version }}/main" 6 | __postgresql_daemon: postgresql 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-contrib 10 | - libpq-dev 11 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/Ubuntu-18.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "10" 3 | __postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main" 4 | __postgresql_bin_path: "/usr/lib/postgresql/{{ __postgresql_version }}/bin" 5 | __postgresql_config_path: "/etc/postgresql/{{ __postgresql_version }}/main" 6 | __postgresql_daemon: postgresql 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-contrib 10 | - libpq-dev 11 | postgresql_python_library: python3-psycopg2 12 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/Ubuntu-20.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "12" 3 | __postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main" 4 | __postgresql_bin_path: "/usr/lib/postgresql/{{ __postgresql_version }}/bin" 5 | __postgresql_config_path: "/etc/postgresql/{{ __postgresql_version }}/main" 6 | __postgresql_daemon: postgresql 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-contrib 10 | - libpq-dev 11 | postgresql_python_library: python3-psycopg2 12 | -------------------------------------------------------------------------------- /roles/oelabox.geerlingguy.postgresql/vars/Ubuntu-22.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __postgresql_version: "14" 3 | __postgresql_data_dir: "/var/lib/postgresql/{{ __postgresql_version }}/main" 4 | __postgresql_bin_path: "/usr/lib/postgresql/{{ __postgresql_version }}/bin" 5 | __postgresql_config_path: "/etc/postgresql/{{ __postgresql_version }}/main" 6 | __postgresql_daemon: postgresql 7 | __postgresql_packages: 8 | - postgresql 9 | - postgresql-contrib 10 | - libpq-dev 11 | postgresql_python_library: python3-psycopg2 12 | -------------------------------------------------------------------------------- /roles/oelabox.ipagetcert/.ansible-lint: -------------------------------------------------------------------------------- 1 | warn_list: 2 | - '204' # Lines should be less than 160 characters 3 | - '701' # meta/main.yml should contain relevant info 4 | skip_list: 5 | - '106' # Role name must match ^[a-z][a-z0-9_]+$ pattern 6 | -------------------------------------------------------------------------------- /roles/oelabox.ipagetcert/.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | repos: 3 | - repo: https://github.com/pre-commit/pre-commit-hooks 4 | rev: v3.3.0 5 | hooks: 6 | - id: trailing-whitespace 7 | - id: end-of-file-fixer 8 | - id: check-added-large-files 9 | - id: check-case-conflict 10 | - id: check-executables-have-shebangs 11 | - id: check-json 12 | - id: pretty-format-json 13 | 14 | 15 | - repo: local 16 | hooks: 17 | - id: ansible-lint 18 | name: Ansible-lint 19 | description: This hook runs ansible-lint. 20 | entry: ansible-lint --force-color 21 | language: python 22 | # do not pass files to ansible-lint, see: 23 | # https://github.com/ansible/ansible-lint/issues/611 24 | pass_filenames: false 25 | always_run: true 26 | 27 | - repo: https://github.com/adrienverge/yamllint.git 28 | rev: v1.24.2 29 | hooks: 30 | - id: yamllint 31 | files: \.(yaml|yml)$ 32 | types: [file, yaml] 33 | entry: yamllint 34 | -------------------------------------------------------------------------------- /roles/oelabox.ipagetcert/.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | 4 | rules: 5 | line-length: 6 | max: 140 7 | level: warning 8 | 9 | ignore: | 10 | .travis.yml 11 | .github 12 | -------------------------------------------------------------------------------- /roles/oelabox.ipagetcert/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [Unreleased] 8 | - what do we need to do 9 | 10 | ## [0.0.1] - 2020-12-13 11 | ### Added 12 | - Initial 13 | 14 | ### Changed 15 | - None 16 | 17 | ### Removed 18 | - None 19 | -------------------------------------------------------------------------------- /roles/oelabox.ipagetcert/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Darkbat91 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 | -------------------------------------------------------------------------------- /roles/oelabox.ipagetcert/README.md: -------------------------------------------------------------------------------- 1 | CI Badge 2 | 3 | # ipa-getcert Ansible Role 4 | This is a modified version of the Rocky Linux ipa-getcert role for Oela Box. 5 | 6 | A very basic ipa-getcert role used for certificates issued for internal communication. This assumes the client is enrolled with FreeIPA. 7 | 8 | This is loosely based on another project on github with some heavy modifications and adapted for the Rocky Linux infrastructure. In particular, we have made it more modular. This may be used and copied. 9 | 10 | **Note**: Note that the certificates should auto-renew when requested via `ipa-getcert`. However. if you turn on the chain, you will have to fix that manually. 11 | 12 | ## Getting started 13 | Ensure all dependencies are installed and then follow the below process 14 | 1. `git clone repo` Get the development repository 15 | 2. `pre-commit install` Install the pre-commit hooks 16 | 3. Make edits as explained in the customization section 17 | 4. `pre-commit` Make sure existing code is good 18 | 5. `do development` You know what to do 19 | 6. `pre-commit` Make sure the edits are good to go 20 | 7. `molecule converge` 21 | 22 | ## Dependencies 23 | This repo expects 3 things installed on the local machine 24 | 1. [pre-commit](https://pre-commit.com/) Methodology to test yaml style 25 | 2. [ansible-lint](https://github.com/ansible-community/ansible-lint) lint ansible code for best practices 26 | 3. [yamllint](https://github.com/adrienverge/yamllint) Ensures all yaml is well formed 27 | 28 | ### Customization 29 | If you can come up with a customization to this, go for it! 30 | 31 | ### Optional 32 | The github actions are configured to automatically run the molecule tests but if you want to load them locally you will also need molecule installed on the development machine 33 | 34 | ## Advanced 35 | There are numerous other options within the [defaults/main.yml](./defaults/main.yml) that can change other parts of the behavior of the system 36 | 37 | ## Changelog 38 | The [changelog](./CHANGELOG.md) is stored externally 39 | 40 | -------------------------------------------------------------------------------- /roles/oelabox.ipagetcert/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # ansible default variables - most variables live here 3 | ipa_getcert_key_default_location: "/etc/pki/tls/private/{{ ansible_fqdn }}.key" 4 | ipa_getcert_cert_default_location: "/etc/pki/tls/certs/{{ ansible_fqdn }}.crt" 5 | ipa_getcert_nss_default_location: "/etc/pki/tls/nss" 6 | ipa_getcert_owner_default: root 7 | 8 | # List of hostnames that should be requested 9 | ipa_getcert_requested_hostnames: 10 | - name: "{{ ansible_fqdn }}" 11 | key_location: /etc/pki/tls/private/name.key 12 | cert_location: /etc/pki/tls/certs/name.crt 13 | 14 | # If you need a different ownership, you can setup the above sort of like this: 15 | # ipa_getcert_requested_hostnames: 16 | # - name: name 17 | # postcmd: "/bin/systemctl restart ejabberd" 18 | # owner: ejabberd 19 | # key_location: /opt/ejabberd/conf/pki 20 | # cert_location: /opt/ejabberd/conf/pki 21 | 22 | # If you are using NSS. 23 | # ipa_getcert_nss: true 24 | # ipa_getcert_requested_hostnames: 25 | # - name: name 26 | # postcmd: "/bin/systemctl restart sigul_server" 27 | # owner: sigul 28 | # nss_db_dir: /etc/pki/tls/nss 29 | # nss_nickname: name 30 | 31 | # If you are using cnames 32 | # ipa_getcert_requested_hostnames: 33 | # - name: name 34 | # postcmd: "/bin/systemctl restart httpd" 35 | # owner: apache 36 | # key_location: /etc/pki/tls/private/web.crt 37 | # cert_location: /etc/pki/tls/certs/web.crt 38 | # cnames: 39 | # - cname.example.com 40 | 41 | # This feature coming soon 42 | #ipa_getcert_fqdn_symlink: true 43 | 44 | ipa_getcert_chain: false 45 | ipa_getcert_chain_location: /etc/pki/tls/chains 46 | 47 | # Note that when you set this to true, key_location and cert_location are 48 | # effectively ignored. 49 | ipa_getcert_nss: false 50 | -------------------------------------------------------------------------------- /roles/oelabox.ipagetcert/github/workflows/ansible-lint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # https://github.com/ansible/ansible-lint-action 3 | name: Ansible Lint 4 | 5 | on: 6 | push: 7 | paths: 8 | - '**.yml' 9 | - '**.yaml' 10 | 11 | jobs: 12 | ansible-lint: 13 | runs-on: ubuntu-latest 14 | timeout-minutes: 7 15 | 16 | steps: 17 | - name: Git checkout 18 | uses: actions/checkout@v2 19 | 20 | - name: Add installed collections in Ansible configuration 21 | run: | 22 | echo '[defaults]' > ansible.cfg 23 | echo 'collections_paths = ./collections' >> ansible.cfg 24 | - name: Install role requirements 25 | run: ansible-galaxy role install -r molecule/requirements.yml 26 | # TODO: Figure out how to get this not to error so this action is universal 27 | # - name: Install collection requirements 28 | # run: ansible-galaxy collection install -r molecule/requirements.yml 29 | 30 | - name: Ansible Lint 31 | uses: rocky-linux/ansible-lint-action@master 32 | with: 33 | args: "--exclude .github" 34 | -------------------------------------------------------------------------------- /roles/oelabox.ipagetcert/github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: CI 3 | 4 | 'on': 5 | pull_request: 6 | push: 7 | branches: 8 | - main 9 | schedule: 10 | - cron: "30 6 * * 2" 11 | 12 | jobs: 13 | molecule: 14 | name: Molecule 15 | runs-on: ubuntu-latest 16 | strategy: 17 | matrix: 18 | include: 19 | - distro: centos7 20 | playbook: converge.yml 21 | steps: 22 | - name: Check out the codebase. 23 | uses: actions/checkout@v2 24 | 25 | - name: Set up Python 3. 26 | uses: actions/setup-python@v2 27 | with: 28 | python-version: '3.x' 29 | 30 | - name: Install test dependencies. 31 | run: pip3 install ansible molecule[docker] docker 32 | 33 | - name: Run Molecule tests. 34 | run: molecule test 35 | env: 36 | PY_COLORS: '1' 37 | ANSIBLE_FORCE_COLOR: '1' 38 | MOLECULE_DISTRO: ${{ matrix.distro }} 39 | MOLECULE_PLAYBOOK: ${{ matrix.playbook }} 40 | -------------------------------------------------------------------------------- /roles/oelabox.ipagetcert/github/workflows/yaml-lint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # https://github.com/ibiqlik/action-yamllint 3 | name: YAML Lint 4 | 5 | on: 6 | push: 7 | paths: 8 | - '**.yml' 9 | - '**.yaml' 10 | 11 | jobs: 12 | yamllint: 13 | runs-on: ubuntu-latest 14 | timeout-minutes: 1 15 | 16 | steps: 17 | - name: Git checkout 18 | uses: actions/checkout@v2 19 | 20 | - name: yamllint 21 | uses: ibiqlik/action-yamllint@v3 22 | -------------------------------------------------------------------------------- /roles/oelabox.ipagetcert/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: Louis Abel 3 | description: Basic ipa-getcert role 4 | company: Rocky Linux Foundation 5 | license: MIT 6 | min_ansible_version: 2.8 7 | platforms: 8 | - name: EL 9 | versions: 10 | - 7 11 | - 8 12 | galaxy_tags: 13 | - freeipa 14 | dependencies: [] 15 | -------------------------------------------------------------------------------- /roles/oelabox.ipagetcert/molecule/default/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | become: true 5 | 6 | pre_tasks: 7 | - name: Update apt cache. 8 | apt: update_cache=true cache_valid_time=600 9 | when: ansible_os_family == 'Debian' 10 | changed_when: false 11 | 12 | roles: 13 | - role: ansible-role-mycoolrole 14 | -------------------------------------------------------------------------------- /roles/oelabox.ipagetcert/molecule/default/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | options: 5 | ignore-certs: true 6 | role-file: molecule/requirements.yml 7 | 8 | driver: 9 | name: docker 10 | 11 | # lint: | 12 | # set -e 13 | # yamllint . 14 | # ansible-lint 15 | platforms: 16 | - name: instance 17 | image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" 18 | command: ${MOLECULE_DOCKER_COMMAND:-""} 19 | volumes: 20 | - /sys/fs/cgroup:/sys/fs/cgroup:ro 21 | privileged: true 22 | pre_build_image: true 23 | provisioner: 24 | name: ansible 25 | playbooks: 26 | converge: ${MOLECULE_PLAYBOOK:-converge.yml} 27 | -------------------------------------------------------------------------------- /roles/oelabox.ipagetcert/molecule/requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | roles: 3 | ## Deps go here Should be very short and only if Absolutely needed 4 | -------------------------------------------------------------------------------- /roles/oelabox.ipagetcert/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Request the certificate for the host from IPA 3 | # System must be enrolled as an IPA Client and must be ran as root 4 | - name: Check if host is IPA enrolled 5 | shell: /usr/sbin/ipa-client-install --unattended 2>&1 | grep "already configured" 6 | register: ipacheck 7 | ignore_errors: true 8 | changed_when: false 9 | 10 | - name: Verify host is IPA enrolled 11 | ansible.builtin.assert: 12 | that: 13 | - ipacheck.rc == 0 | mandatory 14 | fail_msg: "System is not enrolled to IPA" 15 | success_msg: "IPA enrolled, moving on" 16 | quiet: true 17 | 18 | - name: IPA Certificate Operations 19 | block: 20 | - name: Deploy ipa-getcert script 21 | ansible.builtin.template: 22 | src: "get_cert.sh.j2" 23 | dest: "/root/get_cert.sh" 24 | owner: root 25 | group: root 26 | mode: '0750' 27 | 28 | - name: Request Certificate 29 | ansible.builtin.raw: /root/get_cert.sh 30 | register: ipa_cert_request 31 | 32 | - name: Chain link certificates 33 | block: 34 | - name: Create chain directory 35 | ansible.builtin.file: 36 | state: directory 37 | path: "{{ ipa_getcert_chain_location }}" 38 | owner: root 39 | group: "{{ ipa_getcert_group }}" 40 | mode: '0750' 41 | 42 | - name: Chain link certs 43 | ansible.builtin.file: 44 | state: link 45 | src: "{{ item.cert_location | default(ipa_getcert_cert_default_location) }}/{{ item.name }}.crt" 46 | dest: "{{ ipa_getcert_chain_location }}/{{ item.name }}.crt" 47 | owner: "{{ item.owner | default(ipa_getcert_owner_default) }}" 48 | group: "{{ item.owner | default(ipa_getcert_owner_default) }}" 49 | with_items: "{{ ipa_getcert_requested_hostnames }}" 50 | 51 | - name: Chain link keys 52 | ansible.builtin.file: 53 | state: link 54 | src: "{{ item.key_location | default(ipa_getcert_cert_default_location) }}/{{ item.name }}.key" 55 | path: "{{ ipa_getcert_chain_location }}/{{ item.name }}.key" 56 | owner: "{{ item.owner | default(ipa_getcert_owner_default) }}" 57 | group: "{{ item.owner | default(ipa_getcert_owner_default) }}" 58 | with_items: "{{ ipa_getcert_requested_hostnames }}" 59 | 60 | - name: Assemble the chain 61 | ansible.builtin.assemble: 62 | src: "{{ ipa_getcert_chain_location }}" 63 | dest: "{{ ipa_getcert_chain_location }}/{{ item.name }}.pem" 64 | regexp: "^{{ item.name }}.(crt|key)$" 65 | owner: "{{ item.owner | default(ipa_getcert_owner_default) }}" 66 | group: "{{ item.owner | default(ipa_getcert_owner_default) }}" 67 | mode: '0640' 68 | with_items: "{{ ipa_getcert_requested_hostnames }}" 69 | when: 70 | - ipa_getcert_chain|bool 71 | - ipa_cert_request.rc == 0 72 | rescue: 73 | - name: "Erroring out with message" 74 | ansible.builtin.debug: 75 | msg: "We caught an error, likely with the ipa-getcert script. Please verify the output." 76 | when: 77 | - ipacheck.rc == 0 78 | -------------------------------------------------------------------------------- /roles/oelabox.ipagetcert/templates/get_cert.sh.j2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This script will take care of the certificate process for IPA. 3 | # There may be more than one request done based on the vars of the playbook. 4 | 5 | {% for ipahosts in ipa_getcert_requested_hostnames %} 6 | 7 | {% if ipa_getcert_nss %} 8 | nss_db_path="{{ ipahosts.nss_db_dir | default(ipa_getcert_nss_default_location) }}" 9 | if [ ! -d "${nss_db_path}" ] && [ ! -L "${nss_db_path}" ]; then 10 | mkdir -p "${nss_db_path}" 11 | fi 12 | {% endif %} 13 | 14 | /usr/bin/ipa-getcert request -r -w \ 15 | -I "{{ ipahosts.name }}" \ 16 | -N "CN={{ ipahosts.name }}" \ 17 | -D "{{ ipahosts.name }}" \ 18 | {% if ipahosts.cnames is defined %} 19 | {% for cname in ipahosts.cnames %} 20 | -D "{{ cname }}" \ 21 | {% endfor %} 22 | {% endif %} 23 | {% if ipa_getcert_nss %} 24 | -d "${nss_db_path}" \ 25 | -n {{ ipahosts.nss_nickname | default(ansible_fqdn) }} \ 26 | {% else %} 27 | -k "{{ ipahosts.key_location | default(ipa_getcert_key_default_location) }}" \ 28 | -f "{{ ipahosts.cert_location | default(ipa_getcert_cert_default_location) }}" \ 29 | {% endif %} 30 | {% if ipahosts.postcmd is defined %} 31 | -C "{{ ipahosts.postcmd }}" \ 32 | {% endif %} 33 | {% if ipahosts.owner is defined %} 34 | -O "{{ ipahosts.owner }}" \ 35 | -o "{{ ipahosts.owner }}" \ 36 | {% endif %} 37 | -K "{{ ipahosts.service | default('host') }}/{{ ipahosts.name }}" 38 | 39 | {% endfor %} 40 | -------------------------------------------------------------------------------- /roles/oelabox.ipagetcert/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file - Nothing should really go here but dynamic imports 3 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/.ansible-lint: -------------------------------------------------------------------------------- 1 | warn_list: 2 | - '204' # Lines should be less than 160 characters 3 | - '701' # meta/main.yml should contain relevant info 4 | skip_list: 5 | - '106' # Role name must match ^[a-z][a-z0-9_]+$ pattern 6 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | repos: 3 | - repo: https://github.com/pre-commit/pre-commit-hooks 4 | rev: v3.3.0 5 | hooks: 6 | - id: trailing-whitespace 7 | - id: end-of-file-fixer 8 | - id: check-added-large-files 9 | - id: check-case-conflict 10 | - id: check-executables-have-shebangs 11 | - id: check-json 12 | - id: pretty-format-json 13 | 14 | 15 | - repo: local 16 | hooks: 17 | - id: ansible-lint 18 | name: Ansible-lint 19 | description: This hook runs ansible-lint. 20 | entry: ansible-lint --force-color 21 | language: python 22 | # do not pass files to ansible-lint, see: 23 | # https://github.com/ansible/ansible-lint/issues/611 24 | pass_filenames: false 25 | always_run: true 26 | 27 | - repo: https://github.com/adrienverge/yamllint.git 28 | rev: v1.24.2 29 | hooks: 30 | - id: yamllint 31 | files: \.(yaml|yml)$ 32 | types: [file, yaml] 33 | entry: yamllint 34 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | 4 | rules: 5 | line-length: 6 | max: 140 7 | level: warning 8 | 9 | ignore: | 10 | .travis.yml 11 | .github 12 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [Unreleased] 8 | - what do we need to do 9 | 10 | ## [0.0.1] - 2020-12-13 11 | ### Added 12 | - Initial 13 | 14 | ### Changed 15 | - None 16 | 17 | ### Removed 18 | - None 19 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Darkbat91 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 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/README.md: -------------------------------------------------------------------------------- 1 | CI Badge 2 | 3 | # Kojid Role 4 | This role prepares a system to be a koji builder. This requires kerberos keytabs. 5 | 6 | ## Getting started 7 | Ensure all dependencies are installed and then follow the below process 8 | 1. `git clone repo` Get the development repository 9 | 2. `pre-commit install` Install the pre-commit hooks 10 | 3. Make edits as explained in the customization section 11 | 4. `pre-commit` Make sure existing code is good 12 | 5. `do development` Dont ask me :D 13 | 6. `pre-commit` Make sure the edits are good to go 14 | 7. `molecule converge` 15 | 16 | ## Dependencies 17 | This repo expects 3 things installed on the local machine 18 | 1. [pre-commit](https://pre-commit.com/) Methodology to test yaml style 19 | 2. [ansible-lint](https://github.com/ansible-community/ansible-lint) lint ansible code for best practices 20 | 3. [yamllint](https://github.com/adrienverge/yamllint) Ensures all yaml is well formed 21 | 22 | ### Customization 23 | There are a few files that are required to be updated when using this template 24 | 1. [molecule/requirements.yml](molecule/requirements.yml) - Update with any required roles or collections 25 | 2. [molecule/default/converge.yml](molecule/default/converge.yml) - update with new role name 26 | 3. [molecule/default/molecule.yml](molecule/default/molecule.yml) - update with desired distributions and extra playbooks 27 | 4. [github](github) - Rename to `.github` and push, this will set up yamllint, ansible-lint and a CI check job for the `main` branch 28 | 1. NOTE: If you are using a SAML token this may fail. You can created the files within the Github web app 29 | 30 | ### Optional 31 | The github actions are configured to automatically run the molecule tests but if you want to load them locally you will also need molecule installed on the development machine 32 | 33 | ## Advanced 34 | 35 | There are numerous other options within the [defaults/main.yml](./defaults/main.yml) that can change other parts of the behavior of the system 36 | 37 | ## Changelog 38 | The [changelog](./CHANGELOG.md) is stored externally 39 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # kojid 3 | kojid_packages: 4 | - koji-builder 5 | - koji-builder-plugins 6 | - python3-koji 7 | - python3-kickstart 8 | - libvirt-client 9 | - strace 10 | - mock 11 | - createrepo_c 12 | - dnf-plugins-core 13 | - gpgme 14 | - pykickstart 15 | - rng-tools 16 | 17 | kojid_vendor: Oela 18 | kojid_packager: infrastructure@oelabox.local 19 | kojid_distribution: Oela 20 | kojid_web_url: https://koji.oelabox.local/koji 21 | kojid_hub_url: https://koji.oelabox.local/kojihub 22 | kojid_files_url: https://koji.oelabox.local/kojifiles 23 | kojid_ca_bundle: /etc/pki/tls/certs/ca-bundle.crt 24 | kojid_keytab: /etc/kojid.keytab 25 | kojid_smtp_host: smtp.oelabox.local 26 | kojid_smtp_user: smtpuser 27 | kojid_smtp_pass: smtppass 28 | kojid_allowed_scm: "github.com:/openela-main/*:off:/usr/bin/getsrc.sh" 29 | kojid_bugzilla: https://bugs.oelabox.local 30 | 31 | kojid_maxjobs: 10 32 | kojid_minspace: 4096 33 | 34 | # NFS 35 | kojid_nfs: false 36 | kojid_mount: /mnt/koji 37 | kojid_nfs_path: nfs.oelabox.local:/export/koji 38 | 39 | # Are we building images? This is definable in a playbook 40 | kojid_image_builder: true 41 | kojid_runroot_builder: true 42 | 43 | # Builtools repo 44 | # Not sure if we're using this yet 45 | kojid_buildtools_repo: False 46 | kojid_buildtools_repo_host: https://localhost 47 | kojid_buildtools_repo_url: "{{ kojid_buildtools_repo_host }}/builder/$basearch/" 48 | kojid_buildtools_repo_gpgcheck: false 49 | kojid_buildtools_repo_gpgkey: RPM-GPG-KEY-Rocky-Infra 50 | 51 | # SSH Pubkeys, define them in a playbook 52 | # mockbuilder_pub_key 53 | # kojibuilder_pub_key 54 | 55 | # Are the kojid builders "shared" builders between different ecosystems 56 | # "production" and "staging" are the predetermined names and are sorted 57 | # as such. 58 | kojid_shared_builders: false 59 | 60 | # Define ulimits to avoid alloc issues 61 | kojid_ulimits_conf: false 62 | kojid_ulimits_nofiles: 10240 63 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/github/workflows/ansible-lint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # https://github.com/ansible/ansible-lint-action 3 | name: Ansible Lint 4 | 5 | on: 6 | push: 7 | paths: 8 | - '**.yml' 9 | - '**.yaml' 10 | 11 | jobs: 12 | ansible-lint: 13 | runs-on: ubuntu-latest 14 | timeout-minutes: 7 15 | 16 | steps: 17 | - name: Git checkout 18 | uses: actions/checkout@v2 19 | 20 | - name: Add installed collections in Ansible configuration 21 | run: | 22 | echo '[defaults]' > ansible.cfg 23 | echo 'collections_paths = ./collections' >> ansible.cfg 24 | - name: Install role requirements 25 | run: ansible-galaxy role install -r molecule/requirements.yml 26 | # TODO: Figure out how to get this not to error so this action is universal 27 | # - name: Install collection requirements 28 | # run: ansible-galaxy collection install -r molecule/requirements.yml 29 | 30 | - name: Ansible Lint 31 | uses: rocky-linux/ansible-lint-action@master 32 | with: 33 | args: "--exclude .github" 34 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: CI 3 | 4 | 'on': 5 | pull_request: 6 | push: 7 | branches: 8 | - main 9 | schedule: 10 | - cron: "30 6 * * 2" 11 | 12 | jobs: 13 | molecule: 14 | name: Molecule 15 | runs-on: ubuntu-latest 16 | strategy: 17 | matrix: 18 | include: 19 | - distro: centos7 20 | playbook: converge.yml 21 | steps: 22 | - name: Check out the codebase. 23 | uses: actions/checkout@v2 24 | 25 | - name: Set up Python 3. 26 | uses: actions/setup-python@v2 27 | with: 28 | python-version: '3.x' 29 | 30 | - name: Install test dependencies. 31 | run: pip3 install ansible molecule[docker] docker 32 | 33 | - name: Run Molecule tests. 34 | run: molecule test 35 | env: 36 | PY_COLORS: '1' 37 | ANSIBLE_FORCE_COLOR: '1' 38 | MOLECULE_DISTRO: ${{ matrix.distro }} 39 | MOLECULE_PLAYBOOK: ${{ matrix.playbook }} 40 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/github/workflows/yaml-lint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # https://github.com/ibiqlik/action-yamllint 3 | name: YAML Lint 4 | 5 | on: 6 | push: 7 | paths: 8 | - '**.yml' 9 | - '**.yaml' 10 | 11 | jobs: 12 | yamllint: 13 | runs-on: ubuntu-latest 14 | timeout-minutes: 1 15 | 16 | steps: 17 | - name: Git checkout 18 | uses: actions/checkout@v2 19 | 20 | - name: yamllint 21 | uses: ibiqlik/action-yamllint@v3 22 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers 3 | - name: restart_kojid 4 | service: 5 | name: kojid 6 | state: restarted 7 | enabled: true 8 | 9 | - name: disable_kojid 10 | service: 11 | name: kojid 12 | state: stopped 13 | enabled: false 14 | 15 | - name: reload_systemd 16 | systemd: 17 | daemon_reload: true 18 | 19 | - name: restart_kojid_staging 20 | service: 21 | name: kojid_staging 22 | state: restarted 23 | enabled: true 24 | 25 | - name: restart_kojid_production 26 | service: 27 | name: kojid_production 28 | state: restarted 29 | enabled: true 30 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: Louis Abel 4 | description: Rocky Linux Koji Builder 5 | company: Rocky Linux 6 | license: MIT 7 | min_ansible_version: 2.9 8 | platforms: 9 | - name: EL 10 | versions: 11 | - 8 12 | galaxy_tags: [] 13 | dependencies: [] 14 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/molecule/default/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | become: true 5 | 6 | pre_tasks: 7 | - name: Update apt cache. 8 | apt: update_cache=true cache_valid_time=600 9 | when: ansible_os_family == 'Debian' 10 | changed_when: false 11 | 12 | roles: 13 | - role: ansible-role-mycoolrole 14 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/molecule/default/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | options: 5 | ignore-certs: true 6 | role-file: molecule/requirements.yml 7 | 8 | driver: 9 | name: docker 10 | 11 | # lint: | 12 | # set -e 13 | # yamllint . 14 | # ansible-lint 15 | platforms: 16 | - name: instance 17 | image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" 18 | command: ${MOLECULE_DOCKER_COMMAND:-""} 19 | volumes: 20 | - /sys/fs/cgroup:/sys/fs/cgroup:ro 21 | privileged: true 22 | pre_build_image: true 23 | provisioner: 24 | name: ansible 25 | playbooks: 26 | converge: ${MOLECULE_PLAYBOOK:-converge.yml} 27 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/molecule/requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | roles: 3 | ## Deps go here Should be very short and only if Absolutely needed 4 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/tasks/config.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # kojid configuration 3 | 4 | # sysctl and limits 5 | - name: set highmem_is_dirtyable on armv7 builders if applicable 6 | ansible.builtin.sysctl: 7 | name: vm.highmem_is_dirtyable 8 | value: 1 9 | state: present 10 | sysctl_set: true 11 | reload: true 12 | when: ansible_architecture == 'armv7l' 13 | 14 | - name: Set nofile limit to 10240 15 | ansible.builtin.template: 16 | src: 00-limit.conf.j2 17 | dest: /etc/security/limits.d/00-limit.conf 18 | owner: root 19 | group: root 20 | mode: '0644' 21 | 22 | # oz and plugins 23 | #- name: OZ Config 24 | # ansible.builtin.template: 25 | # src: oz.cfg.j2 26 | # dest: /etc/oz/oz.cfg 27 | # owner: root 28 | # group: root 29 | # mode: '0644' 30 | # notify: restart_kojid 31 | 32 | - name: runroot config 33 | ansible.builtin.template: 34 | src: runroot.conf.j2 35 | dest: /etc/kojid/plugins/runroot.conf 36 | owner: root 37 | group: root 38 | mode: '0644' 39 | notify: restart_kojid 40 | 41 | # kojid base configuration 42 | - name: Configure koji.conf 43 | ansible.builtin.template: 44 | src: koji.conf.j2 45 | dest: /etc/koji.conf 46 | owner: root 47 | group: root 48 | mode: '0644' 49 | notify: restart_kojid 50 | 51 | - name: Configure kojid 52 | ansible.builtin.template: 53 | src: kojid.conf.j2 54 | dest: /etc/kojid/kojid.conf 55 | owner: root 56 | group: root 57 | mode: '0644' 58 | notify: restart_kojid 59 | 60 | - name: Set /etc/mock/site-defaults.cfg 61 | ansible.builtin.template: 62 | src: site-defaults.cfg.j2 63 | dest: /etc/mock/site-defaults.cfg 64 | owner: root 65 | group: root 66 | mode: '0644' 67 | notify: restart_kojid 68 | 69 | # systemd override 70 | - name: Override kojid.service 71 | ansible.builtin.template: 72 | src: kojid.service.j2 73 | dest: /etc/systemd/system/kojid.service 74 | owner: root 75 | group: root 76 | mode: '0644' 77 | notify: 78 | - reload_systemd 79 | - restart_kojid 80 | 81 | - name: Enable kojid 82 | ansible.builtin.service: 83 | name: kojid 84 | enabled: yes 85 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks 3 | 4 | - name: Install necessary packages 5 | import_tasks: packages.yml 6 | 7 | - name: Apply required SELinux booleans 8 | import_tasks: selinux_boolean.yml 9 | 10 | - name: Create the users for kojid 11 | import_tasks: users.yml 12 | 13 | - name: Configure kojid 14 | import_tasks: config.yml 15 | when: not kojid_shared_builders | bool 16 | 17 | - name: Configure shared kojid 18 | import_tasks: shared/config_shared.yml 19 | when: kojid_shared_builders | bool 20 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/tasks/packages.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Install packages 3 | - name: Install required packages 4 | ansible.builtin.dnf: 5 | name: "{{ kojid_packages }}" 6 | state: present 7 | 8 | # armv7l specific 9 | - name: Install libkcapi for increased armv7 sockets 10 | ansible.builtin.dnf: 11 | name: libkcapi 12 | state: present 13 | when: ansible_architecture == 'armv7l' 14 | 15 | # x86_64 specific 16 | #- name: Install x86_64 specific packages 17 | # ansible.builtin.dnf: 18 | # name: 19 | # - python3-osbs-client 20 | # state: present 21 | # when: ansible_architecture == 'x86_64' 22 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/tasks/selinux_boolean.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Enabling SELinux booleans 4 | ansible.posix.seboolean: 5 | name: "{{ item }}" 6 | persistent: true 7 | state: true 8 | with_items: 9 | - httpd_can_network_connect_db 10 | - httpd_can_network_connect 11 | - allow_httpd_anon_write 12 | - httpd_use_nfs 13 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/tasks/shared/config_shared.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # kojid shared configuration 3 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/tasks/shared/storage_shared.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Shared Storage 3 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/tasks/storage.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Storage 3 | - name: Ensure the koji mountpoint exists 4 | ansible.builtin.file: 5 | path: "{{ kojid_mount }}" 6 | state: directory 7 | owner: apache 8 | group: apache 9 | mode: '0755' 10 | 11 | - name: Mount the NFS store 12 | ansible.builtin.mount: 13 | path: "{{ kojid_mount }}" 14 | src: "{{ kojid_nfs_path }}" 15 | fstype: nfs 16 | state: mounted 17 | when: kojid_nfs|bool 18 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/tasks/users.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Create the users on the koji builder 3 | 4 | # This user likely isn't used... 5 | # - name: add mock user 6 | # user: 7 | # name: mock 8 | # uid: 425 9 | # state: present 10 | # home: /var/lib/mock 11 | # createhome: true 12 | # system: true 13 | 14 | # - name: Fix permissions 15 | # file: 16 | # state: directory 17 | # path: /var/lib/mock 18 | # mode: '2775' 19 | # owner: root 20 | # group: mock 21 | 22 | # - name: Create mock ssh directory 23 | # file: 24 | # state: directory 25 | # path: /var/lib/mock/.ssh 26 | # mode: '0700' 27 | # owner: mock 28 | # group: mock 29 | 30 | - name: mockbuilder user 31 | ansible.builtin.user: 32 | name: mockbuilder 33 | groups: mock 34 | 35 | - name: mockbuilder ssh key 36 | ansible.posix.authorized_key: 37 | user: mockbuilder 38 | key: "{{ mockbuilder_pub_key }}" 39 | when: mockbuilder_pub_key is defined 40 | 41 | - name: kojibuilder user 42 | ansible.builtin.user: 43 | name: kojibuilder 44 | groups: mock 45 | 46 | - name: kojibuilder ssh key 47 | ansible.posix.authorized_key: 48 | user: kojibuilder 49 | key: "{{ kojibuilder_pub_key }}" 50 | when: kojibuilder_pub_key is defined 51 | 52 | # We need the apache user for NFS 53 | - name: apache group 54 | ansible.builtin.group: 55 | name: apache 56 | gid: 48 57 | system: true 58 | state: present 59 | 60 | - name: apache user 61 | ansible.builtin.user: 62 | name: apache 63 | uid: 48 64 | createhome: false 65 | group: apache 66 | shell: /sbin/nologin 67 | system: true 68 | state: present 69 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/templates/00-limit.conf.j2: -------------------------------------------------------------------------------- 1 | # 2 | {% if kojid_ulimits_conf %} 3 | kojibuilder soft nofile {{ kojid_ulimits_nofiles }} 4 | kojibuilder hard nofile {{ kojid_ulimits_nofiles }} 5 | {% else %} 6 | * - nofile 4096 7 | {% endif %} 8 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/templates/buildtools.repo.j2: -------------------------------------------------------------------------------- 1 | [r8-rockytools] 2 | name = Rocky Infra Tools 3 | baseurl = {{ kojid_buildtools_repo_url }} 4 | enabled=1 5 | {% if kojid_buildtools_repo_gpgcheck %} 6 | gpgcheck=1 7 | gpgkey=file:///etc/pki/rpm-gpg/kojid_buildtools_repo_gpgkey 8 | {% else %} 9 | gpgcheck=0 10 | {% endif %} 11 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/templates/koji.conf.j2: -------------------------------------------------------------------------------- 1 | [koji] 2 | ;url of XMLRPC server 3 | server = {{ kojid_hub_url }} 4 | 5 | ;url of web interface 6 | weburl = {{ kojid_web_url }} 7 | 8 | ;url of package download site 9 | topurl = {{ kojid_files_url }} 10 | 11 | ;path to the koji top directory 12 | topdir = {{ kojid_mount }} 13 | 14 | ; https ca, not for ssl auth 15 | serverca = {{ kojid_ca_bundle }} 16 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/templates/kojid.conf.j2: -------------------------------------------------------------------------------- 1 | [kojid] 2 | sleeptime=15 3 | maxjobs={{ kojid_maxjobs }} 4 | minspace={{ kojid_minspace }} 5 | topdir={{ kojid_mount }} 6 | workdir=/tmp/koji 7 | mockdir=/var/lib/mock 8 | mockuser=kojibuilder 9 | vendor={{ kojid_vendor }} 10 | packager={{ kojid_packager }} 11 | mockhost=redhat-linux-gnu 12 | server={{ kojid_hub_url }} 13 | topurl={{ kojid_files_url }} 14 | use_createrepo_c=True 15 | from_addr=Koji Build System 16 | admin_emails="infrastructure@oelabox.local" 17 | ;smtphost={{ kojid_smtp_host }} 18 | ;smtp_user={{ kojid_smtp_user }} 19 | ;smtp_pass={{ kojid_smtp_pass }} 20 | host_principal_format = compile/%s@OELABOX.LOCAL 21 | keytab = {{ kojid_keytab }} 22 | serverca = {{ kojid_ca_bundle }} 23 | 24 | ; Modify 25 | allowed_scms={{ kojid_allowed_scm }} 26 | 27 | ; Other settings 28 | build_arch_can_fail = true 29 | 30 | {% set plugins = [] %} 31 | 32 | {% if kojid_runroot_builder %} 33 | {{ plugins.append("runroot") }} 34 | {% endif %} 35 | 36 | plugins = {{ plugins | join(" ") }} 37 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/templates/kojid.service.j2: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Koji build server 3 | Documentation=https://docs.pagure.org/koji/server_howto/ 4 | 5 | After=network.target 6 | 7 | [Service] 8 | TasksMax=infinity 9 | Restart=on-failure 10 | ExecStart=/usr/sbin/kojid \ 11 | --fg \ 12 | --force-lock \ 13 | --verbose 14 | ExecReload=/bin/kill -USR1 $MAINPID 15 | 16 | {% if kojid_ulimits_conf %} 17 | LimitNOFILE={{ kojid_ulimits_nofiles }} 18 | LimitNOFILESoft={{ kojid_ulimits_nofiles }} 19 | {% endif %} 20 | 21 | [Install] 22 | WantedBy=multi-user.target 23 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/templates/old.site-defaults.cfg: -------------------------------------------------------------------------------- 1 | # Managed by Ansible 2 | #{% if kojid_disable_bootstrap_chroot %} 3 | #config['use_bootstrap'] = False 4 | #{% endif %} 5 | 6 | #{% if kojid_ulimits_conf %} 7 | #config_opts['nspawn_args'] += ['--rlimit=RLIMIT_NOFILE={{ kojid_ulimits_nofiles }}'] 8 | #{% endif %} 9 | 10 | #config_opts['dnf_common_opts'] = ['--setopt=install_weak_deps=0'] 11 | #config_opts['macros']['%bugurl'] = '{{ kojid_bugzilla }}' 12 | #config_opts['nosync'] = True 13 | #config_opts['nosync_force'] = True 14 | #config_opts['environment']['LANG'] = 'C.UTF-8' 15 | config_opts['use_bootstrap_image'] = False 16 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/templates/oz.cfg.j2: -------------------------------------------------------------------------------- 1 | [paths] 2 | output_dir = /var/lib/libvirt/images 3 | data_dir = /var/lib/oz 4 | screenshot_dir = /var/lib/oz/screenshots 5 | # sshprivkey = /etc/oz/id_rsa-icicle-gen 6 | 7 | [libvirt] 8 | uri = qemu:///system 9 | image_type = raw 10 | # type = kvm 11 | # bridge_name = virbr0 12 | {% if ansible_architecture == 'ppc64' or ansible_architecture == 'ppc64le' %} 13 | cpus = 4 14 | {% else %} 15 | cpus = 4 16 | {% endif %} 17 | memory = 4096 18 | 19 | [cache] 20 | original_media = yes 21 | modified_media = no 22 | jeos = no 23 | 24 | [icicle] 25 | safe_generation = no 26 | 27 | [timeouts] 28 | install = 14400 29 | inactivity = 500 30 | boot = 500 31 | shutdown = 90 32 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/templates/production/koji.conf.j2: -------------------------------------------------------------------------------- 1 | [koji] 2 | ;url of XMLRPC server 3 | server = {{ kojid_production_hub_url }} 4 | 5 | ;url of web interface 6 | weburl = {{ kojid_production_web_url }} 7 | 8 | ;url of package download site 9 | topurl = {{ kojid_production_files_url }} 10 | 11 | ;path to the koji top directory 12 | topdir = {{ kojid_production_mount }} 13 | 14 | ; https ca, not for ssl auth 15 | serverca = {{ kojid_ca_bundle }} 16 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/templates/production/kojid.conf.j2: -------------------------------------------------------------------------------- 1 | [kojid] 2 | sleeptime=15 3 | maxjobs={{ kojid_maxjobs }} 4 | minspace={{ kojid_minspace }} 5 | topdir={{ kojid_production_mount }} 6 | workdir=/tmp/koji 7 | mockdir=/var/lib/mock 8 | mockuser=kojibuilder 9 | vendor={{ kojid_vendor }} 10 | packager={{ kojid_packager }} 11 | mockhost=redhat-linux-gnu 12 | server={{ kojid_production_hub_url }} 13 | topurl={{ kojid_production_files_url }} 14 | use_createrepo_c=True 15 | from_addr=Koji Build System 16 | admin_emails="infrastructure@oelabox.local" 17 | ;smtphost={{ kojid_smtp_host }} 18 | ;smtp_user={{ kojid_smtp_user }} 19 | ;smtp_pass={{ kojid_smtp_pass }} 20 | host_principal_format = compile/%s@OELABOX.LOCAL 21 | keytab = {{ kojid_keytab }} 22 | serverca = {{ kojid_ca_bundle }} 23 | 24 | ; Modify 25 | allowed_scms={{ kojid_allowed_scm }} 26 | 27 | ; Other settings 28 | build_arch_can_fail = true 29 | 30 | {% set plugins = [] %} 31 | 32 | {% if kojid_runroot_builder %} 33 | {{ plugins.append("runroot") }} 34 | {% endif %} 35 | 36 | plugins = {{ plugins | join(" ") }} 37 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/templates/production/runroot.conf.j2: -------------------------------------------------------------------------------- 1 | [paths] 2 | ; comma-delimited list of default mountpoints 3 | ; They will be mounted during each run. It is suggested, that these 4 | ; paths has readonly options and are made writable via extra_mounts 5 | ; parameter for individual calls. 6 | default_mounts = {{ kojid_production_mount }} 7 | 8 | ; comma-delimited list of safe roots. 9 | ; Each extra_mount need to start with some of these prefixes. Other paths are 10 | ; not allowed for mounting. Only absolute paths are allowed here, no 11 | ; wildcards. 12 | safe_roots = {{ kojid_production_mount }}/compose,/srv/odcs 13 | 14 | ; path substitutions is tuple per line, delimited by comma, order is 15 | ; important. 16 | ; Path prefixes which can be substituted for other mountpoints. 17 | ; Usable for locations symlinked from other mounts. 18 | ; path_subs = /mnt/archive/prehistory/,/mnt/prehistoric_disk/archive/prehistory 19 | 20 | ; mount origins, order is important here, ordered by best catch 21 | [path0] 22 | mountpoint = {{ kojid_production_mount }}/compose 23 | path = {{ kojid_production_mount }}/compose 24 | fstype = bind 25 | options = bind 26 | 27 | [path1] 28 | mountpoint = {{ kojid_production_mount }} 29 | path = {{ kojid_production_mount }} 30 | fstype = bind 31 | options = bind 32 | 33 | [path2] 34 | mountpoint = /srv/odcs 35 | path = /srv/odcs 36 | fstype = bind 37 | options = bind 38 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/templates/runroot.conf.j2: -------------------------------------------------------------------------------- 1 | [paths] 2 | ; comma-delimited list of default mountpoints 3 | ; They will be mounted during each run. It is suggested, that these 4 | ; paths has readonly options and are made writable via extra_mounts 5 | ; parameter for individual calls. 6 | default_mounts = /mnt/koji 7 | 8 | ; comma-delimited list of safe roots. 9 | ; Each extra_mount need to start with some of these prefixes. Other paths are 10 | ; not allowed for mounting. Only absolute paths are allowed here, no 11 | ; wildcards. 12 | safe_roots = /mnt/koji/compose,/srv/odcs 13 | 14 | ; path substitutions is tuple per line, delimited by comma, order is 15 | ; important. 16 | ; Path prefixes which can be substituted for other mountpoints. 17 | ; Usable for locations symlinked from other mounts. 18 | ; path_subs = /mnt/archive/prehistory/,/mnt/prehistoric_disk/archive/prehistory 19 | 20 | ; mount origins, order is important here, ordered by best catch 21 | [path0] 22 | mountpoint = /mnt/koji/compose 23 | path = /mnt/koji/compose 24 | fstype = bind 25 | options = bind 26 | 27 | [path1] 28 | mountpoint = /mnt/koji 29 | path = /mnt/koji 30 | fstype = bind 31 | options = bind 32 | 33 | [path2] 34 | mountpoint = /srv/odcs 35 | path = /srv/odcs 36 | fstype = bind 37 | options = bind 38 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/templates/site-defaults.cfg.j2: -------------------------------------------------------------------------------- 1 | # Managed by Ansible 2 | config_opts['use_bootstrap_image'] = False 3 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/templates/staging/koji.conf.j2: -------------------------------------------------------------------------------- 1 | [koji] 2 | ;url of XMLRPC server 3 | server = {{ kojid_staging_hub_url }} 4 | 5 | ;url of web interface 6 | weburl = {{ kojid_staging_web_url }} 7 | 8 | ;url of package download site 9 | topurl = {{ kojid_staging_files_url }} 10 | 11 | ;path to the koji top directory 12 | topdir = {{ kojid_staging_mount }} 13 | 14 | ; https ca, not for ssl auth 15 | serverca = {{ kojid_ca_bundle }} 16 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/templates/staging/kojid.conf.j2: -------------------------------------------------------------------------------- 1 | [kojid] 2 | sleeptime=15 3 | maxjobs={{ kojid_maxjobs }} 4 | minspace={{ kojid_minspace }} 5 | topdir={{ kojid_staging_mount }} 6 | workdir=/tmp/koji 7 | mockdir=/var/lib/mock 8 | mockuser=kojibuilder 9 | vendor={{ kojid_vendor }} 10 | packager={{ kojid_packager }} 11 | mockhost=redhat-linux-gnu 12 | server={{ kojid_staging_hub_url }} 13 | topurl={{ kojid_staging_files_url }} 14 | use_createrepo_c=True 15 | from_addr=Koji Build System 16 | admin_emails="infrastructure@oelabox.local" 17 | ;smtphost={{ kojid_smtp_host }} 18 | ;smtp_user={{ kojid_smtp_user }} 19 | ;smtp_pass={{ kojid_smtp_pass }} 20 | host_principal_format = compile/%s@OELABOX.LOCAL 21 | keytab = {{ kojid_keytab }} 22 | serverca = {{ kojid_ca_bundle }} 23 | 24 | ; Modify 25 | allowed_scms={{ kojid_allowed_scm }} 26 | 27 | ; Other settings 28 | build_arch_can_fail = true 29 | 30 | {% set plugins = [] %} 31 | 32 | {% if kojid_runroot_builder %} 33 | {{ plugins.append("runroot") }} 34 | {% endif %} 35 | 36 | plugins = {{ plugins | join(" ") }} 37 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/templates/staging/runroot.conf.j2: -------------------------------------------------------------------------------- 1 | [paths] 2 | ; comma-delimited list of default mountpoints 3 | ; They will be mounted during each run. It is suggested, that these 4 | ; paths has readonly options and are made writable via extra_mounts 5 | ; parameter for individual calls. 6 | default_mounts = {{ kojid_staging_mount }} 7 | 8 | ; comma-delimited list of safe roots. 9 | ; Each extra_mount need to start with some of these prefixes. Other paths are 10 | ; not allowed for mounting. Only absolute paths are allowed here, no 11 | ; wildcards. 12 | safe_roots = {{ kojid_staging_mount }}/compose,/srv/odcs 13 | 14 | ; path substitutions is tuple per line, delimited by comma, order is 15 | ; important. 16 | ; Path prefixes which can be substituted for other mountpoints. 17 | ; Usable for locations symlinked from other mounts. 18 | ; path_subs = /mnt/archive/prehistory/,/mnt/prehistoric_disk/archive/prehistory 19 | 20 | ; mount origins, order is important here, ordered by best catch 21 | [path0] 22 | mountpoint = {{ kojid_staging_mount }}/compose 23 | path = {{ kojid_staging_mount }}/compose 24 | fstype = bind 25 | options = bind 26 | 27 | [path1] 28 | mountpoint = {{ kojid_staging_mount }} 29 | path = {{ kojid_staging_mount }} 30 | fstype = bind 31 | options = bind 32 | 33 | [path2] 34 | mountpoint = /srv/odcs 35 | path = /srv/odcs 36 | fstype = bind 37 | options = bind 38 | -------------------------------------------------------------------------------- /roles/oelabox.kojid/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file - Nothing should really go here but dynamic imports 3 | # and truely static items -------------------------------------------------------------------------------- /roles/oelabox.kojihub/.ansible-lint: -------------------------------------------------------------------------------- 1 | warn_list: 2 | - '204' # Lines should be less than 160 characters 3 | - '701' # meta/main.yml should contain relevant info 4 | skip_list: 5 | - '106' # Role name must match ^[a-z][a-z0-9_]+$ pattern 6 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | repos: 3 | - repo: https://github.com/pre-commit/pre-commit-hooks 4 | rev: v3.3.0 5 | hooks: 6 | - id: trailing-whitespace 7 | - id: end-of-file-fixer 8 | - id: check-added-large-files 9 | - id: check-case-conflict 10 | - id: check-executables-have-shebangs 11 | - id: check-json 12 | - id: pretty-format-json 13 | 14 | 15 | - repo: local 16 | hooks: 17 | - id: ansible-lint 18 | name: Ansible-lint 19 | description: This hook runs ansible-lint. 20 | entry: ansible-lint --force-color 21 | language: python 22 | # do not pass files to ansible-lint, see: 23 | # https://github.com/ansible/ansible-lint/issues/611 24 | pass_filenames: false 25 | always_run: true 26 | 27 | - repo: https://github.com/adrienverge/yamllint.git 28 | rev: v1.24.2 29 | hooks: 30 | - id: yamllint 31 | files: \.(yaml|yml)$ 32 | types: [file, yaml] 33 | entry: yamllint 34 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | 4 | rules: 5 | line-length: 6 | max: 140 7 | level: warning 8 | 9 | ignore: | 10 | .travis.yml 11 | .github 12 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [Unreleased] 8 | - what do we need to do 9 | 10 | ## [0.0.1] - 2020-12-13 11 | ### Added 12 | - Initial 13 | 14 | ### Changed 15 | - None 16 | 17 | ### Removed 18 | - None 19 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Darkbat91 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 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/README.md: -------------------------------------------------------------------------------- 1 | CI Badge 2 | 3 | # Kojihub Role 4 | This role installs kojihub and kojiweb. Note that it does NOT install the database. The database must be installed from a different role or playbook method. This role also assumes you are using a Kerberos infrastructure, such as FreeIPA. 5 | 6 | FAS is not yet implemented. 7 | 8 | Ansible 2.10 users: You will need the community.general collection installed. 9 | 10 | ## Getting started 11 | Ensure all dependencies are installed and then follow the below process 12 | 1. `git clone repo` Get the development repository 13 | 2. `pre-commit install` Install the pre-commit hooks 14 | 3. Make edits as explained in the customization section 15 | 4. `pre-commit` Make sure existing code is good 16 | 5. `do development` Dont ask me :D 17 | 6. `pre-commit` Make sure the edits are good to go 18 | 7. `molecule converge` 19 | 20 | ## Dependencies 21 | This repo expects 3 things installed on the local machine 22 | 1. [pre-commit](https://pre-commit.com/) Methodology to test yaml style 23 | 2. [ansible-lint](https://github.com/ansible-community/ansible-lint) lint ansible code for best practices 24 | 3. [yamllint](https://github.com/adrienverge/yamllint) Ensures all yaml is well formed 25 | 26 | ### Customization 27 | There are a few files that are required to be updated when using this template 28 | 1. [molecule/requirements.yml](molecule/requirements.yml) - Update with any required roles or collections 29 | 2. [molecule/default/converge.yml](molecule/default/converge.yml) - update with new role name 30 | 3. [molecule/default/molecule.yml](molecule/default/molecule.yml) - update with desired distributions and extra playbooks 31 | 4. [github](github) - Rename to `.github` and push, this will set up yamllint, ansible-lint and a CI check job for the `main` branch 32 | 1. NOTE: If you are using a SAML token this may fail. You can created the files within the Github web app 33 | 34 | ### Optional 35 | The github actions are configured to automatically run the molecule tests but if you want to load them locally you will also need molecule installed on the development machine 36 | 37 | ## Advanced 38 | 39 | There are numerous other options within the [defaults/main.yml](./defaults/main.yml) that can change other parts of the behavior of the system 40 | 41 | ## Changelog 42 | The [changelog](./CHANGELOG.md) is stored externally 43 | 44 | 45 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # ansible default variables - most variables live here 3 | koji_hub_packages: 4 | - koji 5 | - koji-hub 6 | - koji-hub-plugins 7 | - koji-web 8 | - koji-utils 9 | - git 10 | - gnupg2 11 | - python3-paho-mqtt 12 | - nfs-utils 13 | - mod_ssl 14 | - mod_auth_gssapi 15 | # - sigul 16 | 17 | koji_default_directories: 18 | - packages 19 | - repos 20 | - work 21 | - scratch 22 | - repos-dist 23 | - compose 24 | 25 | koji_db_name: koji 26 | koji_db_user: koji 27 | koji_db_pass: ThisIsNotThePassword! 28 | koji_db_host: localhost 29 | 30 | # Web 31 | koji_sitename: Oela Build Service 32 | koji_theme: false 33 | koji_theme_name: rocky 34 | koji_theme_file: rocky.tar.gz 35 | koji_web_url: https://koji.oelabox.local/koji 36 | koji_hub_url: https://koji.oelabox.local/kojihub 37 | koji_files_url: https://koji.oelabox.local/kojifiles 38 | koji_web_keytab: /etc/keytabs/koji-web.keytab 39 | 40 | # This should be changed before deployment 41 | koji_hub_secret: cK5XCuzMSXJfgA7yFvXkGwFu 42 | koji_web_cacert: /etc/pki/tls/certs/ca-bundle.crt 43 | koji_web_tls_cert: /etc/pki/tls/certs/koji.oelabox.local.crt 44 | koji_web_tls_key: /etc/pki/tls/private/koji.oelabox.local.key 45 | 46 | # Kojira 47 | koji_kojira: true 48 | koji_kojira_user: kojira 49 | koji_kojira_user_kerb: kojira/koji.oelabox.local 50 | koji_kojira_principal: kojira/koji.oelabox.local@OELABOX.LOCAL 51 | koji_kojira_keytab: /etc/keytabs/kojira.keytab 52 | 53 | # MBS 54 | koji_mbs: true 55 | koji_mbs_user: mbs 56 | koji_mbs_user_kerb: mbs/mbs.oelabox.local 57 | koji_mbs_principal: mbs/mbs.oelabox.local@OELABOX.LOCAL 58 | koji_mbs_keytab: /etc/keytabs/mbs.keytab 59 | 60 | # GC 61 | koji_gc_name: garbageman 62 | koji_gc_keytab: /etc/keytabs/koji-gc.keytab 63 | koji_gc_principal: koji-gc/koji.oelabox.local@OELABOX.LOCAL 64 | 65 | # Sigul 66 | koji_sigul: true 67 | koji_sigul_user: sigul 68 | koji_sigul_user_kerb: sigul/sigul.oelabox.local 69 | koji_sigul_principal: sigul/sigul.oelabox.local@OELABOX.LOCAL 70 | 71 | # Storage 72 | koji_nfs: true 73 | koji_mount: /mnt/koji 74 | koji_nfs_path: nfs.oelabox.local:/export/koji 75 | 76 | # Koji Admin 77 | koji_admin_client: true 78 | koji_admin_user: koji 79 | koji_admin_principal: koji@oelabox.local 80 | koji_admin_localuser: true 81 | koji_admin_localuser_name: koji 82 | 83 | # Hub Settings 84 | koji_hub_principal: "host/kojihub@OELABOX.LOCAL" 85 | koji_hub_proxy_principals: "HTTP/{{ inventory_hostname }}@OELABOX.LOCAL" 86 | koji_hub_keytab: /etc/keytabs/host.keytab 87 | koji_hub_principal_format: compile/%s@OELABOX.LOCAL 88 | # This should be sufficient even for LE 89 | koji_hub_ca: "{{ koji_web_cacert }}" 90 | 91 | # Koji FAS Syncing 92 | # This isn't implemented yet 93 | koji_fas_sync: false 94 | koji_fas_url: https://accounts.OELABOX.LOCAL 95 | 96 | # Koji Plugins 97 | koji_hub_plugins: false 98 | koji_hub_plugins_list: 99 | - key_signing 100 | 101 | koji_hub_plugin_key_gpg_keyphrase: lol 102 | koji_hub_plugin_key_gpg_name: testing-signing 103 | koji_hub_plugin_key_gpg_id: bbe2c108 104 | koji_hub_plugin_key_build_target: "dist-oela8 dist-oela9" 105 | koji_hub_plugin_key_testing_tag: dist-oela8-testing 106 | koji_hub_plugin_key_testing: "True" 107 | koji_hub_plugin_key_sigul_config: "/etc/koji-hub/sigul.conf" 108 | 109 | # Not implemented 110 | koji_hub_plugin_mqtt_host: mqtt.oelabox.local 111 | koji_hub_plugin_mqtt_topic: koji 112 | koji_hub_plugin_mqtt_ca: "{{ koji_hub_ca }}" 113 | koji_hub_plugin_mqtt_tls_cert: /etc/pki/tls/certs/mqtt.pem 114 | koji_hub_plugin_mqtt_tls_key: /etc/pki/tls/certs/mqtt.pem 115 | koji_hub_plugin_mqtt_excluded_tags: 116 | - testing-tag 117 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/files/etc/cron.d/koji-directory-cleanup: -------------------------------------------------------------------------------- 1 | # Adapted from Fedora Infra 2 | 0 8 * * * apache find /mnt/koji/work -xdev -depth -mindepth 2 -mtime +14 \( -type f -o -type l \) -delete -o -type d -empty -delete >& /dev/null 3 | 0 9 * * * apache find /mnt/koji/scratch -xdev -depth -mtime +14 \( -type f -o -type l \) -delete -o -type d -empty -delete >& /dev/null 4 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/files/etc/cron.d/koji-gc: -------------------------------------------------------------------------------- 1 | # Run garbage collector nightly 2 | SCRIPT=/usr/sbin/koji-gc 3 | MAILTO=infrastructure@oelabox.local 4 | 0 8 * * * apache /usr/local/bin/lock-wrapper koji-gc-delete $SCRIPT --action=delete --lock-file /var/tmp/koji-gc.lock 5 | 0 9 * * * apache /usr/local/bin/lock-wrapper koji-gc-trash $SCRIPT --action=trash --lock-file /var/tmp/koji-gc.lock 6 | 0 10 * * * apache /usr/local/bin/lock-wrapper koji-gc-prune $SCRIPT --action=prune --lock-file /var/tmp/koji-gc.lock 7 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/files/etc/cron.d/koji-prune-signed-copies: -------------------------------------------------------------------------------- 1 | # Run prune-signed-copies nightly 2 | MAILTO=infrastructure@oelabox.local 3 | 0 8 * * * apache /usr/local/bin/lock-wrapper koji-prune-signed "/usr/bin/koji --noauth prune-signed-copies --verbose --protect-tag-file=/etc/prune-signed-copies-protected-tags" 4 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/files/etc/koji-hub/plugins/sidetag.conf: -------------------------------------------------------------------------------- 1 | [sidetag] 2 | # automatically remove sidetag on untagging last package 3 | remove_empty = on 4 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/files/usr/lib/koji-hub-plugins/key_signing.py: -------------------------------------------------------------------------------- 1 | # Louis Abel 2 | # This is a koji plugin to assist in auto signing packages in sigul 3 | # This is going through constant change until it "works" 4 | # 5 | # Based on another plugin, updated and refinements where needed: 6 | # -> Config file introduced 7 | # -> Some linting 8 | # 9 | # TODO: Hook into a vault system 10 | 11 | import sys 12 | import logging 13 | import subprocess 14 | import os 15 | 16 | import koji 17 | from koji.plugin import register_callback, ignore_error 18 | if '/usr/share/koji-hub' not in sys.path: 19 | sys.path.append("/usr/share/koji-hub") 20 | import kojihub 21 | from kojihub import RootExports 22 | 23 | # CONVERT TO CONFIG FILE 24 | CONFIG_FILE = '/etc/koji-hub/plugins/key_signing.conf' 25 | CONFIG = None 26 | if not CONFIG: 27 | CONFIG = koji.read_config_files([(CONFIG_FILE, True)]) 28 | 29 | passphrase = CONFIG.get('signing', 'passphrase') 30 | gpg_key_name = CONFIG.get('signing', 'gpg_key_name') 31 | gpg_key_id = CONFIG.get('signing', 'gpg_key_id') 32 | build_target = CONFIG.get('signing', 'build_target').split() 33 | testing_tag = CONFIG.get('signing', 'testing_tag') 34 | send_to_testing = CONFIG.get('signing', 'send_to_testing') 35 | sigul_config = CONFIG.get('signing', 'sigul_config') 36 | 37 | @callback('postTag') 38 | def key_signing(cbtype, *args, **kws): 39 | # Make sure this is a package build and nothing else 40 | if kws['tag']['name'] not in build_target: 41 | return 42 | 43 | # The build has to succeed 44 | if kws['build']['state'] != 1: 45 | logging.getLogger('koji.plugin.key_signing').error('build state is not finished') 46 | return 47 | 48 | logging.getLogger('koji.plugin.key_signing').info('buildinfo: %s',str(kws)) 49 | 50 | # Find all the RPMs that are part of this build 51 | kojifunctions = RootExports() 52 | build_rpms = kojifunctions.listBuildRPMs(kws['build']['id']) 53 | logging.getLogger('koji.plugin.key_signing').info('rpminfo: %s',str(build_rpms)) 54 | 55 | # Sign and write the RPMs 56 | for rpm_info in build_rpms: 57 | rpm_name = "%s.%s" % (rpm_info['nvr'],rpm_info['arch']) 58 | key_signing_rpm(rpm_name) 59 | kojifunctions.writeSignedRPM(rpm_name,gpg_key_id) 60 | 61 | # If configured, tag for a testing repo 62 | if send_to_testing: 63 | kojifunctions.tagBuild(testing_tag,kws['build']['id']) 64 | logging.getLogger('koji.plugin.key_signing').info( 65 | 'the package %s has been tagged to %s' % (kws['build']['name'],testing_tag)) 66 | 67 | def run_sigul(command): 68 | passphrase_to_bytes = '{}\0'.format(passphrase).encode() 69 | p = os.pipe() 70 | os.write(p[1], passphrase_to_bytes) 71 | os.close(p[1]) 72 | send_to_stdin = os.fdopen(p[0], "r") 73 | 74 | child = subprocess.Popen(command, stdin=send_to_stdin, 75 | stdout=subprocess.PIPE, 76 | stderr=subprocess.PIPE,shell=True) 77 | 78 | ret = child.wait() 79 | logging.getLogger('koji.plugin.key_signing').info('sigul returned with code: %s',ret) 80 | if ret != 0: 81 | logging.getLogger('koji.plugin.key_signing').error( 82 | 'sigul command failed: %s returned: %s',command,child.communicate()) 83 | sys.exit(1) 84 | 85 | def key_signing_rpm(rpm_name): 86 | # Check to make sure the key works 87 | command = "sigul -c %s --batch get-public-key %s" % (sigul_config, gpg_key_name) 88 | run_sigul(command) 89 | 90 | # Run the actual sign command 91 | command = ("sigul -c %s --batch sign-rpm --koji-only --store-in-koji" 92 | " --v3-signature %s %s" % (sigul_config, gpg_key_name, rpm_name)) 93 | logging.getLogger('koji.plugin.key_signing').info('running sigul command: %s',command) 94 | run_sigul(command) 95 | 96 | #register_callback('postTag',key_signing) 97 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/files/var/www/html/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/github/workflows/ansible-lint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # https://github.com/ansible/ansible-lint-action 3 | name: Ansible Lint 4 | 5 | on: 6 | push: 7 | paths: 8 | - '**.yml' 9 | - '**.yaml' 10 | 11 | jobs: 12 | ansible-lint: 13 | runs-on: ubuntu-latest 14 | timeout-minutes: 7 15 | 16 | steps: 17 | - name: Git checkout 18 | uses: actions/checkout@v2 19 | 20 | - name: Add installed collections in Ansible configuration 21 | run: | 22 | echo '[defaults]' > ansible.cfg 23 | echo 'collections_paths = ./collections' >> ansible.cfg 24 | - name: Install role requirements 25 | run: ansible-galaxy role install -r molecule/requirements.yml 26 | # TODO: Figure out how to get this not to error so this action is universal 27 | # - name: Install collection requirements 28 | # run: ansible-galaxy collection install -r molecule/requirements.yml 29 | 30 | - name: Ansible Lint 31 | uses: rocky-linux/ansible-lint-action@master 32 | with: 33 | args: "--exclude .github" 34 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: CI 3 | 4 | 'on': 5 | pull_request: 6 | push: 7 | branches: 8 | - main 9 | schedule: 10 | - cron: "30 6 * * 2" 11 | 12 | jobs: 13 | molecule: 14 | name: Molecule 15 | runs-on: ubuntu-latest 16 | strategy: 17 | matrix: 18 | include: 19 | - distro: centos7 20 | playbook: converge.yml 21 | steps: 22 | - name: Check out the codebase. 23 | uses: actions/checkout@v2 24 | 25 | - name: Set up Python 3. 26 | uses: actions/setup-python@v2 27 | with: 28 | python-version: '3.x' 29 | 30 | - name: Install test dependencies. 31 | run: pip3 install ansible molecule[docker] docker 32 | 33 | - name: Run Molecule tests. 34 | run: molecule test 35 | env: 36 | PY_COLORS: '1' 37 | ANSIBLE_FORCE_COLOR: '1' 38 | MOLECULE_DISTRO: ${{ matrix.distro }} 39 | MOLECULE_PLAYBOOK: ${{ matrix.playbook }} 40 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/github/workflows/yaml-lint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # https://github.com/ibiqlik/action-yamllint 3 | name: YAML Lint 4 | 5 | on: 6 | push: 7 | paths: 8 | - '**.yml' 9 | - '**.yaml' 10 | 11 | jobs: 12 | yamllint: 13 | runs-on: ubuntu-latest 14 | timeout-minutes: 1 15 | 16 | steps: 17 | - name: Git checkout 18 | uses: actions/checkout@v2 19 | 20 | - name: yamllint 21 | uses: ibiqlik/action-yamllint@v3 22 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart_kojira 3 | ansible.builtin.service: 4 | name: kojira 5 | state: restarted 6 | 7 | - name: restart_httpd 8 | ansible.builtin.service: 9 | name: httpd 10 | state: restarted 11 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: Louis Abel 3 | description: Rocky Linux Koji Hub 4 | company: Rocky Linux Foundation 5 | license: MIT 6 | min_ansible_version: 2.8 7 | platforms: 8 | - name: EL 9 | versions: 10 | - 8 11 | galaxy_tags: [] 12 | dependencies: [] 13 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/molecule/default/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | become: true 5 | 6 | pre_tasks: 7 | - name: Update apt cache. 8 | apt: update_cache=true cache_valid_time=600 9 | when: ansible_os_family == 'Debian' 10 | changed_when: false 11 | 12 | roles: 13 | - role: ansible-role-mycoolrole 14 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/molecule/default/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | options: 5 | ignore-certs: true 6 | role-file: molecule/requirements.yml 7 | 8 | driver: 9 | name: docker 10 | 11 | # lint: | 12 | # set -e 13 | # yamllint . 14 | # ansible-lint 15 | platforms: 16 | - name: instance 17 | image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" 18 | command: ${MOLECULE_DOCKER_COMMAND:-""} 19 | volumes: 20 | - /sys/fs/cgroup:/sys/fs/cgroup:ro 21 | privileged: true 22 | pre_build_image: true 23 | provisioner: 24 | name: ansible 25 | playbooks: 26 | converge: ${MOLECULE_PLAYBOOK:-converge.yml} 27 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/molecule/requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | roles: 3 | ## Deps go here Should be very short and only if Absolutely needed 4 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/tasks/db.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Note: We do not install postgresql. It's up to you to do so, whether locally or not. 3 | - name: Template for koji admin and kojira 4 | ansible.builtin.template: 5 | src: koji-pgsql.sql.j2 6 | dest: /var/tmp/koji-pgsql.sql 7 | mode: '0644' 8 | 9 | - name: Load schema to postgresql database 10 | community.general.postgresql_db: 11 | name: "{{ koji_db_name }}" 12 | target: /usr/share/koji/schema.sql 13 | owner: "{{ koji_db_user }}" 14 | state: restore 15 | login_host: "{{ koji_db_host }}" 16 | login_user: "{{ koji_db_user }}" 17 | login_password: "{{ koji_db_pass }}" 18 | 19 | - name: Apply the postgres template 20 | community.general.postgresql_db: 21 | name: "{{ koji_db_name }}" 22 | target: /var/tmp/koji-pgsql.sql 23 | state: restore 24 | login_host: "{{ koji_db_host }}" 25 | login_user: "{{ koji_db_user }}" 26 | login_password: "{{ koji_db_pass }}" 27 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/tasks/koji-admin-ipa.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Setup the IPA service account 3 | - name: Create koji config directory 4 | ansible.builtin.file: 5 | path: "/home/{{ koji_admin_user }}/.koji" 6 | state: directory 7 | owner: "{{ koji_admin_user }}" 8 | group: "{{ koji_admin_user }}" 9 | mode: '0700' 10 | recurse: true 11 | 12 | - name: Reset permissions 13 | ansible.builtin.file: 14 | path: "/home/{{ koji_admin_user }}" 15 | state: directory 16 | owner: "{{ koji_admin_user }}" 17 | group: "{{ koji_admin_user }}" 18 | mode: '0700' 19 | 20 | - name: Configure the koji client 21 | ansible.builtin.template: 22 | src: koji-client-config.j2 23 | dest: "/home/{{ koji_admin_user }}/.koji/config" 24 | owner: "{{ koji_admin_user }}" 25 | group: "{{ koji_admin_user }}" 26 | mode: '0644' 27 | 28 | - name: Ensuring we have our scripts store 29 | ansible.builtin.file: 30 | path: /opt/rocky-tools/scripts 31 | state: directory 32 | owner: "{{ koji_admin_user }}" 33 | group: "{{ koji_admin_user }}" 34 | mode: '0750' 35 | recurse: true 36 | 37 | # name: Cron job to rebuild repos 38 | # cron: 39 | # name: "Regenerate repos" 40 | # job: "/opt/rocky-tools/scripts/regen_build_repos.sh > /dev/null 2>&1" 41 | # minute: "5" 42 | # hour: "3" 43 | # user: "{{ koji_admin_user }}" 44 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/tasks/koji-admin-local.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Create the koji admin user 3 | - name: Create local koji admin user 4 | ansible.builtin.user: 5 | name: "{{ koji_admin_localuser_name }}" 6 | comment: "Local Koji Admin" 7 | 8 | - name: Create koji config directory 9 | ansible.builtin.file: 10 | path: "/home/{{ koji_admin_localuser_name }}/.koji" 11 | state: directory 12 | owner: "{{ koji_admin_localuser_name }}" 13 | group: "{{ koji_admin_localuser_name }}" 14 | mode: '0700' 15 | recurse: true 16 | 17 | - name: Reset permissions 18 | ansible.builtin.file: 19 | path: "/home/{{ koji_admin_localuser_name }}" 20 | state: directory 21 | owner: "{{ koji_admin_localuser_name }}" 22 | group: "{{ koji_admin_localuser_name }}" 23 | mode: '0700' 24 | 25 | - name: Configure the koji client 26 | ansible.builtin.template: 27 | src: koji-client-config.j2 28 | dest: "/home/{{ koji_admin_localuser_name }}/.koji/config" 29 | owner: "{{ koji_admin_localuser_name }}" 30 | group: "{{ koji_admin_localuser_name }}" 31 | mode: '0644' 32 | 33 | - name: Ensuring we have our scripts store 34 | ansible.builtin.file: 35 | path: /opt/rocky-tools/scripts 36 | state: directory 37 | owner: "{{ koji_admin_localuser_name }}" 38 | group: "{{ koji_admin_localuser_name }}" 39 | mode: '0750' 40 | recurse: true 41 | 42 | # name: Cron job to rebuild repos 43 | # cron: 44 | # name: "Regenerate repos" 45 | # job: "/opt/rocky-tools/scripts/regen_build_repos.sh > /dev/null 2>&1" 46 | # minute: "5" 47 | # hour: "3" 48 | # user: "{{ koji_admin_localuser_name }}" 49 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/tasks/koji-gc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Configure gc 3 | - name: Configure garbage collector 4 | ansible.builtin.template: 5 | src: etc/koji-gc/koji-gc.conf.j2 6 | dest: /etc/koji-gc/koji-gc.conf 7 | owner: root 8 | group: root 9 | mode: '0644' 10 | 11 | - name: Enable the gc timer 12 | ansible.builtin.service: 13 | name: koji-gc.timer 14 | enabled: true 15 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/tasks/kojira.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Kojira 3 | - name: Configure kojira 4 | ansible.builtin.template: 5 | src: etc/kojira/kojira.conf.j2 6 | dest: /etc/kojira/kojira.conf 7 | mode: '0644' 8 | notify: 9 | - restart_kojira 10 | 11 | - name: Ensure kojira is running 12 | ansible.builtin.service: 13 | name: kojira 14 | state: started 15 | enabled: yes 16 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Koji hub and web installation 3 | # This is not for builder nodes 4 | 5 | - name: Apply required SELinux booleans 6 | import_tasks: selinux_boolean.yml 7 | 8 | - name: Ensure Storage is ready 9 | import_tasks: storage.yml 10 | 11 | - name: Install required packages 12 | ansible.builtin.dnf: 13 | name: "{{ koji_hub_packages }}" 14 | state: present 15 | 16 | - name: Configure koji database 17 | import_tasks: db.yml 18 | 19 | - name: Configure local koji admin 20 | import_tasks: koji-admin-local.yml 21 | when: koji_admin_client 22 | 23 | - name: Configure plugins 24 | import_tasks: plugins.yml 25 | when: koji_hub_plugins 26 | 27 | - name: Configure kojihub and web 28 | ansible.builtin.template: 29 | src: "{{ item }}.j2" 30 | dest: "/{{ item }}" 31 | mode: '0644' 32 | owner: root 33 | group: root 34 | with_items: 35 | - etc/koji-hub/hub.conf 36 | - etc/kojiweb/web.conf 37 | notify: 38 | - restart_httpd 39 | 40 | - name: Make sure to use custom OelaBOX ssl.conf 41 | template: 42 | src: "templates/ssl.conf.j2" 43 | dest: "/etc/httpd/conf.d/ssl.conf" 44 | mode: '0644' 45 | owner: root 46 | group: root 47 | notify: restart_httpd 48 | 49 | - name: Configure kojira 50 | import_tasks: kojira.yml 51 | 52 | - name: Configure httpd for hub and web 53 | ansible.builtin.template: 54 | src: "etc/httpd/conf.d/{{ item }}.j2" 55 | dest: "/etc/httpd/conf.d/{{ item }}" 56 | mode: '0644' 57 | owner: root 58 | group: root 59 | with_items: 60 | - kojihub.conf 61 | - kojiweb.conf 62 | notify: 63 | - restart_httpd 64 | 65 | - name: Configure robots.txt 66 | ansible.builtin.copy: 67 | src: "var/www/html/robots.txt" 68 | dest: "/var/www/html/robots.txt" 69 | owner: root 70 | group: root 71 | mode: '0644' 72 | notify: 73 | - restart_httpd 74 | 75 | - name: Enable httpd 76 | ansible.builtin.service: 77 | name: httpd 78 | enabled: yes 79 | 80 | - name: Deploy custom theme for koji 81 | ansible.builtin.unarchive: 82 | src: "{{ koji_theme_file }}" 83 | dest: / 84 | when: koji_theme 85 | 86 | - name: Configure garbage collector 87 | import_tasks: koji-gc.yml 88 | 89 | - name: User Sync from FAS 90 | import_tasks: user-sync.yml 91 | when: koji_fas_sync 92 | 93 | - name: Set SELinux fcontexts 94 | import_tasks: selinux_fcontexts.yml 95 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/tasks/plugins.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Plugins 3 | - name: Deploying enabled plugins 4 | ansible.builtin.copy: 5 | src: "plugins/{{ item }}.py" 6 | dest: "/usr/lib/koji-hub-plugins/{{ item }}.py" 7 | mode: 0755 8 | with_items: "{{ koji_hub_plugins_list }}" 9 | 10 | - name: Configuring enabled plugins 11 | ansible.builtin.template: 12 | src: "etc/koji-hub/plugins/{{ item }}.conf.j2" 13 | dest: "/etc/koji-hub/plugins/{{ item }}.conf" 14 | mode: 0644 15 | with_items: "{{ koji_hub_plugins_list }}" 16 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/tasks/selinux_boolean.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Enabling SELinux booleans 3 | ansible.posix.seboolean: 4 | name: "{{ item }}" 5 | persistent: true 6 | state: true 7 | with_items: 8 | - httpd_can_network_connect_db 9 | - httpd_can_network_connect 10 | - allow_httpd_anon_write 11 | - httpd_use_nfs 12 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/tasks/selinux_fcontexts.yml: -------------------------------------------------------------------------------- 1 | - name: Allow apache to R/W /mnt/koji 2 | community.general.sefcontext: 3 | target: "/mnt/koji(/.*)?" 4 | setype: public_content_rw_t 5 | state: present 6 | 7 | - name: Allow apache to R/W /mnt/koji subdirs 8 | ansible.builtin.file: 9 | path: /mnt/koji/{{ item }} 10 | state: directory 11 | mode: "0755" 12 | owner: apache 13 | group: apache 14 | setype: public_content_rw_t 15 | with_items: 16 | - 17 | - packages 18 | - repos 19 | - work 20 | - scratch 21 | - repos-dist 22 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/tasks/storage.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Storage 3 | - name: Ensure the koji mountpoint exists 4 | ansible.builtin.file: 5 | path: "{{ koji_mount }}" 6 | state: directory 7 | owner: '48' 8 | group: '48' 9 | mode: '0755' 10 | 11 | - name: Mount the NFS store 12 | ansible.builtin.mount: 13 | path: "{{ koji_mount }}" 14 | src: "{{ koji_nfs_path }}" 15 | fstype: nfs 16 | state: mounted 17 | when: koji_nfs 18 | 19 | - name: Create required default directories 20 | ansible.builtin.file: 21 | path: "{{ koji_mount }}/{{ item }}" 22 | state: directory 23 | owner: '48' 24 | group: '48' 25 | mode: '0755' 26 | with_items: "{{ koji_default_directories }}" 27 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/tasks/user-sync.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # No tasks 3 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/templates/etc/httpd/conf.d/kojihub.conf.j2: -------------------------------------------------------------------------------- 1 | # 2 | # koji-hub is an xmlrpc interface to the Koji database 3 | # 4 | 5 | Alias /kojihub /usr/share/koji-hub/kojiapp.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 {{ koji_mount }} 26 | Alias /kojifiles "{{ koji_mount }}/" 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 | # uncomment this to enable authentication via GSSAPI 45 | 46 | AuthType GSSAPI 47 | AuthName "GSSAPI Single Sign On Login" 48 | GssapiCredStore keytab:{{ koji_web_keytab }} 49 | Require valid-user 50 | 51 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/templates/etc/httpd/conf.d/kojiweb.conf.j2: -------------------------------------------------------------------------------- 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 | RewriteEngine on 6 | RewriteCond %{HTTPS} off 7 | RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L] 8 | RewriteRule ^/$ /koji [R,L] 9 | 10 | Header always set X-Frame-Options "SAMEORIGIN" 11 | Header always set X-Xss-Protection "1; mode=block" 12 | Header always set X-Content-Type-Options "nosniff" 13 | Header always set Referrer-Policy "same-origin" 14 | 15 | # Python 3 Cheetah expectes unicode everywhere, apache's default lang is C 16 | # which is not sufficient to open our templates 17 | WSGIDaemonProcess koji lang=C.UTF-8 18 | WSGIProcessGroup koji 19 | 20 | 21 | Options ExecCGI 22 | SetHandler wsgi-script 23 | WSGIProcessGroup koji 24 | WSGIApplicationGroup %{GLOBAL} 25 | # ^ works around an OpenSSL issue 26 | # see: https://cryptography.io/en/latest/faq/#starting-cryptography-using-mod-wsgi-produces-an-internalerror-during-a-call-in-register-osrandom-engine 27 | 28 | Order allow,deny 29 | Allow from all 30 | 31 | = 2.4> 32 | Require all granted 33 | 34 | 35 | 36 | # uncomment this to enable authentication via Kerberos 37 | 38 | AuthType GSSAPI 39 | AuthName "Koji Web UI" 40 | GssapiCredStore keytab:{{ koji_web_keytab }} 41 | Require valid-user 42 | ErrorDocument 401 /koji-static/errors/unauthorized.html 43 | 44 | 45 | Alias /koji-static/ "/usr/share/koji-web/static/" 46 | 47 | 48 | Options None 49 | AllowOverride None 50 | 51 | Order allow,deny 52 | Allow from all 53 | 54 | = 2.4> 55 | Require all granted 56 | 57 | 58 | 59 | Alias /repos {{ koji_mount }}/repos 60 | 61 | Options Indexes FollowSymLinks 62 | AllowOverride None 63 | #HeaderName /header/header.html 64 | 65 | Order allow,deny 66 | Allow from all 67 | 68 | = 2.4> 69 | IndexOptions FancyIndexing VersionSort NameWidth=* HTMLTable Charset=UTF-8 70 | Require all granted 71 | 72 | 73 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/templates/etc/koji-gc/koji-gc.conf.j2: -------------------------------------------------------------------------------- 1 | [main] 2 | ; Kerberos Auth 3 | principal = {{ koji_gc_principal }} 4 | keytab = {{ koji_gc_keytab }} 5 | krb_rdns = False 6 | key_aliases = 7 | 6D745A60 signing 8 | BBE2C108 testing-signing 9 | 10 | unprotected_keys = 11 | testing-signing 12 | 13 | server = {{ koji_hub_url }} 14 | weburl = {{ koji_web_url }} 15 | 16 | # We don't know what we're doing with SSL CA's yet 17 | serverca = {{ koji_web_cacert }} 18 | 19 | # The domain name that will be appended to Koji usernames 20 | # when creating email notifications 21 | #email_domain = fedoraproject.org 22 | 23 | # SMTP user and pass (uncomment and fill in if your smtp server requires authentication) 24 | #smtp_user=user@example.com 25 | #smtp_pass=CHANGEME 26 | 27 | [prune] 28 | policy = 29 | #stuff to protect 30 | #note that tags with master lock engaged are already protected 31 | tag *-updates :: keep 32 | # protect modules 33 | tag *-modular-* :: keep 34 | tag *-modular :: keep 35 | tag module-* :: keep 36 | # protect infra 37 | tag *-infra :: keep 38 | # general age 39 | age < 30 day :: skip 40 | 41 | # sig protect 42 | sig signing && age < 16 weeks :: keep 43 | 44 | #stuff to chuck semi-rapidly 45 | #tag *-testing *-candidate :: { # nested rules 46 | # order >= 2 :: untag 47 | # order > 0 && age > 6 weeks :: untag 48 | #} #closing braces must be on a line by themselves (modulo comments/whitespace) 49 | #tag *-candidate && age > 60 weeks :: untag 50 | #tag *-testing *-candidate *-override && order >= 2 :: untag 51 | #tag *-testing *-candidate && order > 0 && age > 6 weeks :: untag 52 | #tag *-candidate && age > 8 weeks :: untag 53 | 54 | #default: keep the last 3 55 | order > 2 :: untag 56 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/templates/etc/koji-hub/hub.conf.j2: -------------------------------------------------------------------------------- 1 | [hub] 2 | 3 | ## ConfigParser style config file, similar to ini files 4 | ## http://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_db_name }} 11 | DBUser = {{ koji_db_user }} 12 | DBHost = {{ koji_db_host }} 13 | DBPass = {{ koji_db_pass }} 14 | KojiDir = {{ koji_mount }} 15 | 16 | AuthPrincipal = {{ koji_hub_principal }} 17 | AuthKeytab = {{ koji_hub_keytab }} 18 | ProxyPrincipals = {{ koji_hub_proxy_principals }} 19 | HostPrincipalFormat = {{ koji_hub_principal_format }} 20 | 21 | ## Other options ## 22 | LoginCreatesUser = On 23 | KojiWebURL = {{ koji_web_url }} 24 | 25 | # The domain name that will be appended to Koji usernames 26 | # when creating email notifications 27 | EmailDomain = oelabox.local 28 | # whether to send the task owner and package owner email or not on success. this still goes to watchers 29 | NotifyOnSuccess = True 30 | ## Disables all notifications 31 | # DisableNotifications = False 32 | DisableNotifications = True 33 | 34 | ## Extended features 35 | ## Support Maven builds 36 | # EnableMaven = False 37 | ## Support Windows builds 38 | # EnableWin = False 39 | 40 | ## Koji hub plugins 41 | ## The path where plugins are found 42 | # PluginPath = /usr/lib/koji-hub-plugins 43 | ## A space-separated list of plugins to load 44 | # Plugins = echo 45 | {% if koji_hub_plugins %} 46 | Plugins = {% for plugin in koji_hub_plugins_list + koji_hub_noconfig_plugins_list %}{{ plugin }} {% endfor %} 47 | {% endif %} 48 | 49 | ## If KojiDebug is on, the hub will be /very/ verbose and will report exception 50 | ## details to clients for anticipated errors (i.e. koji's own exceptions -- 51 | ## subclasses of koji.GenericError). 52 | # KojiDebug = On 53 | 54 | ## Determines how much detail about exceptions is reported to the client (via faults) 55 | ## Meaningful values: 56 | ## normal - a basic traceback (format_exception) 57 | ## extended - an extended traceback (format_exc_plus) 58 | ## anything else - no traceback, just the error message 59 | ## The extended traceback is intended for debugging only and should NOT be 60 | ## used in production, since it may contain sensitive information. 61 | # KojiTraceback = normal 62 | 63 | ## These options are intended for planned outages 64 | # ServerOffline = False 65 | # OfflineMessage = temporary outage 66 | # LockOut = False 67 | ## If ServerOffline is True, the server will always report a ServerOffline fault (with 68 | ## OfflineMessage as the fault string). 69 | ## If LockOut is True, the server will report a ServerOffline fault for all non-admin 70 | ## requests. 71 | 72 | [policy] 73 | tag = 74 | all :: allow 75 | 76 | package_list = 77 | all :: allow 78 | 79 | build_from_srpm = 80 | tag * :: allow 81 | has_perm build :: allow 82 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/templates/etc/koji-hub/plugins/key_signing.conf.j2: -------------------------------------------------------------------------------- 1 | [signing] 2 | passphrase = {{ koji_hub_key_gpg_keyphrase }} 3 | gpg_key_name = {{ koji_hub_plugin_key_gpg_name }} 4 | gpg_key_id = {{ koji_hub_plugin_key_gpg_id }} 5 | build_target = {{ koji_hub_plugin_key_build_target }} 6 | testing_tag = {{ koji_hub_plugin_key_testing_tag }} 7 | send_to_testing = {{ koji_hub_plugin_key_testing }} 8 | sigul_config = {{ koji_hub_plugin_key_sigul_config }} 9 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/templates/etc/koji-hub/plugins/rockymsg.conf.j2: -------------------------------------------------------------------------------- 1 | [rockymsg] 2 | host = {{ koji_hub_plugin_mqtt_host }} 3 | port = 8883 4 | tls_cert = {{ koji_hub_plugin_mqtt_tls_cert }} 5 | tls_key = {{ koji_hub_plugin_mqtt_tls_key }} 6 | ca_cert = {{ koji_hub_plugin_mqtt_ca }} 7 | tls_insecure = False 8 | tls_version = 2 9 | exclude_tags = {% for tag in koji_hub_plugin_mqtt_excluded_tags %}{{ tag }}{%- if not loop.last -%},{% endif %}{% endfor %} 10 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/templates/etc/kojira/kojira.conf.j2: -------------------------------------------------------------------------------- 1 | [kojira] 2 | server={{ koji_hub_url }} 3 | topdir={{ koji_mount }} 4 | logfile=/var/log/kojira.log 5 | ;with_src=no 6 | principal = {{ koji_kojira_principal }} 7 | keytab = {{ koji_kojira_keytab }} 8 | serverca = {{ koji_hub_ca }} 9 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/templates/etc/kojiweb/web.conf.j2: -------------------------------------------------------------------------------- 1 | [web] 2 | SiteName = {{ koji_sitename }} 3 | {% if koji_theme %} 4 | KojiTheme = {{ koji_theme_name }} 5 | {% endif %} 6 | 7 | # Key urls 8 | KojiHubURL = {{ koji_hub_url }} 9 | KojiFilesURL = {{ koji_files_url }} 10 | 11 | # CA 12 | KojiHubCA = {{ koji_hub_ca }} 13 | 14 | # Kerberos authentication options 15 | WebPrincipal = {{ koji_hub_proxy_principals }} 16 | WebKeytab = {{ koji_hub_keytab }} 17 | WebCCache = /var/tmp/kojiweb.ccache 18 | 19 | LoginTimeout = 72 20 | 21 | # This must be changed and uncommented before deployment 22 | Secret = {{ koji_hub_secret }} 23 | 24 | LibPath = /usr/share/koji-web/lib 25 | LiteralFooter = True 26 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/templates/koji-client-config.j2: -------------------------------------------------------------------------------- 1 | [koji] 2 | 3 | ;url of XMLRPC server 4 | server = {{ koji_hub_url }} 5 | 6 | ;url of web interface 7 | weburl = {{ koji_web_url }} 8 | 9 | ;url of package download site 10 | topurl = {{ koji_files_url }} 11 | 12 | ;path to the koji top directory 13 | topdir = {{ koji_mount }} 14 | 15 | ; https ca, not for ssl auth 16 | serverca = {{ koji_hub_ca }} 17 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/templates/koji-pgsql-kojira.sql.j2: -------------------------------------------------------------------------------- 1 | insert into users (name, status, usertype) values ('{{ koji_kojira_user }}', 0, 0); 2 | INSERT INTO user_perms (user_id, perm_id, creator_id) VALUES (2, 3, 1); 3 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/templates/koji-pgsql.sql.j2: -------------------------------------------------------------------------------- 1 | with user_id as (insert into users (name, status, usertype) values ('{{ koji_admin_user }}', 0, 0) returning id) 2 | insert into user_krb_principals (user_id, krb_principal) values ((select id from user_id),'{{ koji_admin_principal }}'); 3 | insert into user_perms (user_id, perm_id, creator_id) values (1, 1, 1); 4 | with user_id as (insert into users (name, status, usertype) values ('{{ koji_kojira_user }}', 0, 0) returning id) 5 | insert into user_krb_principals (user_id, krb_principal) values ((select id from user_id),'{{ koji_kojira_principal }}'); 6 | INSERT INTO user_perms (user_id, perm_id, creator_id) VALUES (2, 10, 1); 7 | with user_id as (insert into users (name, status, usertype) values ('{{ koji_mbs_user }}', 0, 0) returning id) 8 | insert into user_krb_principals (user_id, krb_principal) values ((select id from user_id),'{{ koji_mbs_principal }}'); 9 | INSERT INTO user_perms (user_id, perm_id, creator_id) VALUES (3, 1, 1); 10 | with user_id as (insert into users (name, status, usertype) values ('{{ koji_sigul_user }}', 0, 0) returning id) 11 | insert into user_krb_principals (user_id, krb_principal) values ((select id from user_id),'{{ koji_sigul_principal }}'); 12 | INSERT INTO user_perms (user_id, perm_id, creator_id) VALUES (4, 1, 1); 13 | with user_id as (insert into users (name, status, usertype) values ('distrobuild', 0, 0) returning id) 14 | insert into user_krb_principals (user_id, krb_principal) values ((select id from user_id),'koji/distrobuild@OELABOX.LOCAL'); 15 | INSERT INTO user_perms (user_id, perm_id, creator_id) VALUES (5, 1, 1); 16 | with user_id as (insert into users (name, status, usertype) values ('{{ koji_gc_name }}', 0, 0) returning id) 17 | insert into user_krb_principals (user_id, krb_principal) values ((select id from user_id),'{{ koji_gc_principal }}'); 18 | INSERT INTO user_perms (user_id, perm_id, creator_id) VALUES (6, 1, 1); 19 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/templates/opt/rocky-tools/regen-buildrepos.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # adapted from centos 3 | logfile=/var/tmp/koji-regen-repo.log 4 | for buildroot in $(koji list-tags \*-build); do 5 | koji regen-repo --nowait $buildroot >> $logfile 2>&1 6 | done 7 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/templates/opt/rocky-tools/regen-buildroots.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | for i in `koji list-tags \*-build`; do 3 | koji regen-repo --nowait $i; 4 | done 5 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/templates/opt/rocky-tools/who.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # adapted from centos tools 3 | for i in `koji list-tags $1*candidate`; do 4 | USERS="$USERS `koji list-tagged --quiet $i | rev | cut -d " " -f 1 | rev | uniq | tr '\n' ' '`" 5 | TMP=`echo ${i} | cut -d "-" -f 1` 6 | SIG=${TMP%?} 7 | done 8 | 9 | echo $1:`echo $USERS|tr " " "\n"|sort|uniq|tr "\n" " "` 10 | -------------------------------------------------------------------------------- /roles/oelabox.kojihub/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file - Nothing should really go here but dynamic imports 3 | # and truely static items -------------------------------------------------------------------------------- /setup-oelabox-tools.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Setup Koji tools 3 | hosts: kojihub 4 | become: true 5 | 6 | tasks: 7 | - name: Install Koji tools 8 | ansible.builtin.include_tasks: 9 | file: "{{ item }}" 10 | with_items: "{{'./tools/oelabox-koji/*/install.yml' | fileglob}}" 11 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | runby="root" 4 | iam=`/usr/bin/id -un` 5 | if [ $iam != "$runby" ] 6 | then 7 | echo "$PGM : program must be run by user \"$runby\"" 8 | exit 9 | fi 10 | 11 | function check_installed() { 12 | dnf list installed | grep -oP "^$1(\.\w+)" &> /dev/null 13 | return $? 14 | } 15 | 16 | function echo_info() { 17 | echo "* $@" 18 | } 19 | 20 | echo_info "Checking if epel-release is installed..." 21 | if ! check_installed epel-release; then 22 | echo_info "epel-release not installed. Installing now." 23 | dnf install epel-release -y 24 | fi 25 | 26 | echo_info "Checking if ansible is installed..." 27 | if ! check_installed ansible; then 28 | echo_info "ansible not installed. Installing now." 29 | dnf install ansible -y 30 | fi 31 | 32 | echo_info "Running ansible playbook..." 33 | ansible-playbook setup.yml 34 | -------------------------------------------------------------------------------- /setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | connection: local 4 | gather_facts: yes 5 | become: yes 6 | 7 | vars: 8 | invoking_user: "{{ lookup('ansible.builtin.env', 'SUDO_USER', default=lookup('ansible.builtin.env', 'USER')) }}" 9 | rockybox: https://dl.rockylinux.org/pub/rocky/9.3/images/x86_64/Rocky-9-Vagrant-Libvirt-9.3-20231113.0.x86_64.box 10 | centosbox: https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-Vagrant-8-20240101.0.x86_64.vagrant-libvirt.box 11 | 12 | tasks: 13 | - name: Add hashicorp repo to system 14 | ansible.builtin.get_url: 15 | url: https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo 16 | dest: /etc/yum.repos.d/hashicorp.repo 17 | owner: root 18 | group: root 19 | mode: '0644' 20 | 21 | - name: Install vagrant 22 | ansible.builtin.dnf: 23 | name: vagrant 24 | state: present 25 | 26 | - name: Enable the CRB repository (Rocky) 27 | community.general.ini_file: 28 | dest: /etc/yum.repos.d/rocky.repo 29 | section: crb 30 | option: enabled 31 | value: 1 32 | owner: root 33 | group: root 34 | mode: '0644' 35 | when: ansible_distribution == "Rocky" 36 | 37 | - name: Enable the CRB repository (Oracle) 38 | community.general.ini_file: 39 | dest: /etc/yum.repos.d/oracle-linux-ol9.repo 40 | section: ol9_codeready_builder 41 | option: enabled 42 | value: 1 43 | owner: root 44 | group: root 45 | mode: '0644' 46 | when: ansible_distribution == "OracleLinux" 47 | 48 | - name: Install libvirt-devel and libvirt 49 | ansible.builtin.dnf: 50 | name: 51 | - libvirt-devel 52 | - libvirt 53 | state: present 54 | 55 | - name: Start libvirtd 56 | ansible.builtin.service: 57 | name: libvirtd 58 | state: started 59 | 60 | - name: Enable libvirtd 61 | ansible.builtin.service: 62 | name: libvirtd 63 | enabled: yes 64 | 65 | - name: Install ruby and ruby-devel 66 | ansible.builtin.dnf: 67 | name: 68 | - ruby 69 | - ruby-devel 70 | state: present 71 | 72 | - name: Install "Development Tools" group 73 | ansible.builtin.dnf: 74 | name: '@Development Tools' 75 | state: present 76 | 77 | - name: Install "Virtualization Host" group 78 | ansible.builtin.dnf: 79 | name: '@Virtualization Host' 80 | state: present 81 | 82 | - name: Add invoking user to the libvirt group 83 | ansible.builtin.user: 84 | name: "{{ invoking_user }}" 85 | groups: libvirt 86 | append: yes 87 | 88 | - name: Install vagrant-libvirt plugin 89 | ansible.builtin.shell: "vagrant plugin install vagrant-libvirt" 90 | changed_when: "1 != 1" 91 | become: true 92 | become_user: "{{ invoking_user }}" 93 | 94 | - name: Add Rocky Linux 9.2 box to Vagrant 95 | ansible.builtin.shell: "vagrant box add --name rockylinux/9 -f {{ rockybox }}" 96 | changed_when: "1 != 1" 97 | become: true 98 | become_user: "{{ invoking_user }}" 99 | 100 | - name: Add CentOS Stream 8 box to Vagrant 101 | ansible.builtin.shell: "vagrant box add --name centos/stream8 -f {{ centosbox }}" 102 | changed_when: "1 != 1" 103 | become: true 104 | become_user: "{{ invoking_user }}" 105 | 106 | - name: Overwrite /etc/hosts 107 | ansible.builtin.copy: 108 | dest: "/etc/hosts" 109 | owner: root 110 | group: root 111 | mode: '0644' 112 | content: | 113 | 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 114 | ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 115 | 192.168.121.10 dns.oelabox.local 116 | 192.168.121.11 ipa.oelabox.local 117 | 192.168.121.12 koji.oelabox.local 118 | 119 | - name: Install freeipa.ansible_freeipa collection 120 | ansible.builtin.shell: "ansible-galaxy collection install freeipa.ansible_freeipa" 121 | changed_when: "1 != 1" 122 | become: true 123 | become_user: "{{ invoking_user }}" 124 | 125 | - name: Install git if it is not installed (by some means) 126 | ansible.builtin.dnf: 127 | name: git 128 | state: present 129 | 130 | - name: Install pandoc 131 | ansible.builtin.dnf: 132 | name: pandoc 133 | state: present 134 | 135 | - name: Clone ktdreyer.koji_ansible collection 136 | ansible.builtin.git: 137 | repo: 'https://github.com/ktdreyer/koji-ansible' 138 | dest: /tmp/koji-ansible 139 | become: true 140 | become_user: "{{ invoking_user }}" 141 | 142 | - name: Build ktdreyer.koji_ansible collection 143 | ansible.builtin.shell: "/tmp/koji-ansible/build-collection" 144 | changed_when: "1 != 1" 145 | become: true 146 | become_user: "{{ invoking_user }}" 147 | 148 | - name: Install ktdreyer.koji_ansible collection 149 | ansible.builtin.shell: "ansible-galaxy collection install /tmp/koji-ansible/_build" 150 | changed_when: "1 != 1" 151 | become: true 152 | become_user: "{{ invoking_user }}" 153 | -------------------------------------------------------------------------------- /tasks/oelabox-dns/client-setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - import_tasks: disable-nm-dns-processing.yml 3 | 4 | - import_tasks: custom-resolv-conf.yml 5 | -------------------------------------------------------------------------------- /tasks/oelabox-dns/custom-resolv-conf.yml: -------------------------------------------------------------------------------- 1 | - name: Custom resolv.conf 2 | ansible.builtin.template: 3 | src: templates/oelabox-dns/resolv.conf.j2 4 | dest: /etc/resolv.conf 5 | owner: root 6 | group: root 7 | mode: '0644' 8 | notify: 9 | - restart_networkmanager 10 | 11 | -------------------------------------------------------------------------------- /tasks/oelabox-dns/disable-nm-dns-processing.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure 'dns=none' is set for Network Manager 3 | community.general.ini_file: 4 | path: /etc/NetworkManager/NetworkManager.conf 5 | state: present 6 | no_extra_spaces: true 7 | section: main 8 | option: dns 9 | value: none 10 | owner: root 11 | group: root 12 | mode: '0644' 13 | backup: true 14 | notify: 15 | - restart_networkmanager 16 | -------------------------------------------------------------------------------- /tasks/oelabox-dns/server-setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install bind and bind-utils 3 | ansible.builtin.dnf: 4 | name: 5 | - bind 6 | - bind-utils 7 | state: present 8 | 9 | - name: Enable and start named 10 | ansible.builtin.service: 11 | name: named 12 | state: started 13 | enabled: yes 14 | 15 | - name: "/var/named/oelabox.local.zone" 16 | ansible.builtin.copy: 17 | src: files/oelabox-dns/oelabox.local.zone 18 | dest: /var/named/oelabox.local.zone 19 | owner: root 20 | group: named 21 | mode: '0640' 22 | notify: 23 | - restart_named 24 | 25 | - name: "/var/named/121.168.192.in-addr.arpa.zone" 26 | ansible.builtin.copy: 27 | src: files/oelabox-dns/121.168.192.in-addr.arpa.zone 28 | dest: /var/named/121.168.192.in-addr.arpa.zone 29 | owner: root 30 | group: named 31 | mode: '0640' 32 | notify: 33 | - restart_named 34 | 35 | - name: "/etc/named.conf" 36 | ansible.builtin.copy: 37 | src: files/oelabox-dns/named.conf 38 | dest: /etc/named.conf 39 | owner: root 40 | group: named 41 | mode: '0640' 42 | notify: 43 | - restart_named 44 | 45 | - import_tasks: disable-nm-dns-processing.yml 46 | 47 | - import_tasks: custom-resolv-conf.yml 48 | 49 | - name: Open DNS port 50 | ansible.builtin.firewalld: 51 | service: dns 52 | permanent: true 53 | state: enabled 54 | -------------------------------------------------------------------------------- /tasks/oelabox-ipa/dns-ext.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Configure ACL for nets 3 | ansible.builtin.template: 4 | src: "templates/oelabox-ipa/etc/named/ipa-ext.conf" 5 | dest: "/etc/named/ipa-ext.conf" 6 | owner: root 7 | group: named 8 | mode: '0640' 9 | notify: restart_named 10 | 11 | - name: Turn on recursion for nets 12 | ansible.builtin.template: 13 | src: "templates/oelabox-ipa/etc/named/ipa-options-ext.conf" 14 | dest: "/etc/named/ipa-options-ext.conf" 15 | owner: root 16 | group: named 17 | mode: '0640' 18 | notify: restart_named 19 | ... 20 | -------------------------------------------------------------------------------- /tasks/oelabox-ipa/domain-prework.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure epel-release and firewalld are installed 3 | ansible.builtin.dnf: 4 | name: 5 | - epel-release 6 | - firewalld 7 | - rocky-release-core 8 | state: present 9 | notify: 10 | - enable_firewalld 11 | - enable_crb 12 | - enable_core_infra 13 | 14 | # We need this immediately. 15 | - name: Flush handlers 16 | ansible.builtin.meta: flush_handlers 17 | 18 | - name: Ensure 'dns=none' is set for Network Manager 19 | community.general.ini_file: 20 | path: /etc/NetworkManager/NetworkManager.conf 21 | state: present 22 | no_extra_spaces: true 23 | section: main 24 | option: dns 25 | value: none 26 | owner: root 27 | group: root 28 | mode: '0644' 29 | backup: true 30 | notify: 31 | - reload_networkmanager 32 | 33 | - name: Install ipa-fas 34 | ansible.builtin.dnf: 35 | name: ipa-fas 36 | state: present 37 | 38 | - name: Open firewalld service before hand 39 | ansible.posix.firewalld: 40 | service: freeipa-4 41 | permanent: true 42 | immediate: true 43 | state: enabled 44 | ... 45 | -------------------------------------------------------------------------------- /tasks/oelabox-ipa/import-ipakeytab.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # This playbook is meant to be used with callable variables, like adhoc or AWX. 3 | # Special thanks to @remyabel for assisting in improving this playbook with 4 | # extended security posture 5 | # What: Pulls keytabs for a kerberos service 6 | # What is expected: 7 | # -> host: The host in the inventory 8 | # -> ipa_service: using this format: SVC/hostname.oelabox.local@OELABOX.LOCAL 9 | # Note: This service MUST exist 10 | # -> ipa_keytab_fullpath: The full path to the keytab. Example: /etc/gitlab/gitlab.keytab 11 | # -> ipa_server: This needs to be one of the IPA servers 12 | # -> ipa_owner: If applicable, the local account that can read this keytab (eg apache) 13 | # -> ipa_admin: The admin user that has kerberos management capabilities (default is admin) 14 | # -> ipaadmin_password: This should be the password of the admin user 15 | - name: "Checking for user variables" 16 | ansible.builtin.assert: 17 | that: 18 | - ipa_admin | mandatory 19 | - ipaadmin_password | mandatory 20 | - ipa_service | mandatory 21 | - ipa_keytab_fullpath | mandatory 22 | - ipa_server | mandatory 23 | success_msg: "Required variables provided" 24 | fail_msg: "We are missing required information" 25 | 26 | - name: "Check that a keytab doesn't already exist" 27 | ansible.builtin.stat: 28 | path: "{{ ipa_keytab_fullpath }}" 29 | register: keytab_status 30 | check_mode: false 31 | changed_when: "1 != 1" 32 | 33 | - name: "Grant {{ host }} and {{ ipa_admin }} access to the service keytab" 34 | #delegate_to: "{{ ipa_server }}" 35 | freeipa.ansible_freeipa.ipaservice: 36 | ipaadmin_principal: "{{ ipa_admin }}" 37 | ipaadmin_password: "{{ ipaadmin_password }}" 38 | name: "{{ ipa_service }}" 39 | allow_retrieve_keytab_user: 40 | - "{{ ipa_admin }}" 41 | allow_retrieve_keytab_host: 42 | - "{{ host }}" 43 | action: member 44 | 45 | - name: "Grant {{ host }} and {{ ipa_admin }} access to the host keytab" 46 | #delegate_to: "{{ ipa_server }}" 47 | freeipa.ansible_freeipa.ipahost: 48 | ipaadmin_principal: "{{ ipa_admin }}" 49 | ipaadmin_password: "{{ ipaadmin_password }}" 50 | name: "{{ host }}" 51 | state: present 52 | allow_retrieve_keytab_user: 53 | - "{{ ipa_admin }}" 54 | managedby_host: "{{ host }}" 55 | action: member 56 | 57 | - name: "Get kerberos ticket" 58 | #delegate_to: "{{ ipa_server }}" 59 | ansible.builtin.shell: "set -o pipefail && echo \"{{ ipaadmin_password }}\" | kinit {{ ipa_admin }}" 60 | check_mode: false 61 | changed_when: "1 != 1" 62 | #when: not keytab_status.stat.exists 63 | 64 | - name: "Attempt to retrieve keytab" 65 | #delegate_to: "{{ ipa_server }}" 66 | ansible.builtin.command: "ipa-getkeytab -r -s {{ ipa_server }} -p {{ ipa_service }} -k /tmp/{{ host }}.kt" 67 | register: ret_result 68 | check_mode: false 69 | changed_when: "1 != 1" 70 | failed_when: "not ('Keytab successfully retrieved' in ret_result.stderr or 'krbPrincipalKey not found' in ret_result.stderr)" 71 | 72 | - name: "Create keytab if it didn't exist, based on the last task" 73 | #delegate_to: "{{ ipa_server }}" 74 | ansible.builtin.command: "ipa-getkeytab -s {{ ipa_server }} -p {{ ipa_service }} -k /tmp/{{ host }}.kt" 75 | when: "'krbPrincipalKey not found' in ret_result.stderr" 76 | 77 | - name: "Destroy admin ticket" 78 | #delegate_to: "{{ ipa_server }}" 79 | ansible.builtin.command: "kdestroy -A" 80 | register: kdestroy_result 81 | changed_when: "kdestroy_result.rc == 0" 82 | 83 | - name: "Put the keytab into a register" 84 | #delegate_to: "{{ ipa_server }}" 85 | ansible.builtin.command: "base64 /tmp/{{ host }}.kt" 86 | register: keytab 87 | check_mode: false 88 | changed_when: "keytab.rc == 0" 89 | 90 | - name: "Destroy local keytab" 91 | #delegate_to: "{{ ipa_server }}" 92 | ansible.builtin.file: 93 | path: "/tmp/{{ host }}.kt" 94 | state: absent 95 | 96 | - name: "Deploy keytab to {{ host }} from register" 97 | ansible.builtin.copy: 98 | dest: "{{ ipa_keytab_fullpath }}.b64" 99 | content: "{{ keytab.stdout }}" 100 | owner: "{{ ipa_owner|default('root') }}" 101 | group: "{{ ipa_owner|default('root') }}" 102 | mode: '0600' 103 | 104 | - name: "Decode keytab" 105 | ansible.builtin.shell: "umask 077 && base64 -d {{ ipa_keytab_fullpath }}.b64 > {{ ipa_keytab_fullpath }}" 106 | changed_when: "1 != 1" 107 | 108 | - name: "Destroy encoded keytab" 109 | ansible.builtin.file: 110 | path: "{{ ipa_keytab_fullpath }}.b64" 111 | state: absent 112 | 113 | - name: "Set ownership if applicable, otherwise it's root owned" 114 | ansible.builtin.file: 115 | path: "{{ ipa_keytab_fullpath }}" 116 | owner: "{{ ipa_owner|default('root') }}" 117 | group: "{{ ipa_owner|default('root') }}" 118 | mode: "{{ ipa_keytab_file_perms|default('0600') }}" 119 | state: file 120 | tags: 121 | - keytab 122 | ... 123 | -------------------------------------------------------------------------------- /tasks/oelabox-ipa/import-ipaservice.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Checking for user variables" 3 | ansible.builtin.assert: 4 | that: 5 | - ipa_admin | mandatory 6 | - ipaadmin_password | mandatory 7 | - ipa_service | mandatory 8 | success_msg: "Required variables provided" 9 | fail_msg: "We are missing required information" 10 | 11 | - name: "Creating Kerberos Service" 12 | freeipa.ansible_freeipa.ipaservice: 13 | ipaadmin_principal: "{{ ipa_admin }}" 14 | ipaadmin_password: "{{ ipaadmin_password }}" 15 | name: "{{ ipa_service }}" 16 | skip_host_check: "{{ ipa_skip_host_check | default(false) }}" 17 | force: "{{ ipa_force | default(false) }}" 18 | tags: 19 | - services 20 | -------------------------------------------------------------------------------- /tasks/oelabox-ipa/import-oelagroups.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Creates the first set of groups for the IdM Infrastructure 3 | - name: "Creating Mandatory Groups" 4 | freeipa.ansible_freeipa.ipagroup: 5 | ipaadmin_password: "{{ ipaadmin_password }}" 6 | name: "{{ item.group }}" 7 | description: "{{ item.description }}" 8 | nonposix: false 9 | user: "{{ item.user | default(none) }}" 10 | membermanager_user: "{{ item.managers_users | default(omit) }}" 11 | membermanager_group: "{{ item.managers_groups | default(omit) }}" 12 | loop: "{{ ipagroups }}" 13 | tags: 14 | - groups 15 | ... 16 | -------------------------------------------------------------------------------- /tasks/oelabox-ipa/import-oelaipaprivs.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Creates necessary privileges for services 3 | - name: "Creating necessary privileges" 4 | freeipa.ansible_freeipa.ipaprivilege: 5 | ipaadmin_password: "{{ ipaadmin_password }}" 6 | name: "{{ item.privilege }}" 7 | description: "{{ item.description }}" 8 | loop: "{{ ipaprivileges }}" 9 | when: ipaprivileges is defined 10 | tags: 11 | - rbac 12 | 13 | - name: "Creating permissions" 14 | freeipa.ansible_freeipa.ipaprivilege: 15 | ipaadmin_password: "{{ ipaadmin_password }}" 16 | name: "{{ item.privilege }}" 17 | permission: "{{ item.permissions }}" 18 | action: member 19 | loop: "{{ ipaprivileges }}" 20 | when: ipaprivileges is defined 21 | tags: 22 | - rbac 23 | 24 | - name: "Creating roles based on custom privileges" 25 | freeipa.ansible_freeipa.iparole: 26 | ipaadmin_password: "{{ ipaadmin_password }}" 27 | name: "{{ item.role }}" 28 | privilege: "{{ item.privilege }}" 29 | user: "{{ item.user|default(omit) }}" 30 | loop: "{{ ipaprivileges }}" 31 | when: ipaprivileges is defined 32 | tags: 33 | - rbac 34 | 35 | - name: "Creating roles based on standard privileges" 36 | freeipa.ansible_freeipa.iparole: 37 | ipaadmin_password: "{{ ipaadmin_password }}" 38 | name: "{{ item.role }}" 39 | privilege: "{{ item.privileges }}" 40 | user: "{{ item.user|default(omit) }}" 41 | loop: "{{ iparoles }}" 42 | when: iparoles is defined 43 | tags: 44 | - rbac 45 | ... 46 | -------------------------------------------------------------------------------- /tasks/oelabox-ipa/import-oelasudo.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Currently only one SUDO role should be created, and that is for the 3 | # Oela Box admins 4 | - name: "Creating SUDO Role for Oela Box Admins" 5 | freeipa.ansible_freeipa.ipasudorule: 6 | ipaadmin_password: "{{ ipaadmin_password }}" 7 | name: All_OelaAdmins 8 | description: Oela Box infrastructure and operations sudo access 9 | group: 10 | - oelaadm 11 | hostcat: all 12 | cmdcat: all 13 | ... 14 | -------------------------------------------------------------------------------- /tasks/oelabox-ipa/import-oelausers.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Creates the first set of users for the IdM Infrastructure. This 3 | # should create both regular and admin accounts for separation of 4 | # privilege. 5 | - name: "Creating Initial Accounts" 6 | freeipa.ansible_freeipa.ipauser: 7 | ipaadmin_password: "{{ ipaadmin_password }}" 8 | name: "{{ item.name }}" 9 | first: "{{ item.first }}" 10 | last: "{{ item.last }}" 11 | email: "{{ item.email|default(omit) }}" 12 | password: "{{ item.password }}" 13 | title: "{{ item.title }}" 14 | loginshell: "{{ item.loginshell }}" 15 | update_password: on_create 16 | loop: "{{ users }}" 17 | tags: 18 | - users 19 | 20 | - name: "Creating Initial Admin Accounts" 21 | freeipa.ansible_freeipa.ipauser: 22 | ipaadmin_password: "{{ ipaadmin_password }}" 23 | name: "{{ item.name }}" 24 | first: "{{ item.first }}" 25 | last: "{{ item.last }}" 26 | email: "{{ item.email|default(omit) }}" 27 | password: "{{ item.password }}" 28 | title: "{{ item.title }}" 29 | loginshell: "{{ item.loginshell }}" 30 | update_password: on_create 31 | loop: "{{ adminusers }}" 32 | tags: 33 | - users 34 | 35 | - name: "Creating Service Accounts" 36 | freeipa.ansible_freeipa.ipauser: 37 | ipaadmin_password: "{{ ipaadmin_password }}" 38 | name: "{{ item.name }}" 39 | first: "{{ item.first }}" 40 | last: "{{ item.last }}" 41 | email: "{{ item.email|default(omit) }}" 42 | password: "{{ item.password }}" 43 | title: "{{ item.title }}" 44 | loginshell: "{{ item.loginshell }}" 45 | update_password: on_create 46 | loop: "{{ svcusers }}" 47 | tags: 48 | - users 49 | 50 | - name: "Creating bind account template - binder" 51 | ansible.builtin.template: 52 | src: "templates/oelabox-ipa/tmp/binder.update.j2" 53 | dest: "/tmp/binder.update" 54 | owner: root 55 | group: root 56 | mode: '0600' 57 | tags: 58 | - users 59 | 60 | - name: "Adding in the bind account - binder" 61 | ansible.builtin.command: "/usr/sbin/ipa-ldap-updater /tmp/binder.update" 62 | register: bind_account 63 | changed_when: "bind_account.rc == 0" 64 | tags: 65 | - users 66 | 67 | - name: "Remove template" 68 | ansible.builtin.file: 69 | path: "/tmp/binder.update" 70 | state: absent 71 | ... 72 | -------------------------------------------------------------------------------- /templates/oelabox-dns/resolv.conf.j2: -------------------------------------------------------------------------------- 1 | # Generated by Oela Box 2 | {% for entry in resolv_entries %} 3 | search {{ entry.search|join(' ') }} 4 | nameserver {{ entry.nameserver }} 5 | {% endfor %} 6 | nameserver 192.168.121.1 7 | 8 | -------------------------------------------------------------------------------- /templates/oelabox-ipa/etc/named/ipa-ext.conf: -------------------------------------------------------------------------------- 1 | /* User customization for BIND named 2 | * 3 | * This file is included in /etc/named.conf and is not modified during IPA 4 | * upgrades. 5 | * 6 | * "options" settings must be configured in /etc/named/ipa-options-ext.conf. 7 | * 8 | * Example: ACL for recursion access: 9 | * 10 | * acl "trusted_network" { 11 | * localnets; 12 | * localhost; 13 | * 234.234.234.0/24; 14 | * 2001::co:ffee:babe:1/48; 15 | * }; 16 | */ 17 | 18 | acl "trusted_nets" { {{ ipa_trusted_nets|join(';') }}; }; 19 | -------------------------------------------------------------------------------- /templates/oelabox-ipa/etc/named/ipa-options-ext.conf: -------------------------------------------------------------------------------- 1 | /* User customization for BIND named 2 | * 3 | * This file is included in /etc/named.conf and is not modified during IPA 4 | * upgrades. 5 | * 6 | * It must only contain "options" settings. Any other setting must be 7 | * configured in /etc/named/ipa-ext.conf. 8 | * 9 | * Examples: 10 | * allow-recursion { trusted_network; }; 11 | * allow-query-cache { trusted_network; }; 12 | */ 13 | 14 | /* turns on IPv6 for port 53, IPv4 is on by default for all ifaces */ 15 | listen-on-v6 { any; }; 16 | 17 | /* dnssec-enable is obsolete and 'yes' by default */ 18 | dnssec-validation yes; 19 | 20 | allow-recursion { trusted_nets; }; 21 | allow-query-cache { trusted_nets; }; 22 | -------------------------------------------------------------------------------- /templates/oelabox-ipa/tmp/binder.update.j2: -------------------------------------------------------------------------------- 1 | dn: uid={{ ipa_binder_name }},cn=sysaccounts,cn=etc,dc=oelabox,dc=local 2 | add:objectclass:account 3 | add:objectclass:simplesecurityobject 4 | add:uid:{{ ipa_binder_name }} 5 | add:userPassword:{{ ipa_binder_password }} 6 | add:passwordExpirationTime:20380119031407Z 7 | add:nsIdleTimeout:0 8 | -------------------------------------------------------------------------------- /tools/oelabox-koji/oelaimporter/install.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install package dependencies 3 | ansible.builtin.dnf: 4 | name: 5 | - make 6 | - gcc 7 | - python3.11 8 | - python3.11-devel 9 | - python3.11-pip 10 | - krb5-devel 11 | 12 | - name: Install pip dependencies 13 | ansible.builtin.pip: 14 | name: 15 | - pygithub 16 | - koji 17 | executable: pip3.11 18 | 19 | - name: Create tools directory 20 | ansible.builtin.file: 21 | path: /home/vagrant/tools 22 | state: directory 23 | owner: vagrant 24 | group: vagrant 25 | mode: '0755' 26 | 27 | - name: Install Oela Importer 28 | ansible.builtin.copy: 29 | src: tools/oelabox-koji/oelaimporter 30 | dest: /home/vagrant/tools 31 | owner: vagrant 32 | group: vagrant 33 | mode: '0644' 34 | 35 | -------------------------------------------------------------------------------- /vars/oelabox-dns/common.yml: -------------------------------------------------------------------------------- 1 | resolv_entries: 2 | - entry: 3 | nameserver: 192.168.121.10 4 | search: 5 | - oelabox.local 6 | -------------------------------------------------------------------------------- /vars/oelabox-dns/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Vars that should not be overridden 3 | -------------------------------------------------------------------------------- /vars/oelabox-ipa/ipa/adminusers.yml: -------------------------------------------------------------------------------- 1 | --- 2 | adminusers: 3 | - name: oelaadmin 4 | first: Oela 5 | last: Admin 6 | password: ThisIsNotMyPassword1! 7 | title: Oela Box Admin 8 | loginshell: /bin/bash 9 | ... 10 | -------------------------------------------------------------------------------- /vars/oelabox-ipa/ipa/agreements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Vars for Agreements for the Oela Box Project 3 | ... 4 | -------------------------------------------------------------------------------- /vars/oelabox-ipa/ipa/common.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ipa_trusted_nets: 3 | - localnets 4 | - localhost 5 | - 10.0.0.0/8 6 | ... 7 | -------------------------------------------------------------------------------- /vars/oelabox-ipa/ipa/fdns.yml: -------------------------------------------------------------------------------- 1 | --- 2 | fdns: 3 | - oelabox.local. 4 | ... 5 | -------------------------------------------------------------------------------- /vars/oelabox-ipa/ipa/groups.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ipagroups: 3 | - group: infrastructure 4 | description: Infrastructure Team 5 | user: 6 | - oelauser 7 | - group: development 8 | description: Development Team 9 | user: 10 | - oelauser 11 | - group: oela 12 | description: Oela Linux Team 13 | user: 14 | - oelauser 15 | - group: oelaadm 16 | description: Oela Box Administrators - Only Admin Accounts 17 | user: 18 | - oelaadmin 19 | - group: gitadm 20 | description: Oela Box GitLab Admins 21 | user: 22 | - oelauser 23 | - group: gitusers 24 | description: Oela Box GitLab Users 25 | user: 26 | - oelauser 27 | managers_users: 28 | - oelauser 29 | - group: services 30 | description: Oela Box Service Accounts 31 | user: 32 | - userman 33 | - hostman 34 | - kerbman 35 | - oelakoji 36 | - pubsub_federation 37 | - oelapubsub 38 | - oelaautomation 39 | - group: releng 40 | description: Oela Box Release Engineering 41 | user: 42 | - oelauser 43 | managers_users: 44 | - oelauser 45 | - group: mq_pub_readonly 46 | user: 47 | - oelauser 48 | description: RabbitMQ ReadOnly 49 | ... 50 | -------------------------------------------------------------------------------- /vars/oelabox-ipa/ipa/ipaclient.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # IPA Client Vars 3 | ipaclient_domain: oelabox.local 4 | ipaclient_realm: OELABOX.LOCAL 5 | ipaadmin_principal: admin 6 | ipaclient_no_ntp: true 7 | ipaclient_mkhomedir: true 8 | ipaclient_ssh_trust_dns: true 9 | ipasssd_enable_dns_updates: true 10 | ipatype: client 11 | ... 12 | -------------------------------------------------------------------------------- /vars/oelabox-ipa/ipa/ipaprivs.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # privileges 3 | ipaprivileges: 4 | - privilege: Privileges - Kerberos Managers 5 | description: Kerberos Key Managers 6 | permissions: 7 | - "System: Manage Host Keytab" 8 | - "System: Manage Host Keytab Permissions" 9 | - "System: Manage Service Keytab" 10 | - "System: Manage Service Keytab Permissions" 11 | - "System: Manage User Principals" 12 | role: Kerberos Managers 13 | user: 14 | - kerbman 15 | 16 | # Standalone Roles 17 | iparoles: 18 | - role: IPA Client Managers 19 | description: IPA Client Managers 20 | privileges: 21 | - "DNS Administrators" 22 | - "DNS Servers" 23 | - "Host Administrators" 24 | - "Host Enrollment" 25 | - "Host Group Administrators" 26 | - "Netgroups Administrators" 27 | user: 28 | - hostman 29 | - role: Kerberos Managers 30 | description: Kerberos Key Managers 31 | privileges: 32 | - "Privileges - Kerberos Managers" 33 | - "Service Administrators" 34 | user: 35 | - kerbman 36 | - role: IPA User Managers 37 | description: Oela Box IPA User Managers responsible for idm flow 38 | privileges: 39 | - "Group Administrators" 40 | - "Stage User Administrators" 41 | - "User Administrators" 42 | - "FAS Agreement Administrators" 43 | ... 44 | -------------------------------------------------------------------------------- /vars/oelabox-ipa/ipa/ipareplica.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # IPA Replica 3 | ipaadmin_principal: admin 4 | ipaclient_no_ntp: true 5 | ipaclient_mkhomedir: true 6 | ipaserver_realm: OELABOX.LOCAL 7 | ipareplica_domain: oelabox.local 8 | ipareplica_auto_forwarders: true 9 | ipareplica_setup_firewalld: true 10 | ipareplica_setup_ca: true 11 | ipareplica_setup_kra: true 12 | ipareplica_setup_dns: true 13 | ipatype: replica 14 | ... 15 | -------------------------------------------------------------------------------- /vars/oelabox-ipa/ipa/ipaserver.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # IPA Server 3 | ipaserver_domain: oelabox.local 4 | ipaserver_realm: OELABOX.LOCAL 5 | ipaserver_setup_dns: true 6 | ipaserver_setup_kra: true 7 | ipaserver_auto_forwarders: true 8 | ipaserver_no_host_dns: true 9 | ipaserver_allow_zone_overlap: true 10 | ipaserver_setup_firewalld: true 11 | ipaclient_no_ntp: true 12 | ipaclient_mkhomedir: true 13 | ipaserver_no_hbac_allow: true 14 | ipaserver_reverse_zones: ["121.168.192.in-addr.arpa."] 15 | ipatype: server 16 | ... 17 | -------------------------------------------------------------------------------- /vars/oelabox-ipa/ipa/rdns.yml: -------------------------------------------------------------------------------- 1 | --- 2 | rdns: 3 | - 121.168.192.in-addr.arpa. 4 | ... 5 | -------------------------------------------------------------------------------- /vars/oelabox-ipa/ipa/sudorules.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ... 3 | -------------------------------------------------------------------------------- /vars/oelabox-ipa/ipa/svcusers.yml: -------------------------------------------------------------------------------- 1 | --- 2 | svcusers: 3 | - name: hostman 4 | first: Host 5 | last: Manager 6 | password: ThisIsNotMyPassword1! 7 | title: System Account - Host Manager 8 | loginshell: /sbin/nologin 9 | - name: kerbman 10 | first: Kerberos 11 | last: Manager 12 | password: ThisIsNotMyPassword1! 13 | title: System Account - Kerberos Key Manager 14 | loginshell: /sbin/nologin 15 | - name: userman 16 | first: User 17 | last: Manager 18 | password: ThisIsNotMyPassword1! 19 | title: System Account - User Manager 20 | loginshell: /sbin/nologin 21 | - name: oelakoji 22 | first: Koji 23 | last: Manager 24 | password: ThisIsNotMyPassword1! 25 | title: System Account - Koji Manager 26 | loginshell: /sbin/nologin 27 | - name: pubsub_federation 28 | first: pubsub 29 | last: federation 30 | password: ThisIsNotMyPassword1! 31 | title: System Account - pubsub federator 32 | loginshell: /sbin/nologin 33 | - name: oelapubsub 34 | first: Oela 35 | last: pubsub 36 | password: ThisIsNotMyPassword1! 37 | title: System Account - pubsub 38 | loginshell: /sbin/nologin 39 | - name: oelaautomation 40 | first: Oela 41 | last: Automation 42 | password: ThisIsNotMyPassword1! 43 | title: System Account - Automation 44 | loginshell: /sbin/nologin 45 | ... 46 | -------------------------------------------------------------------------------- /vars/oelabox-ipa/ipa/users.yml: -------------------------------------------------------------------------------- 1 | --- 2 | users: 3 | - name: oelauser 4 | first: Oela 5 | last: User 6 | email: oelauser@oelabox.local 7 | password: ThisIsNotMyPassword1! 8 | title: Oela Box User 9 | loginshell: /bin/bash 10 | ... 11 | -------------------------------------------------------------------------------- /vars/oelabox-ipa/ipaserver.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ipatype: server 3 | ... 4 | -------------------------------------------------------------------------------- /vars/oelabox-ipa/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Vars that should not be overridden 3 | -------------------------------------------------------------------------------- /vars/oelabox-koji/common.yml: -------------------------------------------------------------------------------- 1 | --- 2 | oela_ipa_realm: "OELABOX.LOCAL" 3 | oela_ldap_bind_dn: "uid=binder,cn=sysaccounts,cn=etc,dc=oelabox,dc=local" 4 | oela_ldap_user_basedn: "cn=users,cn=accounts,dc=oelabox,dc=local" 5 | oela_ldap_group_basedn: "cn=groups,cn=accounts,dc=oelabox,dc=local" 6 | oela_ldap_account_basedn: "cn=accounts,dc=oelabox,dc=local" 7 | # Requires jinja 2.9+ 8 | oela_ipaserver_list: "{{ groups['ipaserver'] + groups['ipareplicas'] }}" 9 | oela_ipaserver_lb: "ipa.oelabox.local" 10 | # These will be in a vault 11 | #rocky_ldap_bind_pw: "{{ ipa_binder_password }}" 12 | oela_ldap_bind_pw: freeloader 13 | 14 | oela_smtp_address: "oelabox.local" 15 | oela_smtp_port: "587" 16 | # username / pw need to be setup 17 | oela_smtp_domain: "oelabox.local" 18 | oela_smtp_authentication: "login" 19 | oela_smtp_enable_starttls_auto: "true" 20 | oela_smtp_tls: "true" 21 | oela_smtp_openssl_verify_mode: "none" 22 | oela_smtp_ca_path: "/etc/pki/tls/certs" 23 | oela_smtp_ca_file: "/etc/pki/tls/certs/ca-bundle.crt" 24 | allowed_rsyslog_clients: 25 | - 127.0.0.1 26 | - 192.168.121.0/24 27 | remote_rsyslog_host: "" 28 | ... 29 | -------------------------------------------------------------------------------- /vars/oelabox-koji/ipa-keytabs.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ipa_keytabs: 3 | - keytab: 4 | path: /etc/kojid.keytab 5 | service: '{{ kojid_service }}' 6 | - keytab: 7 | path: /etc/keytabs/koji-web.keytab 8 | service: '{{ koji_web_service }}' 9 | - keytab: 10 | path: /etc/keytabs/kojira.keytab 11 | service: '{{ kojira_service }}' 12 | - keytab: 13 | path: /etc/keytabs/koji-gc.keytab 14 | service: '{{ koji_gc_service }}' 15 | #- keytab: 16 | # path: /etc/keytabs/host.keytab 17 | #service: host/koji.oelabox.local 18 | 19 | -------------------------------------------------------------------------------- /vars/oelabox-koji/ipa-services.yml: -------------------------------------------------------------------------------- 1 | --- 2 | kojid_service: "compile/koji.oelabox.local" 3 | koji_web_service: "HTTP/koji.oelabox.local" 4 | kojira_service: "kojira/koji.oelabox.local" 5 | koji_gc_service: "koji-gc/koji.oelabox.local" 6 | 7 | ipa_services: 8 | - "{{ kojid_service }}" 9 | - "{{ koji_web_service }}" 10 | - "{{ kojira_service }}" 11 | - "{{ koji_gc_service }}" 12 | -------------------------------------------------------------------------------- /vars/oelabox-koji/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Vars that should not be overridden 3 | -------------------------------------------------------------------------------- /vars/oelabox-koji/production/koji-common.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Koji common 3 | koji_efs_mount_path: /mnt/koji 4 | koji_efs_fsid: whatever.amazonaws.com 5 | koji_efs_fs_ip_map: 6 | us-east-2a: 10.x.x.x 7 | us-east-2b: 10.x.x.x 8 | us-east-2c: 10.x.x.x 9 | koji_efs_fs_type: efs 10 | koji_efs_fs_opts: 11 | - _netdev 12 | - tls 13 | - iam 14 | ... 15 | -------------------------------------------------------------------------------- /vars/oelabox-koji/production/kojid.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars for kojid 3 | 4 | kojid_vendor: Oela 5 | kojid_packager: infrastructure@oelabox.local 6 | kojid_distribution: Oela 7 | # These three should probably be specified by special vars 8 | kojid_web_url: https://koji.oelabox.local/koji 9 | kojid_hub_url: https://koji.oelabox.local/kojihub 10 | kojid_files_url: https://koji.oelabox.local/kojifiles 11 | 12 | #kojid_ca_bundle: /etc/pki/tls/certs/ca-bundle.crt 13 | koji_ca_bundle: /etc/pki/tls/certs/koji.oelabox.local.crt 14 | kojid_keytab: /etc/kojid.keytab 15 | kojid_smtp_host: smtp.oelabox.local 16 | kojid_allowed_scm: "github.com:/openela-main/*:off:/usr/bin/getsrc.sh" 17 | ... 18 | -------------------------------------------------------------------------------- /vars/oelabox-koji/production/kojihub.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # koji hub settings 3 | # This should be the front-facing URL of koji 4 | koji_url_name: koji.oelabox.local 5 | 6 | # Use an internal CA (IPA) 7 | koji_internal_ca: true 8 | 9 | # Use postgresql on this machine rather than managed service 10 | koji_postgresql_vm: true 11 | 12 | # Database settings 13 | koji_db_name: koji 14 | koji_db_user: koji 15 | # This will need to change when koji_postgresql_vm is false 16 | koji_db_host: "{{ ansible_fqdn }}" 17 | 18 | koji_web_url: "https://{{ koji_url_name }}/koji" 19 | koji_hub_url: "https://{{ koji_url_name }}/kojihub" 20 | koji_files_url: "https://{{ koji_url_name }}/kojifiles" 21 | 22 | # The IPA internal CA is combined with the others 23 | # Change before deployment or store in vault 24 | koji_hub_secret: cK5XCuzMSXJfgA7yFvXkGwFu 25 | #koji_web_cacert: /etc/pki/tls/certs/ca-bundle.crt 26 | #koji_web_cacert: /etc/pki/tls/certs/koji.oelabox.local.crt 27 | koji_web_cacert: /etc/ipa/ca.crt 28 | koji_web_tls_cert: "/etc/pki/tls/certs/{{ ansible_fqdn }}.crt" 29 | koji_web_tls_key: "/etc/pki/tls/private/{{ ansible_fqdn }}.key" 30 | 31 | # Kojira 32 | koji_kojira: true 33 | koji_kojira_user: kojira 34 | koji_kojira_user_kerb: kojira/koji.oelabox.local 35 | koji_kojira_principal: kojira/koji.oelabox.local@OELABOX.LOCAL 36 | koji_kojira_keytab: /etc/keytabs/kojira.keytab 37 | 38 | # MBS 39 | koji_mbs: true 40 | koji_mbs_user: mbs 41 | koji_mbs_user_kerb: mbs/mbs.oelabox.local 42 | koji_mbs_principal: mbs/mbs.oelabox.local@OELABOX.LOCAL 43 | koji_mbs_keytab: /etc/keytabs/mbs.keytab 44 | 45 | # GC 46 | koji_gc_keytab: /etc/keytabs/koji-gc.keytab 47 | koji_gc_principal: koji-gc/koji.oelabox.local@OELABOX.LOCAL 48 | 49 | # Sigul 50 | koji_sigul: true 51 | koji_sigul_user: sigul 52 | koji_sigul_user_kerb: sigul/sigul.oelabox.local 53 | koji_sigul_principal: sigul/sigul.oelabox.local@OELABOX.LOCAL 54 | 55 | # NFS? We need a place. 56 | koji_nfs: false 57 | koji_mount: /mnt/koji 58 | koji_nfs_path: nfs.oelabox.local:/export/koji 59 | 60 | # Koji Admin Settings 61 | koji_admin_client: true 62 | koji_admin_user: oelakoji 63 | koji_admin_principal: oelakoji@OELABOX.LOCAL 64 | koji_admin_localuser: true 65 | koji_admin_localuser_name: koji 66 | 67 | # Hub Settings 68 | koji_hub_principal: "host/kojihub@OELABOX.LOCAL" 69 | koji_hub_proxy_principals: "HTTP/{{ inventory_hostname }}@OELABOX.LOCAL" 70 | koji_hub_keytab: /etc/keytabs/host.keytab 71 | koji_hub_principal_format: compile/%s@OELABOX.LOCAL 72 | # This should be sufficient even for LE 73 | koji_hub_ca: "{{ koji_web_cacert }}" 74 | 75 | # Koji FAS Syncing 76 | # This isn't implemented yet in the role 77 | koji_fas_sync: false 78 | koji_fas_url: https://accounts.oelabox.local 79 | 80 | # IPA Certs if Required 81 | ipa_getcert_requested_hostnames: 82 | - name: "{{ ansible_fqdn }}" 83 | owner: apache 84 | key_location: "{{ koji_web_tls_key }}" 85 | cert_location: "{{ koji_web_tls_cert }}" 86 | postcmd: "/bin/systemctl reload httpd" 87 | 88 | # postgresql vars 89 | postgresql_restarted_state: "restarted" 90 | postgresql_python_library: python3-psycopg2 91 | postgresql_user: postgres 92 | postgresql_group: postgres 93 | postgresql_hba_entries: 94 | - type: local 95 | database: koji 96 | user: koji 97 | auth_method: trust 98 | - type: local 99 | database: all 100 | user: postgres 101 | auth_method: peer 102 | - type: host 103 | database: koji 104 | user: koji 105 | address: '192.168.121.0/24' 106 | auth_method: md5 107 | 108 | postgresql_databases: 109 | - name: "{{ koji_db_name }}" 110 | owner: "{{ koji_db_user }}" 111 | 112 | postgresql_users: 113 | - name: "{{ koji_db_user }}" 114 | password: "{{ koji_db_pass }}" 115 | role_attr_flags: "NOCREATEDB,NOSUPERUSER,NOCREATEROLE" 116 | db: "{{ koji_db_name }}" 117 | state: present 118 | 119 | postgresql_global_config_options: 120 | - option: listen_addresses 121 | value: '*' 122 | ... 123 | --------------------------------------------------------------------------------