diff --git a/Dockerfile b/Dockerfile index f1bf3af52c..d14c3a4e37 100644 --- a/Dockerfile +++ b/Dockerfile @@ -811,6 +811,7 @@ END FROM rootfs-base-${TARGETARCH} AS rootfs-base RUN echo "true" > /rootfs/usr/etc/in-container +RUN rm -rf /rootfs/lib/modules/* RUN find /rootfs -print0 \ | xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}" diff --git a/cmd/talosctl/cmd/mgmt/cluster/create.go b/cmd/talosctl/cmd/mgmt/cluster/create.go index 5dbba1de2f..2d1b155e03 100644 --- a/cmd/talosctl/cmd/mgmt/cluster/create.go +++ b/cmd/talosctl/cmd/mgmt/cluster/create.go @@ -22,6 +22,7 @@ import ( "strings" "time" + "github.com/docker/cli/opts" "github.com/dustin/go-humanize" "github.com/google/uuid" "github.com/hashicorp/go-getter/v2" @@ -193,6 +194,7 @@ var ( withJSONLogs bool debugShellEnabled bool configInjectionMethodFlag string + mountOpts opts.MountOpt ) // createCmd represents the cluster up command. @@ -900,6 +902,7 @@ func create(ctx context.Context) error { Memory: controlPlaneMemory, NanoCPUs: controlPlaneNanoCPUs, Disks: disks, + Mounts: mountOpts.Value(), SkipInjectingConfig: skipInjectingConfig, ConfigInjectionMethod: configInjectionMethod, BadRTC: badRTC, @@ -976,6 +979,7 @@ func create(ctx context.Context) error { Memory: workerMemory, NanoCPUs: workerNanoCPUs, Disks: disks, + Mounts: mountOpts.Value(), Config: cfg, ConfigInjectionMethod: configInjectionMethod, SkipInjectingConfig: skipInjectingConfig, @@ -1328,6 +1332,7 @@ func init() { createCmd.Flags().Var(&withSiderolinkAgent, "with-siderolink", "enables the use of siderolink agent as configuration apply mechanism. `true` or `wireguard` enables the agent, `tunnel` enables the agent with grpc tunneling") //nolint:lll createCmd.Flags().BoolVar(&withJSONLogs, "with-json-logs", false, "enable JSON logs receiver and configure Talos to send logs there") createCmd.Flags().StringVar(&configInjectionMethodFlag, "config-injection-method", "", "a method to inject machine config: default is HTTP server, 'metal-iso' to mount an ISO (QEMU only)") + createCmd.Flags().Var(&mountOpts, "mount", "attach a mount to the container (Docker only)") createCmd.MarkFlagsMutuallyExclusive(inputDirFlag, nodeInstallImageFlag) createCmd.MarkFlagsMutuallyExclusive(inputDirFlag, configDebugFlag) diff --git a/go.mod b/go.mod index 17a882d2f2..9e6a53f343 100644 --- a/go.mod +++ b/go.mod @@ -76,6 +76,7 @@ require ( github.com/coreos/go-iptables v0.8.0 github.com/cosi-project/runtime v0.6.4 github.com/distribution/reference v0.6.0 + github.com/docker/cli v27.1.1+incompatible github.com/docker/docker v27.3.1+incompatible github.com/docker/go-connections v0.5.0 github.com/dustin/go-humanize v1.0.1 @@ -245,7 +246,6 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/cyphar/filepath-securejoin v0.3.4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/docker/cli v27.1.1+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/go-units v0.5.0 // indirect diff --git a/pkg/provision/providers/docker/node.go b/pkg/provision/providers/docker/node.go index 04e9ab83a7..240bea7e33 100644 --- a/pkg/provision/providers/docker/node.go +++ b/pkg/provision/providers/docker/node.go @@ -11,6 +11,7 @@ import ( "fmt" "net/netip" "runtime" + "slices" "strings" "github.com/docker/docker/api/types" @@ -115,7 +116,7 @@ func (p *provisioner) createNode(ctx context.Context, clusterReq provision.Clust } // Create the host config. - mounts := make([]mount.Mount, 0, len(constants.Overlays)+5) + mounts := make([]mount.Mount, 0, len(constants.Overlays)+5+len(nodeReq.Mounts)) for _, path := range []string{"/run", "/system", "/tmp"} { mounts = append(mounts, mount.Mount{ @@ -131,6 +132,8 @@ func (p *provisioner) createNode(ctx context.Context, clusterReq provision.Clust }) } + mounts = slices.Concat(mounts, nodeReq.Mounts) + hostConfig := &container.HostConfig{ Privileged: true, SecurityOpt: []string{"seccomp:unconfined"}, diff --git a/pkg/provision/request.go b/pkg/provision/request.go index fa0c1cc8cb..d8f831319f 100644 --- a/pkg/provision/request.go +++ b/pkg/provision/request.go @@ -10,6 +10,7 @@ import ( "slices" "time" + mounttypes "github.com/docker/docker/api/types/mount" "github.com/google/uuid" "github.com/siderolabs/go-procfs/procfs" @@ -187,8 +188,10 @@ type NodeRequest struct { NanoCPUs int64 // Memory limit in bytes Memory int64 - // Disks (volumes), if applicable + // Disks (volumes), if applicable (VM only) Disks []*Disk + // Mounts (containers only) + Mounts []mounttypes.Mount // Ports Ports []string // SkipInjectingConfig disables reading configuration from http server diff --git a/website/content/v1.9/reference/cli.md b/website/content/v1.9/reference/cli.md index 1ea4932df5..3f1d8f226a 100644 --- a/website/content/v1.9/reference/cli.md +++ b/website/content/v1.9/reference/cli.md @@ -188,6 +188,7 @@ talosctl cluster create [flags] --kubernetes-version string desired kubernetes version to run (default "1.32.0-alpha.3") --memory int the limit on memory usage in MB (each control plane/VM) (default 2048) --memory-workers int the limit on memory usage in MB (each worker/VM) (default 2048) + --mount mount attach a mount to the container (Docker only) --mtu int MTU of the cluster network (default 1500) --nameservers strings list of nameservers to use (default [8.8.8.8,1.1.1.1,2001:4860:4860::8888,2606:4700:4700::1111]) --no-masquerade-cidrs strings list of CIDRs to exclude from NAT (QEMU provisioner only)