Skip to content
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
1 change: 1 addition & 0 deletions containerfiles/dns/cluster-hosts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
10.88.0.2 registry registry.cluster.local
10.88.0.3 auth-registry auth-registry.cluster.local
4 changes: 1 addition & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/spf13/viper v1.21.0
go.podman.io/common v0.69.0
go.podman.io/podman/v6 v6.0.2
golang.org/x/crypto v0.54.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/api v0.36.3
k8s.io/apimachinery v0.36.3
Expand Down Expand Up @@ -81,7 +82,6 @@ require (
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
github.com/godbus/dbus/v5 v5.2.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gnostic-models v0.7.0 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/go-containerregistry v0.21.6 // indirect
Expand Down Expand Up @@ -121,7 +121,6 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/nxadm/tail v1.4.11 // indirect
github.com/opencontainers/cgroups v0.0.8 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
Expand Down Expand Up @@ -167,7 +166,6 @@ require (
go.podman.io/storage v1.64.0 // indirect
go.yaml.in/yaml/v2 v2.4.4 // indirect
go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/crypto v0.54.0 // indirect
golang.org/x/mod v0.37.0 // indirect
golang.org/x/net v0.56.0 // indirect
golang.org/x/oauth2 v0.36.0 // indirect
Expand Down
128 changes: 6 additions & 122 deletions go.sum

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions internal/cli/cluster/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ func runStart(ctx context.Context, logger *logrus.Logger, nodeName string, nodeI
if err := registryMgr.EnsureRegistry(ctx); err != nil {
return fmt.Errorf("ensuring registry: %w", err)
}
if err := registryMgr.EnsureAuthRegistry(ctx); err != nil {
return fmt.Errorf("ensuring auth registry: %w", err)
}
logger.Info("")

logger.Info("Step 3: Ensuring DNS container...")
Expand Down Expand Up @@ -197,6 +200,10 @@ func runStart(ctx context.Context, logger *logrus.Logger, nodeName string, nodeI
logger.Infof(" Push: podman push --tls-verify=false localhost:%d/<image>:<tag>", config.RegistryPort)
logger.Infof(" Pull (in-cluster): %s.%s:%d/<image>:<tag>", config.RegistryHostname, config.ClusterDomain, config.RegistryPort)
logger.Info("")
logger.Info("Auth registry (pull with credentials):")
logger.Infof(" Pull (in-cluster): %s.%s:%d/<image>:<tag>", config.AuthRegistryHostname, config.ClusterDomain, config.AuthRegistryPort)
logger.Infof(" Credentials: %s / %s", config.AuthRegistryUsername, config.AuthRegistryPassword)
logger.Info("")

if exposePath != "" {
logger.Info("Step 9: Exposing API server...")
Expand Down
2 changes: 1 addition & 1 deletion internal/cli/cluster/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func runStop(ctx context.Context, logger *logrus.Logger, force, removeData bool)
} else {
logger.Info("✅ All cluster data removed")
}
logger.Info("Note: Shared registry (bink-registry) is preserved. Use 'bink registry stop' to remove it.")
logger.Info("Note: Shared registries (bink-registry, bink-auth-registry) are preserved. Use 'bink registry stop' to remove them.")
}

return nil
Expand Down
27 changes: 22 additions & 5 deletions internal/cli/registry/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,28 @@ func newInfoCmd() *cobra.Command {
status = define.ContainerStateRunning.String()
}

fmt.Printf("Registry: %s\n", status)
fmt.Printf("IP: %s\n", info.IP)
fmt.Printf("Host port: %d\n", info.HostPort)
fmt.Printf("Push: podman push --tls-verify=false %s/<image>:<tag>\n", info.PushURL)
fmt.Printf("Pull: %s/<image>:<tag>\n", info.PullURL)
fmt.Printf("Registry (unauthenticated): %s\n", status)
fmt.Printf(" IP: %s\n", info.IP)
fmt.Printf(" Host port: %d\n", info.HostPort)
fmt.Printf(" Push: podman push --tls-verify=false %s/<image>:<tag>\n", info.PushURL)
fmt.Printf(" Pull: %s/<image>:<tag>\n", info.PullURL)
fmt.Println()

authInfo, err := mgr.AuthRegistryInfo(cmd.Context())
if err != nil {
return fmt.Errorf("getting auth registry info: %w", err)
}

authStatus := "stopped"
if authInfo.Running {
authStatus = define.ContainerStateRunning.String()
}

fmt.Printf("Registry (authenticated): %s\n", authStatus)
fmt.Printf(" IP: %s\n", authInfo.IP)
fmt.Printf(" Host port: %d\n", authInfo.HostPort)
fmt.Printf(" Pull: %s/<image>:<tag>\n", authInfo.PullURL)
fmt.Printf(" Credentials: %s / %s\n", authInfo.Username, authInfo.Password)

return nil
},
Expand Down
16 changes: 13 additions & 3 deletions internal/cli/registry/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,33 @@ import (
)

func newStartCmd() *cobra.Command {
var authOnly bool

cmd := &cobra.Command{
Use: "start",
Short: "Start the local container registry",
Long: "Start the shared local registry container, creating it if it doesn't exist",
Long: "Start the shared local registry containers, creating them if they don't exist",
RunE: func(cmd *cobra.Command, args []string) error {
mgr, err := registrypkg.NewManager()
if err != nil {
return fmt.Errorf("creating registry manager: %w", err)
}

if err := mgr.EnsureRegistry(cmd.Context()); err != nil {
return fmt.Errorf("starting registry: %w", err)
if !authOnly {
if err := mgr.EnsureRegistry(cmd.Context()); err != nil {
return fmt.Errorf("starting registry: %w", err)
}
}

if err := mgr.EnsureAuthRegistry(cmd.Context()); err != nil {
return fmt.Errorf("starting auth registry: %w", err)
}

return nil
},
}

cmd.Flags().BoolVar(&authOnly, "auth", false, "Start only the authenticated registry")

return cmd
}
22 changes: 19 additions & 3 deletions internal/cli/registry/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,40 @@ import (
)

func newStopCmd() *cobra.Command {
var authOnly bool

cmd := &cobra.Command{
Use: "stop",
Short: "Stop and remove the local registry",
Long: "Stop the shared local registry container and remove its data volume",
Short: "Stop and remove the local registries",
Long: "Stop both local registry containers and remove the shared data volume. Use --auth to stop only the authenticated registry.",
RunE: func(cmd *cobra.Command, args []string) error {
mgr, err := registrypkg.NewManager()
if err != nil {
return fmt.Errorf("creating registry manager: %w", err)
}

if err := mgr.StopAuthRegistry(cmd.Context()); err != nil {
if authOnly {
return fmt.Errorf("stopping auth registry: %w", err)
}
logrus.Warnf("Failed to stop auth registry: %v", err)
}

if authOnly {
logrus.Info("Auth registry stopped and removed")
return nil
}

if err := mgr.StopRegistry(cmd.Context()); err != nil {
return fmt.Errorf("stopping registry: %w", err)
}

logrus.Info("Registry stopped and data removed")
logrus.Info("All registries stopped and data removed")
return nil
},
}

cmd.Flags().BoolVar(&authOnly, "auth", false, "Stop only the authenticated registry")

return cmd
}
8 changes: 8 additions & 0 deletions internal/config/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,14 @@ const (
RegistryStaticIP = "10.88.0.2"
RegistryHostname = "registry"
RegistryVolume = "bink-registry-data"
RegistryHTTPSecret = "bink-shared-secret"

AuthRegistryContainerName = "bink-auth-registry"
AuthRegistryPort = 5001
AuthRegistryStaticIP = "10.88.0.3"
AuthRegistryHostname = "auth-registry"
AuthRegistryUsername = "testuser"
AuthRegistryPassword = "testpassword"

HAProxyImage = "docker.io/library/haproxy:lts-alpine"
HAProxyContainerName = "haproxy"
Expand Down
8 changes: 8 additions & 0 deletions internal/node/cloudinit.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ type CloudInitData struct {
RegistryHostname string
ServiceCIDR string
TargetImgRef string

AuthRegistryStaticIP string
AuthRegistryPort int
AuthRegistryHostname string
}

func (n *Node) newCloudInitData(sshPubKey string) CloudInitData {
Expand All @@ -56,6 +60,10 @@ func (n *Node) newCloudInitData(sshPubKey string) CloudInitData {
RegistryHostname: config.RegistryHostname,
ServiceCIDR: config.ServiceCIDR,
TargetImgRef: n.TargetImgRef,

AuthRegistryStaticIP: config.AuthRegistryStaticIP,
AuthRegistryPort: config.AuthRegistryPort,
AuthRegistryHostname: config.AuthRegistryHostname,
}
}

Expand Down
14 changes: 14 additions & 0 deletions internal/node/cloudinit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package node

import (
"fmt"
"strings"
"testing"

Expand All @@ -25,6 +26,10 @@ func testCloudInitData() CloudInitData {
RegistryPort: config.RegistryPort,
RegistryHostname: config.RegistryHostname,
ServiceCIDR: config.ServiceCIDR,

AuthRegistryStaticIP: config.AuthRegistryStaticIP,
Comment thread
HarshwardhanPatil07 marked this conversation as resolved.
AuthRegistryPort: config.AuthRegistryPort,
AuthRegistryHostname: config.AuthRegistryHostname,
}
}

Expand Down Expand Up @@ -117,6 +122,15 @@ func TestRenderTemplate_UserData(t *testing.T) {
if !strings.Contains(s, registryURL) {
t.Errorf("missing registry URL %s", registryURL)
}

authRegistryURL := fmt.Sprintf("%s:%d", config.AuthRegistryStaticIP, config.AuthRegistryPort)
if !strings.Contains(s, authRegistryURL) {
t.Errorf("missing auth registry URL %s", authRegistryURL)
}
authRegistryFQDN := fmt.Sprintf("%s.%s:%d", config.AuthRegistryHostname, config.ClusterDomain, config.AuthRegistryPort)
if !strings.Contains(s, authRegistryFQDN) {
t.Errorf("missing auth registry FQDN %s", authRegistryFQDN)
}
}

func TestValidateYAML(t *testing.T) {
Expand Down
10 changes: 9 additions & 1 deletion internal/node/templates/user-data.yaml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ write_files:
- path: /etc/crio/crio.conf.d/03-local-registry.conf
content: |
[crio.image]
insecure_registries = ["{{.RegistryStaticIP}}:{{.RegistryPort}}", "{{.RegistryHostname}}.{{.ClusterDomain}}:{{.RegistryPort}}"]
insecure_registries = ["{{.RegistryStaticIP}}:{{.RegistryPort}}", "{{.RegistryHostname}}.{{.ClusterDomain}}:{{.RegistryPort}}", "{{.AuthRegistryStaticIP}}:{{.AuthRegistryPort}}", "{{.AuthRegistryHostname}}.{{.ClusterDomain}}:{{.AuthRegistryPort}}"]
- path: /etc/containers/registries.conf.d/10-local-registry.conf
content: |
[[registry]]
Expand All @@ -52,6 +52,14 @@ write_files:
[[registry]]
location = "{{.RegistryHostname}}.{{.ClusterDomain}}:{{.RegistryPort}}"
insecure = true

[[registry]]
location = "{{.AuthRegistryStaticIP}}:{{.AuthRegistryPort}}"
insecure = true

[[registry]]
location = "{{.AuthRegistryHostname}}.{{.ClusterDomain}}:{{.AuthRegistryPort}}"
insecure = true
- path: /etc/systemd/system/var-mnt-cluster_images.mount
content: |
[Unit]
Expand Down
Loading
Loading