Skip to content

Commit 75380ac

Browse files
authored
Merge pull request #25 from tnevrlka/integration-tests-macos
Make integration tests work on macOS
2 parents 7c1b733 + 96dbcdd commit 75380ac

File tree

2 files changed

+78
-4
lines changed

2 files changed

+78
-4
lines changed

integration_tests/framework/common.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,12 @@ var (
2727
)
2828

2929
func init() {
30-
cliBinPath = path.Join(KonfluxBuildCliCompileDir, KonfluxBuildCli)
30+
compileDir, err := filepath.EvalSymlinks(KonfluxBuildCliCompileDir)
31+
if err != nil {
32+
fmt.Printf("failed to resolve symlinks for %s: %s\n", KonfluxBuildCliCompileDir, err.Error())
33+
os.Exit(2)
34+
}
35+
cliBinPath = path.Join(compileDir, KonfluxBuildCli)
3136

3237
// Init logger
3338
logLevel := "info"
@@ -82,6 +87,7 @@ func CompileKonfluxCli() error {
8287
}
8388

8489
os.Setenv("CGO_ENABLED", "0")
90+
os.Setenv("GOOS", "linux")
8591
compileArgs := []string{"build"}
8692
if Debug {
8793
compileArgs = append(compileArgs, "-gcflags", "all=-N -l")
@@ -119,6 +125,13 @@ func CreateTempDir(prefix string) (string, error) {
119125
if err != nil {
120126
return "", err
121127
}
128+
// On macOS, /tmp is a symlink to /private/tmp. The podman machine mount
129+
// /private from macOS but not /tmp, so volume mounts using /tmp paths
130+
// would look in the VM's own tmp instead of the macOS host.
131+
tmpDir, err = filepath.EvalSymlinks(tmpDir)
132+
if err != nil {
133+
return "", err
134+
}
122135
err = os.Chmod(tmpDir, 0777)
123136
if err != nil {
124137
return "", err

integration_tests/framework/registry_zot_local.go

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package integration_tests_framework
33
import (
44
"crypto/tls"
55
"crypto/x509"
6+
"encoding/base64"
67
"encoding/json"
78
"fmt"
89
"io"
@@ -66,11 +67,30 @@ func NewZotRegistry() ImageRegistry {
6667
log.Fatal(err)
6768
}
6869

70+
zotRegistryStorageHostDirAbsolutePath, err := filepath.Abs(zotRegistryStorageHostDir)
71+
if err != nil {
72+
log.Fatal(err)
73+
}
74+
75+
if err := EnsureDirectory(zotRegistryStorageHostDirAbsolutePath); err != nil {
76+
log.Fatal(err)
77+
}
78+
79+
zotRegistryStorageHostDirAbsolutePath, err = filepath.EvalSymlinks(zotRegistryStorageHostDirAbsolutePath)
80+
if err != nil {
81+
log.Fatal(err)
82+
}
83+
6984
zotRegistryPort := os.Getenv("ZOT_REGISTRY_PORT")
7085
if zotRegistryPort == "" {
7186
zotRegistryPort = zotRegistryDefaultPort
7287
}
7388

89+
// Validate port is numeric
90+
if _, err := strconv.Atoi(zotRegistryPort); err != nil {
91+
log.Fatalf("ZOT_REGISTRY_PORT must be a valid port number, got: %s", zotRegistryPort)
92+
}
93+
7494
return &ZotRegistry{
7595
container: NewTestRunnerContainer(zotRegistryContainerName, zotRegistryImage),
7696
logger: l.Logger.WithField("logger", "zot"),
@@ -84,7 +104,7 @@ func NewZotRegistry() ImageRegistry {
84104
zotKeyPath: path.Join(zotConfigDataDirAbsolutePath, zotKeyFileName),
85105
zotCertPath: path.Join(zotConfigDataDirAbsolutePath, zotCertFileName),
86106
dockerConfigJsonPath: path.Join(zotConfigDataDirAbsolutePath, "config.json"),
87-
zotRegistryStorageDir: path.Join(zotRegistryStorageHostDir, strconv.FormatInt(time.Now().UnixMilli(), 10)),
107+
zotRegistryStorageDir: path.Join(zotRegistryStorageHostDirAbsolutePath, strconv.FormatInt(time.Now().UnixMilli(), 10)),
88108
}
89109
}
90110

@@ -436,8 +456,7 @@ func (z *ZotRegistry) ensureZotCaCertInPodmanConfig(executor *cliWrappers.CliExe
436456
zotRegistryPodmanCaCertPath := path.Join(zotRegistryPodmanCertsDir, zotRootCertFileName)
437457

438458
if FileExists(zotRegistryPodmanCaCertPath) {
439-
// Check if the cert in Podman config is the same as teh cert in Zot config
440-
459+
// Check if the cert in Podman config is the same as the cert in Zot config
441460
zotCaCertFileStat, err := os.Stat(z.rootCertPath)
442461
if err != nil {
443462
return fmt.Errorf("failed to stat Zot CA cert file: %w", err)
@@ -458,5 +477,47 @@ func (z *ZotRegistry) ensureZotCaCertInPodmanConfig(executor *cliWrappers.CliExe
458477
z.logger.Errorf("failed to copy root CA cert into podman config dir: %s\n%s", stdout, stderr)
459478
return err
460479
}
480+
481+
// podman can run inside a podman machine VM
482+
if isPodmanMachineRunning(executor) {
483+
if err := z.ensureZotCaCertInPodmanMachine(executor); err != nil {
484+
return err
485+
}
486+
}
487+
488+
return nil
489+
}
490+
491+
func isPodmanMachineRunning(executor *cliWrappers.CliExecutor) bool {
492+
_, _, exitCode, _ := executor.Execute("podman", "machine", "inspect")
493+
return exitCode == 0
494+
}
495+
496+
// ensureZotCaCertInPodmanMachine copies the CA cert into the podman machine VM
497+
func (z *ZotRegistry) ensureZotCaCertInPodmanMachine(executor *cliWrappers.CliExecutor) error {
498+
vmCertsDir := "/etc/containers/certs.d/" + z.GetRegistryDomain()
499+
vmCertPath := vmCertsDir + "/" + zotRootCertFileName
500+
501+
// Create the directory in the VM
502+
if stdout, stderr, _, err := executor.Execute("podman", "machine", "ssh", "sudo", "mkdir", "-p", vmCertsDir); err != nil {
503+
z.logger.Errorf("failed to create certs dir in podman machine: %s\n%s", stdout, stderr)
504+
return err
505+
}
506+
507+
// Read the cert and encode as base64
508+
certContent, err := os.ReadFile(z.rootCertPath)
509+
if err != nil {
510+
return fmt.Errorf("failed to read CA cert: %w", err)
511+
}
512+
certBase64 := base64.StdEncoding.EncodeToString(certContent)
513+
514+
// Use base64 decode in the VM to write the cert
515+
sshCmd := fmt.Sprintf("echo '%s' | base64 -d | sudo tee %s > /dev/null", certBase64, vmCertPath)
516+
if stdout, stderr, _, err := executor.Execute("podman", "machine", "ssh", sshCmd); err != nil {
517+
z.logger.Errorf("failed to copy CA cert into podman machine: %s\n%s", stdout, stderr)
518+
return err
519+
}
520+
521+
z.logger.Info("Copied CA cert into podman machine VM")
461522
return nil
462523
}

0 commit comments

Comments
 (0)