Skip to content
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

snap: support "command: foo $ENV_STRING" #3995

Merged
merged 7 commits into from
Oct 9, 2017

Conversation

mvo5
Copy link
Contributor

@mvo5 mvo5 commented Sep 30, 2017

Tiny branch that will allow to use environment strings in the "command:" part of meta/snap.yaml. Needs some more tests but pushing now to get the benefit of spread tests (here at the airport that is a bit tricky to run locally with the given network).

Copy link
Contributor

@zyga zyga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have a look at my review. It mostly looks good but I have a few ideas for your consideration.

tmpCmdArgv := strings.Split(cmdAndArgs, " ")
cmd := tmpCmdArgv[0]

cmdArgs := make([]string, 0, len(tmpCmdArgv[1:]))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd feel better if this was a separate function that can be tested in isolation.

@@ -0,0 +1,3 @@
#!/bin/sh

echo $1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick, use "$@" instead of $1 as that has special expansion rules and lets us use multiple arguments.

@@ -0,0 +1,6 @@
name: basic-run
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a snap called test-snapd-sh that lets you run sh directly without any fuss. Would it suffice?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, what I need is a env variable inside the command: part of the app. I could add that to another test snap of course if you think this is overkill.

@@ -15,9 +15,6 @@ prepare: |
restore: |
rm basic-hooks_1.0_all.snap

restore: |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch :)

. $TESTSLIB/snaps.sh
install_local basic-run

restore: |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that we don't need to remove those snaps as install_local handles that now.

@@ -15,9 +15,6 @@ prepare: |
restore: |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we don't need to remove those manually as install_local handles that now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm missing something, but I don't see any cleanup code in install_local() in snaps.sh. It would be very desirable though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, sorry. What I meant was that install_local caches the built snap at a separate location and that we don't have to remove the built snap explicitly.

// strings.Split() is ok here because we validate all app fields
// and the whitelist is pretty strict (see
// snap/validate.go:appContentWhitelist)
tmpCmdArgv := strings.Split(cmdAndArgs, " ")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add a comment to https://github.com/snapcore/snapd/blob/master/snap/validate.go#L168 so that if the regexp there ever contains ", ' or ` then we need to adjust shell argument parser used here.

for _, kv := range env {
l := strings.SplitN(kv, "=", 2)
if len(l) == 2 {
if k == l[0] {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use a map to get rid of the quadratic complexity here.

@zyga
Copy link
Contributor

zyga commented Oct 5, 2017

@mvo5 the tests fail on rm of a built snap that is now located in a different directory. I think the right way to approach this is to not remove the snap anymore.

Copy link
Contributor

@zyga zyga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woot, thank you, LGTM

osutil/env.go Outdated
// EnvMap takes a list of "key=value" strings and transforms them into
// a map.
func EnvMap(env []string) map[string]string {
out := make(map[string]string)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you might as well make it of size len(env)

func expandEnvCmdArgs(args []string, env map[string]string) []string {
cmdArgs := make([]string, 0, len(args))
for _, arg := range args {
maybeExpanded := os.Expand(arg, func(k string) string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to look into what defining the function inside the for looks like, compared to defining it outside; a priori it makes me nervous :-)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... benchmarking says they're indistinguishable. Fair 'nuf.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for checking!

@chipaca chipaca merged commit 61ee255 into canonical:master Oct 9, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants