Skip to content

Commit

Permalink
Add ability to manage a Copr project
Browse files Browse the repository at this point in the history
  • Loading branch information
ehelms committed Apr 18, 2023
1 parent d1f114b commit d6aa864
Show file tree
Hide file tree
Showing 10 changed files with 244 additions and 0 deletions.
29 changes: 29 additions & 0 deletions obal/data/module_utils/copr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""
A copr-cli wrapper and support functions for Copr
"""
from subprocess import check_output, CalledProcessError

class CoprCliCommandError(Exception):
"""Raised when copr-cli command fails"""
def __init__(self, message, command):
self.message = message
self.command = command
super(CoprCliCommandError, self).__init__(message) #pylint: disable-all

def copr_cli(command, executable=None):
"""
Run a copr-cli command
"""
if executable is None:
executable = 'copr-cli'

try:
return check_output([executable] + command, universal_newlines=True)
except CalledProcessError as error:
raise CoprCliCommandError(error.output, error.cmd)

def full_name(user, project):
"""
Returns a full Copr name: user/project
"""
return "%s/%s" %(user, project)
54 changes: 54 additions & 0 deletions obal/data/modules/copr_chroot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""
Manage a chroot in a Copr project
"""

from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.copr import copr_cli, CoprCliCommandError, full_name # pylint:disable=import-error,no-name-in-module


def main():
"""
Manage a chroot in a Copr project
"""
module = AnsibleModule(
argument_spec=dict(
user=dict(type='str', required=True),
project=dict(type='str', required=True),
chroot=dict(type='str', required=True),
external_repos=dict(type='list', required=False, default=[]),
buildroot_packages=dict(type='list', required=False, default=[]),
modules=dict(type='list', required=False, default=[]),
)
)

user = module.params['user']
project = module.params['project']
chroot = module.params['chroot']
external_repos = module.params['external_repos']
buildroot_packages = module.params['buildroot_packages']
modules = module.params['modules']

command = [
'edit-chroot',
"%s/%s" % (full_name(user, project), chroot)
]

if external_repos:
command.extend(['--repos', ' '.join(external_repos)])

if buildroot_packages:
command.extend(['--packages', ' '.join(buildroot_packages)])

if modules:
command.extend(['--modules', ','.join(modules)])

try:
output = copr_cli(command)
except CoprCliCommandError as error:
module.fail_json(msg='Copr chroot edit failed', command=' '.join(error.command), output=error.message)

module.exit_json(changed=True, output=output)


if __name__ == '__main__':
main()
59 changes: 59 additions & 0 deletions obal/data/modules/copr_project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"""
Create a Project in Copr
"""

from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.copr import copr_cli, CoprCliCommandError, full_name # pylint:disable=import-error,no-name-in-module


def main():
"""
Create a Project in Copr
"""
module = AnsibleModule(
argument_spec=dict(
user=dict(type='str', required=True),
project=dict(type='str', required=True),
chroots=dict(type='list', required=True),
description=dict(type='str', required=False),
unlisted_on_homepage=dict(type='bool', required=False, default=True),
delete_after_days=dict(type='str', required=False, default=None),
)
)

user = module.params['user']
project = module.params['project']
chroots = module.params['chroots']
description = module.params['description']
unlisted_on_homepage = module.params['unlisted_on_homepage']
delete_after_days = module.params['delete_after_days']

if not description:
description = project

command = [
'create',
full_name(user, project),
'--description',
"%s" % description
]

for chroot in chroots:
command.extend(['--chroot', chroot])

if unlisted_on_homepage:
command.extend(['--unlisted-on-hp', 'on'])

if delete_after_days:
command.extend(['--delete-after-days', delete_after_days])

try:
output = copr_cli(command)
except CoprCliCommandError as error:
module.fail_json(msg='Copr project creation failed', command=' '.join(error.command), output=error.message)

module.exit_json(changed=True, output=output)


if __name__ == '__main__':
main()
9 changes: 9 additions & 0 deletions obal/data/playbooks/copr-project/copr-project.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
- name: Configure Copr projects
hosts:
- copr_projects
- packages
serial: 1
gather_facts: false
roles:
- role: copr_project
7 changes: 7 additions & 0 deletions obal/data/playbooks/copr-project/metadata.obal.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
help: |
This action configures Copr projects
variables:
copr_project_user:
parameter: --user
help: Copr user to use instead of the default value
1 change: 1 addition & 0 deletions obal/data/roles/copr_project/defaults/main.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
---
22 changes: 22 additions & 0 deletions obal/data/roles/copr_project/tasks/main.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
- name: 'Create Copr project'
copr_project:
user: "{{ copr_project_user }}"
project: "{{ copr_project_name }}"
chroots: "{{ copr_project_chroots | map(attribute='name') }}"
description: "{{ copr_project_description | default(omit) }}"
delete_after_days: "{{ copr_project_delete_after_days | default(omit) }}"
unlisted_on_homepage: "{{ copr_project_unlisted_on_homepage | default(omit) }}"
register: create_output

- name: Configure chroots
copr_chroot:
user: "{{ copr_project_user }}"
project: "{{ copr_project_name }}"
chroot: "{{ chroot.name }}"
external_repos: "{{ chroot.external_repos | default(omit) }}"
buildroot_packages: "{{ chroot.buildroot_packages | default(omit) }}"
modules: "{{ chroot.modules | default(omit) }}"
loop: "{{ copr_project_chroots }}"
loop_control:
loop_var: chroot
18 changes: 18 additions & 0 deletions tests/fixtures/help/copr-project.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
usage: obal copr-project [-h] [-v] [-e EXTRA_VARS] [--user COPR_PROJECT_USER]
target [target ...]

This action configures Copr projects

positional arguments:
target the target to execute the action against

optional arguments:
-h, --help show this help message and exit
-v, --verbose verbose output
--user COPR_PROJECT_USER
Copr user to use instead of the default value

advanced arguments:
-e EXTRA_VARS, --extra-vars EXTRA_VARS
set additional variables as key=value or YAML/JSON, if
filename prepend with @
20 changes: 20 additions & 0 deletions tests/fixtures/testrepo/copr/package_manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,23 @@ packages:
repoclosures:
hosts:
core-repoclosure: {}

copr_projects:
vars:
copr_project_user: 'example'
hosts:
foreman:
copr_project_name: "foreman"
copr_project_chroots:
- name: epel-7-x86_64
external_repos:
- http://mirror.centos.org/centos/7/sclo/x86_64/rh/
buildroot_packages:
- rh-ruby24-build
- scl-utils-build
client:
copr_project_name: "foreman-client"
copr_project_chroots:
- name: rhel-9-x86_64
- name: rhel-8-x86_64
- name: rhel-7-x86_64
25 changes: 25 additions & 0 deletions tests/test_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -801,3 +801,28 @@ def test_obal_verify_tag_all():
'koji list-pkgs --quiet --tag obaltest-nightly-rhel7'
]
assert_mockbin_log(expected_log)

@obal_cli_test(repotype='copr')
def test_copr_project_one_chroot():
assert_obal_success(['copr-project', 'foreman'])

expected_log = [
"copr-cli create example/foreman --description foreman --chroot epel-7-x86_64 --unlisted-on-hp on", # noqa: E501
"copr-cli edit-chroot example/foreman/epel-7-x86_64 --repos http://mirror.centos.org/centos/7/sclo/x86_64/rh/ --packages 'rh-ruby24-build scl-utils-build'", # noqa: E501

]
assert_mockbin_log(expected_log)


@obal_cli_test(repotype='copr')
def test_copr_project_many_chroots():
assert_obal_success(['copr-project', 'client'])

expected_log = [
"copr-cli create example/foreman-client --description foreman-client --chroot rhel-9-x86_64 --chroot rhel-8-x86_64 --chroot rhel-7-x86_64 --unlisted-on-hp on", # noqa: E501
"copr-cli edit-chroot example/foreman-client/rhel-9-x86_64",
"copr-cli edit-chroot example/foreman-client/rhel-8-x86_64",
"copr-cli edit-chroot example/foreman-client/rhel-7-x86_64"

]
assert_mockbin_log(expected_log)

0 comments on commit d6aa864

Please sign in to comment.