-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
storage: Anaconda mode #19352
storage: Anaconda mode #19352
Conversation
@jkonecny12, please check this out! (start with the demo) |
3480ea7
to
a1f76ce
Compare
doc/anaconda.md
Outdated
However, Cockpit (via UDisks2) will still write the new mount point | ||
configuration into the real /etc/fstab (_not_ /sysroot/etc/fstab). | ||
|
||
Anaconda will read the real /etc/fstab and reverse engineer the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vojtechtrefny @VladimirSlavik @poncovka I think Blivet has some support for fstab parsing, right ? I just wonder what else could be there in fstab & if we can't get into a situation where we can't tell what we want to forward to the target system & what now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Blivet doesn't have support for parsing fstab yet, but it is planned. But I think it would be better to not write to fstab -- in the "anaconda" mode Cockpit could simply write the mount points to a custom configuration file, all we need in Anaconda is a simple device -> mountpoint "mapping", we don't need the full fstab entry. We could avoid a lot of potential issues by not writing to fstab on the live image (which is not empty by the way).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We (now speaking as a udisks developer) could also add a new option/type to AddConfigurationItem to be able to write to a fstab in a different location than the default /etc/fstab
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We (now speaking as a udisks developer) could also add a new option/type to AddConfigurationItem to be able to write to a fstab in a different location than the default
/etc/fstab
.
I think that would only help if UDisks2 would also watch and read that different location. If modifying the real /etc/fstab is not acceptable, I think I would rather change Cockpit Storage to maintain its own "virtual fstab" (in Browser storage?) and use that instead of the UDisks2 API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could avoid a lot of potential issues by not writing to fstab on the live image (which is not empty by the way).
What issues do you see?
I can't think of any, tbh. Cockpit Storage will of course not corrupt /etc/fstab, if that is one of your concerns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cockpit now stores a mountpoint -> device map for Anaconda.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that would only help if UDisks2 would also watch and read that different location.
I guess we could do that, but that would be something too anaconda-specific and I am not sure if @tbzatek would be happy about it.
What issues do you see?
My main issue is with the existing entries in fstab and potential for Anaconda to mix these up with the "installer" entries created by Cockpit.
I am also not sure how well Cockpit (or UDisks to be more precise) handles btrfs subvolumes in fstab, but that's a different story.
There must be Python code for parsing fstab files
Anaconda has some functions for parsing fstab and we are working on more generic support in blivet (see storaged-project/blivet#1119)
but Anaconda probably also needs to look into udev to find the block device that holds a filesystem with a given UUID.
Blivet has this covered.
Can the "simple device" also be a device mapper device, like "/dev/dm-2"? Can Anaconda figure out from there that this is a LVM2 logical volume, for example?
Yes, we (blivet) can identify a device by name, uuid, all the /dev
symlinks, basically everything.
In [2]: b.devicetree.resolve_device("/dev/dm-2")
Out[2]:
LVMLogicalVolumeDevice instance (0x7f53ec3957d0) --
name = fedora_aida-root status = True id = 78
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that would only help if UDisks2 would also watch and read that different location.
I guess we could do that, but that would be something too anaconda-specific and I am not sure if @tbzatek would be happy about it.
What issues do you see?
My main issue is with the existing entries in fstab and potential for Anaconda to mix these up with the "installer" entries created by Cockpit.
Does Anaconda already look into fstab, or are you referring to Anaconda getting confused during my proposed 'reverse engineering'? If the latter, I think this becomes moot now that Cockpit provides Anaconda with a separate mount-point -> device mapping.
I am also not sure how well Cockpit (or UDisks to be more precise) handles btrfs subvolumes in fstab, but that's a different story.
Once Cockpit supports btrfs, it will handle the subvolumes correctly, see #16408. But currently it is indeed pretty bad at it.
Can the "simple device" also be a device mapper device, like "/dev/dm-2"? Can Anaconda figure out from there that this is a LVM2 logical volume, for example?
Yes, we (blivet) can identify a device by name, uuid, all the
/dev
symlinks, basically everything.
Nice!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that would only help if UDisks2 would also watch and read that different location.
I guess we could do that, but that would be something too anaconda-specific and I am not sure if @tbzatek would be happy about it.
@tbzatek would not be so happy with this I'm afraid.
What issues do you see?
My main issue is with the existing entries in fstab and potential for Anaconda to mix these up with the "installer" entries created by Cockpit.
I have no idea how entries from multiple sources will be visualized (on the D-Bus interface). Besides, the whole RFE seems a little off the UDisks project target.
However, if something like this is about to be needed, we need to think in bigger picture. There are various files that we watch and/or modify. In some cases where these files are consumed by other libraries we pull in - a problem with different prefix in the build time sometimes causes unexpected issues.
Which brings me into another question - should this be considered with (not actually planned yet) mount namespace support? Would this be interesting for your use case?
Feel free to detach this conversation to a separate ticket.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[...] Besides, the whole RFE seems a little off the UDisks project target.
Our idea was that we don't want to change UDisks2 at all, or run it in a special way. All should be done in the top-most UI layers of Cockpit.
I still think this is achievable.
Cockpit would write to /etc/fstab (via the UDisks API) for its own bookkeeping benefits. Nobody else needs to pay any attention to it.
004ffbb
to
7592ccb
Compare
037df3d
to
ce99530
Compare
ce99530
to
714697f
Compare
714697f
to
1608eb9
Compare
1608eb9
to
0928a0c
Compare
0928a0c
to
7a8fcd0
Compare
fc2eaea
to
a1208d9
Compare
e252280
to
f55a870
Compare
c4e15df
to
9c04721
Compare
9c04721
to
45201d0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some remaining tiny nits, but from my POV this is basically ready to go. Then @KKoukiou can start playing around with it from the main-builds COPR.
45201d0
to
f8bec94
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀 as this remains fully malleable for the time being.
Upps, I have found a bug: leaving the "Mount point" field empty results in "/" being used as the mount point. Instead it should keep the meaning of "no mount point specified" and either be an error, or lead to skipping of fstab updates. |
f8bec94
to
b396123
Compare
Changes since last review:
And the bug fix in storage: Only action failures should disable the apply button |
Pixels need to updated. |
5f933e4
to
8eb1cc7
Compare
8eb1cc7
to
cbae721
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i386 unit test has some trouble, retried.
client.anaconda = null; | ||
} | ||
|
||
console.log("ANACONDA", client.anaconda); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, this runs unconditionally... it's better to remove it I guess.
cbae721
to
0a02f8c
Compare
@@ -242,6 +247,10 @@ function format_dialog_internal(client, path, start, size, enable_dos_extended, | |||
if (old_opts == undefined) | |||
old_opts = initial_mount_options(client, block); | |||
|
|||
old_dir = client.strip_mount_point_prefix(old_dir); | |||
if (old_dir === false) | |||
return Promise.reject(_("This device can not be used for the installation target.")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This added line is not executed by any test. Details
} catch { | ||
console.warn("Can't parse cockpit_anaconda configuration as JSON"); | ||
client.anaconda = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These 3 added lines are not executed by any test. Details
|
||
if (dir && mpp) { | ||
if (dir.indexOf(mpp) != 0) | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This added line is not executed by any test. Details
const mpp = client.anaconda?.mount_point_prefix; | ||
if (mpp && dir != "") { | ||
if (dir == "/") | ||
dir = mpp; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This added line is not executed by any test. Details
if (dir == "/") | ||
dir = mpp; | ||
else | ||
dir = mpp + dir; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This added line is not executed by any test. Details
"stratis-pool-member": _("member of Stratis pool"), | ||
mounted: _("Filesystem outside the target"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These 2 added lines are not executed by any test. Details
if (use.usage == "mounted") { | ||
location = client.strip_mount_point_prefix(location); | ||
if (location === false) | ||
location = _("(Not part of target)"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This added line is not executed by any test. Details
if (mount_point) { | ||
mp_text = client.strip_mount_point_prefix(mount_point); | ||
if (mp_text == false) | ||
return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This added line is not executed by any test. Details
@@ -47,6 +47,10 @@ export function mounting_dialog(client, block, mode, forced_options) { | |||
const [old_config, old_dir, old_opts, old_parents] = get_fstab_config(block, true); | |||
const options = old_config ? old_opts : initial_tab_options(client, block, true); | |||
|
|||
const old_dir_for_display = client.strip_mount_point_prefix(old_dir); | |||
if (old_dir_for_display === false) | |||
return Promise.reject(_("This device can not be used for the installation target.")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This added line is not executed by any test. Details
@@ -107,7 +110,7 @@ function create_fs(pool) { | |||
}), | |||
SelectOne("at_boot", _("At boot"), | |||
{ | |||
value: "nofail", | |||
value: client.in_anaconda_mode() ? "local" : "nofail", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This added line is not executed by any test. Details
Anaconda code: https://github.com/mvollmer/anaconda-webui/tree/cockpit-storage
Demo: https://www.youtube.com/watch?v=x3KfKJhBxD0
Next steps after this PR: