Skip to content

Commit

Permalink
generating the config for the containerd fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Mehul-Kumar-27 committed Oct 29, 2024
1 parent 949c60c commit 1b6b45c
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 149 deletions.
59 changes: 24 additions & 35 deletions cmd/container_runtime/containerd.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"container-registry.com/harbor-satellite/internal/utils"
"container-registry.com/harbor-satellite/logger"
"container-registry.com/harbor-satellite/registry"
containerd "github.com/containerd/containerd/pkg/cri/config"
toml "github.com/pelletier/go-toml"
"github.com/rs/zerolog"
"github.com/spf13/cobra"
Expand All @@ -21,6 +20,7 @@ const (
DefaultGeneratedTomlName = "config.toml"
ContainerdRuntime = "containerd"
DefaultContainerdConfigPath = "/etc/containerd/config.toml"
DefaultConfigVersion = 2
)

type ContainerdController interface {
Expand Down Expand Up @@ -80,7 +80,12 @@ func NewContainerdCommand() *cobra.Command {
if generateConfig {
log.Info().Msg("Generating containerd config file for containerd ...")
log.Info().Msgf("Fetching containerd config from path path: %s", containerdConfigPath)
return GenerateContainerdHostConfig(containerDCertPath, DefaultGenPath, log, *satelliteHostConfig)
err := GenerateContainerdHostConfig(containerDCertPath, DefaultGenPath, log, *satelliteHostConfig)
if err != nil {
log.Err(err).Msg("Error generating containerd config")
return fmt.Errorf("could not generate containerd config: %w", err)
}
return GenerateConfig(defaultZotConfig, log, containerdConfigPath, containerDCertPath)
}
return nil
},
Expand All @@ -104,48 +109,32 @@ func GenerateConfig(defaultZotConfig *registry.DefaultZotConfig, log *zerolog.Lo
return fmt.Errorf("could not read config file: %w", err)
}
// Now we marshal the data into the containerd config
containerdConfig := &containerd.Config{}
containerdConfig := &ContainerdConfigToml{}
err = toml.Unmarshal(data, containerdConfig)
if err != nil {
log.Err(err).Msg("Error unmarshalling config")
return fmt.Errorf("could not unmarshal config: %w", err)
}
// Steps to configure the containerd config:
// 1. Set the default registry config cert path
// -- This is the path where the certs of the registry are stored
// -- If the user has already has a cert path then we do not set it rather we would now use the
// user path as the default path
if containerdConfig.PluginConfig.Registry.ConfigPath == "" {
containerdConfig.PluginConfig.Registry.ConfigPath = containerdCertPath
// Add the certs.d path to the config
if containerdConfig.Plugins.Cri.Registry.ConfigPath == "" {
containerdConfig.Plugins.Cri.Registry.ConfigPath = containerdCertPath
}
log.Info().Msgf("Setting the registry cert path to: %s", containerdConfig.PluginConfig.Registry.ConfigPath)
// Now we add the local registry to the containerd config mirrors
registryMirror := map[string]containerd.Mirror{
defaultZotConfig.HTTP.Address: {
Endpoints: []string{defaultZotConfig.HTTP.Address + ":" + defaultZotConfig.HTTP.Port},
},
// Set default version
if containerdConfig.Version == 0 {
containerdConfig.Version = DefaultConfigVersion
}
if containerdConfig.PluginConfig.Registry.Mirrors == nil {
containerdConfig.PluginConfig.Registry.Mirrors = registryMirror
} else {
for key, value := range registryMirror {
containerdConfig.PluginConfig.Registry.Mirrors[key] = value
// if config disabled plugins container cri then remove it
if len(containerdConfig.DisabledPlugins) > 0 {
filteredPlugins := make([]string, len(containerdConfig.DisabledPlugins))
for _, plugin := range containerdConfig.DisabledPlugins {
if plugin != "cri" {
filteredPlugins = append(filteredPlugins, plugin)
}
}
}
registryConfig := map[string]containerd.RegistryConfig{
defaultZotConfig.HTTP.Address: {
TLS: &containerd.TLSConfig{
InsecureSkipVerify: config.UseUnsecure(),
},
},
}
// Now we add the local registry to the containerd config registry
if containerdConfig.PluginConfig.Registry.Configs == nil {
containerdConfig.PluginConfig.Registry.Configs = registryConfig
} else {
for key, value := range registryConfig {
containerdConfig.PluginConfig.Registry.Configs[key] = value
if len(filteredPlugins) == 0 {
containerdConfig.DisabledPlugins = nil
}
containerdConfig.DisabledPlugins = filteredPlugins
}
// ToDo: Find a way to remove the unwanted configuration added to the config file while marshalling
pathToWrite := filepath.Join(DefaultGenPath, DefaultGeneratedTomlName)
Expand Down
169 changes: 169 additions & 0 deletions cmd/container_runtime/containerd_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
package runtime

// ContainerdConfigToml provides containerd configuration data for the server
type ContainerdConfigToml struct {
// Version of the config file
Version int `toml:"version"`
// Root is the path to a directory where containerd will store persistent data
Root string `toml:"root"`
// State is the path to a directory where containerd will store transient data
State string `toml:"state"`
// TempDir is the path to a directory where to place containerd temporary files
TempDir string `toml:"temp,omitempty"`
// PluginDir is the directory for dynamic plugins to be stored
//
// Deprecated: Please use proxy or binary external plugins.
PluginDir string `toml:"plugin_dir,omitempty"`
// GRPC configuration settings
GRPC GRPCConfig `toml:"grpc,omitempty"`
// TTRPC configuration settings
TTRPC TTRPCConfig `toml:"ttrpc,omitempty"`
// Debug and profiling settings
Debug Debug `toml:"debug,omitempty"`
// Metrics and monitoring settings
Metrics MetricsConfig `toml:"metrics,omitempty"`
// DisabledPlugins are IDs of plugins to disable. Disabled plugins won't be
// initialized and started.
// DisabledPlugins must use a fully qualified plugin URI.
DisabledPlugins []string `toml:"disabled_plugins,omitempty"`
// RequiredPlugins are IDs of required plugins. Containerd exits if any
// required plugin doesn't exist or fails to be initialized or started.
// RequiredPlugins must use a fully qualified plugin URI.
RequiredPlugins []string `toml:"required_plugins,omitempty"`
// Plugins provides plugin specific configuration for the initialization of a plugin
Plugins PluginsConfig `toml:"plugins,omitempty"`
// OOMScore adjust the containerd's oom score
OOMScore int `toml:"oom_score,omitempty"`
// Cgroup specifies cgroup information for the containerd daemon process
Cgroup CgroupConfig `toml:"cgroup,omitempty"`
// ProxyPlugins configures plugins which are communicated to over GRPC
ProxyPlugins map[string]ProxyPlugin `toml:"proxy_plugins,omitempty"`
// Timeouts specified as a duration
Timeouts map[string]string `toml:"timeouts,omitempty"`
// Imports are additional file path list to config files that can overwrite main config file fields
Imports []string `toml:"imports,omitempty"`
// StreamProcessors configuration
StreamProcessors map[string]StreamProcessor `toml:"stream_processors,omitempty"`
}

type StreamProcessor struct {
// Accepts specific media-types
Accepts []string `toml:"accepts,omitempty"`
// Returns the media-type
Returns string `toml:"returns,omitempty"`
// Path or name of the binary
Path string `toml:"path"`
// Args to the binary
Args []string `toml:"args,omitempty"`
// Environment variables for the binary
Env []string `toml:"env,omitempty"`
}

type GRPCConfig struct {
Address string `toml:"address"`
TCPAddress string `toml:"tcp_address,omitempty"`
TCPTLSCA string `toml:"tcp_tls_ca,omitempty"`
TCPTLSCert string `toml:"tcp_tls_cert,omitempty"`
TCPTLSKey string `toml:"tcp_tls_key,omitempty"`
UID int `toml:"uid,omitempty"`
GID int `toml:"gid,omitempty"`
MaxRecvMsgSize int `toml:"max_recv_message_size,omitempty"`
MaxSendMsgSize int `toml:"max_send_message_size,omitempty"`
}

// TTRPCConfig provides TTRPC configuration for the socket
type TTRPCConfig struct {
Address string `toml:"address"`
UID int `toml:"uid,omitempty"`
GID int `toml:"gid,omitempty"`
}

// Debug provides debug configuration
type Debug struct {
Address string `toml:"address,omitempty"`
UID int `toml:"uid,omitempty"`
GID int `toml:"gid,omitempty"`
Level string `toml:"level,omitempty"`
// Format represents the logging format. Supported values are 'text' and 'json'.
Format string `toml:"format,omitempty"`
}

// MetricsConfig provides metrics configuration
type MetricsConfig struct {
Address string `toml:"address,omitempty"`
GRPCHistogram bool `toml:"grpc_histogram,omitempty"`
}

// CgroupConfig provides cgroup configuration
type CgroupConfig struct {
Path string `toml:"path,omitempty"`
}

// ProxyPlugin provides a proxy plugin configuration
type ProxyPlugin struct {
Type string `toml:"type"`
Address string `toml:"address"`
Platform string `toml:"platform,omitempty"`
Exports map[string]string `toml:"exports,omitempty"`
Capabilities []string `toml:"capabilities,omitempty"`
}

type PluginsConfig struct {
Cri CriConfig `toml:"io.containerd.grpc.v1.cri,omitempty"`
Cgroups MonitorConfig `toml:"io.containerd.monitor.v1.cgroups,omitempty"`
LinuxRuntime interface{} `toml:"io.containerd.runtime.v1.linux,omitempty"`
Scheduler GCSchedulerConfig `toml:"io.containerd.gc.v1.scheduler,omitempty"`
Bolt interface{} `toml:"io.containerd.metadata.v1.bolt,omitempty"`
Task RuntimeV2TaskConfig `toml:"io.containerd.runtime.v2.task,omitempty"`
Opt interface{} `toml:"io.containerd.internal.v1.opt,omitempty"`
Restart interface{} `toml:"io.containerd.internal.v1.restart,omitempty"`
Tracing interface{} `toml:"io.containerd.internal.v1.tracing,omitempty"`
Otlp interface{} `toml:"io.containerd.tracing.processor.v1.otlp,omitempty"`
Aufs interface{} `toml:"io.containerd.snapshotter.v1.aufs,omitempty"`
Btrfs interface{} `toml:"io.containerd.snapshotter.v1.btrfs,omitempty"`
Devmapper interface{} `toml:"io.containerd.snapshotter.v1.devmapper,omitempty"`
Native interface{} `toml:"io.containerd.snapshotter.v1.native,omitempty"`
Overlayfs interface{} `toml:"io.containerd.snapshotter.v1.overlayfs,omitempty"`
Zfs interface{} `toml:"io.containerd.snapshotter.v1.zfs,omitempty"`
}

type MonitorConfig struct {
NoPrometheus bool `toml:"no_prometheus,omitempty"`
}

type GCSchedulerConfig struct {
PauseThreshold float64 `toml:"pause_threshold,omitempty"`
DeletionThreshold int `toml:"deletion_threshold,omitempty"`
MutationThreshold int `toml:"mutation_threshold,omitempty"`
ScheduleDelay string `toml:"schedule_delay,omitempty"`
StartupDelay string `toml:"startup_delay,omitempty"`
}

type RuntimeV2TaskConfig struct {
Platforms []string `toml:"platforms,omitempty"`
SchedCore bool `toml:"sched_core,omitempty"`
}

type CriConfig struct {
Containerd CriContainerdConfig `toml:"containerd,omitempty"`
Registry RegistryConfig `toml:"registry,omitempty"`
}

type CriContainerdConfig struct {
DefaultRuntimeName string `toml:"default_runtime_name,omitempty"`
Runtimes map[string]RuntimeConfig `toml:"runtimes,omitempty"`
}

type RuntimeConfig struct {
PrivilegedWithoutHostDevices bool `toml:"privileged_without_host_devices,omitempty"`
RuntimeType string `toml:"runtime_type"`
Options RuntimeOptions `toml:"options,omitempty"`
}

type RuntimeOptions struct {
BinaryName string `toml:"BinaryName,omitempty"`
}

type RegistryConfig struct {
ConfigPath string `toml:"config_path,omitempty"`
}
7 changes: 6 additions & 1 deletion registry/default_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io"
"os"
"strings"
)

type DefaultZotConfig struct {
Expand All @@ -22,7 +23,11 @@ type DefaultZotConfig struct {
}

func (c *DefaultZotConfig) GetLocalRegistryURL() string {
return fmt.Sprintf("%s:%s", c.HTTP.Address, c.HTTP.Port)
address := c.HTTP.Address
if !strings.HasPrefix(address, "http://") && !strings.HasPrefix(address, "https://") {
address = "http://" + address
}
return fmt.Sprintf("%s:%s", address, c.HTTP.Port)
}

// ReadConfig reads a JSON file from the specified path and unmarshals it into a Config struct.
Expand Down
Loading

0 comments on commit 1b6b45c

Please sign in to comment.