Commit graph

137 commits

Author SHA1 Message Date
b72c417510 cmds.posix.CmdCopy: Support platform macros
Expand platform macros (as in %{codename}) in the src and dst command
arguments. Expansion can be turned off by -F --fixed-strings.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-04-16 13:35:02 +02:00
ef21dc1b1e App.distro_info(): Add method
Add a method distro_info() to App, essentially providing CmdInfo's
macro-expansion of platform information to other interested code.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-04-16 13:25:37 +02:00
888c0495ec lib.base: Add module
Add lib.base to provide basic definitions.

For now, move the definiions of Result, Input and InputMode from
ExecContext into lib.base. Having to import them from the ExecContect
module is too heavy-handed for those simple types.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-04-16 12:57:04 +02:00
e811b2dc14 cmds.posix.CmdCopy: Add module
Add CmdCopy, designed to copy data from the filesystem to another
location in the filesystem. Not necessarily local file systems, the
URLs can be all URLs supported by ExecContext.run().

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-04-16 12:56:43 +02:00
16bb4e5bed cmds.CmdPosix: Add command
Add a new group of commands - "posix". The current command categories
are not a good fit for that: "projects" is for CI, "distro" is
distribution-specific for CD, and secrets is for handling secrets
specifically. Introduce the more general command group "posix", a
class of commands not POSIX compliant in the exposed API, but
primarily using POSIX utilities as workhorse.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-04-16 12:56:22 +02:00
1214451c15 lib.ExecContext.close(): Add method
Add ExecContext.close() as a hook to clean up async resources living
longer than an ExecContext method call.

Also, implement __aenter__() and __aexit__(), to allow using
ExecContext as context manager.  close() is invoked it goes out of
scope.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-04-16 10:21:25 +02:00
04b294917f lib.ExecContext: Support bytes-typed cmd_input
The Input instance passed as cmd_input to ExecContext.run() and
.sudo() currently may be of type str. Allow to pass bytes, too.

At the same time, disallow None to be passed as cmd_input. Force the
caller to be more explicit how it wants input to be handled, notably
with respect to interactivity.

Along the way fix a bug: Content in cmd_input should result in
CallContext.interactive == False but doesn't. Fix that.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-04-16 10:21:25 +02:00
281cdf4ec7 cmds.projects.CmdCanonicalizeRemotes: Add command
CmdCanonicalizeRemotes / canonicalize-remotes and the respective
target in topdir.mk remove the /srv/git portion from all remotes'
URLs pointing to git.janware.com.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-04-13 12:23:02 +02:00
5ad65f85fd cmds.secrets.lib.util: Add module
To be able to use secret handling code from other modules, move the
bulk of it from the "secrets"-command centric implementation in
cmds.secrets.Cmd into a new module cmds.secrets.lib.util.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-04-11 14:56:21 +02:00
98ad7442d9 cmds.projects.CmdListRepos: Beautify error logging
Call run_curl() with parse_json=True to make that explicit, and be a
little more verbose about the outcome.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-04-08 10:49:58 +02:00
5fded01d00 cmds.projects.CmdListRepos: Init SSHClient with app opts
Use the global --verbose and --interactive command-line options as
defaults for constructing a SSHClient instance for use with listing
repos over SSH.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-04-07 15:39:29 +02:00
40511947c9 cmds.projects.BaseCmdPkgRelations: Add --hide-jw-pkg
Support --hide-jw-pkg. This is a step towards replacing
required-os-pkg, which leaves out packages from pkg.requires.jw
sections.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-04-06 16:47:46 +02:00
ad0e03f14c cmds.projects.BaseCmdPkgRelations: Fix cross-sec deps
If a package P is added, only those of its dependendencies are added
along which are in the same os-cascade section as P. That's wrong,
fix it.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-04-06 16:02:34 +02:00
a0dcf59277 cmds.projects.BaseCmdPkgRelations: Better variables
Make variable names a little more readable and searchable within the
long pkg_relations_list() method by making their names longer and
truer to what they actually mean.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-04-06 16:02:34 +02:00
8c34dae526 cmds.projects.CmdPrereq: Remove class
CmdPrereq was mostly redundant to PkgRequired all along. CmdPrereq
has grown more versatile, and CmdPrereq is not used throughout jw-pkg
anylonger by now. Remove it.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-04-06 16:02:34 +02:00
e589cdbdbf cmds and lib: Don't print() log messages
print() should be used to output information requested by a certain
command, but not for logging the process to achieve it. log() should
be used for the latter. The current code has the distinction not down
clearly, fix that.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-30 08:11:39 +02:00
9b6ec109a1 cmds and lib: Don't print() log messages
print() should be used to output information requested by a certain
command, but not for logging the process to achieve it. log() should
be used for the latter. The current code has the distinction not down
clearly, fix that.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-27 09:16:14 +01:00
e461b2815d cmds.projects.BaseCmdPkgRelations: Fix Debian simple deps
Simple dependencies (i.e. non-triplet dependencies, e.g gcc > 15.0)
raise an exception on Debian, fix that.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-25 09:50:28 +00:00
21e67291b5 Fix: Decode run_cmd() result
Since commit 02697af5, ExecContext.run() returns bytes for stdout and
stderr and fixes that in calling code. The thing it did not fix was
the code calling run_cmd(), which also made return bytes. This commit
catches up on that.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-25 07:32:45 +01:00
f37f025b17 lib.SSHClient: Move to lib.ec
SSHClient in an ExecContext, hence it's better off in lib.ec, move it
there and adapt the references.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-20 13:35:11 +01:00
5078c27682 cmds.projects.CmdListRepos.run(): Fix trailing newline
projects list-repos prints a traling newline, remove that.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-20 10:30:25 +01:00
02697af568 lib.ExecContext: Align .sudo() prototype to .run()
ExecContext's .sudo() omits many of run()'s parameters, and this
commit adds them. To avoid redundancy around repeating and massaging
the long parameter list of both functions and their return values, it
also adds some deeper changes:

  - Make run(), _run(), sudo() and _sudo() always return instances of
    Result. Before it was allowed to return a triplet of stdout,
    stderr, and exit status.

  - Have ExecContext stay out of the business of decoding the result
    entirely. Result provides a convenience method .decode()
    operating on stdout and stderr and leaves the decision to the
    caller.

    This entails miniscule adaptations in calling code, namely in
    App.os_release, util.get_profile_env() and CmdListRepos._run().

  - Wrap the _run() and _sudo() callbacks in a context manager object
    of type CallContext to avoid code duplication.

  - Consistently name the first argument to run(), _run(), sudo() and
    _sudo() "cmd", not "args". The latter suggests that the caller is
    omitting the executable, which is not the case.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-20 10:30:25 +01:00
db9bf1826d cmds.projects.CmdListRepos: Use new SSHClient API
Use SSHClient as an ExecContext, i.e. use the .run() method instead
of .run_cmd(). Also, let SSHClient decide which implementation to
use.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-20 10:30:25 +01:00
666f778e05 cmds.distro.CmdInfo: Beautify exception logging
CmdInfo._expand_macros() raises a custom exception during exception
handling. Replace that by logging some details and raising the
original exception to keep the stack trace readable.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-20 10:30:25 +01:00
d0776db01f lib.SSHClient.run_cmd(): Accept cmd: list[str]
Make SSHClient accept a list of strings for the cmd argument to align
with the other run_cmd() functions in jw-pkg.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-17 16:23:34 +01:00
a6bf4b164a cmds/__init__.py: Make class loading dynamic
Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-17 10:44:24 +01:00
8869a2d3df cmds.projects.BaseCmdPkgRelations: Code beautification
pkg_relations_list() has an intricate case distinction around
expand_semver_revision_range, clean that up.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-16 06:05:01 +01:00
5b3118319c cmds.projects.CmdRequiredOsPkg|BaseCmdPkgRelations: Align APIs
In a push to eventually merge the classes, somewhat align the
command-line API of CmdRequiredOsPkg to the one of
BaseCmdPkgRelations by using dependency flavours as mandatory, first
argument.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-15 18:33:51 +01:00
d7e4bd9e33 cmds.projects.BaseCmdPkgRelations: Support --hide-self
To support the pkg-install-testbuild-deps target, a selector is
needed listing all prerequisites to be installed except the project
under test. --hide-self should be useful for that.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-15 18:33:51 +01:00
489652a02f cmds.projects.BaseCmdPkgRelations: Support --skip-excluded
In a push to eventually merge class CmdRequiredOsPkg into this class,
add the --skip-excluded option required by it.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-15 18:33:51 +01:00
f075d3d0cf cmds.projects.BaseCmdPkgRelations: Support --quote
In a push to eventually merge class CmdRequiredOsPkg into this class,
add the --quote option required by it.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-15 18:33:51 +01:00
d643956846 cmds.projects.BaseCmdPkgRelations: Add pkg_relations_list()
Add a function pkg_relations_list(), doing pretty much the same as
pkg_relations(), but taking individual arguments instead of an
argparse.Namespace args argument, in order to provide the
functionality to derived classes.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-15 18:33:51 +01:00
5f81f8d4da cmds.projects.BaseCmdPkgRelations: Add type hints
Add type hints to the class's methods.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-15 16:42:04 +01:00
57f204ccaa cmds.projects.BaseCmdPkgRelations: Remove --no-version
Merge --no-version into the --syntax option as "--syntax names-only"
to remove redundancy.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-15 16:41:59 +01:00
7046983d7c cmds.projects.BaseCmdPkgRelations: --syntax debian
Add support for --syntax to BaseCmdPkgRelations.pkg_relations(), and
default to 'semver', i.e. the current state of affairs. If that's
changed to 'debian', relations declared in project.conf as

  pkg.requires.os.devel = jw-pkg-devel > 1.2.3

will be output as

  jw-pkg-devel >> 1.2.3

which is what Debian expects.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-15 10:43:08 +01:00
509fe1c5e0 cmds.projects.BaseCmdPkgRelations: --expand-semver-revision-range
Add support for --expand-semver-revision-range to
cmds.projects.BaseCmdPkgRelations.pkg_relations(). The options turns
a dependency in projects.conf

  pkg.requires.os.devel = jw-pkg-devel = VERSION

into

  jw-pkg-devel >= 1.2.3, jw-pkg-devel < 1.2.4

Note that this will break as soon as a real range is specified in
projects.conf. To be fixed later, this commit is at least less
breakage than before.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-15 10:42:51 +01:00
2e1115e722 cmds.projects.CmdRequiredOsPkg: Select devel with release
The output of

  jw.pkg.py projects required-os-pkg --flavours release

should include all packages required by flavour devel, because during
the release process, -devel and -run packages are both installed, and
installing the -devel package is only possible if its dependencies
are installed.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-14 12:09:42 +01:00
281e6e2440 cmds.secrets.CompileTemplates: Log missing secrets
Log the number of secrets missing to fully compile all templates.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-09 20:01:26 +01:00
f3c4a51b85 cmds.secrets.CmdCompileTemplates: Support -ogm
Add support for the -o (--owner) -g (--group) -m (--mode) options.
They allow to specify a default for compiling templates, but _don't_
override what's in the #conf: specification line in .jw-tmpl or
.jw-secret files.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-09 19:58:28 +01:00
1ffac7b365 cmds.secrets.CmdXX: Add option --all
Support option --all to jw-pkg.py secrets list-compilation-output and
list-secrets (CmdListCompilationOutput & CmdSecrets). This allows
them to also report non-existent files.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-09 19:58:02 +01:00
699980c32e cmds.secrets.Cmd: Fix errors on Kali 2026.1
Fix errors dug up by testing on Kali Linux 2026.1:

  - Nested class Cmds.Attrs is constructed without scope

  - "replace" falls back to empty list, not empty dictionary

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-09 19:57:56 +01:00
18de6f2cf2 cmds.CmdSecrets: Add command class + subcommands
jw-pkg.py secrets [sub-command] [packages] is a set of utility
commands designed to manage configuration files containing secrets.

To keep secrets from leaking via version control or packages, a
_template_ should be packaged for every sensitive configuration file.
Then, during post-install, configuration files can be generated from
packaged templates via

  jw-pkg.py secrets compile-templates <package> <package> ...

During post-uninstall

  jw-pkg.py secrets rm-compilation-output <package> <package> ...

removes them.

Not specifying any packages will compile or remove all templates on
the system.

To identify which files to consider and generate or remove, the
compilation scans <package> for files ending in .jw-tmpl. For each
match, e.g.

  /path/to/some.conf.jw-tmpl

it will read key-value pairs from

  /path/to/some.conf.jw-secret

and generate

  /path/to/some.conf

from it, replacing all keys by their respective values. The file
attributes of the generated file can be determined by the first line:
of some.conf.jw-tmpl or some.conf.jw-secret:

  # conf: owner=mysql; group=mysql; mode=0640

There are other commands for managing all secrets on the system at
once, see jw-pkg.py secrets --help:

    compile-templates   Compile package template files
    list-compilation-output
                        List package compilation output files
    list-secrets        List package secret files
    list-templates      List package template files
    rm-compilation-output
                        Remove package compilation output files

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-07 21:51:17 +01:00
18c16917b2 App, .cmds.Cmd: Add .distro property
DistroBase's option --id is now redundant to the new global option
--distro-id in the App class, so remove --id. The only added value
DistroBase then brings to the table is its .distro property, which
can be provided by App just fine at this point, given that App has
all it needs to construct a Distro object, so add .distro to App and
remove the entire DistroBase class.

For convenience, also make App.distro available as a newly added
cmds.Cmd.distro property. This also obviates the need for the
distro-related properties in the .distro.Cmd class, remove all that.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-07 14:35:54 +01:00
67a2931f5e App: Support --verbose
Add the --verbose global option, which is made available as the
App.verbose property.

Some functions still take a verbose parameter, but the type of these
parameters is converted from bool to bool|None.  The idea is that, if
they are None, their verbosity falls back to the global default.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-06 19:02:22 +01:00
3e897f4df8 lib.Distro, ExecContext: Add classes, refactor lib.distro
The code below lib.distro, as left behind by the previous commit, is
geared towards being directly used as a command-line API. This commit
introduces the abstract base class Distro, a proxy for
distribution-specific interactions. The proxy abstracts distro
specifics into an API with proper method prototypes, not
argparse.Namespace contents, and can thus be more easily driven by
arbitrary code.

The Distro class is initialized with a member variable of type
ExecContext, another new class introduced by this commit. It is
designed to abstract the communication channel to the distribution
instance.  Currently only one specialization exists, Local, which
interacts with the distribution and root file system it is running
in, but is planned to be subclassed to support interaction via SSH,
serial, chroot, or chains thereof.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-06 14:56:46 +01:00
7e7cee6d11 cmds.distro: Move all modules to lib
Functions abstracting the distribution are not only needed in the
context of the distro subcommand, but also by other code, so make the
bulk of the code abstracting the distribution available in some place
more universally useful than below cmds.distro.

This commit leaves the source files mostly unchanged. They are only
patched to fix import paths, so that functionality is preserved.
Refactoring the code from command-line API to library API will be
done by the next commit.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-06 12:06:28 +01:00
f94a2ac037 cmds.DistroBase: Add class
Move most of CmdDistro into the new class DistroBase, meant to serve
as base class for distro-aware commands other than "distro".

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-06 12:06:28 +01:00
404901bcff cmds.distro.backend.debian.Util: Remove --fix-broken
--fix-broken is added to apt-get options in non-interactive mode, but
seems to work only with apt-get install, not with apt-get update.
Don't add it at all for now.

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-04 16:39:39 +00:00
a25701991d distro.backend.debian.Refresh.run(): Fix apt_get()
Fix call to apt_get(), needs to be a list, not a string.
2026-03-04 16:30:43 +00:00
4eeb12c12e cmds.distro.backend.debian.Util.apt_get(): Fix -yes
Fix a typo in the non-interactive command-line option (--yes) passed
to apt_get().

Signed-off-by: Jan Lindemann <jan@janware.com>
2026-03-04 16:16:20 +00:00