mudler / luet

:package: :whale: 0-dependency Container-based Package Manager using SAT solver and QLearning
https://luet.io
GNU General Public License v3.0
254 stars 24 forks source link

Avoid configuration duplication #283

Open msdobrescu opened 2 years ago

msdobrescu commented 2 years ago

Is your feature request related to a problem? Please describe.

I try to share configurations between collections, in order to maintain the common parts in one place.

Describe the solution you'd like

Currently, templating is supported in build.yaml only. Currently, to a collection can be added a collection of anchors to be reused across the collection, like:

Collection A collection.yaml file :

anchors:

- &layers-X
  category: "layers"
  name: "X"
  version: ">=0"

- &buildbase-X
  category: "buildbase"
  name: "X"
  version: ">=0"

packages:

- category: "apps"
  name: "app"
  version: "9999+20"

... (rest of the package definition omitted)  

  requires:
  - <<: *layers-X
  build_requires:
  - <<: *buildbase-X

If another collection needs the same anchors, would need to copy them there and maintain them in both places.

My proposed solution is to support templating for anchors:

/templates/anchors.yaml :

{{ define "anchors" }}

anchors:

- &layers-X
  category: "layers"
  name: "X"
  version: ">=0"

- &buildbase-X
  category: "buildbase"
  name: "X"
  version: ">=0"

{{ end }}

Collection A collection.yaml file :

{{ template "anchors" }}

packages:

- category: "apps"
  name: "app"
  version: "9999+20"

... (rest of the package definition omitted)  

  requires:
  - <<: *layers-X
  build_requires:
  - <<: *buildbase-X

Additionally, common scripts (that are usually referred by build.yaml), is productive to refer from any collection build. They could be in a common place or even in templates directory, but accessible and referred somehow in the build.yaml file. Either way, the structure could look like this (if technically possible):

\- Collection A
\-- build.yaml
\-- collection.yaml
\-- finalize.yaml
\- Collection B
\-- build.yaml
\-- collection.yaml
\-- finalize.yaml
\- templates
\-- build.yaml
\-- finalize.yaml
\-- script.sh

/Collection A/build.yaml could be:

{{ template "collection_build" . }}

... or more complex, according to the needs, using the templates defined in /templates.

By analogy, also /Collection A/finalize.yaml could be:

install:
{{ template "collection_finalize_install" .  }}

while /Collection B/finalize.yaml could be:

install:
{{ template "collection_finalize_install" .  }}
- source /etc/profile && env-update

where /templates/finalize.yaml could be:

{{ define "collection_finalize_install" }}

{{ range .Values.requires | uniq }}
  {{ if or (eq .name "X") (eq .name "gnome-common") (eq .name "gnome") }}
- glib-compile-schemas /usr/share/glib-2.0/schemas > /dev/null 2>&1
  {{ end }}
{{ end }}
- update-mime-database /usr/share/mime/
- ldconfig

{{ end }}

I am aware of the fact that finalizers would be generated and packed rather than run at install time, right?

Another question here is: could be possible to have a finalizer handling to run once a set of commands that each package would have? Currently, at the end of installation, when several packages are handled, their finalizers run each, so it comes to run repeatedly the same batch of commands again and again.

Describe alternatives you've considered

Additional context

This is just a draft, could be extended to regular definition.yaml too.

msdobrescu commented 1 year ago

Being hit by this again.

To summarize, I need a way to refer to common definitions from separate collections, similar to header files from C++, but full definitions to be built. Those are atoms, not possible to make a layer/buildbase.

To me, best way would be to use templates in collections. What do you think?

Next, there is a problem to do the same for the .use, .accept_keywords, .unmask, .license and so on. Those may be generated from defs, I think.