From 78491fcbdbee704fbe84389487156a0fb291479a Mon Sep 17 00:00:00 2001 From: Silvie Chlupova Date: Dec 14 2020 11:39:26 +0000 Subject: frontend: cli: api: tests: Setting isolation option per chroot Fixes: #1611 --- diff --git a/cli/copr_cli/build_config.py b/cli/copr_cli/build_config.py index dd6b6d0..994f27a 100644 --- a/cli/copr_cli/build_config.py +++ b/cli/copr_cli/build_config.py @@ -12,9 +12,7 @@ include('/etc/mock/{{chroot}}.cfg') config_opts['root'] = '{{ rootdir }}' -{%- if isolation == "default" %} -config_opts['isolation'] = 'auto' -{%- elif isolation %} +{%- if isolation not in ["default", None] %} config_opts['isolation'] = '{{ isolation }}' {%- endif %} diff --git a/cli/copr_cli/main.py b/cli/copr_cli/main.py index c2efd50..335393d 100644 --- a/cli/copr_cli/main.py +++ b/cli/copr_cli/main.py @@ -623,6 +623,7 @@ class Commands(object): comps=args.upload_comps, delete_comps=args.delete_comps, additional_packages=args.packages, additional_repos=args.repos, bootstrap=args.bootstrap, bootstrap_image=args.bootstrap_image, + isolation=args.isolation, ) print("Edit chroot operation was successful.") @@ -1011,7 +1012,7 @@ def setup_parser(): parser_modify.add_argument("--auto-prune", choices=["on", "off"], help="If auto-deletion of project's obsoleted builds should be enabled.\ This option can only be specified by a COPR admin.") - parser_modify.add_argument("--isolation", choices=["simple", "nspawn", "default"], default="default", + parser_modify.add_argument("--isolation", choices=["simple", "nspawn", "default"], help="Choose the isolation method for running commands in buildroot.") parser_modify.add_argument( @@ -1155,7 +1156,7 @@ def setup_parser(): help="If you don't need this build for all the project's chroots. You can use it several times for each chroot you need.") parser_build_parent.add_argument("--background", dest="background", action="store_true", default=False, help="Mark the build as a background job. It will have lesser priority than regular builds.") - parser_build_parent.add_argument("--isolation", choices=["simple", "nspawn", "default"], default="default", + parser_build_parent.add_argument("--isolation", choices=["simple", "nspawn", "default"], default="unchanged", help="Choose the isolation method for running commands in buildroot.") parser_build_parent.add_argument( @@ -1279,6 +1280,8 @@ def setup_parser(): help="space separated string of package names to be added to buildroot") parser_edit_chroot.add_argument("--repos", help="space separated string of additional repo urls for chroot") + parser_edit_chroot.add_argument("--isolation", choices=["simple", "nspawn", "default"], default="unchanged", + help="Choose the isolation method for running commands in buildroot.") parser_edit_chroot.add_argument( "--bootstrap", diff --git a/cli/man/copr-cli.1.asciidoc b/cli/man/copr-cli.1.asciidoc index b13c8c9..eb08eed 100644 --- a/cli/man/copr-cli.1.asciidoc +++ b/cli/man/copr-cli.1.asciidoc @@ -106,6 +106,7 @@ usage: copr-cli create [-h] --chroot CHROOTS [--repo REPOS] [--unlisted-on-hp {on,off}] [--persistent] [--auto-prune {on,off}] + [--isolation {default, nspawn, simple}] name --chroot:: @@ -138,6 +139,9 @@ Project and its builds will be undeletable. This option can only be specified by --auto-prune:: If backend auto-prunning script should be run for this project. This option can only be specified by a COPR admin. +--isolation ISOLATION:: +Choose the isolation method for running commands in buildroot + name:: Can be just name of the project or in form username/projectname or @groupname/projectname. @@ -152,6 +156,7 @@ usage: copr-cli modify [-h] [--repo REPOS] [--enable-net {on,off}] [--unlisted-on-hp {on,off}] [--auto-prune {on,off}] + [--isolation {default, nspawn, simple}] name Alters only specified project property. @@ -183,6 +188,9 @@ This project will not be listed on COPR home page. --auto-prune:: If backend auto-prunning script should be run for this project. This option can only be specified by a COPR admin. +--isolation ISOLATION:: +Choose the isolation method for running commands in buildroot + name:: Can be just name of the project or in form username/projectname or @groupname/projectname. @@ -193,7 +201,7 @@ BUILD ACTIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~ usage: copr-cli build [-h] [-r, --chroot CHROOTS] [--memory MEMORY] [--timeout TIMEOUT] [--nowait] - [--background] + [--background] [--isolation {default, nspawn, simple}] copr_repo PKG [PKG ...] -r, --chroot:: @@ -211,6 +219,9 @@ Don't wait for build completion. --background:: Run the build at a lower priority. +--isolation ISOLATION:: +Choose the isolation method for running commands in buildroot. + copr_repo:: The copr repository to build the package in. This can be a simple name of some of your projects or it can be specified fully as username/project or @groupname/project. @@ -402,7 +413,7 @@ CHROOT ACTIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ usage: copr edit-chroot [-h] [--upload-comps FILEPATH | --delete-comps] - [--packages PACKAGES] [--repos REPOS] + [--packages PACKAGES] [--repos REPOS] [--isolation {default, nspawn, simple}] coprchroot Edit the specified coprchroot. @@ -422,6 +433,9 @@ space separated string of package names to be added to buildroot (e.g. "gcc ghc" --repos REPOS:: space separated string of additional repo urls for chroot (e.g. "http://foo http://bar") +--isolation ISOLATION:: +Choose the isolation method for running commands in buildroot + `copr-cli get-chroot coprchroot` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/cli/tests/test_cli.py b/cli/tests/test_cli.py index 0683d6a..7e986de 100644 --- a/cli/tests/test_cli.py +++ b/cli/tests/test_cli.py @@ -396,6 +396,21 @@ def test_create_project_with_isolation(_config_from_file, project_proxy_add, cap assert stdout == "New project was successfully created.\n" +@mock.patch('copr.v3.proxies.project_chroot.ProjectChrootProxy.edit') +@mock.patch('copr_cli.main.config_from_file', return_value=mock_config) +def test_edit_chroot_with_isolation(_config_from_file, project_chroot_proxy_edit, capsys): + main.main(argv=[ + "edit-chroot", "foo/f20", + "--isolation", "simple", + ]) + stdout, stderr = capsys.readouterr() + project_chroot_proxy_edit.assert_called_once() + kwargs = project_chroot_proxy_edit.call_args[1] + assert stderr == '' + assert kwargs["isolation"] == "simple" + assert stdout == "Edit chroot operation was successful.\n" + + @mock.patch('copr.v3.proxies.project.ProjectProxy.add') @mock.patch('copr_cli.main.config_from_file', return_value=mock_config) def test_create_multilib_project(config_from_file, project_proxy_add, capsys): diff --git a/cli/tests/test_distgit.py b/cli/tests/test_distgit.py index 87a92d5..dd7ab91 100644 --- a/cli/tests/test_distgit.py +++ b/cli/tests/test_distgit.py @@ -41,7 +41,7 @@ class TestDistGitMethodBuild(object): 'chroots': None, 'background': False, 'progress_callback': None, - 'isolation': 'default', + 'isolation': 'unchanged', }, 'packagename': 'test', 'distgit': None, @@ -90,7 +90,7 @@ class TestDistGitMethodBuild(object): "chroots": ['fedora-rawhide-x86_64'], "background": True, "progress_callback": None, - 'isolation': 'default', + 'isolation': 'unchanged', }, }) assert call[1] == result diff --git a/cli/tests/test_mock_config.py b/cli/tests/test_mock_config.py index 87cd279..034e008 100644 --- a/cli/tests/test_mock_config.py +++ b/cli/tests/test_mock_config.py @@ -74,6 +74,7 @@ best=1 "use_bootstrap_container": False, "with_opts": [], "without_opts":[], + "isolation": "default" }) @pytest.yield_fixture @@ -160,7 +161,7 @@ best=1 "config_opts['root'] = 'test-test_fedora-rawhide-x86_64'\n", "") - def test_no_repos(self, f_get_build_config, f_test_config, capsys): + def test_no_repos_with_additional(self, f_get_build_config, f_test_config, capsys): config = self.get_build_config_result() additional = { 'id': 'x', diff --git a/frontend/coprs_frontend/alembic/versions/8fd7c4714189_isolation_option_for_chroot.py b/frontend/coprs_frontend/alembic/versions/8fd7c4714189_isolation_option_for_chroot.py new file mode 100644 index 0000000..b80335f --- /dev/null +++ b/frontend/coprs_frontend/alembic/versions/8fd7c4714189_isolation_option_for_chroot.py @@ -0,0 +1,22 @@ +""" +isolation option for chroot + +Revision ID: 8fd7c4714189 +Revises: d6cbf6cd74da +Create Date: 2020-11-27 14:57:55.008281 +""" + +import sqlalchemy as sa +from alembic import op + + +revision = '8fd7c4714189' +down_revision = 'd6cbf6cd74da' + + +def upgrade(): + op.add_column('copr_chroot', sa.Column('isolation', sa.Text(), nullable=True)) + + +def downgrade(): + op.drop_column('copr_chroot', 'isolation') diff --git a/frontend/coprs_frontend/coprs/forms.py b/frontend/coprs_frontend/coprs/forms.py index 02d4d03..5722b0a 100644 --- a/frontend/coprs_frontend/coprs/forms.py +++ b/frontend/coprs_frontend/coprs/forms.py @@ -107,7 +107,9 @@ def create_isolation_field(level): ('simple', 'simple chroot'), ] - if level == 'build': + if level == "build": + choices.append(("unchanged", "Use project/chroot settings")) + elif level == "chroot": choices.append(("unchanged", "Use project settings")) choices.extend(default_choices) @@ -1327,7 +1329,7 @@ class ChrootForm(FlaskForm): bootstrap = create_mock_bootstrap_field("chroot") bootstrap_image = create_mock_bootstrap_image_field() - isolation = create_isolation_field("build") + isolation = create_isolation_field("chroot") def validate(self, *args, **kwargs): # pylint: disable=signature-differs """ We need to special-case custom_image configuration """ diff --git a/frontend/coprs_frontend/coprs/logic/complex_logic.py b/frontend/coprs_frontend/coprs/logic/complex_logic.py index 018df36..25752f1 100644 --- a/frontend/coprs_frontend/coprs/logic/complex_logic.py +++ b/frontend/coprs_frontend/coprs/logic/complex_logic.py @@ -423,8 +423,8 @@ class BuildConfigLogic(object): 'chroot': chroot_id, 'with_opts': chroot.with_opts.split(), 'without_opts': chroot.without_opts.split(), - 'isolation': copr.isolation, } + config_dict.update(chroot.isolation_setup) config_dict.update(chroot.bootstrap_setup) return config_dict @@ -455,8 +455,6 @@ class BuildConfigLogic(object): if build.isolation_set: isolation["isolation"] = build.isolation - if isolation["isolation"] == "default": - del isolation['isolation'] return isolation @classmethod diff --git a/frontend/coprs_frontend/coprs/logic/coprs_logic.py b/frontend/coprs_frontend/coprs/logic/coprs_logic.py index 75f0746..301381a 100644 --- a/frontend/coprs_frontend/coprs/logic/coprs_logic.py +++ b/frontend/coprs_frontend/coprs/logic/coprs_logic.py @@ -218,7 +218,7 @@ class CoprsLogic(object): @classmethod def add(cls, user, name, selected_chroots, repos=None, description=None, instructions=None, check_for_duplicates=False, group=None, persistent=False, - auto_prune=True, bootstrap=None, follow_fedora_branching=False, + auto_prune=True, bootstrap=None, follow_fedora_branching=False, isolation=None, **kwargs): if not flask.g.user.admin and flask.g.user != user: @@ -244,6 +244,7 @@ class CoprsLogic(object): persistent=persistent, auto_prune=auto_prune, bootstrap=bootstrap, + isolation=isolation, follow_fedora_branching=follow_fedora_branching, **kwargs) @@ -654,7 +655,7 @@ class CoprChrootsLogic(object): def create_chroot(cls, user, copr, mock_chroot, buildroot_pkgs=None, repos=None, comps=None, comps_name=None, with_opts="", without_opts="", delete_after=None, delete_notify=None, module_toggle="", - bootstrap=None, bootstrap_image=None): + bootstrap=None, bootstrap_image=None, isolation=None): """ :type user: models.User :type mock_chroot: models.MockChroot @@ -670,7 +671,7 @@ class CoprChrootsLogic(object): chroot = models.CoprChroot(copr=copr, mock_chroot=mock_chroot) cls._update_chroot(buildroot_pkgs, repos, comps, comps_name, chroot, with_opts, without_opts, delete_after, delete_notify, - module_toggle, bootstrap, bootstrap_image) + module_toggle, bootstrap, bootstrap_image, isolation) # reassign old build_chroots, if the chroot is re-created get_old = logic.builds_logic.BuildChrootsLogic.by_copr_and_mock_chroot @@ -682,7 +683,7 @@ class CoprChrootsLogic(object): @classmethod def update_chroot(cls, user, copr_chroot, buildroot_pkgs=None, repos=None, comps=None, comps_name=None, with_opts="", without_opts="", delete_after=None, delete_notify=None, module_toggle="", - bootstrap=None, bootstrap_image=None): + bootstrap=None, bootstrap_image=None, isolation=None): """ :type user: models.User :type copr_chroot: models.CoprChroot @@ -693,13 +694,13 @@ class CoprChrootsLogic(object): cls._update_chroot(buildroot_pkgs, repos, comps, comps_name, copr_chroot, with_opts, without_opts, delete_after, delete_notify, module_toggle, - bootstrap, bootstrap_image) + bootstrap, bootstrap_image, isolation) return copr_chroot @classmethod def _update_chroot(cls, buildroot_pkgs, repos, comps, comps_name, copr_chroot, with_opts, without_opts, delete_after, delete_notify, module_toggle, - bootstrap, bootstrap_image): + bootstrap, bootstrap_image, isolation): if buildroot_pkgs is not None: copr_chroot.buildroot_pkgs = buildroot_pkgs @@ -729,6 +730,9 @@ class CoprChrootsLogic(object): if bootstrap is not None: copr_chroot.bootstrap = bootstrap + if isolation is not None: + copr_chroot.isolation = isolation + if bootstrap_image is not None: # By CLI/API we can set custom_image, and keep bootstrap unset. In # such case set also bootstrap to correct value. diff --git a/frontend/coprs_frontend/coprs/models.py b/frontend/coprs_frontend/coprs/models.py index 421e403..fc7a5a4 100644 --- a/frontend/coprs_frontend/coprs/models.py +++ b/frontend/coprs_frontend/coprs/models.py @@ -1536,6 +1536,8 @@ class CoprChroot(db.Model, helpers.Serializer): bootstrap = db.Column(db.Text) bootstrap_image = db.Column(db.Text) + isolation = db.Column(db.Text, default="unchanged") + def update_comps(self, comps_xml): if isinstance(comps_xml, str): data = comps_xml.encode("utf-8") @@ -1646,6 +1648,17 @@ class CoprChroot(db.Model, helpers.Serializer): return {} return settings + @property + def isolation_setup(self): + """ Is isolation config from project overwritten by chroot? """ + settings = {'isolation': self.copr.isolation} + if self.isolation and self.isolation != 'unchanged': + settings['isolation'] = self.isolation + if settings['isolation'] in [None, "default"]: + return {} + return settings + + class BuildChroot(db.Model, helpers.Serializer): """ Representation of Build<->MockChroot relation diff --git a/frontend/coprs_frontend/coprs/templates/coprs/detail/edit_chroot.html b/frontend/coprs_frontend/coprs/templates/coprs/detail/edit_chroot.html index a0edf2e..0577dd2 100644 --- a/frontend/coprs_frontend/coprs/templates/coprs/detail/edit_chroot.html +++ b/frontend/coprs_frontend/coprs/templates/coprs/detail/edit_chroot.html @@ -59,6 +59,8 @@ {{ render_bootstrap_options(form) }} + {{ render_field(form.isolation, placeholder='unchanged') }} +