gopuppet

Unable to set go env -w <ENV> via puppet


When I try to perform

exec { 'set_go_env':
  command => '/snap/bin/go env -w GOPATH=/root/go/pkg'
}

I get the error

'/snap/bin/go env -w GOPATH=/root/go/pkg' returned 1 instead of one of [0]

/Stage[main]/Testmodul/Exec[set_go_env]/returns) change from 'notrun
' to ['0'] failed: '/snap/bin/go env -w GOPATH=/root/go/pkg' returned 1 instead of one of [0] (corrective)

/Stage[main]/Testmodul/Exec[set_go_env]/returns) go: cannot find go 
env config: neither $XDG_CONFIG_HOME nor $HOME are defined

But when I perform the command /snap/bin/go env -w GOPATH=/root/go/pkg via shell on the host per ssh, I won't get any errors.

So, I tried to check via inotifywait which file was being accessed and I checked via auditd which user was accessing that file.

According to inotifywait, for example file /snap/go/10630/go.env was affected.

And below, you can see the auditd log:

time->Fri Jun 14 12:00:16 2024 
type=PROCTITLE msg=audit(1718366416.295:176): 
proctitle=2F736E61702F676F2F31303633302F62696E2F676F00656E76002D770047 
4F504154483D2F726F6F742F676F2F706B67 
type=PATH msg=audit(1718366416.295:176): item=0 name="/snap/go/10630/go.env" inode=43 dev=07:01 mode=0100644 ouid=0 
ogid=0 rdev=00:00 nametype=NORMAL cap_fp=0 cap_fi=0 cap_fe=0 cap_fver=0 cap_frootid=0 
type=CWD msg=audit(1718366416.295:176): cwd="/home/user"
type=SYSCALL msg=audit(1718366416.295:176): arch=c000003e syscall=257 success=yes exit=3 
a0=ffffffffffffff9c a1=c00002c228 a2=80000 a3=0 items=1 ppid=4851 pid=4895 auid=1000 
uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=3 comm="go" 
exe="/snap/go/10630/bin/go" subj=snap.go.go key="env_ac"

So, according to that log, the user root was trying to access that file during the puppet run. But why do I get that error? When I perform that command as root via ssh, everything works.

Edit: Below, there are 2 logs from inotifywait - I did perform the command via puppet and via ssh

puppet:

/var/lib/snapd/inhibit/ OPEN go.lock
/snap/go/10630/meta/ OPEN snap.yaml
/snap/go/10630/meta/ ACCESS snap.yaml
/var/lib/snapd/sequence/ OPEN go.json
/var/lib/snapd/sequence/ ACCESS go.json
/var/lib/snapd/cookie/ OPEN snap.go
/var/lib/snapd/cookie/ ACCESS snap.go
/root/snap/ OPEN,ISDIR go
/root/snap/go/ OPEN,ISDIR 
/root/snap/go/ OPEN,ISDIR 10630
/root/snap/go/10630/ OPEN,ISDIR 
/var/lib/snapd/seccomp/bpf/ OPEN snap.go.go.bin2
/var/lib/snapd/seccomp/bpf/ ACCESS snap.go.go.bin2
/snap/go/10630/meta/ OPEN snap.yaml
/snap/go/10630/meta/ ACCESS snap.yaml
/snap/go/10630/bin/ OPEN go
/snap/go/10630/bin/ ACCESS go
/snap/go/10630/bin/ ACCESS go
/snap/go/10630/ OPEN go.env
/snap/go/10630/ ACCESS go.env

ssh:

/var/lib/snapd/inhibit/ OPEN go.lock
/snap/go/10630/meta/ OPEN snap.yaml
/snap/go/10630/meta/ ACCESS snap.yaml
/var/lib/snapd/sequence/ OPEN go.json
/var/lib/snapd/sequence/ ACCESS go.json
/var/lib/snapd/cookie/ OPEN snap.go
/var/lib/snapd/cookie/ ACCESS snap.go
/root/snap/ OPEN,ISDIR go
/root/snap/go/ OPEN,ISDIR 
/root/snap/go/ OPEN,ISDIR 10630
/root/snap/go/10630/ OPEN,ISDIR 
/var/lib/snapd/seccomp/bpf/ OPEN snap.go.go.bin2
/var/lib/snapd/seccomp/bpf/ ACCESS snap.go.go.bin2
/snap/go/10630/meta/ OPEN snap.yaml
/snap/go/10630/meta/ ACCESS snap.yaml
/snap/go/10630/bin/ OPEN go
/snap/go/10630/bin/ ACCESS go
/snap/go/10630/bin/ ACCESS go
/root/.config/go/ OPEN env
/root/.config/go/ ACCESS env
/snap/go/10630/ OPEN go.env
/snap/go/10630/ ACCESS go.env
/root/.config/go/ OPEN env
/root/.config/go/ ACCESS env
/root/.config/go/ MODIFY env
/root/.config/go/ OPEN env
/root/.config/go/ MODIFY env

Solution

  • The Puppet exec resource executes a command with the posix provider by default on *NIX systems, and therefore the environment variables associated with shell are not retained. This is why it succeeds with shell commands manually, but throws errors related to missing environment variables when applied with Puppet. Also the user environment variables are not automatically inherited, and would therefore need to be explicitly input.

    You would therefore need to modify the resource provider to be shell and input the environment variable:

    exec { 'set_go_env':
      command     => '/snap/bin/go env -w GOPATH=/root/go/pkg',
      provider    => shell,
      environment => ['HOME=/root']
    }
    

    I assume you already know that go env -w persists the go environment in a config file. If the use case is e.g. developer environment setup then no need for further consideration. If this is only for subsequent Puppet resources then one could assign environment => ['GOPATH=/root/go/pkg', 'HOME=/root'] as a default for exec resources related to go, and skip applying this resource altogether.

    The exec resource provider documentation provides additional information.