package main

import (
	"encoding/json"
	"fmt"
	"os"
	"strings"
	"syscall"

	"github.com/concourse/docker-image-resource/cmd/print-metadata/passwd"
)

type imageMetadata struct {
	User string   `json:"user,omitempty"`
	Env  []string `json:"env"`
}

var blacklistedEnv = map[string]bool{
	"HOSTNAME": true,
}

func main() {
	username, err := username()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Unable to determine username, will not be included in metadata")
	}

	err = json.NewEncoder(os.Stdout).Encode(imageMetadata{
		User: username,
		Env:  env(),
	})
	if err != nil {
		panic(err)
	}
}

func username() (string, error) {
	users, err := passwd.ReadUsers("/etc/passwd")
	if err != nil {
		return "", err
	}

	name, found := users.NameForID(syscall.Getuid())
	if !found {
		return "", fmt.Errorf("could not find user in /etc/passwd")
	}

	return name, nil
}

func env() []string {
	var envVars []string
	for _, e := range os.Environ() {
		parts := strings.SplitN(e, "=", 2)
		name := parts[0]

		if !blacklistedEnv[name] {
			envVars = append(envVars, e)
		}
	}

	return envVars
}

package main

import (
	"encoding/json"
	"os"
	"strings"
	"syscall"

	"github.com/concourse/docker-image-resource/cmd/print-metadata/passwd"
)

type imageMetadata struct {
	User string   `json:"user"`
	Env  []string `json:"env"`
}

var blacklistedEnv = map[string]bool{
	"HOSTNAME": true,
}

func main() {
	err := json.NewEncoder(os.Stdout).Encode(imageMetadata{
		User: username(),
		Env:  env(),
	})
	if err != nil {
		panic(err)
	}
}

func username() string {
	users, err := passwd.ReadUsers("/etc/passwd")
	if err != nil {
		panic(err)
	}

	name, found := users.NameForID(syscall.Getuid())
	if !found {
		panic("could not find user in /etc/passwd")
	}

	return name
}

func env() []string {
	var envVars []string
	for _, e := range os.Environ() {
		parts := strings.SplitN(e, "=", 2)
		name := parts[0]

		if !blacklistedEnv[name] {
			envVars = append(envVars, e)
		}
	}

	return envVars
}

--- 
+++ 
@@ -2,6 +2,7 @@
 
 import (
 	"encoding/json"
+	"fmt"
 	"os"
 	"strings"
 	"syscall"
@@ -10,7 +11,7 @@
 )
 
 type imageMetadata struct {
-	User string   `json:"user"`
+	User string   `json:"user,omitempty"`
 	Env  []string `json:"env"`
 }
 
@@ -19,8 +20,13 @@
 }
 
 func main() {
-	err := json.NewEncoder(os.Stdout).Encode(imageMetadata{
-		User: username(),
+	username, err := username()
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "Unable to determine username, will not be included in metadata")
+	}
+
+	err = json.NewEncoder(os.Stdout).Encode(imageMetadata{
+		User: username,
 		Env:  env(),
 	})
 	if err != nil {
@@ -28,18 +34,18 @@
 	}
 }
 
-func username() string {
+func username() (string, error) {
 	users, err := passwd.ReadUsers("/etc/passwd")
 	if err != nil {
-		panic(err)
+		return "", err
 	}
 
 	name, found := users.NameForID(syscall.Getuid())
 	if !found {
-		panic("could not find user in /etc/passwd")
+		return "", fmt.Errorf("could not find user in /etc/passwd")
 	}
 
-	return name
+	return name, nil
 }
 
 func env() []string {
Handle when /etc/passwd is missing because the image is built using scratch or another base layer that does not provide that file.
