Index: head/sysutils/docker/Makefile =================================================================== --- head/sysutils/docker/Makefile (revision 466367) +++ head/sysutils/docker/Makefile (revision 466368) @@ -1,28 +1,32 @@ # Created by: Nikolai Lifanov # $FreeBSD$ PORTNAME= docker -PORTVERSION= 17.12.0 +PORTVERSION= 18.03.0 DISTVERSIONPREFIX= v DISTVERSIONSUFFIX= -ce CATEGORIES= sysutils MAINTAINER= lifanov@FreeBSD.org COMMENT= Open-source application container engine LICENSE= APACHE20 PLIST_FILES= bin/docker USE_GITHUB= yes GH_PROJECT= docker-ce USES= go GO_PKGNAME= github.com/${PORTNAME} GO_TARGET= ${GO_PKGNAME}/cli/cmd/docker pre-build: @${MV} ${GO_WRKSRC}/components/* ${GO_WRKSRC}/ + @${CP} ${FILESDIR}/default_store_freebsd.go \ + ${GO_WRKSRC}/cli/cli/config/credentials/ + @${CP} ${FILESDIR}/pass_freebsd.go \ + ${GO_WRKSRC}/cli/vendor/github.com/docker/docker-credential-helpers/pass/ .include Index: head/sysutils/docker/distinfo =================================================================== --- head/sysutils/docker/distinfo (revision 466367) +++ head/sysutils/docker/distinfo (revision 466368) @@ -1,3 +1,3 @@ -TIMESTAMP = 1515075041 -SHA256 (docker-docker-ce-v17.12.0-ce_GH0.tar.gz) = 1303483c878ded1c0e19f323f04316cef6d4c0c895f85c412af6468647d18ef9 -SIZE (docker-docker-ce-v17.12.0-ce_GH0.tar.gz) = 11008332 +TIMESTAMP = 1522780844 +SHA256 (docker-docker-ce-v18.03.0-ce_GH0.tar.gz) = 07651973b4a4adac86599b5c1abc9b1c82aa143ac18205ff399afa814d403280 +SIZE (docker-docker-ce-v18.03.0-ce_GH0.tar.gz) = 12751925 Index: head/sysutils/docker/files/patch-components_cli_vendor_github.com_docker_docker-credential-helpers_pass_pass__freebsd.go =================================================================== --- head/sysutils/docker/files/patch-components_cli_vendor_github.com_docker_docker-credential-helpers_pass_pass__freebsd.go (revision 466367) +++ head/sysutils/docker/files/patch-components_cli_vendor_github.com_docker_docker-credential-helpers_pass_pass__freebsd.go (nonexistent) @@ -1,211 +0,0 @@ ---- components/cli/vendor/github.com/docker/docker-credential-helpers/pass/pass_freebsd.go.orig 2018-01-03 19:51:59 UTC -+++ components/cli/vendor/github.com/docker/docker-credential-helpers/pass/pass_freebsd.go -@@ -0,0 +1,208 @@ -+// A `pass` based credential helper. Passwords are stored as arguments to pass -+// of the form: "$PASS_FOLDER/base64-url(serverURL)/username". We base64-url -+// encode the serverURL, because under the hood pass uses files and folders, so -+// /s will get translated into additional folders. -+package pass -+ -+import ( -+ "encoding/base64" -+ "errors" -+ "fmt" -+ "io/ioutil" -+ "os" -+ "os/exec" -+ "path" -+ "strings" -+ -+ "github.com/docker/docker-credential-helpers/credentials" -+) -+ -+const PASS_FOLDER = "docker-credential-helpers" -+ -+var ( -+ PassInitialized bool -+) -+ -+func init() { -+ PassInitialized = exec.Command("pass").Run() == nil -+} -+ -+func runPass(stdinContent string, args ...string) (string, error) { -+ cmd := exec.Command("pass", args...) -+ -+ stdin, err := cmd.StdinPipe() -+ if err != nil { -+ return "", err -+ } -+ defer stdin.Close() -+ -+ stderr, err := cmd.StderrPipe() -+ if err != nil { -+ return "", err -+ } -+ defer stderr.Close() -+ -+ stdout, err := cmd.StdoutPipe() -+ if err != nil { -+ return "", err -+ } -+ defer stdout.Close() -+ -+ err = cmd.Start() -+ if err != nil { -+ return "", err -+ } -+ -+ _, err = stdin.Write([]byte(stdinContent)) -+ if err != nil { -+ return "", err -+ } -+ stdin.Close() -+ -+ errContent, err := ioutil.ReadAll(stderr) -+ if err != nil { -+ return "", fmt.Errorf("error reading stderr: %s", err) -+ } -+ -+ result, err := ioutil.ReadAll(stdout) -+ if err != nil { -+ return "", fmt.Errorf("Error reading stdout: %s", err) -+ } -+ -+ cmdErr := cmd.Wait() -+ if cmdErr != nil { -+ return "", fmt.Errorf("%s: %s", cmdErr, errContent) -+ } -+ -+ return string(result), nil -+} -+ -+// Pass handles secrets using Linux secret-service as a store. -+type Pass struct{} -+ -+// Add adds new credentials to the keychain. -+func (h Pass) Add(creds *credentials.Credentials) error { -+ if !PassInitialized { -+ return errors.New("pass store is uninitialized") -+ } -+ -+ if creds == nil { -+ return errors.New("missing credentials") -+ } -+ -+ encoded := base64.URLEncoding.EncodeToString([]byte(creds.ServerURL)) -+ -+ _, err := runPass(creds.Secret, "insert", "-f", "-m", path.Join(PASS_FOLDER, encoded, creds.Username)) -+ return err -+} -+ -+// Delete removes credentials from the store. -+func (h Pass) Delete(serverURL string) error { -+ if !PassInitialized { -+ return errors.New("pass store is uninitialized") -+ } -+ -+ if serverURL == "" { -+ return errors.New("missing server url") -+ } -+ -+ encoded := base64.URLEncoding.EncodeToString([]byte(serverURL)) -+ _, err := runPass("", "rm", "-rf", path.Join(PASS_FOLDER, encoded)) -+ return err -+} -+ -+// listPassDir lists all the contents of a directory in the password store. -+// Pass uses fancy unicode to emit stuff to stdout, so rather than try -+// and parse this, let's just look at the directory structure instead. -+func listPassDir(args ...string) ([]os.FileInfo, error) { -+ passDir := os.ExpandEnv("$HOME/.password-store") -+ for _, e := range os.Environ() { -+ parts := strings.SplitN(e, "=", 2) -+ if len(parts) < 2 { -+ continue -+ } -+ -+ if parts[0] != "PASSWORD_STORE_DIR" { -+ continue -+ } -+ -+ passDir = parts[1] -+ break -+ } -+ -+ p := path.Join(append([]string{passDir, PASS_FOLDER}, args...)...) -+ contents, err := ioutil.ReadDir(p) -+ if err != nil { -+ if os.IsNotExist(err) { -+ return []os.FileInfo{}, nil -+ } -+ -+ return nil, err -+ } -+ -+ return contents, nil -+} -+ -+// Get returns the username and secret to use for a given registry server URL. -+func (h Pass) Get(serverURL string) (string, string, error) { -+ if !PassInitialized { -+ return "", "", errors.New("pass store is uninitialized") -+ } -+ -+ if serverURL == "" { -+ return "", "", errors.New("missing server url") -+ } -+ -+ encoded := base64.URLEncoding.EncodeToString([]byte(serverURL)) -+ -+ usernames, err := listPassDir(encoded) -+ if err != nil { -+ return "", "", err -+ } -+ -+ if len(usernames) < 1 { -+ return "", "", fmt.Errorf("no usernames for %s", serverURL) -+ } -+ -+ actual := strings.TrimSuffix(usernames[0].Name(), ".gpg") -+ secret, err := runPass("", "show", path.Join(PASS_FOLDER, encoded, actual)) -+ return actual, secret, err -+} -+ -+// List returns the stored URLs and corresponding usernames for a given credentials label -+func (h Pass) List() (map[string]string, error) { -+ if !PassInitialized { -+ return nil, errors.New("pass store is uninitialized") -+ } -+ -+ servers, err := listPassDir() -+ if err != nil { -+ return nil, err -+ } -+ -+ resp := map[string]string{} -+ -+ for _, server := range servers { -+ if !server.IsDir() { -+ continue -+ } -+ -+ serverURL, err := base64.URLEncoding.DecodeString(server.Name()) -+ if err != nil { -+ return nil, err -+ } -+ -+ usernames, err := listPassDir(server.Name()) -+ if err != nil { -+ return nil, err -+ } -+ -+ if len(usernames) < 1 { -+ return nil, fmt.Errorf("no usernames for %s", serverURL) -+ } -+ -+ resp[string(serverURL)] = strings.TrimSuffix(usernames[0].Name(), ".gpg") -+ } -+ -+ return resp, nil -+} Property changes on: head/sysutils/docker/files/patch-components_cli_vendor_github.com_docker_docker-credential-helpers_pass_pass__freebsd.go ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sysutils/docker/files/patch-components_cli_cli_config_credentials_default__store__freebsd.go =================================================================== --- head/sysutils/docker/files/patch-components_cli_cli_config_credentials_default__store__freebsd.go (revision 466367) +++ head/sysutils/docker/files/patch-components_cli_cli_config_credentials_default__store__freebsd.go (nonexistent) @@ -1,16 +0,0 @@ ---- components/cli/cli/config/credentials/default_store_freebsd.go.orig 2018-01-03 19:51:59 UTC -+++ components/cli/cli/config/credentials/default_store_freebsd.go -@@ -0,0 +1,13 @@ -+package credentials -+ -+import ( -+ "github.com/docker/docker-credential-helpers/pass" -+) -+ -+func defaultCredentialsStore() string { -+ if pass.PassInitialized { -+ return "pass" -+ } -+ -+ return "secretservice" -+} Property changes on: head/sysutils/docker/files/patch-components_cli_cli_config_credentials_default__store__freebsd.go ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sysutils/docker/files/default_store_freebsd.go =================================================================== --- head/sysutils/docker/files/default_store_freebsd.go (nonexistent) +++ head/sysutils/docker/files/default_store_freebsd.go (revision 466368) @@ -0,0 +1,13 @@ +package credentials + +import ( + "github.com/docker/docker-credential-helpers/pass" +) + +func defaultCredentialsStore() string { + if pass.PassInitialized { + return "pass" + } + + return "secretservice" +} Property changes on: head/sysutils/docker/files/default_store_freebsd.go ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sysutils/docker/files/pass_freebsd.go =================================================================== --- head/sysutils/docker/files/pass_freebsd.go (nonexistent) +++ head/sysutils/docker/files/pass_freebsd.go (revision 466368) @@ -0,0 +1,204 @@ +package pass + +import ( + "encoding/base64" + "errors" + "fmt" + "io/ioutil" + "os" + "os/exec" + "path" + "strings" + + "github.com/docker/docker-credential-helpers/credentials" +) + +const PASS_FOLDER = "docker-credential-helpers" + +var ( + PassInitialized bool +) + +func init() { + PassInitialized = exec.Command("pass").Run() == nil +} + +func runPass(stdinContent string, args ...string) (string, error) { + cmd := exec.Command("pass", args...) + + stdin, err := cmd.StdinPipe() + if err != nil { + return "", err + } + defer stdin.Close() + + stderr, err := cmd.StderrPipe() + if err != nil { + return "", err + } + defer stderr.Close() + + stdout, err := cmd.StdoutPipe() + if err != nil { + return "", err + } + defer stdout.Close() + + err = cmd.Start() + if err != nil { + return "", err + } + + _, err = stdin.Write([]byte(stdinContent)) + if err != nil { + return "", err + } + stdin.Close() + + errContent, err := ioutil.ReadAll(stderr) + if err != nil { + return "", fmt.Errorf("error reading stderr: %s", err) + } + + result, err := ioutil.ReadAll(stdout) + if err != nil { + return "", fmt.Errorf("Error reading stdout: %s", err) + } + + cmdErr := cmd.Wait() + if cmdErr != nil { + return "", fmt.Errorf("%s: %s", cmdErr, errContent) + } + + return string(result), nil +} + +// Pass handles secrets using Linux secret-service as a store. +type Pass struct{} + +// Add adds new credentials to the keychain. +func (h Pass) Add(creds *credentials.Credentials) error { + if !PassInitialized { + return errors.New("pass store is uninitialized") + } + + if creds == nil { + return errors.New("missing credentials") + } + + encoded := base64.URLEncoding.EncodeToString([]byte(creds.ServerURL)) + + _, err := runPass(creds.Secret, "insert", "-f", "-m", path.Join(PASS_FOLDER, encoded, creds.Username)) + return err +} + +// Delete removes credentials from the store. +func (h Pass) Delete(serverURL string) error { + if !PassInitialized { + return errors.New("pass store is uninitialized") + } + + if serverURL == "" { + return errors.New("missing server url") + } + + encoded := base64.URLEncoding.EncodeToString([]byte(serverURL)) + _, err := runPass("", "rm", "-rf", path.Join(PASS_FOLDER, encoded)) + return err +} + +// listPassDir lists all the contents of a directory in the password store. +// Pass uses fancy unicode to emit stuff to stdout, so rather than try +// and parse this, let's just look at the directory structure instead. +func listPassDir(args ...string) ([]os.FileInfo, error) { + passDir := os.ExpandEnv("$HOME/.password-store") + for _, e := range os.Environ() { + parts := strings.SplitN(e, "=", 2) + if len(parts) < 2 { + continue + } + + if parts[0] != "PASSWORD_STORE_DIR" { + continue + } + + passDir = parts[1] + break + } + + p := path.Join(append([]string{passDir, PASS_FOLDER}, args...)...) + contents, err := ioutil.ReadDir(p) + if err != nil { + if os.IsNotExist(err) { + return []os.FileInfo{}, nil + } + + return nil, err + } + + return contents, nil +} + +// Get returns the username and secret to use for a given registry server URL. +func (h Pass) Get(serverURL string) (string, string, error) { + if !PassInitialized { + return "", "", errors.New("pass store is uninitialized") + } + + if serverURL == "" { + return "", "", errors.New("missing server url") + } + + encoded := base64.URLEncoding.EncodeToString([]byte(serverURL)) + + usernames, err := listPassDir(encoded) + if err != nil { + return "", "", err + } + + if len(usernames) < 1 { + return "", "", fmt.Errorf("no usernames for %s", serverURL) + } + + actual := strings.TrimSuffix(usernames[0].Name(), ".gpg") + secret, err := runPass("", "show", path.Join(PASS_FOLDER, encoded, actual)) + return actual, secret, err +} + +// List returns the stored URLs and corresponding usernames for a given credentials label +func (h Pass) List() (map[string]string, error) { + if !PassInitialized { + return nil, errors.New("pass store is uninitialized") + } + + servers, err := listPassDir() + if err != nil { + return nil, err + } + + resp := map[string]string{} + + for _, server := range servers { + if !server.IsDir() { + continue + } + + serverURL, err := base64.URLEncoding.DecodeString(server.Name()) + if err != nil { + return nil, err + } + + usernames, err := listPassDir(server.Name()) + if err != nil { + return nil, err + } + + if len(usernames) < 1 { + return nil, fmt.Errorf("no usernames for %s", serverURL) + } + + resp[string(serverURL)] = strings.TrimSuffix(usernames[0].Name(), ".gpg") + } + + return resp, nil +} Property changes on: head/sysutils/docker/files/pass_freebsd.go ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property