-
Notifications
You must be signed in to change notification settings - Fork 471
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
Command optional exec style #871
base: master
Are you sure you want to change the base?
Conversation
- This is wrong way to do it - This is meant to be generated with `genny`
@aelsabbahy I've got this working on Linux for shell and exec style commands. I've made it draft as I'm unsure of a few things. If you have the time I'd appreciate some feedback. Once I have this change in acceptable form, I want to add:
This would expose more of https://pkg.go.dev/os/exec#Cmd to goss Command resource. So far, I've just worked on posix platform. The existing code in system/system.go, and can only pass a single string from resource to system (besides context.Context, *System, and util2.Config). I couldn't work out how to properly using I feel there are a lot of similar types in the files:
and there is code between resource, system, and util, to covert between the similar types. Later when I expand on this work, I'll want to be passing more data, env vars and working directory. Also, in system/system.go it imports util as util2, I don't understand why it needs to alias it, why can't it default to |
I'm looking into the ci/build.sh and test failures with the unmarshal errors. |
Fixed, so passes tests in CI now. For me locally it fails:
But the fix in code looked correct to me, and in CI it passes. So I think it is something to do with my local setup. |
I'm a bit mixed on this UX. I understand it, it makes sense, is very elegant, which makes me love it. However, it does mean that command is a string or an array of strings.. which no other resource does, and it can't be used with The I don't have an easy fix for you to be honest. Is a solution possible if NewCommand took an interface and then type asserted it to a string or []string? I'm on my phone, so didn't dig deep into the code to see if it's viable or not. Assuming we can get the codebase to corporate without any odd foot guns, this does seem to be an extremely elegant solution. |
At the moment I made it take a struct instead of a string: and the code looks at the attributes of the struct. Perhaps an interface and type assertions like you suggest would work too, to make all the code use the same function prototype. Thanks for the feedback and ideas. |
Reflecting on this.. I don't think it's necessary. It's fine if adding by cli only uses shell.. and only way to handle exec is by editing the YAML. Let's try the interface change or any approach that won't require manual edits to resource_list.go as all the code in there is generated and similar across all resource types. |
@aelsabbahy I've implemented the The All goss checks uses only strings, except command which can be either a string or a string slice (for the exec style, the point of this PR). In the I can update the rest of the resources to check if there was an error, rather than ignore it. I think the genny code could be replaced with native Go generics introduced in Go v1.18, and possibly other parts of the code could use generics too. Thus far I think this is the only bit of code using them: Line 114 in e73553f
I think generics would be a better solution because IIUC the type checking would happen at build time, based on type constraints, rather than at runtime. Because the type checking would happen at build time, runtime checks shouldn't be needed, and so checking for returned errors wouldn't be needed either. With the I tested locally that the exec style commands are working. I will be adding unit tests in this PR.
After the implementation is solidified, I'll work on the remaining tasks (Error handling for all resource types (if needed), Unit/Integration Tests, Docs, json and yaml schemas). |
Looked over the code changes. Some questions:
|
Looping back on this, any update? |
Fixes #870
Checklist
make test-linux-all
(UNIX) passes. CI will also test thisDescription of change
This change allows specifying a command to be executed exec style without a shell.
This change is backwards compatible, and existing goss configuration files should continue to work as expected.
This change is needed for operating in environments where a shell doesn't exist, such as testing a distroless docker image.
The syntax is inspired by the Dockerfile
RUN
,ENTRYPOINT
,CMD
instructions that can take either a string (shell style), or a list (exec style). This allows specifying arguments that contain spaces, etc, as the argument list is explicit.Shell syntax (unchanged from before):
This would be wrapped and executed as
sh -c "figlet test"
Exec syntax (this change introduces):
This would be executed directly, without a shell, as
figlet test
, wherefiglet
is arg 0 andtest
is arg 1.The above could use alternative yaml syntax: