Charles Short dfa239a329 compose: Add compose "create" sub-command
The purpose of the create subcommand is to take a
yaml based configuration and turn it into a rootfs
directory and convert into a ostree deployable branch.
This branch would be able to used create virtual machine
images and even linux containers.

To create an apt-ostree configuration use the sample
from config/debian/bookworm/bootstrap.yaml. You can
create a branch by running the following command:

sudo apt-ostree compose create --repo <path to repo> \
	--base <config directory> \
	<name of ostree branch>

If the ostree repo branch doesnt exist, then apt-ostree
will create the spcified repo in the repo flag.

Sample rootfs configuration include

* debian:
   - bookworm
   - bullseye
* starlingx:
   - master

Testing:
PASSED Installed apt-ostree from git repo.
PASSED Run "apt-ostree compose create --base config/debian/bookworm \
       --repo=/tmp/test debian/bookworm"
PASSED Checked for config in /tmp/test.
PASSED Ran "ostree --repo=/tmp/test refs" to see the "test"
       branch.

Story: 2010867
Task: 48556

Change-Id: I7a311f1b93ea2ac80c7ab24efc9c51d0d990e5e0
Signed-off-by: Charles Short <charles.short@windriver.com>
2023-08-14 11:41:09 -04:00

82 lines
2.0 KiB
Python

"""
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
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}")
@contextlib.contextmanager
def complete_step(text, text2=None):
global LEVEL
log_step(text)
LEVEL += 1
try:
args: list[Any] = []
yield args
finally:
LEVEL -= 1
assert LEVEL >= 0
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)