When async tasks fail, all exceptions need to be collected to not get
subsequent exceptions about invalid future states. This is achieved by
gathering the task results, instead of just waiting for them. By
gathering the results, also user-requested cancellation (e.g. via
ctrl-c) works without throwing tons of additional exceptions.
Since ac437308 we more likely run into that case, which unvealed the bug.
By properly handling the exception, a TaskResultError is returned
instead of the underlying CommandExecError. This change is reflected in
the corresponding unit test.
Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
This patch replaces all direct invocations of sys.exit outside of the
main invocation to KasUserError based exceptions. By that, only one
method for returning is used and return codes can be handled
consistently. In addition, this makes it possible to handle specific
errors differently.
Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
This patch adds the KasUserError exception class to distinguish between
internal kas exceptions and user or configuration errors. Exceptions
previously raised on user errors are ported over by deriving
KasUserError. In case of user errors, only the exception message is
shown, but no stacktrace. This makes it easier for users to locate the
issue as the reason is now stated in the last line of the output.
Kas internal exceptions are not subject to this change to help the
developers to find the root cause more easily.
Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
The 'kas' function does not return any value, hence we must not use the
return value.
Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
KAS by default will output a lot of information (INFO) messages for
all operations, which makes it difficult to spot warnings thru all
that 'noise'.
Add a command line argument so that the default log level can be
modified.
For backward compatibility, the --debug parameter is still supported
but marked as deprecated in the help message.
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
[Jan: style fixes]
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
To make it easier to display (and modify) the default log level,
especially with the introduction of the new (future commit) argument
--log-level.
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
[Jan: style fix]
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
This allows to define plugins which do not need have any of common args.
Move setup_parser_common_args into libkas for this as it now becomes a
library function.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
When packaging kas for OpenSUSE, rpmlint threw the following warnings:
RPMLINT report:
===============
kas.noarch: W: non-executable-script /usr/lib/python3.6/site-packages/kas/__main__.py 644 /usr/bin/env python3
kas.noarch: W: non-executable-script /usr/lib/python3.6/site-packages/kas/kas.py 644 /usr/bin/env python3
This text file contains a shebang or is located in a path dedicated for
executables, but lacks the executable bits and cannot thus be executed. If
the file is meant to be an executable script, add the executable bits,
otherwise remove the shebang or move the file elsewhere.
2 packages and 0 specfiles checked; 0 errors, 2 warnings.
The Python files inside the kas module don't need shebang lines as they
are not executed directly so we can just remove them.
Signed-off-by: Paul Barker <paul@pbarker.dev>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
As we still support 3.5..3.7, we need to catch the case that
asyncio.get_running_loop and asyncio.all_tasks are not yet available.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
This fixes the missing sub-command entries in the User Guide section of
the docs by allowing the commands and arguments introduced by the
plugins to be seen by sphinx when building the docs.
Signed-off-by: Paul Barker <pbarker@konsulko.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
This change moves all plugin handling code into the kas.plugins module.
New accessor functions `plugins.get(name)` and `plugins.all()` are
provided to wrap the plugins dictionary so that the kas main function
doesn't need to worry about how this is accessed. Plugins are loaded at
runtime rather than at parse time by calling `plugins.load()` which
gives us an improved ability to handle errors.
The `@kasplugin` decorator is removed as it modified and attribute on
the kasplugin function itself when a plugin module was loaded. Importing
a module should not result in changes to a variable in a different
module as it leads to an initialization code flow which is difficult to
reason about. Instead, plugin modules should now list the plugins which
they introduce in a `__KAS_PLUGINS__` list which will be walked at
runtime by `plugins.load()`.
Signed-off-by: Paul Barker <pbarker@konsulko.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
This support for external plugins is undocumented and results in
differences between how internal and external plugins are loaded. It
will shortly be replaced by more integrated support for dynamically
finding and loading plugins.
Signed-off-by: Paul Barker <pbarker@konsulko.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
This change groups the plugin modules together under kas.plugins and
moves the @kasplugin decorator to this submodule. This will ensure the
codebase stays organised as more plugins are added.
Signed-off-by: Paul Barker <pbarker@konsulko.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
By storing plugins in a dictionary indexed by plugin name rather than a
list, we can simplify plugin lookup and remove the undocumented need for
a plugin's run() method to return True when it has matched the given
command.
The command will be rejected by the argument parser if it does not match
one of the plugin names so we do not need to handle failure to lookup
the plugin in the dictionary.
Signed-off-by: Paul Barker <pbarker@konsulko.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
By default we do not update a repository if the desired refspec is
already checked out and so we do not pull any new commits that may have
been added to this refspec upstream. If the new `--update` argument is
passed on the command line then we instead pull in any new upstream
commits.
Signed-off-by: Paul Barker <pbarker@konsulko.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
When checking out a repository the default behaviour is to abort if
local changes are present. If the new `--force-checkout` argument is
passed on the command line then any local changes will instead be
discarded so that the desired refspec can be checked out.
Signed-off-by: Paul Barker <pbarker@konsulko.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
By defining the plugin name and help message as attributes of the plugin
class we can move the argument parser creation up into the
kas_get_argparser() function. This will allow us to further reduce
duplication in following commits.
Signed-off-by: Paul Barker <pbarker@konsulko.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
The return value of kas() is used as the argument to sys.exit() so it
should be 0 to report successful completion.
Signed-off-by: Paul Barker <pbarker@konsulko.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
PEP8:
"""
To better support introspection, modules should explicitly declare the
names in their public API using the __all__ attribute.
"""
flake8 reports
./kas/kas.py:51:1: F401 '.build' imported but unused
./kas/kas.py:52:1: F401 '.shell' imported but unused
Signed-off-by: Daniel Wagner <daniel.wagner@siemens.com>
pylint has been a great tool to get the initial code base into shape
but since then we mostely false postives. All those warnings needed to
be annonated.
This allong wouldn't be reason enough to remove it. The main problem
is that the pylint version on gitlab is updated in the back and
suddenly we get new warnings which are bogus.
Signed-off-by: Daniel Wagner <daniel.wagner@siemens.com>
This seems to be the cleanest and simplest way of properly terminating
kas while one or more sub-processes are running: just ignore the signal.
The sub-processes will get it as well, and they will terminate
themselves properly. kas will get an error then and shut down. Problem
solved.
Forwarding the signal didn't work reliably anyway because we couldn't
count on kas being a process group leader in all cases.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Another, hopefully better attempt: Ignore the TERM signal in the sending
process so that we can properly clean up all the futures before actually
closing. This also avoids a "Terminated" message even on regular kas
endings.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Documentation for the 'build' and 'shell' command line were missing.
Also fixed kas command line documentation mentioning 'ebs-yocto'.
Signed-off-by: Claudius Heine <ch@denx.de>
With Sphinx it is possible to create the command line documentation
automatically if there is a function that returns just the command line
parser.
Currently the creation of the argument parser is rather entangled with
the rest of kas. This patches seperates this.
Signed-off-by: Claudius Heine <ch@denx.de>
This shortens the include from "from .__version__ import __version__"
to "from . import __version__" within the module.
Signed-off-by: Claudius Heine <ch@denx.de>