Lindley Vieira fe0404eae9 Update summary in apt-ostree repos
When ostree changes a repository it requires a summary update for
the changes to be seen by clients of this remote repository.

This commit adds summary update call after every change in the repo.

Test Plan:
PASS: Deploy a host after a deploy start to apply
PASS: Undeploy a host after a deploy start to remove
PASS: Undeploy a host after an abort

Story: 2010676
Task: 51017

Change-Id: I276fd823b81db8c66cb0c83f8ab19f963d182bf0
Signed-off-by: Lindley Vieira <lindley.vieira@windriver.com>
2024-09-24 11:26:49 -03:00

161 lines
5.7 KiB
Python

"""
Copyright (c) 2023 Wind River Systems, Inc.
SPDX-License-Identifier: Apache-2.0
"""
import logging
import sys
from rich.console import Console
from apt_ostree.apt import Apt
from apt_ostree.deploy import Deploy
from apt_ostree.ostree import Ostree
class Rebase:
def __init__(self, state):
self.state = state
self.console = Console()
self.ostree = Ostree(self.state)
self.deploy = Deploy(self.state)
self.apt = Apt(self.state)
self.logging = logging.getLogger(__name__)
def rebase(self, update):
"""Switch to another branch."""
# Verify the branch is formatted correctly.
try:
(remote, branch) = self.state.branch.split(":")
except KeyError:
self.logging.error(
"Branch must be in the format of <remote>:<branch>"
)
sys.exit(1)
# Make sure that we have remotes configured.
if len(self._get_remotes()) == 0:
self.logging.error("No remotes configured.")
sys.exit(1)
if update:
self.logging.info(f"Pulling {branch} from {remote}.")
with self.console.status(f"Fetching {branch} from {remote}"):
self._fetch(remote, branch)
sys.exit(1)
else:
# Get the current deployment, check for
# a deployed sysroot.
sysroot = self.ostree.get_sysroot()
if sysroot is None:
self.logging.error("Not running ostree.")
sys.exit(1)
csum = sysroot.get_booted_deployment().get_csum()
origin = sysroot.get_booted_deployment().get_origin()
refspec = origin.get_string('origin', 'refspec')
if refspec is None:
self.logging.error("Unable to determine branch.")
sys.exit(1)
self.logging.info(f"Rebasing {refspec} on to {self.state.branch}.")
self.logging.info(f"Local deployment: {refspec} ({csum[:10]}).")
# Get a list of manually installed packages.
# These include packages that were installed after an
# initial boostrap as well.
current_packages = self.get_current_packages(refspec, csum)
# If we didnt fetch the latest repository do it now.
self.logging.info(f"Pulling {branch} from {remote}.")
self._fetch(remote, branch)
# Prepare the new branch for deployment.
ref = self.ostree.ostree_ref(self.state.branch)
if ref is None:
self.logging.error(f"Failed to fetch {self.state.branch}")
sys.exit(1)
self.logging.debug(f"Fetched {self.state.branch} ({ref[:10]})")
# Rebase onto the pristine branch.
rootfs = self.deploy.get_sysroot(self.state.branch)
if rootfs is None:
self.logging.error(f"Unable to checkout {self.state.branch}")
sys.exit(1)
# Prestaging
self.deploy.prestaging(rootfs)
self.apt.apt_update(rootfs)
cache = self.apt.cache(rootfs)
new_packages = self.apt.get_installed_packages(cache)
# Determine packages that are missing and install them.
self.logging.debug(
f"Deteriming package delta between {refspec} "
f"and {self.state.branch}."
)
packages = list(current_packages - new_packages)
if len(packages) != 0:
commit = f"Resynchronize {self.state.branch} ({ref[:10]})"\
f" with {refspec} ({csum[:10]}).\n\n"
subject = "Resynchronize package list"
for pkg in packages:
version = self.apt.get_version(cache, pkg)
commit += f" - {pkg} {version}"
self.logging.info(f"Installing {pkg} ({version}).")
self.apt.apt_install(cache, packages, rootfs)
else:
subject = f"Updated {origin}"
commit = "Previous deployment: {csum[:10]}"
self.deploy.poststaging(rootfs)
self.logging.info(f"Commiting to {self.state.branch}.")
self.ostree.ostree_commit(
root=str(rootfs),
branch=self.state.branch,
repo=self.state.repo,
subject=subject,
msg=commit
)
self.ostree.ostree_summary_update(self.state.repo)
self.deploy.cleanup(rootfs)
def _get_remotes(self):
"""List of remotes configured."""
return [
refs for refs in self.ostree.remotes_list()
if refs != "origin"]
def _fetch(self, remote, branch):
"""Wrapper around ostree fetch."""
self.ostree.fetch(remote, branch)
self.ostree.ostree_summary_update()
def get_current_packages(self, branch, ref):
"""Steps to prepare the systeem before a rebase."""
self.logging.debug(
f"Deploying current deployment {branch} ({ref[:10]})")
rootfs = self.deploy.get_sysroot(branch)
if not rootfs.exists():
self.logging.error("Unable to determine rootfs: {rootfs}")
sys.exit(1)
# Deploy the current booted deployment and run apt-update
# to configure apt.
self.deploy.prestaging(rootfs)
self.apt.apt_update(rootfs)
# Check for packages that are installed.
self.logging.debug("Querying installed packages.")
cache = self.apt.cache(rootfs)
pkgs = self.apt.get_installed_packages(cache)
# Just remove the directory since we are done with it
self.deploy.cleanup(rootfs)
return pkgs