The name of the env parameter to ExecContext.run() and .sudo() is not descriptive enough for which environment is supposed to be modified and how, so rename and split it up as follows:
- .run(): env -> mod_env
- .sudo(): env -> mod_env_sudo and mod_env_cmd
The parameters have the following meaning:
- "mod_env*" means that the environment is modified, not replaced
- "mod_env" and "mod_env_cmd" modify the environment "cmd" runs in
- "mod_env_sudo" modifies the environment sudo runs in
Fix the fallout of the API change all over jw-pkg.
The "secrets" class of commands currently only works on the host it's invoked on. Use the current FileContext to allow using the existing commands on a target host.
Don't pass mode as a string to put(). Given the multitunde of possible string representations for numbers, some understood by int(string, 0) and some not, there's too much room for passing strings which are unparseable, or worse, prone to be parsed wrongly.
However, pass mode down to _put() as a string for convenience, because that's what most _put() implementations will need to use. If they don't, converting to int is easy from the one defined string format.
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.
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().
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.
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.
CmdCanonicalizeRemotes / canonicalize-remotes and the respective target in topdir.mk remove the /srv/git portion from all remotes' URLs pointing to git.janware.com.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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.
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
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
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.
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.
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.