blue-build / modules

BlueBuild standard modules used for building your Atomic Images
Apache License 2.0
23 stars 25 forks source link

module idea: homefiles #118

Open xynydev opened 5 months ago

xynydev commented 5 months ago

Sets up a systemd service unit to copy select files to the users home directory.

fiftydinar commented 5 months ago

Sets up a systemd service unit to copy select files to the users home directory.

Using /usr/etc/skel performs this functionality without using systemd.

But it copies files when user is created only, which means no updates to that content after that.

So yeah, systemd approach is needed for this.

xynydev commented 5 months ago

Looks like you answered your own critcism...

fiftydinar commented 5 months ago

One hard task I found with this type of module is to detect which files/folders need to be deleted in the home directory in case user decided that he doesn't want that file/folder anymore in the module.

By just copying functionality, module can potentially leave a mess in user's home directory over time.

It's maybe simple to implement this by deleting every differed file/folder in home compared to module every boot.

But what about some crucial files like .bashrc?

This makes this module hard to implement reliably as a systemd service.

Using skel to implement home changes is a reliable method, with disadvantage that it lacks auto-update functionality.

xynydev commented 5 months ago

Hmm... I guess there could be two options, ovewrite: true would always remove the users configuration while being warned as destructive, while overwrite: false would only copy if destination doesn't exist. I agree that skel is more reliable, but there was already one user looking to implement this type of functionality by themselves, so there is at least some demand...

gerblesh commented 4 months ago

I've had to implement the functionality manually in my custom sway and hyprland image for a couple of config files. Would be great to see this standardized though

fiftydinar commented 1 month ago

I started some work here: https://github.com/fiftydinar/gidro-os/pull/21

xynydev commented 1 month ago

That UX seems a tad bit more complicated than I initially thought this'd be?

I was thinking more like:

type: homefiles
files:
    # split source/dest as per #203
    - source: dots/
      destination: ~/.config
      duplicate-file-policy: skip
    - source: gtkconfig/ # this should probably be done with /usr/share/gtk-4.0/, but it's the best example I could come up with
      destination: ~/.config/gtk-4.0
      duplicate-file-policy: replace

All the source files from config/homefiles/ or eventually files/ would then be copied into /usr/share/bluebuild/homefiles/ with all the metadata needed as you're already doing with config.yml and set up the systemd units, etc., but that's all transparent to the user.

If someone wants to write only to /etc/skel/, they can just do it with the files module IMO. With the files/ restructuring it should also be possible to copy the same files to the home using homefiles and to /etc/skel/ with files.

fiftydinar commented 1 month ago

That UX seems a tad bit more complicated than I initially thought this'd be?

I was thinking more like:

type: homefiles
files:
    # split source/dest as per #203
    - source: dots/
      destination: ~/.config
      duplicate-file-policy: skip
    - source: gtkconfig/ # this should probably be done with /usr/share/gtk-4.0/, but it's the best example I could come up with
      destination: ~/.config/gtk-4.0
      duplicate-file-policy: replace

Well I thought that source & destination should be automatic, which I intend to be from /config/homefiles/ (in future /files/homefiles). So it would mimic the $HOME/ file structure that user would want.

I assumed that users can just write type: homefiles in the recipe file, while editing the configuration would be only necessary for some exceptions, which I tried to convey into config.

There can be some improvements still, that's for sure.

All the source files from config/homefiles/ or eventually files/ would then be copied into /usr/share/bluebuild/homefiles/ with all the metadata needed as you're already doing with config.yml and set up the systemd units, etc., but that's all transparent to the user.

That's clear.

If someone wants to write only to /etc/skel/, they can just do it with the files module IMO. With the files/ restructuring it should also be possible to copy the same files to the home using homefiles and to /etc/skel/ with files.

EDIT: I misunderstood this sentence.

It is true that writing only to /etc/skel is possible from files module, but this is also true for systemd module, where users can include service files in /usr/lib/systemd/. However, merging this related functionality into homefiles makes this separation clearer imo.

Config file can possibly be a bit better structured & documented to make it clearer to the users, so that's where I'll try to work on.

xynydev commented 1 month ago

Well I thought that source & destination should be automatic, which I intend to be from /config/homefiles/ (in future /files/homefiles). So it would mimic the $HOME/ file structure that user would want.

Sure, in my example one could configure it like that:

type: homefiles
files:
    - source: homefiles/
      destination: ~/
      duplicate-file-policy: skip

I just kind of thought that working with the entire home directory could be brittle, when it'd usually just be one folder or file that should be copied, with different files/folders following different policies. If the entire directory is worked with at once, it needs those -exception options, which I find more clumsy.

fiftydinar commented 1 month ago

Sure, in my example one could configure it like that:

type: homefiles
files:
    - source: homefiles/
      destination: ~/
      duplicate-file-policy: skip

I just kind of thought that working with the entire home directory could be brittle, when it'd usually just be one folder or file that should be copied, with different files/folders following different policies. If the entire directory is worked with at once, it needs those -exception options, which I find more clumsy.

You're right. With this illustrated example, I see things better.

I will adopt this recipe format & adjust the script according to that.

fiftydinar commented 1 month ago

I changed duplicate-file-policy naming to changed-file-policy. I think it's more accurate.

Although, I'm thinking on how to handle the scenario where file in subdirectory is the only one which you want to have replace policy instead of skip or vice-versa. To avoid needlessly editing the module recipe.

Here's the real example in my repo on what I want to achieve:

I want this file to have replace policy in io.gitlab.librewolf-community subfolder:

~/.var/app/io.gitlab.librewolf-community/.librewolf/librewolf.overrides.cfg

But I want those 4 files to have skip policy:

~/.var/app/com.github.neithern.g4music/config/glib-2.0/settings/keyfile ~/.var/app/com.github.rafostar.Clapper/config/glib-2.0/settings/keyfile ~/.var/app/org.gnome.Calculator/config/glib-2.0/settings/keyfile ~/.var/app/org.gnome.TextEditor/config/glib-2.0/settings/keyfile

This one would result in conflict & it looks complicated:

type: homefiles
files:
    - source: homefiles/.var/app/
      destination: ~/.var/app/
      changed-file-policy: skip
    - source: homefiles/.var/app/io.gitlab.librewolf-community/.librewolf/
      destination: ~/.var/app/io.gitlab.librewolf-community/.librewolf/
      changed-file-policy: replace

I separated 2 folders in order to solve this long-term:

type: homefiles
files:
    - source: homefiles/changed-files-skip/
      destination: ~/
      changed-file-policy: skip
    - source: homefiles/changed-files-replace/
      destination: ~/
      changed-file-policy: replace

But I'm not sure if we should encourage users to separate folders based on changed-file-policy or not. Maybe there's a better way to solve this.

xynydev commented 1 month ago

I changed duplicate-file-policy naming to changed-file-policy. I think it's more accurate.

I disagree, as if a custom image updates to add a homefile, that is previously created by a user of the image, the file isn't "changed", it's more like "overlapping". Maybe one of existing-file-policy, file-overwrite-policy, file-replace-policy, or conflict-policy would be better?

This one would result in conflict & it looks complicated: ...

In my opinion that looks fine and is what I had in mind. What sort of conflict would it result in and would it be possible to circumvent that? I would maybe make the source a different directory, though, and not a subdirectory of the other one, but I'd guess that this would work too.

I separated 2 folders in order to solve this long-term: ... But I'm not sure if we should encourage users to separate folders based on changed-file-policy or not. Maybe there's a better way to solve this.

I would not recommend this. It doesn't seem like something that should be set using the directory tree. But I guess it's cool that it's possibly if someone wants it.

fiftydinar commented 1 month ago

existing-file-policy, file-overwrite-policy, file-replace-policy, or conflict-policy would be better?

I like existing-file-policy. file-conflict-policy also sounds good, but I maybe prefer the 1st one a bit more.

In my opinion that looks fine and is what I had in mind. What sort of conflict would it result in and would it be possible to circumvent that? I would maybe make the source a different directory, though, and not a subdirectory of the other one, but I'd guess that this would work too.

I'll try to figure out something.

fiftydinar commented 1 month ago

We might be able to utilize tmpfiles.d for something here.

https://www.freedesktop.org/software/systemd/man/latest/tmpfiles.d.html

fiftydinar commented 1 month ago

One thing where I'm stuck & confused with the current config is how files inside source directory should be copied:

mydots/ (copies mydots directory & all files inside it)

or

mydots/* (copies only mydots config file content)

Maybe some additional YAML key can be added to specify this behavior, since getting the /* expansion is not possible, as it's treated as a string.

YAML key can be named something like:

inside-source-copy (bad name, but something like this)

Edit: I have an idea on how to solve this (by just checking if source has ending /* in input & then proceed accordingly)

xynydev commented 1 month ago

If you want to make use of globs, I think at least Nushell just has a glob-expansion command. I don’t know why it would be required here, though.

fiftydinar commented 1 month ago

If you want to make use of globs, I think at least Nushell just has a glob-expansion command. I don’t know why it would be required here, though.

Because in your example with custom directories, homefiles/ folder would be copied to $HOME too, which is not desired.

star-glob would be required to prevent that scenario & to only copy everything inside homefiles/, so in recipe file it's defined as homefiles/*.

type: homefiles
files:
    - source: homefiles/
      destination: ~/
      duplicate-file-policy: skip

Basically:

homefiles is file homefiles/ is a directory homefiles/* is everything inside that directory