Currently, the partition form stores the size as a human readable value.
(e.g., 123456K, 1.1G, 1.876G, 100G). When we exit the size field (i.e., upon
losing focus), we convert the value to a number of bytes and then align
it up to the nearest MiB (or whatever the alignment requirement is).
Unfortunately, after computing the aligned value, we turn it back into a
human-readable string and store it as is. It is not okay because the
conversion does not ensure that the alignment requirement is still
honored.
For instance, if the user types in 1.1G, we do the following:
* convert it to a number of bytes -> 1181116006.4 (surprise, it is not
even an integer).
* round it up to the nearest MiB -> 1181745152 (this is the correct
value)
* transform it into a human readable string and store it as is -> 1.1G
- which actually corresponds to the original value.
This leads to an exception later when creating the partition:
File "subiquity/models/filesystem.py", line 1841, in add_partition
raise Exception(
Exception: ('size %s or offset %s not aligned to %s', 1181116006, 1048576, 1048576)
Fixed by storing the actual size as a number of bytes - alongside the
human readable size.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
The existing event based method of watching for has_network has a flaw.
The incoming route_change events from probert do not distinguish routes
on the same interface but a different metric, so if 2 routes on one
interface appear, we only get one event. Then if one of those routes is
removed, we will inappropriately remove this route from the
default_routes list.
Aside from the code watching the event stream, the set of default routes
is an elaborate boolean value.
Simplify the code by passing around a boolean, and when we get a
route_change event, use that to go looking again at the list of default
routes.
LP: #2004659
create_task has the following note:
Important: Save a reference to the result of this function, to avoid a
task disappearing mid-execution.
Convert existing usage of create_task to run_bg_task, if that
create_task is not actually storing the result.
The new ConfirmationOverlay object along with the
BaseView.ask_confirmation helper can be used to open a confirmation
dialog and get back the decision from the user.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
We now have the view display the user-code fetched via u-a-c and
automatically validate the contract token when the contract selection
succeeds.
If the magic token expires (i.e., u-a-c times out), a new contract
selection is initiated.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
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>
The network view code used to crawl all over the network model object,
which isn't really going to work with the upcoming client/server split.
So this adds a much better defined interface between the view and
controller.
* annotate a few missed string literals with _()
* try to consistently use named placeholders when formatting strings
for display (i.e. _("frob the {thing}") not _("frob the {}")
* run selector values, form captions and form help through _() before
display
* use ngettext in one place. not sure if there need to be more...
* reduce cuteness about how strings are constructed in a few places
this required adding TableListRow.set_contents.
it fixes (partly by accident) a crash when a row becomes unselectable
after a refresh (https://bugs.launchpad.net/subiquity/+bug/1874114), it
also makes the home and end keys do something sane.
really this view should not rebuild every row on any change, but that's
something for another day.