coreos / ignition

First boot installer and configuration tool
https://coreos.github.io/ignition/
Apache License 2.0
835 stars 245 forks source link

Exporting Ignition's `renderConfig` functionality #599

Open abhinavdahiya opened 6 years ago

abhinavdahiya commented 6 years ago

Feature Request

Exporting Ignition's renderConfig functionality so that external agents can resolve Ignition configs same way as Ignition engines does on nodes.

Desired Feature

Ignition uses renderConfig on machines to resolve remote sources for replace and append directives.

Exporting the renderConfig function would allow external agents to render an Ignition config that is complaint with Ignition's behaviour.

Specific Use Case

To manage the configuration for machines in Openshift clusters, there is plan to deploy an Ignition endpoint inside the cluster, that will serve Ignition config to machines. The config served to machines should be static and should have no remote sources.

Rendering the remote sources in the ignition config (that might have been provided by user) ensures that machines joining the cluster at a time in future continue to receive the same configuration even if the contents of the remote location have changed.

/cc: @crawford @yifan-gu

ajeddeloh commented 6 years ago

This probably should be part of the config/shared package. It's made complicated by the fact that Ignition's chaining rules can involve changing things like timeouts and adding CA certs as the rendering process continues. In addition, it uses other Engine bits like the logger.

For this use case, since there are no remote resources, having that functionality isn't a concern, but the logic still needs to be there for Ignition's use. Refactoring that out would be hairy. There is currently the exported config.Append and config.Replace functions, which might be enough for your use case.

abhinavdahiya commented 6 years ago

For this use case, since there are no remote resources, having that functionality isn't a concern

Sorry @ajeddeloh , if I wasn't clear in my description. The user might define an ignition config for a set of machines, which indirects to remote source for its contents. We don't want our internal cluster ignition endpoint to serve this user's config as-is because we cannot ensure uniformity among the set if the contents of the remote url change. Therefore, we want to render the config once (fetching any remote configs if specified) in similar fashion to the Engine and serving that rendered ignition config to the cluster.

This would mean both the Fetcher and renderConfig might have to be exported.

abhinavdahiya commented 6 years ago

Also couldn't find a config.Replace ?

arithx commented 6 years ago

Exporting both Fetcher & renderConfig would be a pretty sizable refactor.

If we do end up needing to go down this path of exposing this functionality I think that the long talked about potential Ignition Stage 0, which fetches & creates the final config, would be the better entrypoint.

Would a binary that you can run an Ignition config through that returns a finalized (fully rendered) config solve your problem?

ajeddeloh commented 6 years ago

Oh, whoops. config.Replace may not exist since it just says "use this other config" and probably wouldn't be useful for your use case?

ajeddeloh commented 6 years ago

Whoops, I misunderstood the original bug. I thought you meant "I have a bunch of configs locally and want to render them into another local config".

"Stage 0" is what you want. We should make it public (i.e. exported and not internal) when we implement it. It's been on the backburner of our minds for a while (with the possibility of moving it to another language that makes the translation process easier (i.e. Rust)).

Rewriting stage 0 is a big task since it handles

Refactoring it out into it's own stage without rewriting is still a decent chunk of work but is doable in the short term.

How urgently is this needed? It'd be nice to not have to implement stage 0 twice if possible. Are you wanting to consume a golang library? Would something with a C interface also work? Would a binary that just writes out a file work?

The absolute fastest way to hack this up would be to fork Ignition and make the disks/files stages no-ops, then just use the Ignition binary to write it out to disk.

crawford commented 6 years ago

How urgently is this needed?

We don't need this for 4.0, but I figured it would be a lot of work, so I wanted to get the ball rolling now.

Are you wanting to consume a golang library? Would something with a C interface also work? Would a binary that just writes out a file work?

Golang would be ideal, but we can always write a wrapper around a shared object or exec another process.

ajeddeloh commented 5 years ago

Dropping this from the spec 3.0.0 milestone after some discussion with other teams. It's not spec related anyway