-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add support for nerdctl config and default variables (#73)
Signed-off-by: Shubharanshu Mahapatra <[email protected]>
- Loading branch information
1 parent
80fdae9
commit 284c73f
Showing
6 changed files
with
273 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package main | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"os" | ||
|
||
"github.com/containerd/containerd" | ||
"github.com/containerd/containerd/namespaces" | ||
"github.com/containerd/nerdctl/pkg/api/types" | ||
"github.com/containerd/nerdctl/pkg/config" | ||
toml "github.com/pelletier/go-toml/v2" | ||
"github.com/runfinch/finch-daemon/api/router" | ||
"github.com/runfinch/finch-daemon/internal/backend" | ||
"github.com/runfinch/finch-daemon/internal/service/builder" | ||
"github.com/runfinch/finch-daemon/internal/service/container" | ||
"github.com/runfinch/finch-daemon/internal/service/exec" | ||
"github.com/runfinch/finch-daemon/internal/service/image" | ||
"github.com/runfinch/finch-daemon/internal/service/network" | ||
"github.com/runfinch/finch-daemon/internal/service/system" | ||
"github.com/runfinch/finch-daemon/internal/service/volume" | ||
"github.com/runfinch/finch-daemon/pkg/archive" | ||
"github.com/runfinch/finch-daemon/pkg/ecc" | ||
"github.com/runfinch/finch-daemon/pkg/flog" | ||
"github.com/spf13/afero" | ||
) | ||
|
||
// handleConfigOptions gets nerdctl config value from nerdctl.toml file. | ||
func handleConfigOptions(cfg *config.Config, options *DaemonOptions) error { | ||
tomlPath := options.configPath | ||
r, err := os.Open(tomlPath) | ||
if err != nil { | ||
if errors.Is(err, os.ErrNotExist) { | ||
return nil // File not found; this is not an error. | ||
} | ||
return err // Return other errors directly. | ||
} | ||
defer r.Close() | ||
|
||
dec := toml.NewDecoder(r).DisallowUnknownFields() | ||
if err := dec.Decode(cfg); err != nil { | ||
return fmt.Errorf( | ||
"failed to load config from %q : %w", | ||
tomlPath, err, | ||
) | ||
} | ||
return nil | ||
} | ||
|
||
// initializeConfig initializes configuration from file, environment, and set default values. | ||
func initializeConfig(options *DaemonOptions) (*config.Config, error) { | ||
conf := config.New() | ||
|
||
if err := handleConfigOptions(conf, options); err != nil { | ||
return nil, err | ||
} | ||
|
||
if options.debug { | ||
conf.Debug = options.debug | ||
} | ||
if conf.Namespace == "" || conf.Namespace == namespaces.Default { | ||
conf.Namespace = defaultNamespace | ||
} | ||
|
||
return conf, nil | ||
} | ||
|
||
// createNerdctlWrapper creates the Nerdctl wrapper and checks for the nerdctl binary. | ||
func createNerdctlWrapper(clientWrapper *backend.ContainerdClientWrapper, conf *config.Config) (*backend.NerdctlWrapper, error) { | ||
// GlobalCommandOptions is actually just an alias for Config, see | ||
// https://github.com/containerd/nerdctl/blob/9f8655f7722d6e6851755123730436bf1a6c9995/pkg/api/types/global.go#L21 | ||
globalOptions := (*types.GlobalCommandOptions)(conf) | ||
ncWrapper := backend.NewNerdctlWrapper(clientWrapper, globalOptions) | ||
if _, err := ncWrapper.GetNerdctlExe(); err != nil { | ||
return nil, fmt.Errorf("failed to find nerdctl binary: %w", err) | ||
} | ||
return ncWrapper, nil | ||
} | ||
|
||
// createContainerdClient creates and wraps the containerd client. | ||
func createContainerdClient(conf *config.Config) (*backend.ContainerdClientWrapper, error) { | ||
client, err := containerd.New(conf.Address, containerd.WithDefaultNamespace(conf.Namespace)) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to create containerd client: %w", err) | ||
} | ||
return backend.NewContainerdClientWrapper(client), nil | ||
} | ||
|
||
// createRouterOptions creates router options by initializing all required services. | ||
func createRouterOptions( | ||
conf *config.Config, | ||
clientWrapper *backend.ContainerdClientWrapper, | ||
ncWrapper *backend.NerdctlWrapper, | ||
logger *flog.Logrus, | ||
) *router.Options { | ||
fs := afero.NewOsFs() | ||
tarCreator := archive.NewTarCreator(ecc.NewExecCmdCreator(), logger) | ||
tarExtractor := archive.NewTarExtractor(ecc.NewExecCmdCreator(), logger) | ||
|
||
return &router.Options{ | ||
Config: conf, | ||
ContainerService: container.NewService(clientWrapper, ncWrapper, logger, fs, tarCreator, tarExtractor), | ||
ImageService: image.NewService(clientWrapper, ncWrapper, logger), | ||
NetworkService: network.NewService(clientWrapper, ncWrapper, logger), | ||
SystemService: system.NewService(clientWrapper, ncWrapper, logger), | ||
BuilderService: builder.NewService(clientWrapper, ncWrapper, logger, tarExtractor), | ||
VolumeService: volume.NewService(ncWrapper, logger), | ||
ExecService: exec.NewService(clientWrapper, logger), | ||
NerdctlWrapper: ncWrapper, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package main | ||
|
||
import ( | ||
"os" | ||
"testing" | ||
|
||
"github.com/containerd/nerdctl/pkg/config" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestInitializeConfig(t *testing.T) { | ||
options := &DaemonOptions{} | ||
options.debug = true | ||
|
||
cfg, err := initializeConfig(options) | ||
require.NoError(t, err, "Initialization should succeed.") | ||
|
||
assert.True(t, cfg.Debug, "Debug mode should be enabled.") | ||
assert.Equal(t, "finch", defaultNamespace, "check default namespace") | ||
} | ||
|
||
func TestHandleConfigOptions_FileNotFound(t *testing.T) { | ||
cfg := &config.Config{} | ||
options := &DaemonOptions{} | ||
options.configPath = "/non/existing/path/nerdctl.toml" | ||
|
||
err := handleConfigOptions(cfg, options) | ||
assert.NoError(t, err, "File not found should not cause an error.") | ||
} | ||
|
||
func TestHandleConfigOptions_InvalidTOML(t *testing.T) { | ||
cfg := &config.Config{} | ||
options := &DaemonOptions{} | ||
|
||
tmpFile, err := os.CreateTemp("/tmp", "invalid.toml") | ||
require.NoError(t, err) | ||
|
||
defer os.Remove(tmpFile.Name()) | ||
|
||
options.configPath = tmpFile.Name() | ||
|
||
_, _ = tmpFile.WriteString("invalid_toml") | ||
|
||
err = handleConfigOptions(cfg, options) | ||
assert.Error(t, err, "Invalid TOML should cause an error.") | ||
} | ||
|
||
func TestHandleConfigOptions_ValidTOML(t *testing.T) { | ||
cfg := &config.Config{} | ||
options := &DaemonOptions{} | ||
|
||
// Create a temporary valid TOML file | ||
tmpFile, err := os.CreateTemp("", "valid.toml") | ||
require.NoError(t, err) | ||
|
||
defer os.Remove(tmpFile.Name()) | ||
|
||
options.configPath = tmpFile.Name() | ||
|
||
_, _ = tmpFile.WriteString(` | ||
address = "test_address" | ||
namespace = "test_namespace" | ||
`) | ||
|
||
err = handleConfigOptions(cfg, options) | ||
assert.NoError(t, err, "Valid TOML should not cause an error.") | ||
assert.Equal(t, "test_address", cfg.Address) | ||
assert.Equal(t, "test_namespace", cfg.Namespace) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
|
||
# Configuring finch-daemon specific config | ||
|
||
Finch Daemon takes parameters to configure daemon specific parameters. | ||
|
||
**Flag** | **Description** | **Default Value** | | ||
|---------------------|--------------------------------------------------------|--------------------------| | ||
| `--socket-addr` | The Unix socket address where the server listens. | `/run/finch.sock` | | ||
| `--debug` | Enable debug-level logging. | `false` | | ||
| `--socket-owner` | Set the UID and GID of the server socket owner. | `-1` (no owner) | | ||
| `--config-file` | Path to the daemon's configuration file (TOML format). | `/etc/finch/finch.toml` | | ||
|
||
|
||
Example usage: | ||
```bash | ||
finch-daemon --socket-addr /tmp/finch.sock --debug --socket-owner 1001 --config-file /path/to/config.toml | ||
``` | ||
|
||
# Configuring nerdctl with `finch.toml` | ||
|
||
Finch daemon toml config is used to configure nerdctl parameters. For more details refer to nerdctl github page. [nerdctl configuration guide](https://github.com/containerd/nerdctl/blob/main/docs/config.md). | ||
|
||
|
||
## File path | ||
- `/etc/finch/finch.toml` | ||
|
||
## Example | ||
|
||
```toml | ||
|
||
debug = false | ||
debug_full = false | ||
address = "unix:///run/k3s/containerd/containerd.sock" | ||
namespace = "k8s.io" | ||
snapshotter = "soci" | ||
cgroup_manager = "cgroupfs" | ||
hosts_dir = ["/etc/containerd/certs.d", "/etc/docker/certs.d"] | ||
experimental = true | ||
``` | ||
|
||
## Properties | ||
|
||
| **TOML Property** | **CLI Flag(s)** | **Description** | | ||
|---------------------|------------------------------------------|----------------------------------------------------------------------------------------------------------------------------| | ||
| `debug` | `--debug` | Enable debug mode. | | ||
| `debug_full` | `--debug-full` | Enable debug mode with full output. | | ||
| `address` | `--address`, `--host`, `-a`, `-H` | Address of the containerd daemon. | | ||
| `namespace` | `--namespace`, `-n` | containerd namespace. | | ||
| `snapshotter` | `--snapshotter`, `--storage-driver` | containerd snapshotter or storage driver. | | ||
| `cni_path` | `--cni-path` | Directory containing CNI binaries. | | ||
| `cni_netconfpath` | `--cni-netconfpath` | Directory containing CNI network configurations. | | ||
| `data_root` | `--data-root` | Directory to store persistent state. | | ||
| `cgroup_manager` | `--cgroup-manager` | cgroup manager to use. | | ||
| `insecure_registry` | `--insecure-registry` | Allow communication with insecure registries. | | ||
| `hosts_dir` | `--hosts-dir` | Directory for `certs.d` files. | | ||
| `experimental` | `--experimental` | Enable [experimental features]. | | ||
| `host_gateway_ip` | `--host-gateway-ip` | IP address for the special 'host-gateway' in `--add-host`. Defaults to the host IP. Has no effect without `--add-host`. | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.