Use python standard logging

Make the UI consistent by using python standarized logging everywhere.

Also log to the systemd-journald service so the logs are kept
around when a user deploys a newer version of a branch.

Story: 2010867
Task: 48556

Change-Id: I9f203dd6d3e0e17c0563f59efd5f4fa003fa030e
Signed-off-by: Charles Short <charles.short@windriver.com>
This commit is contained in:
Charles Short 2023-10-23 09:50:38 -04:00
parent 5c76c2af4c
commit 2d8d3e9a3f
11 changed files with 182 additions and 215 deletions

View File

@ -5,26 +5,25 @@ SPDX-License-Identifier: Apache-2.0
"""
import logging
import subprocess
import sys
import apt
import click
from rich.console import Console
from apt_ostree.utils import run_sandbox_command
class Apt:
def __init__(self, state):
self.logging = logging.getLevelName(__name__)
self.state = state
self.console = Console()
def cache(self, rootfs):
try:
cache = apt.Cache(rootdir=rootfs)
except AttributeError as e:
click.secho(f"Failed to load apt cache: {e.message}")
self.logging.error(f"Failed to load apt cache: {e.message}")
sys.exit(1)
return cache
@ -38,7 +37,7 @@ class Apt:
["apt-get", "update", "-y"],
rootfs)
if r.returncode != 0:
click.secho("Failed to run apt-get update", fg="red")
self.logging.error("Failed to run apt-get update.")
return r
def apt_install(self, packages, rootfs):
@ -48,7 +47,7 @@ class Apt:
cmd += packages
r = run_sandbox_command(cmd, rootfs)
if r.returncode != 0:
click.secho("Failed to run apt-get install", fg="red")
self.logging.error("Failed to run apt-get install.")
return r
def apt_list(self, rootfs, action):
@ -65,7 +64,7 @@ class Apt:
["apt-get", "upgrade"],
rootfs)
if r.returncode != 0:
click.secho("Failed to run apt-get upgrade", fg="red")
self.logging.error("Failed to run apt-get upgrade.")
return r
def apt_uninstall(self, packages, rootfs):
@ -75,7 +74,7 @@ class Apt:
cmd += packages
r = run_sandbox_command(cmd, rootfs)
if r.returncode != 0:
click.secho("Failed to run apt-get remove", fg="red")
self.logging.error("Failed to run apt-get remove.")
return r
def check_valid_packages(self, cache, packages):

View File

@ -6,65 +6,67 @@ SPDX-License-Identifier: Apache-2.0
"""
import hashlib
import logging
import os
import shutil
import sys
import apt
import click
from rich.console import Console
from apt_ostree.constants import excluded_packages
from apt_ostree.log import complete_step
from apt_ostree.log import log_step
from apt_ostree.ostree import Ostree
from apt_ostree.utils import run_command
class Bootstrap:
def __init__(self, state):
self.logging = logging.getLogger(__name__)
self.console = Console()
self.state = state
self.ostree = Ostree(self.state)
def create_rootfs(self):
"""Create a Debian system from a configuration file."""
if not self.state.base.exists():
click.secho("Configuration directory does not exist.", fg="red")
self.logging.error("Configuration directory does not exist.")
sys.exit(1)
click.secho(f"Found configuration directory: {self.state.base}")
self.logging.info(f"Found configuration directory: {self.state.base}")
config = self.state.base.joinpath("bootstrap.yaml")
if not config.exists():
click.sceho("bootstrap.yaml does not exist.", fg="red")
self.logging.error("bootstrap.yaml does not exist.")
sys.exit(1)
else:
click.secho("Found configuration file bootstrap.yaml.")
self.loging.info("Found configuration file bootstrap.yaml.")
with complete_step(f"Setting up workspace for {self.state.branch}."):
with self.console.status(
f"Setting up workspace for {self.state.branch}."):
workspace = self.state.workspace
workdir = workspace.joinpath(f"build/{self.state.branch}")
rootfs = workdir.joinpath("rootfs")
log_step(f"Building workspace for {self.state.branch} "
f"in {workspace}")
self.logging.info(f"Building workspace for {self.state.branch} "
f"in {workspace}")
if workdir.exists():
log_step("Found working directory from "
"previous run...removing.")
self.logging.info("Found working directory from "
"previous run...removing.")
shutil.rmtree(workdir)
workdir.mkdir(parents=True, exist_ok=True)
rootfs.mkdir(parents=True, exist_ok=True)
log_step("Running bdebstrap, please wait.")
verbosity = "-q"
if self.state.debug:
verbosity = "-v"
run_command(
["bdebstrap", "-c", "bootstrap.yaml", verbosity,
"--force", "--name", str(
self.state.branch), "--target", str(rootfs),
"--output", str(workdir)], cwd=self.state.base)
self.logging.info("Running bdebstrap, please wait.")
verbosity = "-q"
if self.state.debug:
verbosity = "-v"
run_command(
["bdebstrap", "-c", "bootstrap.yaml", verbosity,
"--force", "--name", str(self.state.branch),
"--target", str(rootfs),
"--output", str(workdir)], cwd=self.state.base)
self.ostree.init()
click.secho(f"Found ostree branch: {self.state.branch}")
self.logging.info(f"Found ostree branch: {self.state.branch}")
self.create_ostree(rootfs)
r = self.ostree.ostree_commit(
rootfs,
@ -73,14 +75,14 @@ class Bootstrap:
subject="Commit by apt-ostree",
msg="Initialized by apt-ostree.")
if r.returncode != 0:
click.secho(f"Failed to commit {self.state.branch} to "
f"{self.state.repo}.")
click.secho(f"Commited {self.state.repo} to {self.state.repo}.")
self.logging.info(f"Failed to commit {self.state.branch} to "
f"{self.state.repo}.")
self.logging.info(f"Commited {self.state.repo} to {self.state.repo}.")
def create_ostree(self, rootdir):
"""Create an ostree branch from a rootfs."""
with complete_step(f"Creating ostree from {rootdir}."):
log_step("Setting up /usr/lib/ostree-boot")
with self.console.status(f"Creating ostree from {rootdir}."):
self.logging.info("Setting up /usr/lib/ostree-boot")
self.setup_boot(rootdir,
rootdir.joinpath("boot"),
rootdir.joinpath("usr/lib/ostree-boot"))
@ -94,17 +96,17 @@ class Bootstrap:
"vmlinuz", "vmlinuz.old"]
assert rootdir is not None and rootdir != ""
with complete_step(f"Converting {rootdir} to ostree."):
with self.console.status(f"Converting {rootdir} to ostree."):
dir_perm = 0o755
# Emptying /dev
log_step("Emptying /dev.")
self.logging.info("Emptying /dev.")
shutil.rmtree(rootdir.joinpath("dev"))
os.mkdir(rootdir.joinpath("dev"), dir_perm)
# Copying /var
self.sanitize_usr_symlinks(rootdir)
log_step("Moving /var to /usr/rootdirs.")
self.logging.info("Moving /var to /usr/rootdirs.")
os.mkdir(rootdir.joinpath("usr/rootdirs"), dir_perm)
# Make sure we preserve file permissions otherwise
# bubblewrap will complain that a file/directory
@ -118,7 +120,7 @@ class Bootstrap:
os.mkdir(rootdir.joinpath("var"), dir_perm)
# Remove unecessary files
log_step("Removing unnecessary files.")
self.logging.info("Removing unnecessary files.")
for c in CRUFT:
try:
os.remove(rootdir.joinpath(c))
@ -126,11 +128,11 @@ class Bootstrap:
pass
# Setup and split out etc
log_step("Moving /etc to /usr/etc.")
self.logging.info("Moving /etc to /usr/etc.")
shutil.move(rootdir.joinpath("etc"),
rootdir.joinpath("usr"))
log_step("Setting up /ostree and /sysroot.")
self.logging.info("Setting up /ostree and /sysroot.")
try:
rootdir.joinpath("ostree").mkdir(
parents=True, exist_ok=True)
@ -139,7 +141,7 @@ class Bootstrap:
except OSError:
pass
log_step("Setting up symlinks.")
self.logging.info("Setting up symlinks.")
TOPLEVEL_LINKS = {
"media": "run/media",
"mnt": "var/mnt",
@ -240,7 +242,7 @@ class Bootstrap:
def create_tmpfile_dir(self, rootdir):
"""Ensure directoeies in /var are created."""
with complete_step("Creating systemd-tmpfiles configuration"):
with self.console.status("Creating systemd-tmpfiles configuration"):
cache = apt.cache.Cache(rootdir=rootdir)
dirs = []
for pkg in cache:

View File

@ -4,11 +4,11 @@ Copyright (c) 2023 Wind River Systems, Inc.
SPDX-License-Identifier: Apache-2.0
"""
import logging
import shutil
import sys
import click
from rich.console import Console
from apt_ostree.ostree import Ostree
@ -17,6 +17,7 @@ from apt_ostree.repo import Repo
class Compose:
def __init__(self, state):
self.logging = logging.getLogger(__name__)
self.state = state
self.ostree = Ostree(self.state)
self.repo = Repo(self.state)
@ -30,11 +31,11 @@ class Compose:
def create(self):
"""Create an OSTree repository."""
if self.state.repo.exists():
click.secho(
f"Repository already exists: {self.state.repo}", fg="red")
self.logging.error(
f"Repository already exists: {self.state.repo}")
sys.exit(1)
click.secho(f"Found ostree repository: {self.state.repo}")
self.logging.info(f"Found ostree repository: {self.state.repo}")
self.ostree.init()
def enablerepo(self):
@ -42,7 +43,7 @@ class Compose:
try:
self.repo.add_repo()
except Exception as e:
click.secho(f"Failed to add repo: {e}", fg="red")
self.logging.error(f"Failed to add repo: {e}")
sys.exit(1)
def disablerepo(self):
@ -50,11 +51,10 @@ class Compose:
def commit(self, parent):
"""Commit changes to an ostree repo."""
self.console.print(f"Cloning {self.state.branch} from {parent}.",
highlight=False)
self.logging.info(f"Cloning {self.state.branch} from {parent}.")
rev = self._checkout(parent)
if not rev:
click.secho("Failed to fetch commit", fg="red")
self.logging.error("Failed to fetch commit")
sys.exit(1)
with self.console.status(f"Commiting {rev[:10]}."):
@ -67,18 +67,16 @@ class Compose:
msg=f"Forked from {parent} ({rev[:10]})."
)
if r.returncode != 0:
click.secho("Failed to commit.", fg="red")
self.logging.error("Failed to commit.")
sys.exit(1)
self.console.print(f"Successfully commited {self.state.branch}"
f"({rev[:10]}) from {parent}.",
highlight=False)
self.console.print("Cleaning up.")
self.logging.info(f"Successfully commited {self.state.branch}"
f"({rev[:10]}) from {parent}.")
self.logging.info("Cleaning up.")
try:
shutil.rmtree(self.rootfs)
except OSError as e:
click.secho(f"Failed to remove rootfs {self.rootfs}: {e}",
fg="red")
self.logging.error(f"Failed to remove rootfs {self.rootfs}: {e}")
def _checkout(self, branch):
"""Checkout a commit from an ostree branch."""

View File

@ -5,12 +5,12 @@ SPDX-License-Identifier: Apache-2.0
"""
import logging
import os
import shutil
import subprocess
import sys
import click
from rich.console import Console
from apt_ostree.ostree import Ostree
@ -19,9 +19,10 @@ from apt_ostree import utils
class Deploy:
def __init__(self, state):
self.console = Console()
self.logging = logging.getLogger(__name__)
self.state = state
self.ostree = Ostree(self.state)
self.console = Console()
self.workspace = self.state.workspace
self.workdir = self.state.workspace.joinpath("deployment")
@ -31,7 +32,7 @@ class Deploy:
def prestaging(self, rootfs):
"""Pre stage steps."""
if not rootfs.exists():
click.secho("rootfs not found: {rootfs}", fg="red")
self.logging.error("rootfs not found: {rootfs}")
sys.exit(1)
with self.console.status("Running prestaging steps."):
@ -60,17 +61,17 @@ class Deploy:
# 73 - configuration ok, but could not be created
# 1 - other error
if r.returncode not in [0, 65]:
click.secho("Failed to populate /var,", fg="red")
click.secho(f"Error code: {r.returncode}", fg="red")
self.logging.error("Failed to populate /var,")
self.logging.error(f"Error code: {r.returncode}")
sys.exit(1)
def poststaging(self, rootfs):
"""Post staging steps."""
if not rootfs.exists():
click.secho("rootfs not found: {rootfs}", fg="red")
self.logging.error("rootfs not found: {rootfs}")
sys.exit(1)
self.console.print("Running post deploy steps.")
self.logging.info("Running post deploy steps.")
fd = os.open(rootfs, os.O_DIRECTORY)
if os.path.exists(rootfs.joinpath("etc")):
os.unlink("etc", dir_fd=fd)
@ -105,33 +106,33 @@ class Deploy:
"""Run ostree admin deploy."""
ref = self.ostree.ostree_ref(self.state.branch)
if not ref:
click.secho(
f"Unable to find branch: {self.state.branch}.", fg="red")
self.logging.error(
f"Unable to find branch: {self.state.branch}.")
sys.exit(1)
r = utils.run_command(
["ostree", "admin", "deploy", self.state.branch]
)
if r.returncode != 0:
click.secho("Failed to deploy.", fg="red")
self.logging.error("Failed to deploy.")
sys.exit(1)
if update:
self.console.print("Updating grub.")
self.logging.info("Updating grub.")
r = utils.run_command(
["update-grub"]
)
if r.returncode != 0:
click.secho("Failed to update grub.", fg="red")
self.logging.error("Failed to update grub.")
sys.exit(1)
if reboot:
self.console.print("Rebooting now.")
self.logging.info("Rebooting now.")
r = utils.run_command(
["shutdown", "-r", "now"]
)
if r.returncode != 0:
click.secho("Failed to reboot.", fg="red")
self.logging.error("Failed to reboot.")
sys.exit(1)
else:
self.console.print("Please reboot for the changes to take affect.")
self.logging.info("Please reboot for the changes to take affect.")

View File

@ -5,24 +5,26 @@ SPDX-License-Identifier: Apache-2.0
"""
import logging
import shutil
import click
from rich.console import Console
from apt_ostree.log import complete_step
from apt_ostree.log import log_step
from apt_ostree.utils import run_command
class Image:
def __init__(self, state):
self.logging = logging.getLogger(__name__)
self.console = Console()
self.state = state
def create_image(self):
"""Create a raw disk image from an ostree repository."""
click.secho(f"Found ostree repository: {self.state.repo}")
click.secho(f"Found ostree branch: {self.state.branch}")
with complete_step(f"Setting up workspace for {self.state.branch}"):
self.logging.info(f"Found ostree repository: {self.state.repo}")
self.logging.info(f"Found ostree branch: {self.state.branch}")
with self.console.status(
f"Setting up workspace for {self.state.branch}."):
workdir = self.state.workspace.joinpath(
f"build/{self.state.branch}")
img_dir = workdir.joinpath("image")
@ -33,25 +35,26 @@ class Image:
self.state.base.joinpath("image"),
img_dir, dirs_exist_ok=True)
with complete_step("Creating local ostree repository"):
log_step("Creating image build repository")
run_command(
["ostree", "init", f"--repo={str(ostree_repo)}"],
cwd=img_dir)
log_step(f"Pulling {self.state.branch} in image build repository")
run_command(
["ostree", "pull-local", f"--repo={str(ostree_repo)}",
str(self.state.repo), str(self.state.branch)],
cwd=img_dir)
log_step("Running debos...")
self.logging.info("Creating image build repository")
run_command(
["ostree", "init", f"--repo={str(ostree_repo)}"],
cwd=img_dir)
self.logging.info(
f"Pulling {self.state.branch} in image build repository")
run_command(
["ostree", "pull-local", f"--repo={str(ostree_repo)}",
str(self.state.repo), str(self.state.branch)],
cwd=img_dir)
self.logging.info("Running debos...")
cmd = ["debos",
"-t", f"branch:{self.state.branch}",
]
if self.state.debug:
cmd += ["-v"]
cmd += ["image.yaml"]
cmd = [
"debos",
"-t", f"branch:{self.state.branch}",
]
if self.state.debug:
cmd += ["-v"]
cmd += ["image.yaml"]
run_command(cmd, cwd=img_dir)
run_command(cmd, cwd=img_dir)
click.secho(f"Image can be found in {img_dir}")
self.logging.info(f"Image can be found in {img_dir}")

View File

@ -4,78 +4,35 @@ Copyright (c) 2023 Wind River Systems, Inc.
SPDX-License-Identifier: Apache-2.0
"""
import contextlib
import logging
import os
import sys
from typing import Any
LEVEL = 0
from rich.console import Console
from rich.logging import RichHandler
from systemd.journal import JournalHandler
def log_step(text):
prefix = " " * LEVEL
if sys.exc_info()[0]:
logging.info(f"{prefix}({text})")
else:
logging.info(f"{prefix}{Style.bold}{text}{Style.reset}")
def setup_log(debug=False):
level = logging.DEBUG if debug else logging.INFO
fmt = "%(message)s"
rootLogger = logging.getLogger()
rootLogger.setLevel(logging.NOTSET)
@contextlib.contextmanager
def complete_step(text, text2=None):
global LEVEL
journald_handler = JournalHandler(
SYSLOG_IDENTIFIER="apt-ostree")
journald_handler.setLevel(level)
journald_handler.setFormatter(logging.Formatter(
'[%(levelname)s] %(message)s'))
rootLogger.addHandler(journald_handler)
log_step(text)
console = Console(highlight=False)
LEVEL += 1
try:
args: list[Any] = []
yield args
finally:
LEVEL -= 1
assert LEVEL >= 0
rich_handler = RichHandler(show_path=False,
show_time=False,
show_level=False,
console=console)
rich_handler.setLevel(level)
rich_handler.setFormatter(logging.Formatter(fmt))
rootLogger.addHandler(rich_handler)
if text2 is not None:
log_step(text2.format(*args))
class Style:
bold = "\033[0;1;39m" if sys.stderr.isatty() else ""
gray = "\x1b[38;20m" if sys.stderr.isatty() else ""
red = "\033[31;1m" if sys.stderr.isatty() else ""
yellow = "\033[33;1m" if sys.stderr.isatty() else ""
reset = "\033[0m" if sys.stderr.isatty() else ""
class OstreeFormatter(logging.Formatter):
def __init__(self, fmt=None, *args, **kwargs):
fmt = fmt or "%(message)s"
self.formatters = {
logging.DEBUG: logging.Formatter(
f"{Style.gray}{fmt}{Style.reset}"),
logging.INFO: logging.Formatter(
f"{fmt}"),
logging.WARNING: logging.Formatter(
f"{Style.yellow}{fmt}{Style.reset}"),
logging.ERROR: logging.Formatter(
f"{Style.red}{fmt}{Style.reset}"),
logging.CRITICAL: logging.Formatter(
f"{Style.red}{Style.bold}{fmt}{Style.reset}"),
}
super().__init__(fmt, *args, **kwargs)
def format(self, record):
return self.formatters[record.levelno].format(record)
def setup_log():
handler = logging.StreamHandler(stream=sys.stderr)
level = logging.getLevelName(
os.getenv("SYSTEMD_LOG_LEVEL", "info").upper())
handler.setFormatter(OstreeFormatter())
logging.getLogger().addHandler(handler)
logging.getLogger().setLevel(level)
return rootLogger

View File

@ -5,10 +5,10 @@ SPDX-License-Identifier: Apache-2.0
"""
import logging
import subprocess
import sys
import click
from rich.console import Console
from apt_ostree.utils import run_command
@ -25,6 +25,7 @@ AT_FDCWD = -100
class Ostree:
def __init__(self, state):
self.logging = logging.getLogger(__name__)
self.state = state
self.console = Console()
@ -38,7 +39,7 @@ class Ostree:
repo.create(mode)
self.console.print("Sucessfully initialized ostree repository.")
except GLib.GError as e:
click.secho(f"Failed to create repo: {e}", fg="red")
self.logging.error(f"Failed to create repo: {e}")
sys.exit(1)
def ostree_commit(self,
@ -64,16 +65,16 @@ class Ostree:
cmd += [str(root)]
r = run_command(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if r.returncode != 0:
click.secho("Failed to commit to tree.", fg="red")
self.logging.error("Failed to commit to tree.")
sys.exit(1)
click.secho(f"Sucessfully commited to {branch}.")
self.logging.info(f"Sucessfully commited to {branch}.")
return r
def get_sysroot(self):
"""Load the /ostree directory (sysroot)."""
sysroot = OSTree.Sysroot()
if not sysroot.load():
click.secho("Unable to load /sysroot", fg="red")
self.logging.error("Unable to load /sysroot.")
sys.exit(1)
return sysroot
@ -82,15 +83,15 @@ class Ostree:
if self.state.repo:
repo = OSTree.Repo.new(Gio.File.new_for_path(str(self.state.repo)))
if not repo.open(None):
click.secho(
"Opening the archive OSTree repository failed.", fg="red")
self.logging.error(
"Opening the archive OSTree repository failed.")
sys.exit(1)
else:
sysroot = self.get_sysroot()
_, repo = sysroot.get_repo()
if not repo.open():
click.secho(
"Opening the archive OSTree repository failed.", fg="red")
self.logging.error(
"Opening the archive OSTree repository failed.")
sys.exit(1)
return repo
@ -103,7 +104,7 @@ class Ostree:
try:
repo.checkout_at(opts, AT_FDCWD, str(rootfs), rev, None)
except GLib.GError as e:
click.secho(f"Failed to checkout {rev}: {e.message}", fg="red")
self.logging.error(f"Failed to checkout {rev}: {e.message}")
raise
def ostree_ref(self, branch):
@ -111,7 +112,7 @@ class Ostree:
repo = self.open_ostree()
ret, rev = repo.resolve_rev(branch, True)
if not rev:
click.secho(f"{branch} not found in {self.state.repo}", fg="red")
self.logging.error(f"{branch} not found in {self.state.repo}")
sys.exit(1)
return rev
@ -143,7 +144,7 @@ class Ostree:
remotes = repo.remote_list()
return remotes
except GLib.GError as e:
click.secho(f"Failed to fetch remotes: {e}")
self.logging.error(f"Failed to fetch remotes: {e}")
def get_remote_url(self, remote):
"""Fetch the URL of a remote."""
@ -171,10 +172,10 @@ class Ostree:
options,
None)
if check:
self.console.print(
self.looging.info(
f"Successfully added {self.state.remote}.")
except GLib.GError as e:
click.secho(f"Failed to add remote: {e}")
self.logging.warning(f"Failed to add remote: {e}")
def remote_remove(self):
"""Delete a remote."""
@ -182,10 +183,10 @@ class Ostree:
repo = self.open_ostree()
check = repo.remote_delete(self.state.remote, None)
if check:
self.console.print(
self.logging.info(
f"Successfully removed {self.state.remote}.")
except GLib.GError as e:
click.secho(f"Failed to remove remote: {e}")
self.logging.error(f"Failed to remove remote: {e}")
def remote_refs(self, remote):
try:
@ -193,5 +194,5 @@ class Ostree:
_, refs = repo.remote_list_refs(remote)
return refs
except GLib.GError as e:
click.secho(f"Failed to fetch refs: {e}")
self.logging.error(f"Failed to fetch refs: {e}")
sys.exit(1)

View File

@ -4,9 +4,10 @@ Copyright (c) 2023 Wind River Systems, Inc.
SPDX-License-Identifier: Apache-2.0
"""
import logging
import sys
import click
from rich.console import Console
from apt_ostree.apt import Apt
@ -16,10 +17,11 @@ from apt_ostree.ostree import Ostree
class Packages:
def __init__(self, state):
self.console = Console()
self.logging = logging.getLogger(__name__)
self.state = state
self.apt = Apt(self.state)
self.ostree = Ostree(self.state)
self.console = Console()
self.deploy = Deploy(self.state)
def install(self, packages):
@ -31,7 +33,7 @@ class Packages:
branch = self.ostree.get_branch()
rootfs = self.deploy.get_sysroot()
if not rootfs.exists():
click.secho("Unable to determine rootfs: {rootfs}", fg="red")
self.logging.error("Unable to determine rootfs: {rootfs}")
sys.exit(1)
# Step 0 - Run the prestaging steps.
@ -44,7 +46,7 @@ class Packages:
# Step 2 - Check to see if the packages are valid.
packages = self.apt.check_valid_packages(cache, packages)
if len(packages) == 0:
click.secho("No valid packages found.", fg="red")
self.logging.error("No valid packages found.")
sys.exit(1)
# Step 3 - Generate the commit message.
@ -70,8 +72,7 @@ class Packages:
self.deploy.poststaging(rootfs)
# Step 6 - Ostree commit.
self.console.print(f"Commiting to {branch}",
highlight=False)
self.logging.info(f"Commiting to {branch}")
self.ostree.ostree_commit(
root=str(rootfs),
branch=self.ostree.get_branch(),
@ -87,7 +88,7 @@ class Packages:
"""Use apt to install Debian packages."""
rootfs = self.deploy.get_sysroot()
if not rootfs.exists():
click.secho("Unable to determine rootfs: {rootfs}", fg="red")
self.logging.error("Unable to determine rootfs: {rootfs}")
sys.exit(1)
# Step 0 - Setup prestaging.
@ -108,7 +109,7 @@ class Packages:
cache.upgrade(False)
packages = [package.name for package in cache.get_changes()]
if len(packages) == 0:
click.secho("No package to upgrade.", fg="red")
self.logging.error("No package to upgrade.")
sys.exit(1)
# Step 3 - Build the commit message
@ -150,7 +151,7 @@ class Packages:
"""Use apt to uninstall Debian packages."""
rootfs = self.deploy.get_sysroot()
if not rootfs.exists():
click.secho("Unable to determine rootfs: {rootfs}", fg="red")
self.logging.error("Unable to determine rootfs: {rootfs}")
sys.exit(1)
# Step 0 - Run the prestaging steps.

View File

@ -5,6 +5,8 @@ SPDX-License-Identifier: Apache-2.0
"""
import logging
from rich.console import Console
from rich.table import Table
@ -13,9 +15,10 @@ from apt_ostree.ostree import Ostree
class Remotes:
def __init__(self, state):
self.console = Console()
self.logging = logging.getLogger(__name__)
self.state = state
self.ostree = Ostree(self.state)
self.console = Console()
def remotes(self, refs):
"""Dispaly remotes or refs at remotes."""
@ -35,8 +38,8 @@ class Remotes:
table.add_column("Checksum", justify="center")
url = self.ostree.get_remote_url(self.state.remote)
self.console.print(
f"\nRemote: {self.state.remote} ({url})\n", highlight=False)
self.logging.info(
f"\nRemote: {self.state.remote} ({url})\n")
for remote, csum in refs.items():
table.add_row(remote, csum)

View File

@ -4,23 +4,24 @@ Copyright (c) 2023 Wind River Systems, Inc.
SPDX-License-Identifier: Apache-2.0
"""
import logging
import subprocess
import sys
import textwrap
import click
from rich.console import Console
from rich.table import Table
from apt_ostree.deploy import Deploy
from apt_ostree.log import log_step
from apt_ostree.ostree import Ostree
from apt_ostree import utils
class Repo:
def __init__(self, state):
self.console = Console()
self.logging = logging.getLogger(__name__)
self.state = state
self.repo = self.state.feed
self.deploy = Deploy(self.state)
@ -33,18 +34,18 @@ class Repo:
def init(self):
"""Create a Debian archive from scratch."""
log_step("Creating Debian package archive.")
self.logging.info("Creating Debian package archive.")
self.repo = self.repo.joinpath("conf")
if not self.repo.exists():
log_step("Creating package feed directory.")
self.logging.info("Creating package feed directory.")
self.repo.mkdir(parents=True, exist_ok=True)
config = self.repo.joinpath("distributions")
if config.exists():
log_step("Found existing reprepro configuration.")
self.logging.info("Found existing reprepro configuration.")
sys.exit(1)
else:
log_step("Creating reprepro configuration.")
self.logging.info("Creating reprepro configuration.")
config.write_text(
textwrap.dedent(f"""\
Origin: {self.state.origin}
@ -66,14 +67,14 @@ class Repo:
def add(self):
"""Add Debian package(s) to repository."""
for pkg in self.state.packages:
log_step(f"Adding {pkg}.")
self.logging.info(f"Adding {pkg}.")
r = utils.run_command(
["reprepro", "-b", str(self.repo), "includedeb",
self.state.release, pkg])
if r.returncode == 0:
log_step(f"Successfully added {pkg}\n")
self.logging.info(f"Successfully added {pkg}\n")
else:
log_step(f"Failed to add {pkg}\n")
self.logging.error(f"Failed to add {pkg}\n")
def show(self):
"""Display a table of packages in the archive."""
@ -108,22 +109,22 @@ class Repo:
def remove(self):
"""Remove a Debian package from an archive."""
for pkg in self.state.packages:
log_step(f"Removing {pkg}.")
self.logging.info(f"Removing {pkg}.")
r = utils.run_command(
["reprepro", "-b", str(self.repo), "remove",
self.state.release, pkg],
check=True)
if r.returncode == 0:
log_step(f"Successfully removed {pkg}\n")
self.logging.info(f"Successfully removed {pkg}\n")
else:
log_step(f"Failed to remove {pkg}\n")
self.logging.error(f"Failed to remove {pkg}\n")
def disable_repo(self):
"""Disable Debian feed via apt-add-repository."""
rootfs = self.deploy.get_sysroot()
branch = self.ostree.get_branch()
self.deploy.prestaging(rootfs)
self.console.print(
self.logging.info(
"Disablng Debian package feeds.")
cmd = [
"apt-add-repository",
@ -136,14 +137,14 @@ class Repo:
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
if r.returncode != 0:
click.secho("Failed to disable package feed.", fg="red")
self.logging.error("Failed to disable package feed.")
sys.exit(1)
self.console.print(
self.logging.info(
f"Successfully disabled \"{self.state.sources}\".",
highlight=False)
self.deploy.poststaging(rootfs)
self.console.print(f"Committing to {branch} to repo.")
self.logging.info(f"Committing to {branch} to repo.")
r = self.ostree.ostree_commit(
root=str(rootfs),
branch=branch,
@ -152,7 +153,7 @@ class Repo:
msg=f"Disabled {self.state.sources}",
)
if r.returncode != 0:
click.secho("Failed to commit to repository", fg="red")
self.logging.error("Failed to commit to repository.")
self.deploy.cleanup(str(rootfs))
def add_repo(self):
@ -160,7 +161,7 @@ class Repo:
rootfs = self.deploy.get_sysroot()
branch = self.ostree.get_branch()
self.deploy.prestaging(rootfs)
self.console.print(
self.logging.info(
"Enabling addtional Debian package feeds.")
cmd = [
"apt-add-repository",
@ -173,13 +174,13 @@ class Repo:
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
if r.returncode != 0:
click.secho("Failed to add package feed.", fg="red")
self.logging.error("Failed to add package feed.")
sys.exit(1)
self.console.print(
self.logging.info(
f"Successfully added \"{self.state.sources}\".", highlight=False)
self.deploy.poststaging(rootfs)
self.console.print(f"Committing to {branch} to repo.")
self.logging.info(f"Committing to {branch} to repo.")
r = self.ostree.ostree_commit(
root=str(rootfs),
branch=branch,
@ -188,5 +189,5 @@ class Repo:
msg=f"Enabled {self.state.sources}",
)
if r.returncode != 0:
click.secho("Failed to commit to repository", fg="red")
self.logging.error("Failed to commit to repository")
self.deploy.cleanup(str(rootfs))

View File

@ -1,4 +1,5 @@
python3-apt [platform:dpkg]
python3-systemd [platform:dpkg]
ostree [platform:dpkg]
libostree-dev [platform:dpkg]
gir1.2-glib-2.0 [platform:dpkg]