bsdci / libioc

A Python library to manage jails with ioc{age,ell}
https://bsd.ci/libioc
Other
38 stars 11 forks source link

Config API Proposal #656

Open gronke opened 5 years ago

gronke commented 5 years ago

The JailConfig format was inherited from iocage. Because I was blocked from the entire iocage GitHub organization, it is no longer possible to upstream improvements to the project.

With this in mind, the goal to perform compatible operations on existing jails from python-iocage jails appears to remain unreached. We can use thisas an opportunity, however: ioc diverging from iocage, enables this project to re-think constraints from existing config formats.

The flat configuration design translating jail parameters to iocage JailConfig properties, has a design issue. Not only does it lead to confusion of users between the jail man page and ioc, but also it mixes the concepts of abstraction versus transparent passthrough of properties.

Tight control over jail parameters is essential, as such I am convinced that ioc features which access multiple OS features under the hood, must not belong mixed with resource limits and plain jail params.

The ioc Config Format

The proposed configuration format is structured in topics and does not duplicate information (such as interface names in interface and ip4_addr/ip6_addr). It is meant to model ioc features rather than mocking system tools formats with little quirks.

Although the (autocompleted) configuration via the ioc set command and the Python library remain the recommended way, a well structured YAML file appears to be another good option to apply jail configuration.

Example in YAML

---

name: myjail
release: 12.0-RELEASE

network:
  vnet: yes
  defaultrouter: 172.16.0.1
  #resolver: copy
  interface:
    vnet0:
      secure: yes           # secure vnet
      bridge: bridge0
      ip4_addr:
        - 172.16.0.2/24     # inet
        - 172.16.1.2/24     # alias0
    vnet1:
      bridge: bridge0
      ip4_addr: dhcp
      mtu: 1500

limit:
  vmemoryuse: 1g
  process: 512

storage:
  zfs:
    - zroot/my-shared-dataset
  nullfs:
    - source: /my/shared/path
      write: yes
    - source: /my/shared/home
      destination: /home

devfs_rules:
  - add path 'bpf*' unhide

# custom env for hooks and exec
env:
  PORT: 3000

hooks:
  start: |
    echo "This is an exec_start replacement"
    /bin/sh /etc/rc
    echo "The port is $PORT"

tags:
  - www

provision:
  method: puppet
  source: https://github.com/bsdci/puppet-control-repo

jail:
  # security.jail.* sysctl namespace exposed
  # jail params override automaticly configured values
  # which can be handy when ioc is behind on new OS features
  enforce_statfs: 0
  param:
    children:
      max: 100
    allow:
      mount:
        nullfs: 1
        zfs: 1

user:
  custom_field: "This can by any value!"    

Remarks

With these changes implemented, the project finally diverges from iocage. The compatibility layers built remain in place, but will be only available to migrate existing jails to the ioc config format.

It does not matter too much which output format is used, but YAML for instance does not require termination of values, such as the JSON format does.

Your opinion counts. This is not something I want to decide without exploring the ups and downs. Please feel invited to speak up and share your concerns, needs and ideas.

igalic commented 5 years ago

my first question would be from the point of view of people who want to stick with ioc:

how would this affect them? how would it benefit them?

do you see the YAML config format as an interface one could use to talk to ioc, rather than issuing create, set, and fstab commands?

root@container-host: ~ # ioc create < myjail.yaml
myjail created

something like this could immensely aid automation.

gronke commented 5 years ago

@igalic great idea to seed jails from stdin. Can you please file another issue for that?

how would this affect them? how would it benefit them?

The main change would be that the config parameters would have different names. CLI users can additionally benefit from getting jail configuration as tree rather than key/value pairs (which would still be possible though).

do you see the YAML config format as an interface one could use to talk to ioc, rather than issuing create, set, and fstab commands?

The proposed config format does not replace fstab. That one extra idea you've spotted in the config was to demonstrate how jail configuration can be consolidated into one single resource when using a better structure.

The config file is not meant as configuration interface, although it should be possible to validate on exit of an editor, like done by visudo for instance.

igalic commented 5 years ago

The proposed config format does not replace fstab. That one extra idea you've spotted in the config was to demonstrate how jail configuration can be consolidated into one single resource when using a better structure.

i see, so perhaps an invocation of fstab after create could do the trick then?

root@container-host: ~ # ioc create < myjail.yaml
myjail created
root@container-host: ~ # ioc fstab < myjail.yaml

if we were to do this, btw, our YAML file format would become an API.

gronke commented 5 years ago

I was speaking about actually making the config format YAML 😜 As mentioned, please open an Issue for seeding from STDIN. Whatever can be deserialized can potentially be used. Anyhow, it's different from changing the config structure, which is the main goal in this discussion.

urosgruber commented 5 years ago

I like the idea with YAML as well as option to use it via STDIN. I see also config env. Is this a new feature or can this be applied with todays code as well. I'm kinda hacking around with user config for now to add some config stuff related to pf rules etc.

Regarding iocage project. Should I start migrating now (still have some nodes on iocage) if projects are not going in the same direction anymore? Would this complicate things later when ioc is more production ready.

gronke commented 5 years ago

I like the idea with YAML as well as option to use it via STDIN

Same here! Wonder when @igalic will create that Issue - this can easily be implemented without YAML.

I see also config env. Is this a new feature or can this be applied with todays code as well. I'm kinda hacking around with user config for now to add some config stuff related to pf rules etc.

Jail hooks only receive env variables from libioc, but no env variables passed through from the executing shell. The ability to provide a selected set of env variables is not yet implemented, so that using the user.* config namespace is the best option at the moment.

Regarding iocage project. Should I start migrating now (still have some nodes on iocage) if projects are not going in the same direction anymore?

At the moment the project is built aiming for compatibility. Only if we decide that the iocage standard is no longer a constraint (by deprecating features and re-structuring the config), a migration becomes necessary.

As described in the issue body, it it barely possible to "catch up" with iocage - and the project was not willing to question existing API or to negotiate changes, I see little chances that we will ever be able to without blindly inheriting conceptual issues.

Also we spend a lot of time with QA, which we cannot apply to iocage, so that we simply can't say if iocage works as expected. With that said, I already do no longer recommend to mix ioc and python-iocage (sorry @himrock922, I know that sounded differently last December).

Would this complicate things later when ioc is more production ready.

Migration steps required with an update are always unwanted pain. Our decision should be based on the gain for the projects future, and I prefer to move forward early on if we spot such chances.

igalic commented 5 years ago

from what i gather, where ioc and iocage do not part structurally, a compatibility layer is simply a mapper between their config and ours

but where there are structural differences, we'd need to perform some form upgrade, or else we would be restricted to some form of read-only mode.

himrock922 commented 5 years ago

I like the idea with YAML as well as option to use it via STDIN

Me too. Now I doing development jail hosting system via libioc. If each libioc(ioc) commands can passed an argument like config format YAML or database columns, It is simply think said backend library.

By the way, Doesn't means iocage source code remove all? When source code a lot of changes, Doesn't it problem about OSS license?

gronke commented 5 years ago

When source code a lot of changes, Doesn't it problem about OSS license?

There are no license problems ahead. The former project libiocage began as Pull-Request on python-iocage but was built for compatibility with ioc{age,ell}. On one hand both projects are published under BSD 2-clause license, on the other libioc does not share code with iocage - it is designed from scratch. The latter indicates inherited conceptual constraints can be cropped.

If each libioc(ioc) commands can passed an argument like config format YAML or database columns, It is simply think said backend library.

Interesting idea to replace the CLI command arguments (from Python Click) with a YAML parser. This way no code from libioc needs to be changed. @igalic you're still up to create an Issue for your idea? I'm happy to do it, but you deserve the credit for the idea.