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:
parent
5c76c2af4c
commit
2d8d3e9a3f
|
@ -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):
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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."""
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -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}")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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]
|
||||
|
|
Loading…
Reference in New Issue