@@ -95,13 +95,23 @@ func newUpdateCommand(dockerCli command.Cli) *cobra.Command {
9595 flags .Var (& options .hosts , flagHostAdd , "Add a custom host-to-IP mapping (host:ip)" )
9696 flags .SetAnnotation (flagHostAdd , "version" , []string {"1.25" })
9797
98+ // Add needs parsing, Remove only needs the key
99+ flags .Var (newListOptsVar (), flagGenericResourcesRemove , "Remove a Generic resource" )
100+ flags .SetAnnotation (flagHostAdd , "version" , []string {"1.32" })
101+ flags .Var (newListOptsVarWithValidator (ValidateSingleGenericResource ), flagGenericResourcesAdd , "Add a Generic resource" )
102+ flags .SetAnnotation (flagHostAdd , "version" , []string {"1.32" })
103+
98104 return cmd
99105}
100106
101107func newListOptsVar () * opts.ListOpts {
102108 return opts .NewListOptsRef (& []string {}, nil )
103109}
104110
111+ func newListOptsVarWithValidator (validator opts.ValidatorFctType ) * opts.ListOpts {
112+ return opts .NewListOptsRef (& []string {}, validator )
113+ }
114+
105115// nolint: gocyclo
106116func runUpdate (dockerCli command.Cli , flags * pflag.FlagSet , options * serviceOptions , serviceID string ) error {
107117 apiClient := dockerCli .Client ()
@@ -314,6 +324,14 @@ func updateService(ctx context.Context, apiClient client.NetworkAPIClient, flags
314324 updateInt64Value (flagReserveMemory , & task .Resources .Reservations .MemoryBytes )
315325 }
316326
327+ if err := addGenericResources (flags , task ); err != nil {
328+ return err
329+ }
330+
331+ if err := removeGenericResources (flags , task ); err != nil {
332+ return err
333+ }
334+
317335 updateDurationOpt (flagStopGracePeriod , & cspec .StopGracePeriod )
318336
319337 if anyChanged (flags , flagRestartCondition , flagRestartDelay , flagRestartMaxAttempts , flagRestartWindow ) {
@@ -470,6 +488,72 @@ func anyChanged(flags *pflag.FlagSet, fields ...string) bool {
470488 return false
471489}
472490
491+ func addGenericResources (flags * pflag.FlagSet , spec * swarm.TaskSpec ) error {
492+ if ! flags .Changed (flagGenericResourcesAdd ) {
493+ return nil
494+ }
495+
496+ if spec .Resources == nil {
497+ spec .Resources = & swarm.ResourceRequirements {}
498+ }
499+
500+ if spec .Resources .Reservations == nil {
501+ spec .Resources .Reservations = & swarm.Resources {}
502+ }
503+
504+ values := flags .Lookup (flagGenericResourcesAdd ).Value .(* opts.ListOpts ).GetAll ()
505+ generic , err := ParseGenericResources (values )
506+ if err != nil {
507+ return err
508+ }
509+
510+ m , err := buildGenericResourceMap (spec .Resources .Reservations .GenericResources )
511+ if err != nil {
512+ return err
513+ }
514+
515+ for _ , toAddRes := range generic {
516+ m [toAddRes .DiscreteResourceSpec .Kind ] = toAddRes
517+ }
518+
519+ spec .Resources .Reservations .GenericResources = buildGenericResourceList (m )
520+
521+ return nil
522+ }
523+
524+ func removeGenericResources (flags * pflag.FlagSet , spec * swarm.TaskSpec ) error {
525+ // Can only be Discrete Resources
526+ if ! flags .Changed (flagGenericResourcesRemove ) {
527+ return nil
528+ }
529+
530+ if spec .Resources == nil {
531+ spec .Resources = & swarm.ResourceRequirements {}
532+ }
533+
534+ if spec .Resources .Reservations == nil {
535+ spec .Resources .Reservations = & swarm.Resources {}
536+ }
537+
538+ values := flags .Lookup (flagGenericResourcesRemove ).Value .(* opts.ListOpts ).GetAll ()
539+
540+ m , err := buildGenericResourceMap (spec .Resources .Reservations .GenericResources )
541+ if err != nil {
542+ return err
543+ }
544+
545+ for _ , toRemoveRes := range values {
546+ if _ , ok := m [toRemoveRes ]; ! ok {
547+ return fmt .Errorf ("could not find generic-resource `%s` to remove it" , toRemoveRes )
548+ }
549+
550+ delete (m , toRemoveRes )
551+ }
552+
553+ spec .Resources .Reservations .GenericResources = buildGenericResourceList (m )
554+ return nil
555+ }
556+
473557func updatePlacementConstraints (flags * pflag.FlagSet , placement * swarm.Placement ) {
474558 if flags .Changed (flagConstraintAdd ) {
475559 values := flags .Lookup (flagConstraintAdd ).Value .(* opts.ListOpts ).GetAll ()
0 commit comments