Skip to content
Merged
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
7 changes: 7 additions & 0 deletions cli/cmd/daemon/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
runtimestoresql "github.com/agntcy/dir-runtime/store/sql"
reconcilerconfig "github.com/agntcy/dir/reconciler/config"
serverconfig "github.com/agntcy/dir/server/config"
storeconfig "github.com/agntcy/dir/server/store/oci/config"
"github.com/mitchellh/mapstructure"
"github.com/spf13/viper"
)
Expand Down Expand Up @@ -47,6 +48,11 @@ type RuntimeConfig struct {
Store runtimestore.Config `json:"store" mapstructure:"store"`
}

func registerServerDefaults(v *viper.Viper) {
v.SetDefault("server.store.oci.registry_address", storeconfig.DefaultRegistryAddress)
v.SetDefault("server.store.oci.repository_name", storeconfig.DefaultRepositoryName)
}

func registerRuntimeDefaults(v *viper.Viper) {
v.SetDefault("runtime.enabled", false)

Expand Down Expand Up @@ -102,6 +108,7 @@ func loadConfig() (*DaemonConfig, error) {

bindCredentialEnvVars(v)
registerRuntimeDefaults(v)
registerServerDefaults(v)

if opts.ConfigFile != "" {
v.SetConfigFile(opts.ConfigFile)
Expand Down
6 changes: 4 additions & 2 deletions cli/cmd/daemon/daemon.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ server:
store:
provider: "oci"
oci:
local_dir: "store"
# To use a remote OCI registry instead of local_dir, set:
local_dir: "store" # relative to data-dir or can be absolute path like "/tmp/agntcy/dir/oci/"
registry_address: "localhost:5000"
repository_name: "dir"
# To use a remote OCI registry, unset local_dir:
# registry_address: "ghcr.io"
# repository_name: "org/agents"
verification:
Expand Down
84 changes: 83 additions & 1 deletion cli/cmd/daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@
package daemon

import (
"context"
"errors"
"fmt"
"net"
"net/http"
"os"
"path/filepath"
"strconv"
"syscall"

"github.com/spf13/cobra"
"github.com/spf13/pflag"
zotapi "zotregistry.dev/zot/v2/pkg/api"
zotconfig "zotregistry.dev/zot/v2/pkg/api/config"
)

// Options holds all daemon path configuration.
Expand All @@ -21,7 +27,6 @@ type Options struct {
}

func (o *Options) DBFile() string { return filepath.Join(o.DataDir, "dir.db") }
func (o *Options) StoreDir() string { return filepath.Join(o.DataDir, "store") }
func (o *Options) RoutingDir() string { return filepath.Join(o.DataDir, "routing") }
func (o *Options) PIDFile() string { return filepath.Join(o.DataDir, "daemon.pid") }

Expand Down Expand Up @@ -81,6 +86,83 @@ func removePIDFile() {
_ = os.Remove(opts.PIDFile())
}

func runEmbeddedZot(parentCtx context.Context, address string, rootDirectory string) context.Context {
ctx, cancel := context.WithCancel(parentCtx)

host, port, err := net.SplitHostPort(address)
if err != nil {
logger.Error("failed to split host and port", "error", err)

cancel()

return ctx
}

conf := zotconfig.New()
conf.Storage.RootDirectory = rootDirectory

conf.HTTP.Address = host
conf.HTTP.Port = port
conf.Log.Level = "error"

ctrl := zotapi.NewController(conf)

go func(ctx context.Context) {
shutdown := func() {
defer cancel()

logger.Info("shutting down zot controller")
ctrl.Shutdown()
}

go func() {
<-ctx.Done()
shutdown()
}()

defer func() {
shutdown()
}()

if err := ctrl.Init(); err != nil {
logger.Error("failed to init zot controller", "error", err)

return
}

if err := ctrl.Run(); err != nil {
if !errors.Is(err, context.Canceled) {
logger.Error("failed to run zot controller", "error", err)
}

return
}
}(ctx)

return ctx
}

func isZotReady(address string) (bool, error) {
resp, err := http.Get(fmt.Sprintf("http://%s/v2/", address)) //nolint:noctx
if err != nil {
logger.Debug("zot readiness check failed with error", "error", err)

return false, fmt.Errorf("failed to check zot readiness: %w", err)
}

defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
logger.Debug("zot readiness check failed with status code", "status_code", resp.StatusCode)

return false, fmt.Errorf("zot was not ready, /v2/ returned status code: %d", resp.StatusCode)
}

logger.Debug("zot readiness check passed")

return true, nil
}

// Command is the parent command for daemon subcommands.
var Command = &cobra.Command{
Use: "daemon",
Expand Down
41 changes: 41 additions & 0 deletions cli/cmd/daemon/daemon_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright AGNTCY Contributors (https://github.com/agntcy)
// SPDX-License-Identifier: Apache-2.0

package daemon

import (
"context"
"testing"
"time"

"github.com/stretchr/testify/require"
)

// TestEmbeddedZot tests the embedded Zot server.
func TestEmbeddedZot(t *testing.T) {
address := "localhost:5000"
rootDirectory := "/tmp/agntcy/dir/oci/"

go func() {
ctx := runEmbeddedZot(context.Background(), address, rootDirectory)

defer ctx.Done()
}()

var (
zotIsReady bool
err error
)

for range 10 {
zotIsReady, err = isZotReady(address)
if err == nil && zotIsReady {
break
}

time.Sleep(1 * time.Second)
}

require.NoError(t, err)
require.True(t, zotIsReady)
}
11 changes: 11 additions & 0 deletions cli/cmd/daemon/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ func runStart(cmd *cobra.Command, _ []string) error {
ctx, cancel := context.WithCancel(cmd.Context())
defer cancel()

zotCtx := context.Background()

if cfg.Server.Store.OCI.LocalDir != "" {
zotCtx = runEmbeddedZot(ctx, cfg.Server.Store.OCI.RegistryAddress, cfg.Server.Store.OCI.LocalDir)

cfg.Server.Store.OCI.Insecure = true
Comment thread
arpad-csepi marked this conversation as resolved.
cfg.Server.Store.OCI.LocalDir = ""
}

// Create API server
srv, err := server.New(ctx, &cfg.Server)
if err != nil {
Expand Down Expand Up @@ -157,6 +166,8 @@ func runStart(cmd *cobra.Command, _ []string) error {
logger.Info("Received signal, shutting down", "signal", sig)
case err := <-discoveryErrCh:
logger.Error("Runtime discovery service error", "error", err)
case <-zotCtx.Done():
logger.Info("zot context cancelled, shutting down")
case <-ctx.Done():
logger.Info("Context cancelled, shutting down")
}
Expand Down
Loading
Loading