Tests that use run_coro are at risk of being broken by the introduction
of another test using IsolatedAsyncioTestCase. Switch over to only use
IsolatedAsyncioTestCase.
Instead of using isinstance(self.widget, SubFormWidget) in
BoundFormField.is_in_error, we now implement a BoundSubFormField
class that inherits from BoundFormField. It is meant to be instantianted
for subforms fields only.
This class overrides is_in_error() to perform the additional checks in
the forms' sub-fields.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
When the validation of a field fails in a form, we disable the Done
button. With child forms, however, it did not work because they have
their own set of hidden buttons ; that are not the ones the users
interacts with.
This patch makes parent forms recurse on the child forms when checking
if any field is in error. Also, when a child form undertakes validation,
it now propagates to the parent, so that the done button can be
immediately enabled/disabled.
Having a validation error in a child form that is not currently enabled
should not prevent the user from moving forward, so we disable recursion
for child forms that are disabled.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
cancel_restart is a mode for SingleInstanceTask that changes the
behavior when starting the task - if the task is already running, do not
cancel it to start another.
We used to rely on the narrow non-breakable space to be displayed as a
star in basic mode. This is not great and could impact other screens.
We now make use of two check-marks (each replaced by a star in basic
mode) and mask one of them in rich mode using display attributes.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
The "**" signs replace the check-mark for a verified publisher when in
basic mode.
These "**" signs where still used green foreground color. This was the
only place where we tried to display colors in basic mode.
Keep the default colors instead. This should be more compatible.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
In addition to verified publishers being indicated by a check-mark, we
now have starred publishers indicated with a circled star.
If unicode support is not available, for instance with serial
connections, we use a different number of stars to represent:
* verified publishers: 2 stars
* starred publishers: 1 star
* others: no star
Because our mechanism to substitute unicode characters with ascii
equivalents expect a 1:1 mapping, we cannot simply replace the circled
start by two stars. To workaround the issue, we added a narrow
non-breakable space.
When support of unicode is available, this character shows up as a
normal space.
When support of unicode is not available, it gets replaced by a star.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
The following commit added an unconditional return statement in the try
block of _move_screen, effectively making the associated else block
unreachable.
a7bcc7fa add a way to wait for something with notification after 0.1s
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
The make_ui() function / coroutine returns a BaseView (i.e., a
screen to display to the user).
That being said, when the application calls, make_ui(), it does not come
with a guarantee that the view returned will be displayed to the user
immediately.
One of the reason is that there are multiple await statements before the
we call the ui.set_body function. Therefore, tasks running concurrently
cannot reliably expect that they execute after the display is refreshed.
Perhaps more importantly, when the make_ui() function takes more than .1
second to execute, we display a "Progress" screen that stays visible for
at least one second. This can effectively delay a lot the moment when
the view returned by make_ui() is shown to the user. A lot can happen in
the meantime.
As the result, the view returned by make_ui can be outdated by the time
we show it on the screen.
One way to work around this problem is to store in the controller a
reference to the view that it returns in make_ui(). This way, the
controller can modify the view and keep it up-to-date until it gets
shown to the user.
Unfortunately, some controllers (e.g., the storage controller) do not
modify / mutate the existing view object when a modification is needed ;
but instead instantiate a new view object.
This patch introduces a level of indirection that can be used by these
controllers. Instead of returning a view object from make_ui(), the
controllers are now allowed to return a callback ; which in turn will
return a view object.
https://bugs.launchpad.net/subiquity/+bug/1968161
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
We used to only accept lists of strings for commands. We now accept
sequences of strings instead ; which are lists of strings or tuple of
strings.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
After calling .communicate() on an asyncio.subprocess.Process object,
the attribute returncode gets set to a non-None value. Type checkers are
not able to figure this out.
Fixed by adding an assert to help type checkers out.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
If you run dryrun for console-conf, go to the network page, go to an
interface, then info, a crash of the form
TypeError: object str can't be used in 'await' expression
can be seen. The signature for the core version of get_info_for_netdev
is not async, but a non-async method returning str.
So mark the core version of the function async.
Co-authored-by: Michael Hudson-Doyle <michael.hudson@canonical.com>
Create open_perms context manager for custom or multiple writes.
Create generate_config for a small removal of redundancy.
0640 root:adm the resulting files.
So that we consistently return the same value from lsb_release() across
all calls that use dry-run, the function now accepts a dry_run argument
(defaulting to False). This way, in dry-run mode, the caller does not
need to supply the path to a specific example file anymore.
lsb_release(dry_run=True) -> will load examples/lsb-release-focal
Having said that, the caller is still left with the possibility to
specify the example file by using the path argument:
lsb_release(path="example/lsb-release-impish")
The path and dry_run arguments are mutually exclusive: providing both
will result in a ValueError.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
Fix warning:
subiquitycore/tests/test_view.py:24
subiquity/subiquitycore/tests/test_view.py:24:
PytestCollectionWarning: cannot collect test class 'TestStretchy'
because it has a __init__ constructor
As reported in https://bugs.launchpad.net/snapd/+bug/1946656,
not-quite idle connections between subiquity and snapd are piling up and
causing issues when trying to restart subiquity. I don't really
understand why, but using a fresh session for each API access makes the
problem go away.