Ignition should fail validation if a file conflicts with the parent directory of another file/link/dir
marmijo opened this issue · comments
Bug
Operating System Version
Any
Ignition Version
All
Environment
All
Expected Behavior
Ignition should not allow internally inconsistent configs
Actual Behavior
Users can specify a file that would conflict with the parent directory of another file/link/dir. Ignition should fail validation if files/links/dirs conflict with implicit parent directories.
Reproduction Steps
1 - Write a config with a file at /foo/bar
and a file /foo/bar/baz
OR
1 - Write a config with a file at /foo/bar
and a directory at /foo/bar/baz
OR
1 - Write a config with a file at /foo/bar
and a link at /foo/bar/baz
Other Information
On top of general validation for this issue, the validation added by Ignition PR#1456 may need to be updated to include the fix as well.
Hey @marmijo, could you please provide more context about this?
I'm trying to understand the reproduction steps more clearly.
Do I need to write a configuration using Butane and then check the resulting Ignition file?
Thank you! 😸
Hi Yasmin. Yes, you could use butane to create the ignition config. To reproduce, you'll need the resulting ignition config that has the file/link/dir conflicts specified like the ones above and run it through ignition validation. It currently doesn't fail validation but it should. It should be noted that butane isn't needed to write an ignition config, so ignition validation code is needed here.
Basically, it's possible to create an ignition config with two files that conflict with one another in such a way that one file would be an implicit parent directory of the other e.g. /var/home/core/log
(as a file) and /var/home/core/log/output.txt
(which now declares log
as a directory).
Note: when we add this verification, we need to try and not reduce functionality.
Its completely reasonable to have a file /home/bar/zed and a dir home/bar/zed/
with a file in it at /home/bar/zed/zed
AFAIK, Linux disallows dirs/files/links/pipes with the same name in the same directory. It shouldn't be possible to create /home/bar/zed/zed
if /home/bar/zed
already exists as a file/link.
The same is true for creating a file/link at /home/bar/zed
when /home/bar/zed/zed
already exists.
@marmijo Wdyt about simply validating that files end with an extension ?
I think it solves thie issue more directly. and more cleanly. Checking for collisions feels clumsy.
@prestist That doesn't really fix it. It's perfectly valid for directories to have "extensions" and files not to.
I don't think it'd be too hard to validate this. See e.g. getOrderedCreationList()
which already knows how to sort paths from most shallow to deepest. So you can sort all entries, then go down the list from the top. For each entry, check if its path is within the path of the previous entry. If so, verify that the previous entry is a directory. If not, fail.
Obviously, this validation can't catch symlinks that only exist on the host (e.g. if /foo/bar
is a symlink to /foo/baz
and the user wants a file at /foo/baz
and a file at /foo/bar/baz
). Those will just fail at runtime like today.
@jlebon ah, okay that was a wiff on my part, I assumed that directorys would not have extensions, what purpose does that serve for (my own knowledge) ?
Thats great, thank you for the pointer to getOrderedCreationList
. @yasminvalim and my self were going through some of her tests, and I started stumbling a bit on the tests, because I was thinking that it could be possible that the directory is externally derived, however if we are using the config as truth, then with the example 1 - Write a config with a file at /foo/bar and a directory at /foo/bar/baz
if we instead had
1 - Write a config with a file at /foo/bar and a directory at /foo/bar/baz and a directory at /foo/bar
would be valid right?
otherwise we assume user error?
@jlebon ah, okay that was a wiff on my part, I assumed that directorys would not have extensions, what purpose does that serve for (my own knowledge) ?
The base name is mostly an arbitrary string. Indeed, by convention files tend to have extensions and directories tend not to. An common example of directories with an extension are the systemd dropin dirs (i.e. <service>.d
or <target>.wants
). You can run something like find / -name '*.*' -type d
on your system if you want to find more examples.
if we are using the config as truth, then with the example
1 - Write a config with a file at /foo/bar and a directory at /foo/bar/baz
if we instead had1 - Write a config with a file at /foo/bar and a directory at /foo/bar/baz and a directory at /foo/bar
would be valid right?
That would give duplicate entries which should already fail validation today.