From b6e1f8b234ea49e2118201f75dbc74c3456860e8 Mon Sep 17 00:00:00 2001 From: ayush-panta Date: Thu, 16 Oct 2025 22:15:26 -0700 Subject: [PATCH 1/7] ci: add osxkeychain default credhelper for darwin Signed-off-by: ayush-panta --- pkg/config/defaults_darwin.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pkg/config/defaults_darwin.go b/pkg/config/defaults_darwin.go index edb0274f3..85699a6b9 100644 --- a/pkg/config/defaults_darwin.go +++ b/pkg/config/defaults_darwin.go @@ -59,6 +59,13 @@ func cpuDefault(cfg *Finch, deps LoadSystemDeps) { } } +// Different because the other defaults use single values; this uses a slice +func credHelperDefault(cfg *Finch) { + if cfg.CredsHelpers == nil || len(cfg.CredsHelpers) == 0 { + cfg.CredsHelpers = []string{"osxkeychain"} + } +} + // applyDefaults sets default configuration options if they are not already set. func applyDefaults( cfg *Finch, @@ -75,6 +82,6 @@ func applyDefaults( } vmDefault(cfg, supportsVz) rosettaDefault(cfg) - + credHelperDefault(cfg) return cfg } From 3427edec5604a099cb747badbea3b2223675a23d Mon Sep 17 00:00:00 2001 From: ayush-panta Date: Wed, 29 Oct 2025 14:44:05 -0700 Subject: [PATCH 2/7] add echo server and try to mount socket to lima Signed-off-by: ayush-panta --- Makefile | 6 +++- cmd/finch/cred-helper/main.go | 68 +++++++++++++++++++++++++++++++++++ deps/finch-core | 2 +- finch.yaml.d/mac.yaml | 2 ++ 4 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 cmd/finch/cred-helper/main.go diff --git a/Makefile b/Makefile index 75da162e2..9a737f4be 100644 --- a/Makefile +++ b/Makefile @@ -79,7 +79,7 @@ endif FINCH_CORE_DIR := $(CURDIR)/deps/finch-core -remote-all: arch-test finch install.finch-core-dependencies finch.yaml networks.yaml config.yaml $(OUTDIR)/finch-daemon/finch@.service +remote-all: arch-test finch finch-cred-daemon install.finch-core-dependencies finch.yaml networks.yaml config.yaml $(OUTDIR)/finch-daemon/finch@.service ifeq ($(BUILD_OS), Windows_NT) include Makefile.windows @@ -169,6 +169,10 @@ finch-native: finch-all finch-all: $(GO) build -ldflags $(LDFLAGS) -tags "$(GO_BUILD_TAGS)" -o $(OUTDIR)/bin/$(BINARYNAME) $(PACKAGE)/cmd/finch +.PHONY: finch-cred-daemon +finch-cred-daemon: + $(GO) build -ldflags $(LDFLAGS) -o $(OUTDIR)/bin/finch-cred-daemon $(PACKAGE)/cmd/finch/cred-helper + .PHONY: release release: check-licenses all download-licenses diff --git a/cmd/finch/cred-helper/main.go b/cmd/finch/cred-helper/main.go new file mode 100644 index 000000000..c168572cd --- /dev/null +++ b/cmd/finch/cred-helper/main.go @@ -0,0 +1,68 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +// Basic thing + +package main + +import ( + "fmt" + "log" + "net" + "os" + "os/signal" + "syscall" +) + +const sockAddress = "/tmp/cred.sock" + +func main() { + + fmt.Println("This is the credential helper daemon.") + + // Creating the socket and ensuring success + socket, err := net.Listen("unix", sockAddress) + if err != nil { + log.Fatal(err) // Fatal is fine -> unsuccessful + } + + // Cleanup sockfile with go routine (?) + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt, syscall.SIGTERM) + go func() { + <-c + os.Remove(sockAddress) + os.Exit(1) + }() + + for { + // Accept and validate a connection + conn, err := socket.Accept() + if err != nil { + log.Printf("Accept error: %v", err) // instead of Fatal + } + + go func(conn net.Conn) { + // close at the end + defer conn.Close() + + // create buffer for unix socket + buf := make([]byte, 4096) + + // read and display data in string fmt + n, err := conn.Read(buf) + if err != nil { + log.Printf("Read error: %v", err) // instead of Fatal + return + } + fmt.Println("Received: ", string(buf[:n])) + + // write data back + _, err = conn.Write(buf[:n]) + if err != nil { + log.Printf("Write error: %v", err) // instead of Fatal + return + } + }(conn) + } +} diff --git a/deps/finch-core b/deps/finch-core index 30e5e1f2e..b1e34ab47 160000 --- a/deps/finch-core +++ b/deps/finch-core @@ -1 +1 @@ -Subproject commit 30e5e1f2eb742e8bda9a536a171ae1e71a607219 +Subproject commit b1e34ab47a162a63e068d64ffb8257d77cb96288 diff --git a/finch.yaml.d/mac.yaml b/finch.yaml.d/mac.yaml index 1be4e99ee..4f8522dc0 100644 --- a/finch.yaml.d/mac.yaml +++ b/finch.yaml.d/mac.yaml @@ -57,3 +57,5 @@ hostResolver: portForwards: - guestSocket: "/run/finch.sock" hostSocket: "{{.Dir}}/sock/finch.sock" +- guestSocket: "/run/cred.sock" + hostSocket: "/private/tmp/cred.sock" From c2d0a0dded9a505b661d32c3c7fb02dcdbab3fc8 Mon Sep 17 00:00:00 2001 From: ayush-panta Date: Thu, 30 Oct 2025 12:03:01 -0700 Subject: [PATCH 3/7] add cred helper daemon socket (basic) Signed-off-by: ayush-panta --- cmd/finch/cred-helper/main.go | 39 +++++++++++++++++++---------------- finch.yaml.d/common.yaml | 4 ++++ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/cmd/finch/cred-helper/main.go b/cmd/finch/cred-helper/main.go index c168572cd..7bc6faa44 100644 --- a/cmd/finch/cred-helper/main.go +++ b/cmd/finch/cred-helper/main.go @@ -1,8 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -// Basic thing - package main import ( @@ -10,23 +8,22 @@ import ( "log" "net" "os" + "os/exec" "os/signal" + "strings" "syscall" ) const sockAddress = "/tmp/cred.sock" func main() { + fmt.Println("Credential helper daemon started") - fmt.Println("This is the credential helper daemon.") - - // Creating the socket and ensuring success socket, err := net.Listen("unix", sockAddress) if err != nil { - log.Fatal(err) // Fatal is fine -> unsuccessful + log.Fatal(err) } - // Cleanup sockfile with go routine (?) c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, syscall.SIGTERM) go func() { @@ -36,33 +33,39 @@ func main() { }() for { - // Accept and validate a connection conn, err := socket.Accept() if err != nil { - log.Printf("Accept error: %v", err) // instead of Fatal + log.Printf("Accept error: %v", err) + continue } go func(conn net.Conn) { - // close at the end defer conn.Close() - // create buffer for unix socket buf := make([]byte, 4096) - - // read and display data in string fmt n, err := conn.Read(buf) if err != nil { - log.Printf("Read error: %v", err) // instead of Fatal + log.Printf("Read error: %v", err) + return + } + + cmdStr := strings.TrimSpace(string(buf[:n])) + fmt.Printf("Executing: %s\n", cmdStr) + + if cmdStr == "" { + conn.Write([]byte("Error: empty command")) return } - fmt.Println("Received: ", string(buf[:n])) - // write data back - _, err = conn.Write(buf[:n]) + cmd := exec.Command("sh", "-c", cmdStr) + output, err := cmd.CombinedOutput() if err != nil { - log.Printf("Write error: %v", err) // instead of Fatal + result := fmt.Sprintf("Error: %v\nOutput: %s", err, string(output)) + conn.Write([]byte(result)) return } + + conn.Write(output) }(conn) } } diff --git a/finch.yaml.d/common.yaml b/finch.yaml.d/common.yaml index 10b6e52d8..4b96cf651 100644 --- a/finch.yaml.d/common.yaml +++ b/finch.yaml.d/common.yaml @@ -92,6 +92,10 @@ provision: sudo systemctl daemon-reload sudo systemctl restart containerd.service +portForwards: +- guestSocket: "/run/cred.sock" + hostSocket: "/private/tmp/cred.sock" + env: # Containerd namespace is used by the lima cidata script # 40-install-containerd.sh. Specifically this variable is defining the From 16e6af2a975627d54b508f26a4888636a3e12c0c Mon Sep 17 00:00:00 2001 From: ayush-panta Date: Thu, 30 Oct 2025 12:03:17 -0700 Subject: [PATCH 4/7] add docker-cred install to Makefile Signed-off-by: ayush-panta --- Makefile | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9a737f4be..4f3fff523 100644 --- a/Makefile +++ b/Makefile @@ -79,7 +79,7 @@ endif FINCH_CORE_DIR := $(CURDIR)/deps/finch-core -remote-all: arch-test finch finch-cred-daemon install.finch-core-dependencies finch.yaml networks.yaml config.yaml $(OUTDIR)/finch-daemon/finch@.service +remote-all: arch-test finch finch-cred-daemon docker-credential-helper install.finch-core-dependencies finch.yaml networks.yaml config.yaml $(OUTDIR)/finch-daemon/finch@.service ifeq ($(BUILD_OS), Windows_NT) include Makefile.windows @@ -173,6 +173,23 @@ finch-all: finch-cred-daemon: $(GO) build -ldflags $(LDFLAGS) -o $(OUTDIR)/bin/finch-cred-daemon $(PACKAGE)/cmd/finch/cred-helper +CRED_HELPER_VERSION ?= v0.9.4 + +.PHONY: docker-credential-helper +ifeq ($(BUILD_OS), Darwin) +docker-credential-helper: + mkdir -p ~/.finch/cred-helpers + curl -L https://github.com/docker/docker-credential-helpers/releases/download/$(CRED_HELPER_VERSION)/docker-credential-osxkeychain-$(CRED_HELPER_VERSION).darwin-amd64 -o ~/.finch/cred-helpers/docker-credential-osxkeychain + chmod +x ~/.finch/cred-helpers/docker-credential-osxkeychain +else ifeq ($(BUILD_OS), Windows_NT) +docker-credential-helper: + mkdir -p ~/.finch/cred-helpers + curl -L https://github.com/docker/docker-credential-helpers/releases/download/$(CRED_HELPER_VERSION)/docker-credential-wincred-$(CRED_HELPER_VERSION).windows-amd64.exe -o ~/.finch/cred-helpers/docker-credential-wincred.exe +else +docker-credential-helper: + @echo "No credential helper needed for Linux" +endif + .PHONY: release release: check-licenses all download-licenses From ee91e4b00d7961561beed7fc6649e6aefacb1f53 Mon Sep 17 00:00:00 2001 From: ayush-panta Date: Thu, 30 Oct 2025 14:52:53 -0700 Subject: [PATCH 5/7] install binary and create override of binary on vm Signed-off-by: ayush-panta --- Makefile | 16 ++++++++++++++-- pkg/config/nerdctl_config_applier.go | 9 +++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 4f3fff523..647887923 100644 --- a/Makefile +++ b/Makefile @@ -178,13 +178,25 @@ CRED_HELPER_VERSION ?= v0.9.4 .PHONY: docker-credential-helper ifeq ($(BUILD_OS), Darwin) docker-credential-helper: + # Download real binary for host daemon + mkdir -p $(OUTDIR)/bin/cred-helpers + curl -L https://github.com/docker/docker-credential-helpers/releases/download/$(CRED_HELPER_VERSION)/docker-credential-osxkeychain-$(CRED_HELPER_VERSION).darwin-amd64 -o $(OUTDIR)/bin/cred-helpers/docker-credential-osxkeychain + chmod +x $(OUTDIR)/bin/cred-helpers/docker-credential-osxkeychain + # Create dummy script for VM (will be overwritten at runtime) mkdir -p ~/.finch/cred-helpers - curl -L https://github.com/docker/docker-credential-helpers/releases/download/$(CRED_HELPER_VERSION)/docker-credential-osxkeychain-$(CRED_HELPER_VERSION).darwin-amd64 -o ~/.finch/cred-helpers/docker-credential-osxkeychain + echo '#!/bin/bash' > ~/.finch/cred-helpers/docker-credential-osxkeychain + echo 'echo "Dummy credential helper - will be replaced by bridge script"' >> ~/.finch/cred-helpers/docker-credential-osxkeychain chmod +x ~/.finch/cred-helpers/docker-credential-osxkeychain else ifeq ($(BUILD_OS), Windows_NT) docker-credential-helper: + # Download real binary for host daemon + mkdir -p $(OUTDIR)/bin/cred-helpers + curl -L https://github.com/docker/docker-credential-helpers/releases/download/$(CRED_HELPER_VERSION)/docker-credential-wincred-$(CRED_HELPER_VERSION).windows-amd64.exe -o $(OUTDIR)/bin/cred-helpers/docker-credential-wincred.exe + # Create dummy script for VM (will be overwritten at runtime) mkdir -p ~/.finch/cred-helpers - curl -L https://github.com/docker/docker-credential-helpers/releases/download/$(CRED_HELPER_VERSION)/docker-credential-wincred-$(CRED_HELPER_VERSION).windows-amd64.exe -o ~/.finch/cred-helpers/docker-credential-wincred.exe + echo '#!/bin/bash' > ~/.finch/cred-helpers/docker-credential-wincred + echo 'echo "Dummy credential helper - will be replaced by bridge script"' >> ~/.finch/cred-helpers/docker-credential-wincred + chmod +x ~/.finch/cred-helpers/docker-credential-wincred else docker-credential-helper: @echo "No credential helper needed for Linux" diff --git a/pkg/config/nerdctl_config_applier.go b/pkg/config/nerdctl_config_applier.go index 55d7f1339..35f798852 100644 --- a/pkg/config/nerdctl_config_applier.go +++ b/pkg/config/nerdctl_config_applier.go @@ -100,6 +100,15 @@ func updateEnvironment(fs afero.Fs, fc *Finch, finchDir, homeDir, limaVMHomeDir ([ -L /usr/local/bin/docker-credential-%s ] || sudo ln -s "$FINCH_DIR"/cred-helpers/docker-credential-%s /usr/local/bin)` for _, credHelper := range fc.CredsHelpers { + cmdArr = append(cmdArr, fmt.Sprintf(`echo '{"credsStore": "%s"}' > "$FINCH_DIR"/config.json`, credHelper)) + // Create VM-side bridge script + bridgeScript := fmt.Sprintf(`cat > "$FINCH_DIR"/cred-helpers/docker-credential-%s << 'EOF' +#!/bin/bash +# Forward everything to host daemon +{ echo "$@"; cat; } | nc 192.168.5.2 8080 +EOF`, credHelper) + cmdArr = append(cmdArr, bridgeScript) + cmdArr = append(cmdArr, fmt.Sprintf(`chmod +x "$FINCH_DIR"/cred-helpers/docker-credential-%s`, credHelper)) cmdArr = append(cmdArr, fmt.Sprintf(configureCredHelperTemplate, credHelper, credHelper, credHelper, credHelper)) } From f40484a768dde5040fdc4124ec0f4504775648cc Mon Sep 17 00:00:00 2001 From: ayush-panta Date: Mon, 3 Nov 2025 12:50:54 -0800 Subject: [PATCH 6/7] basic cmd forwarding Signed-off-by: ayush-panta --- cmd/finch/cred-helper/main.go | 41 +++++++++++++++++++++------- pkg/config/nerdctl_config_applier.go | 7 +++-- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/cmd/finch/cred-helper/main.go b/cmd/finch/cred-helper/main.go index 7bc6faa44..7a07edb04 100644 --- a/cmd/finch/cred-helper/main.go +++ b/cmd/finch/cred-helper/main.go @@ -17,13 +17,15 @@ import ( const sockAddress = "/tmp/cred.sock" func main() { - fmt.Println("Credential helper daemon started") + // start the socket + fmt.Println("Credential helper daemon started") socket, err := net.Listen("unix", sockAddress) if err != nil { log.Fatal(err) } + // cleanup of socket as goroutine c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, syscall.SIGTERM) go func() { @@ -33,6 +35,8 @@ func main() { }() for { + + // accept the connection conn, err := socket.Accept() if err != nil { log.Printf("Accept error: %v", err) @@ -42,6 +46,7 @@ func main() { go func(conn net.Conn) { defer conn.Close() + // create buffer for socket buf := make([]byte, 4096) n, err := conn.Read(buf) if err != nil { @@ -49,22 +54,38 @@ func main() { return } - cmdStr := strings.TrimSpace(string(buf[:n])) - fmt.Printf("Executing: %s\n", cmdStr) - - if cmdStr == "" { - conn.Write([]byte("Error: empty command")) + // need to read in the data + message := strings.TrimSpace(string(buf[:n])) + lines := strings.Split(message, "\n") + if len(lines) == 0 { + conn.Write([]byte("Error: empty message")) return } - cmd := exec.Command("sh", "-c", cmdStr) + // Parse command and data + cmdName := strings.TrimSpace(lines[0]) + var stdinData string + if len(lines) > 1 { + // Decode HTML entities like " -> " + stdinData = strings.ReplaceAll(strings.Join(lines[1:], "\n"), """, "\"") + } + + fmt.Printf("Command: '%s'\n", cmdName) + fmt.Printf("Stdin data: '%s'\n", stdinData) + + binaryPath := "/Users/ayushkp/Documents/finch-creds/finch/_output/bin/cred-helpers/docker-credential-osxkeychain" + cmd := exec.Command(binaryPath, cmdName) + if stdinData != "" { + cmd.Stdin = strings.NewReader(stdinData) + } + output, err := cmd.CombinedOutput() if err != nil { - result := fmt.Sprintf("Error: %v\nOutput: %s", err, string(output)) - conn.Write([]byte(result)) - return + fmt.Printf("Error: %v\n", err) } + fmt.Printf("Output: %s\n", output) + conn.Write(output) }(conn) } diff --git a/pkg/config/nerdctl_config_applier.go b/pkg/config/nerdctl_config_applier.go index 35f798852..0acaf187f 100644 --- a/pkg/config/nerdctl_config_applier.go +++ b/pkg/config/nerdctl_config_applier.go @@ -104,8 +104,11 @@ func updateEnvironment(fs afero.Fs, fc *Finch, finchDir, homeDir, limaVMHomeDir // Create VM-side bridge script bridgeScript := fmt.Sprintf(`cat > "$FINCH_DIR"/cred-helpers/docker-credential-%s << 'EOF' #!/bin/bash -# Forward everything to host daemon -{ echo "$@"; cat; } | nc 192.168.5.2 8080 +exec 3<>/dev/tcp/192.168.5.2/8080 +printf "%%s\n" "$@" >&3 +cat >&3 +cat <&3 +exec 3<&- EOF`, credHelper) cmdArr = append(cmdArr, bridgeScript) cmdArr = append(cmdArr, fmt.Sprintf(`chmod +x "$FINCH_DIR"/cred-helpers/docker-credential-%s`, credHelper)) From 1cc063d82826e730a8106316fe3002db75d2e1f2 Mon Sep 17 00:00:00 2001 From: ayush-panta Date: Tue, 4 Nov 2025 11:39:18 -0800 Subject: [PATCH 7/7] broken communication Signed-off-by: ayush-panta --- Makefile | 4 ++++ cmd/finch/cred-helper/main.go | 34 +++++++++++++++++++++------- pkg/config/nerdctl_config_applier.go | 26 ++++++++++----------- 3 files changed, 42 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index 647887923..a7677dcb7 100644 --- a/Makefile +++ b/Makefile @@ -180,7 +180,11 @@ ifeq ($(BUILD_OS), Darwin) docker-credential-helper: # Download real binary for host daemon mkdir -p $(OUTDIR)/bin/cred-helpers +ifeq ($(ARCH),arm64) + curl -L https://github.com/docker/docker-credential-helpers/releases/download/$(CRED_HELPER_VERSION)/docker-credential-osxkeychain-$(CRED_HELPER_VERSION).darwin-arm64 -o $(OUTDIR)/bin/cred-helpers/docker-credential-osxkeychain +else curl -L https://github.com/docker/docker-credential-helpers/releases/download/$(CRED_HELPER_VERSION)/docker-credential-osxkeychain-$(CRED_HELPER_VERSION).darwin-amd64 -o $(OUTDIR)/bin/cred-helpers/docker-credential-osxkeychain +endif chmod +x $(OUTDIR)/bin/cred-helpers/docker-credential-osxkeychain # Create dummy script for VM (will be overwritten at runtime) mkdir -p ~/.finch/cred-helpers diff --git a/cmd/finch/cred-helper/main.go b/cmd/finch/cred-helper/main.go index 7a07edb04..988a1f81d 100644 --- a/cmd/finch/cred-helper/main.go +++ b/cmd/finch/cred-helper/main.go @@ -14,13 +14,14 @@ import ( "syscall" ) -const sockAddress = "/tmp/cred.sock" +// const sockAddress = "/tmp/cred.sock" +const hostAddr = "0.0.0.0:8080" // Listen on all interfaces func main() { // start the socket fmt.Println("Credential helper daemon started") - socket, err := net.Listen("unix", sockAddress) + socket, err := net.Listen("tcp", hostAddr) if err != nil { log.Fatal(err) } @@ -30,7 +31,7 @@ func main() { signal.Notify(c, os.Interrupt, syscall.SIGTERM) go func() { <-c - os.Remove(sockAddress) + // os.Remove(hostAddr) os.Exit(1) }() @@ -70,8 +71,14 @@ func main() { stdinData = strings.ReplaceAll(strings.Join(lines[1:], "\n"), """, "\"") } - fmt.Printf("Command: '%s'\n", cmdName) - fmt.Printf("Stdin data: '%s'\n", stdinData) + // Normalize Docker Hub URLs to canonical format + if cmdName == "get" && stdinData != "" { + if strings.Contains(stdinData, "docker.io") || strings.Contains(stdinData, "registry-1.docker.io") { + stdinData = "https://index.docker.io/v1/" + } + } + + fmt.Printf("[RECV] Command: '%s', Data: '%s'\n", cmdName, stdinData) binaryPath := "/Users/ayushkp/Documents/finch-creds/finch/_output/bin/cred-helpers/docker-credential-osxkeychain" cmd := exec.Command(binaryPath, cmdName) @@ -79,13 +86,24 @@ func main() { cmd.Stdin = strings.NewReader(stdinData) } + // Capture both stdout and stderr output, err := cmd.CombinedOutput() if err != nil { - fmt.Printf("Error: %v\n", err) + // Check if it's a "credentials not found" error + outputStr := string(output) + if strings.Contains(outputStr, "credentials not found") || + strings.Contains(outputStr, "could not be found in the keychain") || + strings.Contains(outputStr, "not correct") { + fmt.Printf("[SEND] No credentials found, allowing anonymous access\n") + conn.Write([]byte("")) // Empty = no credentials, try anonymous + return + } + fmt.Printf("[SEND] Error: %v, Output: '%s'\n", err, outputStr) + conn.Write([]byte("")) // Return empty for any error to allow fallback + return } - fmt.Printf("Output: %s\n", output) - + fmt.Printf("[SEND] Success: '%s'\n", string(output)) conn.Write(output) }(conn) } diff --git a/pkg/config/nerdctl_config_applier.go b/pkg/config/nerdctl_config_applier.go index 0acaf187f..9a340fb0e 100644 --- a/pkg/config/nerdctl_config_applier.go +++ b/pkg/config/nerdctl_config_applier.go @@ -95,23 +95,21 @@ func updateEnvironment(fs afero.Fs, fc *Finch, finchDir, homeDir, limaVMHomeDir } //nolint:gosec // G101: Potential hardcoded credentials false positive - const configureCredHelperTemplate = `([ -e "$FINCH_DIR"/cred-helpers/docker-credential-%s ] || \ - (echo "error: docker-credential-%s not found in $FINCH_DIR/cred-helpers directory.")) && \ - ([ -L /usr/local/bin/docker-credential-%s ] || sudo ln -s "$FINCH_DIR"/cred-helpers/docker-credential-%s /usr/local/bin)` + const configureCredHelperTemplate = `[ -x /usr/local/bin/docker-credential-%s ] || ( +echo "Creating credential helper script for %s" && \ +sudo tee /usr/local/bin/docker-credential-%s > /dev/null << 'CREDEOF' +#!/bin/bash +# Forward to host daemon via TCP +stdin_data=$(cat) +response=$(echo -e "$1\n$stdin_data" | nc host.lima.internal 8080) +echo "$response" +CREDEOF +sudo chmod +x /usr/local/bin/docker-credential-%s +)` for _, credHelper := range fc.CredsHelpers { cmdArr = append(cmdArr, fmt.Sprintf(`echo '{"credsStore": "%s"}' > "$FINCH_DIR"/config.json`, credHelper)) - // Create VM-side bridge script - bridgeScript := fmt.Sprintf(`cat > "$FINCH_DIR"/cred-helpers/docker-credential-%s << 'EOF' -#!/bin/bash -exec 3<>/dev/tcp/192.168.5.2/8080 -printf "%%s\n" "$@" >&3 -cat >&3 -cat <&3 -exec 3<&- -EOF`, credHelper) - cmdArr = append(cmdArr, bridgeScript) - cmdArr = append(cmdArr, fmt.Sprintf(`chmod +x "$FINCH_DIR"/cred-helpers/docker-credential-%s`, credHelper)) + // Create VM-side bridge script that forwards to host TCP daemon (only if it doesn't exist) cmdArr = append(cmdArr, fmt.Sprintf(configureCredHelperTemplate, credHelper, credHelper, credHelper, credHelper)) }