From b894c925d1c85a8b42e95d3b9cdcb5dbdc25e7a2 Mon Sep 17 00:00:00 2001 From: Aidan Feldman Date: Wed, 3 Jan 2018 02:33:32 -0500 Subject: [PATCH] make user retrieval for Ansible provisioner more robust Previously, the Ansible provisioner would look for the username from the `USER` environment variable. Unfortunately, this is not always set - particularly in Docker containers. It's very confusing to understand why the error is happening. Switched to using Go's built-in `os/user` package for retrieving the current username. @rickard-von-essen had done this in 7369841, but moved away from it in d59844f because, at the time, it wasn't possible to use that library with cross-compilation. This was fixed in Go in https://github.com/golang/go/commit/795e712b72802ad49b7c077964046f79c4f6586e --- provisioner/ansible/provisioner.go | 8 +++++++- provisioner/ansible/provisioner_test.go | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/provisioner/ansible/provisioner.go b/provisioner/ansible/provisioner.go index dfe5aa6d6..18965d220 100644 --- a/provisioner/ansible/provisioner.go +++ b/provisioner/ansible/provisioner.go @@ -15,6 +15,7 @@ import ( "net" "os" "os/exec" + "os/user" "path/filepath" "regexp" "strconv" @@ -141,7 +142,12 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { } if p.config.User == "" { - p.config.User = os.Getenv("USER") + usr, err := user.Current() + if err != nil { + errs = packer.MultiErrorAppend(errs, err) + } else { + p.config.User = usr.Username + } } if p.config.User == "" { errs = packer.MultiErrorAppend(errs, fmt.Errorf("user: could not determine current user from environment.")) diff --git a/provisioner/ansible/provisioner_test.go b/provisioner/ansible/provisioner_test.go index 47f185c9e..c3300bc6b 100644 --- a/provisioner/ansible/provisioner_test.go +++ b/provisioner/ansible/provisioner_test.go @@ -76,6 +76,16 @@ func TestProvisionerPrepare_Defaults(t *testing.T) { if err != nil { t.Fatalf("err: %s", err) } + defer os.Remove(playbook_file.Name()) + + err = os.Unsetenv("USER") + if err != nil { + t.Fatalf("err: %s", err) + } + err = p.Prepare(config) + if err != nil { + t.Fatalf("err: %s", err) + } } func TestProvisionerPrepare_PlaybookFile(t *testing.T) {