mirror of
https://github.com/psviderski/uncloud.git
synced 2026-08-26 11:03:34 +00:00
feat: implement --pull policy for run command: always, missing, never
This commit is contained in:
@@ -21,6 +21,7 @@ type runOptions struct {
|
|||||||
mode string
|
mode string
|
||||||
name string
|
name string
|
||||||
publish []string
|
publish []string
|
||||||
|
pull string
|
||||||
replicas uint
|
replicas uint
|
||||||
volumes []string
|
volumes []string
|
||||||
|
|
||||||
@@ -50,8 +51,8 @@ func NewRunCommand() *cobra.Command {
|
|||||||
cmd.Flags().StringVar(&opts.entrypoint, "entrypoint", "",
|
cmd.Flags().StringVar(&opts.entrypoint, "entrypoint", "",
|
||||||
"Overwrite the default ENTRYPOINT of the image. Pass an empty string \"\" to reset it.")
|
"Overwrite the default ENTRYPOINT of the image. Pass an empty string \"\" to reset it.")
|
||||||
cmd.Flags().StringVar(&opts.mode, "mode", api.ServiceModeReplicated,
|
cmd.Flags().StringVar(&opts.mode, "mode", api.ServiceModeReplicated,
|
||||||
fmt.Sprintf("Replication mode of the service: either %q (a specified number of containers across "+
|
fmt.Sprintf("Replication mode of the service: either '%s' (a specified number of containers across "+
|
||||||
"the machines) or %q (one container on every machine).",
|
"the machines) or '%s' (one container on every machine).",
|
||||||
api.ServiceModeReplicated, api.ServiceModeGlobal))
|
api.ServiceModeReplicated, api.ServiceModeGlobal))
|
||||||
cmd.Flags().StringSliceVarP(&opts.machines, "machine", "m", nil,
|
cmd.Flags().StringSliceVarP(&opts.machines, "machine", "m", nil,
|
||||||
"Placement constraint by machine name, limiting which machines the service can run on. Can be specified "+
|
"Placement constraint by machine name, limiting which machines the service can run on. Can be specified "+
|
||||||
@@ -68,6 +69,9 @@ func NewRunCommand() *cobra.Command {
|
|||||||
" -p app.example.com:8080/https Publish port 8080 as HTTPS via load balancer with custom hostname\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 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 53:5353/udp@host Bind UDP port 5353 to host port 53")
|
||||||
|
cmd.Flags().StringVar(&opts.pull, "pull", api.PullPolicyMissing,
|
||||||
|
fmt.Sprintf("Pull image from the registry before running service containers ('%s', '%s', '%s').",
|
||||||
|
api.PullPolicyAlways, api.PullPolicyMissing, api.PullPolicyNever))
|
||||||
cmd.Flags().UintVar(&opts.replicas, "replicas", 1,
|
cmd.Flags().UintVar(&opts.replicas, "replicas", 1,
|
||||||
"Number of containers to run for the service. Only valid for a replicated service.")
|
"Number of containers to run for the service. Only valid for a replicated service.")
|
||||||
cmd.Flags().StringSliceVarP(&opts.volumes, "volume", "v", nil,
|
cmd.Flags().StringSliceVarP(&opts.volumes, "volume", "v", nil,
|
||||||
@@ -86,7 +90,13 @@ func run(ctx context.Context, uncli *cli.CLI, opts runOptions) error {
|
|||||||
switch opts.mode {
|
switch opts.mode {
|
||||||
case api.ServiceModeReplicated, api.ServiceModeGlobal:
|
case api.ServiceModeReplicated, api.ServiceModeGlobal:
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("invalid replication mode: %q", opts.mode)
|
return fmt.Errorf("invalid replication mode: '%s'", opts.mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch opts.pull {
|
||||||
|
case api.PullPolicyAlways, api.PullPolicyMissing, api.PullPolicyNever:
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid pull policy: '%s'", opts.pull)
|
||||||
}
|
}
|
||||||
|
|
||||||
var machineFilter deploy.MachineFilter
|
var machineFilter deploy.MachineFilter
|
||||||
@@ -124,9 +134,10 @@ func run(ctx context.Context, uncli *cli.CLI, opts runOptions) error {
|
|||||||
|
|
||||||
spec := api.ServiceSpec{
|
spec := api.ServiceSpec{
|
||||||
Container: api.ContainerSpec{
|
Container: api.ContainerSpec{
|
||||||
Command: opts.command,
|
Command: opts.command,
|
||||||
Image: opts.image,
|
Image: opts.image,
|
||||||
Volumes: opts.volumes,
|
PullPolicy: opts.pull,
|
||||||
|
Volumes: opts.volumes,
|
||||||
},
|
},
|
||||||
Mode: opts.mode,
|
Mode: opts.mode,
|
||||||
Name: opts.name,
|
Name: opts.name,
|
||||||
|
|||||||
+16
-1
@@ -110,10 +110,25 @@ func (cli *Client) CreateContainer(
|
|||||||
|
|
||||||
pw := progress.ContextWriter(ctx)
|
pw := progress.ContextWriter(ctx)
|
||||||
eventID := fmt.Sprintf("Container %s on %s", containerName, machine.Machine.Name)
|
eventID := fmt.Sprintf("Container %s on %s", containerName, machine.Machine.Name)
|
||||||
|
|
||||||
pw.Event(progress.CreatingEvent(eventID))
|
pw.Event(progress.CreatingEvent(eventID))
|
||||||
|
|
||||||
|
if spec.Container.PullPolicy == api.PullPolicyAlways {
|
||||||
|
if err = cli.pullImageWithProgress(ctx, config.Image, machine.Machine.Name, eventID); err != nil {
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
resp, err = cli.Docker.CreateContainer(ctx, config, hostConfig, netConfig, nil, containerName)
|
resp, err = cli.Docker.CreateContainer(ctx, config, hostConfig, netConfig, nil, containerName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
switch spec.Container.PullPolicy {
|
||||||
|
case api.PullPolicyAlways, api.PullPolicyNever:
|
||||||
|
return resp, err
|
||||||
|
case api.PullPolicyMissing:
|
||||||
|
default:
|
||||||
|
return resp, fmt.Errorf("unsupported pull policy: '%s'", spec.Container.PullPolicy)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not found error is expected if the image is missing.
|
||||||
if !dockerclient.IsErrNotFound(err) {
|
if !dockerclient.IsErrNotFound(err) {
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ func (s *RollingStrategy) Plan(
|
|||||||
// planReplicated creates a plan for a replicated service deployment.
|
// planReplicated creates a plan for a replicated service deployment.
|
||||||
// For replicated services, we want to maintain a specific number of containers (replicas) across the available machines
|
// For replicated services, we want to maintain a specific number of containers (replicas) across the available machines
|
||||||
// in the cluster.
|
// in the cluster.
|
||||||
|
// TODO: schedule containers only on machines that contain the image if pull policy is set to 'never'.
|
||||||
func (s *RollingStrategy) planReplicated(
|
func (s *RollingStrategy) planReplicated(
|
||||||
ctx context.Context, cli api.MachineClient, svc *api.Service, spec api.ServiceSpec,
|
ctx context.Context, cli api.MachineClient, svc *api.Service, spec api.ServiceSpec,
|
||||||
) (Plan, error) {
|
) (Plan, error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user