Skip to content

ci: Run integration tests inside finch-vm #93

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ jobs:
needs: [build]
strategy:
matrix:
containerd: ["1.7.27", "2.0.4"]
containerd: ["1.7.27", "2.1.3"]
fail-fast: false
timeout-minutes: 10
env:
Expand Down Expand Up @@ -114,10 +114,10 @@ jobs:
- name: Run opa e2e tests
run: sudo -E make test-e2e-opa
- name: Clean up Daemon socket
run: sudo rm /run/finch.sock && sudo rm /run/finch.pid
run: sudo rm /run/finch.sock && sudo rm /run/finch.pid && sudo rm /run/finch-credential.sock
- name: Start finch-daemon
run: sudo bin/finch-daemon --debug --socket-owner $UID &
run: sudo cp bin/docker-credential-finch /usr/bin && sudo bin/finch-daemon --debug --socket-owner $UID &
- name: Run e2e test
run: sudo make test-e2e
- name: Clean up Daemon socket
run: sudo rm /var/run/finch.sock && sudo rm /run/finch.pid
run: sudo rm /var/run/finch.sock && sudo rm /run/finch.pid && sudo rm /var/run/finch-credential.sock
129 changes: 129 additions & 0 deletions .github/workflows/finch-vm-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
name: Finch VM
on:
push:
branches:
- main
paths-ignore:
- '**.md'
pull_request:
branches:
- main
paths-ignore:
- '**.md'
workflow_dispatch:
env:
GO_VERSION: '1.23.8'
jobs:
mac-test-e2e:
runs-on: codebuild-finch-daemon-arm64-2-instance-${{ github.run_id }}-${{ github.run_attempt }}
timeout-minutes: 30
steps:
- name: Clean macOS runner workspace
run: |
rm -rf ${{ github.workspace }}/*
- name: Configure Git for ec2-user
run: |
git config --global --add safe.directory "*"
shell: bash
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: ${{ env.GO_VERSION }}
cache: false

- name: Configure Go for ec2-user
run: |
# Ensure Go is properly configured for ec2-user
chown -R ec2-user:staff $GOPATH || true
chown -R ec2-user:staff $RUNNER_TOOL_CACHE/go || true
- name: Install Rosetta 2
run: su ec2-user -c 'echo "A" | /usr/sbin/softwareupdate --install-rosetta --agree-to-license || true'

- name: Configure Homebrew for ec2-user
run: |
echo "Creating .brewrc file for ec2-user..."
cat > /Users/ec2-user/.brewrc << 'EOF'
# Homebrew environment setup
export PATH="/opt/homebrew/bin:/opt/homebrew/sbin:$PATH"
export HOMEBREW_PREFIX="/opt/homebrew"
export HOMEBREW_CELLAR="/opt/homebrew/Cellar"
export HOMEBREW_REPOSITORY="/opt/homebrew"
export HOMEBREW_NO_AUTO_UPDATE=1
EOF
chown ec2-user:staff /Users/ec2-user/.brewrc

# Fix Homebrew permissions
echo "Setting permissions for Homebrew directories..."
mkdir -p /opt/homebrew/Cellar
chown -R ec2-user:staff /opt/homebrew
shell: bash

# Install dependencies using ec2-user with custom environment
- name: Install dependencies
run: |
echo "Installing dependencies as ec2-user..."
# Run brew with custom environment
su ec2-user -c 'source /Users/ec2-user/.brewrc && brew install lz4 automake autoconf libtool yq'
shell: bash

- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
# We need to get all the git tags to make version injection work. See VERSION in Makefile for more detail.
fetch-depth: 0
persist-credentials: false
submodules: recursive

- name: Configure workspace for ec2-user
run: |
# Ensure workspace is properly owned by ec2-user
chown -R ec2-user:staff ${{ github.workspace }}

# Install Finch
- name: Install Finch
run: |
echo "Installing Finch as ec2-user..."

# Run brew with custom environment
su ec2-user -c 'source /Users/ec2-user/.brewrc && brew install finch --cask'

# Verify installation
su ec2-user -c 'source /Users/ec2-user/.brewrc && brew list | grep finch || echo "finch not installed"'
mkdir -p /private/var/run/finch-lima
cat /etc/passwd
chown ec2-user:daemon /private/var/run/finch-lima
shell: bash

# Build binaries
- name: Build binaries
run: |
echo "Building cross architecture binaries..."
su ec2-user -c 'cd ${{ github.workspace }} && STATIC=1 GOPROXY=direct GOOS=linux GOARCH=$(GOARCH) make'
su ec2-user -c 'finch vm remove -f'
cp -f ${{ github.workspace }}/bin/finch-daemon /Applications/Finch/finch-daemon/finch-daemon
shell: bash

# Initialize VM and check version
- name: Check Finch version
run: |
echo "Initializing VM and checking version..."
su ec2-user -c 'finch vm init'
sleep 5 # Wait for services to be ready
echo "Checking Finch version..."
su ec2-user -c 'LIMA_HOME=/Applications/Finch/lima/data /Applications/Finch/lima/bin/limactl shell finch curl --unix-socket /var/run/finch.sock -X GET http:/v1.43/version'
shell: bash

# Run e2e tests
- name: Run e2e tests
run: |
echo "Running e2e tests..."
su ec2-user -c 'make test-e2e-inside-vm'
shell: bash

# Cleanup
- name: Stop Finch VM
run: |
echo "Stopping Finch VM as ec2-user..."

# Stop VM using ec2-user with custom environment
su ec2-user -c "source /Users/ec2-user/.brewrc && HOME=/Users/ec2-user finch vm stop"
shell: bash
if: always()
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.17.2"
".": "0.19.1"
}
45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,50 @@
# Changelog

## [0.19.1](https://github.com/runfinch/finch-daemon/compare/v0.19.0...v0.19.1) (2025-07-28)


### Bug Fixes

* downgrade nerdctl from v2.1.3 to v2.1.2 ([#289](https://github.com/runfinch/finch-daemon/issues/289)) ([a7487bf](https://github.com/runfinch/finch-daemon/commit/a7487bfd915424f7e643426f3e60614e347162f6))

## [0.19.0](https://github.com/runfinch/finch-daemon/compare/v0.18.1...v0.19.0) (2025-07-17)


### Features

* Use nerdctl parsing logic for port publishing ([#265](https://github.com/runfinch/finch-daemon/issues/265)) ([1aec7ce](https://github.com/runfinch/finch-daemon/commit/1aec7cefe590a9f7d7857615f6ebebacd887545a))


### Bug Fixes

* restore update network settings for dockercompat ([#286](https://github.com/runfinch/finch-daemon/issues/286)) ([8fc3a1e](https://github.com/runfinch/finch-daemon/commit/8fc3a1eccf2ac5bc880dd184d8c13f58996836e7))

## [0.18.1](https://github.com/runfinch/finch-daemon/compare/v0.18.0...v0.18.1) (2025-07-11)


### Bug Fixes

* verify release artifact ([20dc067](https://github.com/runfinch/finch-daemon/commit/20dc0677673c88f2bacbe7b7f94d307899918108))
* verify release artifact docker-credential-finch ([#284](https://github.com/runfinch/finch-daemon/issues/284)) ([20dc067](https://github.com/runfinch/finch-daemon/commit/20dc0677673c88f2bacbe7b7f94d307899918108))

## [0.18.0](https://github.com/runfinch/finch-daemon/compare/v0.17.2...v0.18.0) (2025-07-11)


### Build System or External Dependencies

* **deps:** Bump github.com/docker/docker from 28.0.2+incompatible to 28.2.2+incompatible ([#251](https://github.com/runfinch/finch-daemon/issues/251)) ([097fb7e](https://github.com/runfinch/finch-daemon/commit/097fb7ee7badd55f4d4cecd671eaaad290c6e92f))
* **deps:** Bump github.com/go-viper/mapstructure/v2 ([0e28455](https://github.com/runfinch/finch-daemon/commit/0e2845588b0b5d922e539359f968c73fd271ac14))
* **deps:** Bump github.com/go-viper/mapstructure/v2 from 2.2.1 to 2.3.0 ([#273](https://github.com/runfinch/finch-daemon/issues/273)) ([0e28455](https://github.com/runfinch/finch-daemon/commit/0e2845588b0b5d922e539359f968c73fd271ac14))
* **deps:** Bump github.com/open-policy-agent/opa from 1.1.0 to 1.4.0 ([#268](https://github.com/runfinch/finch-daemon/issues/268)) ([7ec7d02](https://github.com/runfinch/finch-daemon/commit/7ec7d025266aa4cca0e137ee91390a16d1a21330))


### Features

* Add credential management for container build ([#275](https://github.com/runfinch/finch-daemon/issues/275)) ([47d2a65](https://github.com/runfinch/finch-daemon/commit/47d2a6560e6f5864b6aa4f4030e5ad8ebf977c5e))
* migrate from golang gomock to uber gomock ([#264](https://github.com/runfinch/finch-daemon/issues/264)) ([bb9442a](https://github.com/runfinch/finch-daemon/commit/bb9442a022aeb392822a697f13a238b7f81b8af8))
* Opa middleware support (Experimental) ([#156](https://github.com/runfinch/finch-daemon/issues/156)) ([91b9ac6](https://github.com/runfinch/finch-daemon/commit/91b9ac673ff13bcbe2a948d953481f5505245c4c))


## [0.17.2](https://github.com/runfinch/finch-daemon/compare/v0.17.1...v0.17.2) (2025-06-06)


Expand Down
53 changes: 51 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ FINCH_DAEMON_PROJECT_ROOT ?= $(shell pwd)
PREFIX ?= /usr/local
BINDIR ?= $(PREFIX)/bin

CRED_HELPER_PREFIX ?= /usr
CRED_HELPER_BINDIR ?= $(CRED_HELPER_PREFIX)/bin

BINARY = $(addprefix bin/,finch-daemon)
CREDENTIAL_HELPER = $(addprefix bin/,docker-credential-finch)

PACKAGE := github.com/runfinch/finch-daemon
VERSION ?= $(shell git describe --match 'v[0-9]*' --dirty='.modified' --always --tags)
Expand All @@ -24,7 +28,10 @@ endif
LDFLAGS_BASE := -X $(PACKAGE)/version.Version=$(VERSION) -X $(PACKAGE)/version.GitCommit=$(GITCOMMIT) $(EXTRA_LDFLAGS)

.PHONY: build
build:
build: build-daemon build-credential-helper

.PHONY: build-daemon
build-daemon:
ifeq ($(STATIC),)
@echo "Building Dynamic Binary"
CGO_ENABLED=1 GOOS=linux go build \
Expand All @@ -38,6 +45,21 @@ else
-v -o $(BINARY) $(PACKAGE)/cmd/finch-daemon
endif

.PHONY: build-credential-helper
build-credential-helper:
ifeq ($(STATIC),)
@echo "Building Dynamic Credential Helper"
CGO_ENABLED=1 GOOS=linux go build \
-ldflags "$(LDFLAGS_BASE)" \
-v -o $(CREDENTIAL_HELPER) $(PACKAGE)/cmd/finch-credential-helper
else
@echo "Building Static Credential Helper"
CGO_ENABLED=0 GOOS=linux go build \
-tags netgo \
-ldflags "$(LDFLAGS_BASE) -extldflags '-static'" \
-v -o $(CREDENTIAL_HELPER) $(PACKAGE)/cmd/finch-credential-helper
endif

clean:
@rm -f $(BINARIES)
@rm -rf $(BIN)
Expand All @@ -63,16 +85,21 @@ start-debug: linux build $(DLV) unlink
install: linux
install -d $(DESTDIR)$(BINDIR)
install $(BINARY) $(DESTDIR)$(BINDIR)
install $(CREDENTIAL_HELPER) $(DESTDIR)$(CRED_HELPER_BINDIR)

uninstall:
@rm -f $(addprefix $(DESTDIR)$(BINDIR)/,$(notdir $(BINARY)))
@rm -f $(addprefix $(DESTDIR)$(CRED_HELPER_BINDIR)/,$(notdir $(CREDENTIAL_HELPER)))

# Unlink the unix socket if the link does not get cleaned up properly (or if finch-daemon is already running)
.PHONY: unlink
unlink: linux
ifneq ("$(wildcard /run/finch.sock)","")
sudo unlink /run/finch.sock
endif
ifneq ("$(wildcard /run/finch/credential.sock)","")
sudo unlink /run/finch/credential.sock
endif

.PHONY: gen-code
gen-code: linux
Expand Down Expand Up @@ -135,4 +162,26 @@ coverage: linux
.PHONY: release
release: linux
@echo "$@"
@$(FINCH_DAEMON_PROJECT_ROOT)/scripts/create-releases.sh $(RELEASE_TAG)
@$(FINCH_DAEMON_PROJECT_ROOT)/scripts/create-releases.sh $(RELEASE_TAG)

.PHONY: macos
macos:
ifeq ($(shell uname), Darwin)
@echo "Running on macOS"
else
$(error This target can only be run on macOS!)
endif


DAEMON_DOCKER_HOST := "unix:///Applications/Finch/lima/data/finch/sock/finch.sock"
# DAEMON_ROOT

.PHONY: test-e2e-inside-vm
test-e2e-inside-vm: macos
DOCKER_HOST=$(DAEMON_DOCKER_HOST) \
DOCKER_API_VERSION="v1.41" \
TEST_E2E=1 \
go test ./e2e -test.v -ginkgo.v -ginkgo.randomize-all \
--subject="finch" \
--daemon-context-subject-prefix="/Applications/Finch/lima/bin/limactl shell finch sudo" \
--daemon-context-subject-env="LIMA_HOME=/Applications/Finch/lima/data"
23 changes: 23 additions & 0 deletions api/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import (
// authorization credentials for registry operations (push/pull).
const AuthHeader = "X-Registry-Auth"

// RegistryConfigHeader is the name of the header used to send encoded registry
// configuration for registry operations (build).
const RegistryConfigHeader = "X-Registry-Config"

// DecodeAuthConfig decodes base64url encoded (RFC4648, section 5) JSON
// authentication information as sent through the X-Registry-Auth header.
//
Expand Down Expand Up @@ -61,3 +65,22 @@ func decodeAuthConfigFromReader(rdr io.Reader) (*dockertypes.AuthConfig, error)
}
return authConfig, nil
}

// DecodeRegistryConfig decodes base64url encoded JSON registry configuration.
func DecodeRegistryConfig(registryConfig string) (map[string]dockertypes.AuthConfig, error) {
if registryConfig == "" {
return map[string]dockertypes.AuthConfig{}, nil
}

decoded, err := base64.URLEncoding.DecodeString(registryConfig)
if err != nil {
return nil, errors.Wrap(err, "failed to decode registry config")
}

var registryConfigs map[string]dockertypes.AuthConfig
if err := json.Unmarshal(decoded, &registryConfigs); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal registry config")
}

return registryConfigs, nil
}
26 changes: 26 additions & 0 deletions api/credential-router/router.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package credentialrouter

import (
"net/http"
"os"

ghandlers "github.com/gorilla/handlers"
"github.com/gorilla/mux"

credentialhandler "github.com/runfinch/finch-daemon/api/credential"
"github.com/runfinch/finch-daemon/pkg/credential"
"github.com/runfinch/finch-daemon/pkg/flog"
)

// CreateCredentialHandler creates a dedicated HTTP handler for the credential socket.
func CreateCredentialHandler(credentialService *credential.CredentialService, logger flog.Logger, authMiddleware func(http.Handler) http.Handler) (http.Handler, error) {
r := mux.NewRouter()
r.Use(authMiddleware)

// Register the credential handler
credentialhandler.RegisterHandlers(r, credentialService, logger)
return ghandlers.LoggingHandler(os.Stderr, r), nil
}
Loading
Loading