diff --git a/pykickstart/commands/__init__.py b/pykickstart/commands/__init__.py index 170f7cc0..02fa398b 100644 --- a/pykickstart/commands/__init__.py +++ b/pykickstart/commands/__init__.py @@ -62,6 +62,7 @@ nfs, nvdimm, timesource, + ostreecontainer, ostreesetup, partition, raid, diff --git a/pykickstart/commands/ostreecontainer.py b/pykickstart/commands/ostreecontainer.py new file mode 100644 index 00000000..4f775584 --- /dev/null +++ b/pykickstart/commands/ostreecontainer.py @@ -0,0 +1,94 @@ +# +# Copyright (C) 2023 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +from pykickstart.version import RHEL9 +from pykickstart.base import KickstartCommand +from pykickstart.options import KSOptionParser + +class RHEL9_OSTreeContainer(KickstartCommand): + removedKeywords = KickstartCommand.removedKeywords + removedAttrs = KickstartCommand.removedAttrs + + def __init__(self, *args, **kwargs): + KickstartCommand.__init__(self, *args, **kwargs) + self.op = self._getParser() + self.stateroot = kwargs.get('stateroot', None) + self.url = kwargs.get('url', None) + self.transport = kwargs.get("transport", None) + self.remote = kwargs.get("remote", self.stateroot) + self.noSignatureVerification = kwargs.get('noSignatureVerification', False) + + def __str__(self): + retval = KickstartCommand.__str__(self) + + if not self.seen: + return retval + + retval += "# OSTree container setup\n" + retval += "ostreecontainer %s\n" % self._getArgsAsStr() + + return retval + + def _getArgsAsStr(self): + retcmd = [] + if self.stateroot: + retcmd.append('--stateroot="%s"' % self.stateroot) + if self.remote: + retcmd.append('--remote="%s"' % self.remote) + if self.noSignatureVerification: + retcmd.append('--no-signature-verification') + if self.transport: + retcmd.append('--transport="%s"' % self.transport) + if self.url: + retcmd.append('--url="%s"' % self.url) + return ' '.join(retcmd) + + def _getParser(self): + op = KSOptionParser(prog="ostreecontainer", description=""" + Used for OSTree installations from native container. See + https://coreos.github.io/rpm-ostree/container/ + for more information about OSTree. + + **Experimental. Use on your own risk.** + """, version=RHEL9) + # Rename the osname to stateroot and set default as proposed by + # https://github.com/ostreedev/ostree/issues/2794 + op.add_argument("--stateroot", version=RHEL9, help=""" + Name for the state directory, also known as "osname". + Default value will be `default`.""") + op.add_argument("--url", required=True, version=RHEL9, help=""" + Name of the container image; for the `registry` transport. + This would be e.g. `quay.io/exampleos/foo:latest`.""") + op.add_argument("--transport", version=RHEL9, help=""" + The transport; e.g. registry, oci, oci-archive. + The default is `registry`.""") + op.add_argument("--remote", version=RHEL9, help=""" + Name of the OSTree remote.""") + op.add_argument("--no-signature-verification", + dest="noSignatureVerification", + action="store_true", + version=RHEL9, + help="""Disable verification via an ostree remote.""") + return op + + def parse(self, args): + ns = self.op.parse_args(args=args, lineno=self.lineno) + self.set_to_self(ns) + if not self.remote: + self.remote = self.stateroot + + return self diff --git a/pykickstart/handlers/rhel9.py b/pykickstart/handlers/rhel9.py index 9549ecbb..7aff6076 100644 --- a/pykickstart/handlers/rhel9.py +++ b/pykickstart/handlers/rhel9.py @@ -68,6 +68,7 @@ class RHEL9Handler(BaseHandler): "nfs": commands.nfs.FC6_NFS, "nvdimm": commands.nvdimm.F28_Nvdimm, "timesource": commands.timesource.F33_Timesource, + "ostreecontainer": commands.ostreecontainer.RHEL9_OSTreeContainer, "ostreesetup": commands.ostreesetup.RHEL9_OSTreeSetup, "part": commands.partition.RHEL9_Partition, "partition": commands.partition.RHEL9_Partition, diff --git a/tests/commands/ostreecontainer.py b/tests/commands/ostreecontainer.py new file mode 100644 index 00000000..da466766 --- /dev/null +++ b/tests/commands/ostreecontainer.py @@ -0,0 +1,59 @@ +# +# Copyright 2023 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, modify, +# copy, or redistribute it subject to the terms and conditions of the GNU +# General Public License v.2. This program is distributed in the hope that it +# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the +# implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., 51 +# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Any Red Hat +# trademarks that are incorporated in the source code or documentation are not +# subject to the GNU General Public License and may only be used or replicated +# with the express permission of Red Hat, Inc. +# + +import unittest +from tests.baseclass import CommandTest +from pykickstart.commands.ostreecontainer import RHEL9_OSTreeContainer + +class OSTreeContainer_TestCase(unittest.TestCase): + def runTest(self): + cmd = RHEL9_OSTreeContainer() + self.assertEqual(cmd.noSignatureVerification, False) + + # test if arguments are required + op = cmd._getParser() + for action in op._actions: + if '--url' in action.option_strings: + self.assertEqual(action.required, True) + +class RHEL9_TestCase(CommandTest): + command = "ostreecontainer" + + def runTest(self): + # pass + # the stateroot has default value "default" and remote is set from stateroot if not set + cmdstr = "ostreecontainer --url=\"quay.io/test/test_c:stable\"" + self.assert_parse(cmdstr, cmdstr + "\n") + cmdstr = "ostreecontainer --stateroot=\"fedora-silverblue\" --url=\"quay.io/test/test_c:stable\"" + cmdstr_expected = "ostreecontainer --stateroot=\"fedora-silverblue\" --remote=\"fedora-silverblue\" --url=\"quay.io/test/test_c:stable\"" + self.assert_parse(cmdstr, cmdstr_expected + "\n") + cmdstr = "ostreecontainer --stateroot=\"fedora-silverblue\" --remote=\"test-remote\" --url=\"quay.io/test/test_c:stable\"" + self.assert_parse(cmdstr, cmdstr + "\n") + cmdstr = "ostreecontainer --stateroot=\"fedora-silverblue\" --remote=\"test-remote\" --no-signature-verification --url=\"quay.io/test/test_c:stable\"" + self.assert_parse(cmdstr, cmdstr + "\n") + cmdstr = "ostreecontainer --stateroot=\"fedora-silverblue\" --remote=\"test-remote\" --no-signature-verification --transport=\"repository\" --url=\"quay.io/test/test_c:stable\"" + self.assert_parse(cmdstr, cmdstr + "\n") + + # fail - we have required arguments + self.assert_parse_error("ostreecontainer") + self.assert_parse_error("ostreecontainer --bacon=tasty") + self.assert_parse_error("ostreecontainer --os=fedora-silverblue") + self.assert_parse_error("ostreecontainer --stateroot=fedora-silverblue") + self.assert_parse_error("ostreecontainer --no-signature-verification") + self.assert_parse_error("ostreecontainer --remote=\"sweet\"") + self.assert_parse_error("ostreecontainer --transport=\"test\"")