From 2a898b3eee397d57efd2a27bcad245173258b51e Mon Sep 17 00:00:00 2001 From: Pavel Sviderski Date: Fri, 27 Dec 2024 21:25:33 +1000 Subject: [PATCH] add -v|--volume to bind mount host path into a service container --- cmd/uncloud/service/run.go | 10 ++++++++-- internal/api/service.go | 2 ++ internal/cli/client/service.go | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/cmd/uncloud/service/run.go b/cmd/uncloud/service/run.go index 2b62a6b7..5a0fc4bb 100644 --- a/cmd/uncloud/service/run.go +++ b/cmd/uncloud/service/run.go @@ -15,6 +15,7 @@ type runOptions struct { mode string name string publish []string + volumes []string cluster string } @@ -55,8 +56,11 @@ func NewRunCommand() *cobra.Command { "Supported protocols: tcp, udp, http, https (default is tcp). If a hostname for http(s) port is not specified, a random hostname is generated.\n"+ "Examples:\n"+ " -p app.example.com:8080/https Publish port 8080 as HTTPS via load balancer with custom hostname\n"+ - " -p 9000:8080 Publish port 8080 as TCP port 9000 via load balancer\n"+ - " -p 53:5353/udp@host Bind UDP port 5353 to host port 53") + " -p 9000:8080 Publish port 8080 as TCP port 9000 via load balancer\n"+ + " -p 53:5353/udp@host Bind UDP port 5353 to host port 53") + cmd.Flags().StringSliceVarP(&opts.volumes, "volume", "v", nil, + "Bind mount a host file or directory into a service container using the format "+ + "/host/path:/container/path[:ro]. Can be specified multiple times.") cmd.Flags().StringVarP( &opts.cluster, "cluster", "c", "", @@ -81,11 +85,13 @@ func run(ctx context.Context, uncli *cli.CLI, opts runOptions) error { } ports[i] = port } + // TODO: parse and validate opts.volumes to fail fast if invalid. spec := api.ServiceSpec{ Container: api.ContainerSpec{ Command: opts.command, Image: opts.image, + Volumes: opts.volumes, }, Mode: opts.mode, Name: opts.name, diff --git a/internal/api/service.go b/internal/api/service.go index 6e1a81c1..8db0d496 100644 --- a/internal/api/service.go +++ b/internal/api/service.go @@ -42,6 +42,8 @@ type ContainerSpec struct { Image string // Run a custom init inside the container. If nil, use the daemon's configured settings. Init *bool + // List of volumes to bind mount into the container. + Volumes []string } func (s *ContainerSpec) Validate() error { diff --git a/internal/cli/client/service.go b/internal/cli/client/service.go index b3419a4f..9a159316 100644 --- a/internal/cli/client/service.go +++ b/internal/cli/client/service.go @@ -268,6 +268,7 @@ func (cli *Client) runContainer( } } hostConfig := &container.HostConfig{ + Binds: spec.Container.Volumes, Init: spec.Container.Init, PortBindings: portBindings, }