Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ostreecontainer rhel 9 #5399

Merged
merged 6 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion anaconda.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@ Source0: %{name}-%{version}.tar.bz2
%define libxklavierver 5.4
%define mehver 0.23-1
%define nmver 1.0
%define pykickstartver 3.32.10-1
%define pykickstartver 3.32.11-1
%define pypartedver 2.5-2
%define pythonblivetver 1:3.6.0-4
%define rpmver 4.10.0
%define simplelinever 1.8.3-1
%define subscriptionmanagerver 1.29.31
%define utillinuxver 2.15.1
%define rpmostreever 2023.2

BuildRequires: audit-libs-devel
BuildRequires: libtool
Expand Down Expand Up @@ -100,6 +101,11 @@ Requires: python3-systemd
Requires: python3-productmd
Requires: python3-dasbus >= %{dasbusver}
Requires: flatpak-libs
# dependencies for rpm-ostree payload module
Requires: rpm-ostree >= %{rpmostreever}
Requires: ostree
# used by ostree command for native containers
Requires: skopeo
%if %{defined rhel} && %{undefined centos}
Requires: subscription-manager >= %{subscriptionmanagerver}
%endif
Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ AC_CONFIG_FILES([Makefile
pyanaconda/modules/payloads/source/nfs/Makefile
pyanaconda/modules/payloads/source/repo_files/Makefile
pyanaconda/modules/payloads/source/rpm_ostree/Makefile
pyanaconda/modules/payloads/source/rpm_ostree_container/Makefile
pyanaconda/modules/payloads/source/url/Makefile
pyanaconda/modules/storage/Makefile
pyanaconda/modules/storage/bootloader/Makefile
Expand Down
1 change: 1 addition & 0 deletions pyanaconda/core/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ class DisplayModes(Enum):
SOURCE_TYPE_LIVE_OS_IMAGE = "LIVE_OS_IMAGE"
SOURCE_TYPE_LIVE_IMAGE = "LIVE_IMAGE"
SOURCE_TYPE_RPM_OSTREE = "RPM_OSTREE"
SOURCE_TYPE_RPM_OSTREE_CONTAINER = "RPM_OSTREE_CONTAINER"
SOURCE_TYPE_HMC = "HMC"
SOURCE_TYPE_CDROM = "CDROM"
SOURCE_TYPE_CLOSEST_MIRROR = "CLOSEST_MIRROR"
Expand Down
1 change: 1 addition & 0 deletions pyanaconda/core/kickstart/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
from pykickstart.commands.nfs import FC6_NFS as NFS
from pykickstart.commands.nvdimm import F28_Nvdimm as Nvdimm
from pykickstart.commands.ostreesetup import RHEL9_OSTreeSetup as OSTreeSetup
from pykickstart.commands.ostreecontainer import RHEL9_OSTreeContainer as OSTreeContainer
from pykickstart.commands.partition import RHEL9_Partition as Partition
from pykickstart.commands.raid import RHEL9_Raid as Raid
from pykickstart.commands.realm import F19_Realm as Realm
Expand Down
5 changes: 5 additions & 0 deletions pyanaconda/modules/common/constants/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@
basename="RPMOSTree"
)

PAYLOAD_SOURCE_RPM_OSTREE_CONTAINER = DBusInterfaceIdentifier(
namespace=SOURCE_NAMESPACE,
basename="RPMOSTreeContainer"
)

PAYLOAD_SOURCE = DBusInterfaceIdentifier(
namespace=SOURCE_NAMESPACE
)
Expand Down
74 changes: 73 additions & 1 deletion pyanaconda/modules/common/structures/rpm_ostree.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from dasbus.structure import DBusData
from dasbus.typing import Str, Bool

__all__ = ["RPMOSTreeConfigurationData"]
__all__ = ["RPMOSTreeConfigurationData", "RPMOSTreeContainerConfigurationData"]


class RPMOSTreeConfigurationData(DBusData):
Expand All @@ -33,6 +33,11 @@ def __init__(self):
self._ref = ""
self._gpg_verification_enabled = True

@staticmethod
def is_container():
"""Is this native container source?"""
return False

@property
def osname(self) -> Str:
"""Management root for OS installation."""
Expand Down Expand Up @@ -77,3 +82,70 @@ def gpg_verification_enabled(self) -> Bool:
@gpg_verification_enabled.setter
def gpg_verification_enabled(self, value: Bool):
self._gpg_verification_enabled = value


class RPMOSTreeContainerConfigurationData(DBusData):
"""Structure to hold RPM OSTree from container configuration."""

def __init__(self):
self._stateroot = ""
self._remote = ""
self._transport = ""
self._url = ""
self._signature_verification_enabled = True

@staticmethod
def is_container():
"""Is this native container source?"""
return True

@property
def stateroot(self) -> Str:
"""Name for the state directory, also known as "osname".

This could be optional.
"""
return self._stateroot

@stateroot.setter
def stateroot(self, value: Str):
self._stateroot = value

@property
def transport(self) -> Str:
"""Ostree transport protocol used.

This could be optional (default will be 'repository').
"""
return self._transport

@transport.setter
def transport(self, value: Str):
self._transport = value

@property
def remote(self) -> Str:
"""Name of the OSTree remote."""
return self._remote

@remote.setter
def remote(self, value: Str):
self._remote = value

@property
def url(self) -> Str:
"""URL of the repository to install from."""
return self._url

@url.setter
def url(self, value: Str):
self._url = value

@property
def signature_verification_enabled(self) -> Bool:
"""Is the GPG key verification enabled?"""
return self._signature_verification_enabled

@signature_verification_enabled.setter
def signature_verification_enabled(self, value: Bool):
self._signature_verification_enabled = value
4 changes: 3 additions & 1 deletion pyanaconda/modules/payloads/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
PAYLOAD_TYPE_DNF, PAYLOAD_TYPE_LIVE_OS, PAYLOAD_TYPE_LIVE_IMAGE, \
SOURCE_TYPE_LIVE_OS_IMAGE, SOURCE_TYPE_HMC, SOURCE_TYPE_CDROM, SOURCE_TYPE_REPO_FILES, \
SOURCE_TYPE_NFS, SOURCE_TYPE_URL, SOURCE_TYPE_HDD, SOURCE_TYPE_CDN, \
SOURCE_TYPE_CLOSEST_MIRROR, PAYLOAD_TYPE_RPM_OSTREE, SOURCE_TYPE_RPM_OSTREE, \
SOURCE_TYPE_CLOSEST_MIRROR, PAYLOAD_TYPE_RPM_OSTREE, \
SOURCE_TYPE_RPM_OSTREE, SOURCE_TYPE_RPM_OSTREE_CONTAINER, \
SOURCE_TYPE_LIVE_IMAGE


Expand All @@ -48,6 +49,7 @@ class SourceType(Enum):
LIVE_OS_IMAGE = SOURCE_TYPE_LIVE_OS_IMAGE
LIVE_IMAGE = SOURCE_TYPE_LIVE_IMAGE
RPM_OSTREE = SOURCE_TYPE_RPM_OSTREE
RPM_OSTREE_CONTAINER = SOURCE_TYPE_RPM_OSTREE_CONTAINER
HMC = SOURCE_TYPE_HMC
CDROM = SOURCE_TYPE_CDROM
CLOSEST_MIRROR = SOURCE_TYPE_CLOSEST_MIRROR
Expand Down
1 change: 1 addition & 0 deletions pyanaconda/modules/payloads/kickstart.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class PayloadKickstartSpecification(KickstartSpecification):
"hmc": COMMANDS.Hmc,
"liveimg": COMMANDS.Liveimg,
"nfs": COMMANDS.NFS,
"ostreecontainer": COMMANDS.OSTreeContainer,
"ostreesetup": COMMANDS.OSTreeSetup,
"url": COMMANDS.Url
}
Expand Down
2 changes: 1 addition & 1 deletion pyanaconda/modules/payloads/payload/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def get_type_for_kickstart(cls, data):
:param data: a kickstart data
:return: a payload type
"""
if data.ostreesetup.seen:
if data.ostreesetup.seen or data.ostreecontainer.seen:
return PayloadType.RPM_OSTREE

if data.liveimg.seen:
Expand Down
109 changes: 94 additions & 15 deletions pyanaconda/modules/payloads/payload/rpm_ostree/installation.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,60 @@ def safe_exec_with_redirect(cmd, argv, successful_return_codes=(0,), **kwargs):
)


def _get_ref(data):
"""Get ref or name based on source.

OSTree container don't have ref because it's specified by the container. In that case let's
return just url for reporting.

:param data: OSTree source structure
:return str: ref or name based on source
"""
# Variable substitute the ref: https://pagure.io/atomic-wg/issue/299
if data.is_container():
# we don't have ref with container; there are not multiple references in one container
return data.url
else:
return RpmOstree.varsubst_basearch(data.ref)


def _get_stateroot(data):
"""Get stateroot.

The OSTree renamed old osname to stateroot for containers.

:param data: OSTree source structure
:return str: stateroot or osname value based on source
"""
if data.is_container():
# osname was renamed to stateroot so let's use the new name
if data.stateroot:
return data.stateroot
else:
# The stateroot doesn't have to be defined
# https://github.com/ostreedev/ostree-rs-ext/pull/462/files
# However, it's working just for a subset of calls now.
# TODO: Remove this when all ostree commands undestarstands this
return "default"
else:
return data.osname


def _get_verification_enabled(data):
"""Find out if source has enabled verification.

OSTree sources has different names for enabled verification. This helper function
will make the access consistent.

:param data: OSTree source structure
:return bool: True if verification is enabled
"""
if data.is_container():
return data.signature_verification_enabled
else:
return data.gpg_verification_enabled


class PrepareOSTreeMountTargetsTask(Task):
"""Task to prepare OSTree mount targets."""

Expand Down Expand Up @@ -119,7 +173,10 @@ def _handle_var_mount_point(self, existing_mount_points):

:param [] existing_mount_points: a list of existing mount points
"""
var_root = '/ostree/deploy/' + self._source_config.osname + '/var'
# osname was used for ostreesetup but ostreecontainer renamed it to stateroot
stateroot = _get_stateroot(self._source_config)

var_root = '/ostree/deploy/' + stateroot + '/var'
if existing_mount_points.get("/var") is None:
self._setup_internal_bindmount(var_root, dest='/var', recurse=False)
else:
Expand Down Expand Up @@ -325,7 +382,7 @@ def run(self):

remote_options = {}

if not self._data.gpg_verification_enabled:
if not _get_verification_enabled(self._data):
remote_options['gpg-verify'] = Variant('b', False)

if not conf.payload.verify_ssl:
Expand All @@ -336,9 +393,12 @@ def run(self):
else:
root = None

# Remote is set or it should be named as stateroot is
remote = self._data.remote or _get_stateroot(self._data)

repo.remote_change(root,
OSTree.RepoRemoteChange.ADD_IF_NOT_EXISTS,
self._data.remote,
remote,
self._data.url,
Variant('a{sv}', remote_options),
cancellable)
Expand Down Expand Up @@ -413,7 +473,8 @@ def name(self):

def run(self):
# Variable substitute the ref: https://pagure.io/atomic-wg/issue/299
ref = RpmOstree.varsubst_basearch(self._data.ref)
ref = _get_ref(self._data)
stateroot = _get_stateroot(self._data)

self.report_progress(_("Deployment starting: {}").format(ref))

Expand All @@ -422,21 +483,39 @@ def run(self):
["admin",
"--sysroot=" + self._sysroot,
"os-init",
self._data.osname]
stateroot]
)

log.info("ostree admin deploy starting")
if self._data.is_container():
log.info("ostree image deploy starting")

safe_exec_with_redirect(
"ostree",
["admin",
"--sysroot=" + self._sysroot,
"deploy",
"--os=" + self._data.osname,
self._data.remote + ':' + ref]
)
args = ["container", "image", "deploy",
"--sysroot=" + self._sysroot,
"--image=" + ref]

if self._data.transport:
args.append("--transport=" + self._data.transport)
if self._data.stateroot:
args.append("--stateroot=" + self._data.stateroot)
if not self._data.signature_verification_enabled:
args.append("--no-signature-verification")

safe_exec_with_redirect(
"ostree",
args
)
else:
log.info("ostree admin deploy starting")
safe_exec_with_redirect(
"ostree",
["admin",
"--sysroot=" + self._sysroot,
"deploy",
"--os=" + stateroot,
self._data.remote + ':' + ref]
)

log.info("ostree admin deploy complete")
log.info("ostree deploy complete")
self.report_progress(_("Deployment complete: {}").format(ref))


Expand Down
3 changes: 2 additions & 1 deletion pyanaconda/modules/payloads/payload/rpm_ostree/rpm_ostree.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ def type(self):
def supported_source_types(self):
"""Get list of sources supported by the RPM OSTree module."""
return [
SourceType.RPM_OSTREE
SourceType.RPM_OSTREE,
SourceType.RPM_OSTREE_CONTAINER,
]

def process_kickstart(self, data):
Expand Down
3 changes: 2 additions & 1 deletion pyanaconda/modules/payloads/source/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

SUBDIRS = live_os hmc cdrom repo_files nfs url harddrive cdn closest_mirror rpm_ostree live_image
SUBDIRS = live_os hmc cdrom repo_files nfs url harddrive cdn closest_mirror rpm_ostree \
rpm_ostree_container live_image

pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
payload_moduledir = $(pkgpyexecdir)/modules/payloads/source
Expand Down
6 changes: 6 additions & 0 deletions pyanaconda/modules/payloads/source/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ def create_source(source_type: SourceType):
from pyanaconda.modules.payloads.source.rpm_ostree.rpm_ostree import \
RPMOSTreeSourceModule
return RPMOSTreeSourceModule()
elif source_type == SourceType.RPM_OSTREE_CONTAINER:
from pyanaconda.modules.payloads.source.rpm_ostree_container.rpm_ostree_container import \
RPMOSTreeContainerSourceModule
return RPMOSTreeContainerSourceModule()

raise ValueError("Unknown source type: {}".format(source_type))

Expand Down Expand Up @@ -104,6 +108,8 @@ def get_rpm_ostree_type_for_kickstart(ks_data):
:param ks_data: kickstart data from DNF payload
:return: SourceType value
"""
if ks_data.ostreecontainer.seen:
return SourceType.RPM_OSTREE_CONTAINER
if ks_data.ostreesetup.seen:
return SourceType.RPM_OSTREE

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def setup_kickstart(self, data):
data.ostreesetup.url = self.configuration.url
data.ostreesetup.ref = self.configuration.ref
data.ostreesetup.nogpg = not self.configuration.gpg_verification_enabled
data.ostreesetup.seen = True

def set_up_with_tasks(self):
"""Set up the installation source for installation.
Expand Down
Loading
Loading