-
Notifications
You must be signed in to change notification settings - Fork 80
Butane merge #631
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Butane merge #631
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request refactors the config translation logic by moving generic functionality into a new config/common package. This is a good improvement for code structure and separation of concerns. I've identified two main areas for improvement: the new schema fields InlineButane and LocalButane are introduced without corresponding implementation for translation or validation, which could lead to confusion and unexpected behavior; and an unexported type translator is used in a public API, which is not idiomatic and could be improved for better API clarity. The rest of the changes look solid.
base/v0_7_exp/schema.go
Outdated
| InlineButane *string `yaml:"inline_butane"` | ||
| LocalButane *string `yaml:"local_butane"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new fields InlineButane and LocalButane are added to the schema, but there doesn't seem to be any corresponding logic to handle them in base/v0_7_exp/translate.go or base/v0_7_exp/validate.go. Specifically:
translateResourceintranslate.godoes not process these new fields.Resource.Validateinvalidate.godoes not include them in the check for mutually exclusive source fields (e.g.,inline,local,source). This could allow users to specify multiple sources, leading to ambiguity.
Is the implementation for these fields planned for a future pull request? If so, it might be better to introduce the schema changes and their implementation in the same PR to avoid having unused fields in the schema.
| // translators take a raw config and translate it to a raw Ignition config. The report returned should include any | ||
| // errors, warnings, etc. and may or may not be fatal. If report is fatal, or other errors are encountered while translating | ||
| // translators should return an error. | ||
| type translator func([]byte, TranslateBytesOptions) ([]byte, report.Report, error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The translator type is used in the exported function RegisterTranslator. While Go allows using unexported types in exported function signatures if they are function types, it's more idiomatic and better for API clarity to export the type. This makes it easier for users of the package to understand and implement the required interface.
Consider renaming translator to Translator to make it public. You will also need to update its usage in this file (e.g., in registry, RegisterTranslator, and getTranslator).
| type translator func([]byte, TranslateBytesOptions) ([]byte, report.Report, error) | |
| type Translator func([]byte, TranslateBytesOptions) ([]byte, report.Report, error) |
cc151df to
12d513e
Compare
7d029aa to
766eaa9
Compare
|
Been experimenting with the feature (alongside gomplate integration) it's really great to be able to split butane. (See my experiments here if you want vic1707/homelab-config#52) But the inheritance of the |
|
Added the possibility to use a new custom |
|
Thank you @vic1707 for submitting this, I wanted to reach out to let you know I am aware and am planing to take a look sometime soon. |
prestist
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay. I want to play around with the changes and get a better understanding but here is my first pass.
Thank you for working on this!
| * **_source_** (string): the URL of the certificate bundle (in PEM format). The bundle can contain multiple concatenated certificates. Supported schemes are `http`, `https`, `tftp`, `s3`, `arn`, `gs`, and [`data`](https://tools.ietf.org/html/rfc2397). When using `http`, it is advisable to use the verification option to ensure the contents haven't been modified. Mutually exclusive with `inline` and `local`. | ||
| * **_inline_** (string): the contents of the certificate bundle (in PEM format). The bundle can contain multiple concatenated certificates. Mutually exclusive with `source` and `local`. | ||
| * **_local_** (string): a local path to the contents of the certificate bundle (in PEM format), relative to the directory specified by the `--files-dir` command-line argument. The bundle can contain multiple concatenated certificates. Mutually exclusive with `source` and `inline`. | ||
| * **_inline_butane_** (string): the contents of the certificate bundle. Mutually exclusive with `source` and `local`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, this feels odd; probably coming from the fact that the new fields are in "resource". (noting for self need to check about this)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I can divide the Resource type?
One for "classic" ressources, another one for merged configs?
| // limitations under the License.) | ||
|
|
||
| package v0_7_exp | ||
| package tests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, what cycle issue were you hitting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue arises because I wanted to use cfg.TranslateBytes() (config/config.go:128).
Importing cfg "github.com/coreos/butane/config" in base/v0_7_exp/translate.go causes the import cycle not allowed error as the config module imports every config translator (ie: config/fcos/v1_7_exp) which internally import their own base schemas (ie: base/v0_7_exp) which causes the cyclic import issue.
I tried my best to fix this but the init function of the config modules beat me 😓.
I found 2 solutions when trying to fix it without changing too much existing code:
- the one you're currently testing/reviewing:
- creating a submodule
translatein theconfigmodule so imports are fine - abusing the fact that every entrypoint in
butaneimports theconfigmodule somewhere (mainly in eachmain.go) to load theinitfunction
- creating a submodule
- (can be seen here alt solution? vic1707/butane#3)
- Using the reflexion system to avoid importing anything (but as I don't know go I don't really know if I did it right, it just works as is 😓)
In both cases I'm not a fan of the solutions I came up with as I'm convinced a more experienced go developer can do better (help, hints appreciated!)
| tr.AddCustomTranslator(translatePasswdUser) | ||
| tr.AddCustomTranslator(translateUnit) | ||
| tr.AddCustomTranslator(TranslateIgnition) | ||
| tr.AddCustomTranslator(TranslateFile) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets keep these lower case, in go uppercase makes the func public.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, but without figuring out a new fix for the circular dependency it has to be exported (the tests from the new tests module import them).
Circular issue explained in another comment
| } | ||
| } | ||
|
|
||
| src, compression, err := baseutil.MakeDataURL(contents, to.Compression, !options.NoResourceAutoCompression) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, if we want to simplify existing code it might be better to do that in a follow up pr to avoid confusion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no prob, once we have an idea of all the things I have to change I'll make 2 distincts PRs 👍
| registry = map[string]translator{} | ||
| ) | ||
|
|
||
| // Fields that must be included in the root struct of every spec version. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, why did you want to make a "translate.go" in common. If you want to effect all targets I think we would put it in https://github.com/coreos/butane/blob/main/base/v0_7_exp/translate.go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is due to the circular imports, I don't want to do that, I had to 😓
As for moving this stuff to base/v0_7_exp/translate.go I'll take a look, this will probably be better 👍
|
Thanks for the review and the time you're giving me, if you are experimenting with the changes you might also want to take a look at vic1707#4 which allows for an overwrite of the |
|
This is a great addition, I hope it won't go stale |
Hope so too, if you're able to test/review/hint me a little on how to improve things I'd greatly appreciate ! |
|
Its entirely on me, I am so sorry about the slow turn around on this; I will make this my priority now @vic1707. |
|
Okay, so I finally got around to testing this locally. It works as described for simple cases and is suuuper cool (1 , 2 layers of merge). Two major points of pain: variant: fcos
version: 1.7.0-experimental
ignition:
config:
merge:
- local_butane: self-reference.buI am not sure how to identify this at runtime, and it would only effect the user running it but there are ongoing talks about being able to run from butane configs which could change our risk scope a bit. Additionally this could happen accidentally to something like I think to prevent this best, we could have a depth limit? maybe 10 bonus points if its configurable (not butane file but argument into butane? The cycle issue:Once we translate reference our self's .. bam cycle.
My thoughts are that we need to add a layer of abstraction to avoid this. This would invert the dependency and should get us around the cycle problem. We should be able to do this with interfaces, i.e no longer directly reference implementation but the interface. This can happen external to this PR and probably should. I can create a PR which can do this but I think we should go this route. New Structure: |
|
Hi, Kinda never thought of recursive calls. good catch! Thanks for the proposed solution to the circular imports issue, I like it way more than my 2 current propositions 👍. If you think someone not that familiar with the project can pull it off I'd like giving it a go, hopefully this weekend (if I can free some time), but if you prefer doing it yourself, please be my guest 😁. No matter what I think tackling the circular import si the first thing that needs to be done here. |
|
Lol when I realized I was like wait a moment.. can i... and yes I could Of course. I have no doubt you could pull it off, if you want to give it a try, open a draft PR, I can help you in your branch if you get stuck. Its a loooot of linking around once the interfaces are added but the most pivotal point will be defining the interfaces to be appropriate for use. So I would recommend that we do it in stages,
100% I agree, the main point of pain is technical debt, and improving the environment for this feature. |
|
I'll give it a try asap, that sounds like a fun exercise 😁 |
Again, got caught off guard by GH defaulting to PRs on the original repo not the forked one
This PR implements one of the idea proposed in #118 (stale for ~1 year), hoping to start discussions again. This, combined with #629 opens up so much possibilities !
The idea I implemented is adding
inline_butaneandlocal_butanedirectives. These are converted toignitionformat when parsed.Note: These use the same
filesDiras the mainbutanefile. This might not be the desired behavior (was discussed in #118) I feel like the current proposed change can accommodate a newfiles-dirrelatively easily. Feel free to share your thoughts!Note2: I'm a. bit unsure about the docs I should write, or how to make fields mutually exclusive
Disclaimer: This is my first time working with Go. I'm learning as I go, so things might not be perfect or fully optimized. Please be kind 🙏
I have 2 versions of the same feature (you can see the second version here: vic1707#3).
Both versions do essentially the same thing but circumvent the
cyclic importproblem I encountered when trying to translate the importedbutanetoignition. I have no opinions on which is better nor do I know if there's a better way 😓.