@@ -235,15 +235,17 @@ type resourceOptions struct {
235235 resCPU opts.NanoCPUs
236236 resMemBytes opts.MemBytes
237237 resGenericResources []string
238+ swapBytes opts.MemBytes
239+ memSwappiness int64
238240}
239241
240- func (r * resourceOptions ) ToResourceRequirements () (* swarm.ResourceRequirements , error ) {
242+ func (r * resourceOptions ) ToResourceRequirements (flags * pflag. FlagSet ) (* swarm.ResourceRequirements , error ) {
241243 generic , err := ParseGenericResources (r .resGenericResources )
242244 if err != nil {
243245 return nil , err
244246 }
245247
246- return & swarm.ResourceRequirements {
248+ resreq := & swarm.ResourceRequirements {
247249 Limits : & swarm.Limit {
248250 NanoCPUs : r .limitCPU .Value (),
249251 MemoryBytes : r .limitMemBytes .Value (),
@@ -254,7 +256,20 @@ func (r *resourceOptions) ToResourceRequirements() (*swarm.ResourceRequirements,
254256 MemoryBytes : r .resMemBytes .Value (),
255257 GenericResources : generic ,
256258 },
257- }, nil
259+ }
260+
261+ // SwapBytes and MemorySwappiness are *int64 (pointers), so we need to have
262+ // a variable we can take a pointer to. Additionally, we need to ensure
263+ // that these values are only set if they are set as options.
264+ if flags .Changed (flagSwapBytes ) {
265+ swapBytes := r .swapBytes .Value ()
266+ resreq .SwapBytes = & swapBytes
267+ }
268+ if flags .Changed (flagMemSwappiness ) {
269+ resreq .MemorySwappiness = & r .memSwappiness
270+ }
271+
272+ return resreq , nil
258273}
259274
260275type restartPolicyOptions struct {
@@ -734,7 +749,7 @@ func (options *serviceOptions) ToService(ctx context.Context, apiClient client.N
734749 return networks [i ].Target < networks [j ].Target
735750 })
736751
737- resources , err := options .resources .ToResourceRequirements ()
752+ resources , err := options .resources .ToResourceRequirements (flags )
738753 if err != nil {
739754 return service , err
740755 }
@@ -889,6 +904,10 @@ func addServiceFlags(flags *pflag.FlagSet, options *serviceOptions, defaultFlagV
889904 flags .Var (& options .resources .resMemBytes , flagReserveMemory , "Reserve Memory" )
890905 flags .Int64Var (& options .resources .limitPids , flagLimitPids , 0 , "Limit maximum number of processes (default 0 = unlimited)" )
891906 flags .SetAnnotation (flagLimitPids , "version" , []string {"1.41" })
907+ flags .Var (& options .resources .swapBytes , flagSwapBytes , "Swap Bytes (-1 for unlimited)" )
908+ flags .SetAnnotation (flagLimitPids , "version" , []string {"1.52" })
909+ flags .Int64Var (& options .resources .memSwappiness , flagMemSwappiness , - 1 , "Tune memory swappiness (0-100), -1 to reset to default" )
910+ flags .SetAnnotation (flagLimitPids , "version" , []string {"1.52" })
892911
893912 flags .Var (& options .stopGrace , flagStopGracePeriod , flagDesc (flagStopGracePeriod , "Time to wait before force killing a container (ns|us|ms|s|m|h)" ))
894913 flags .Var (& options .replicas , flagReplicas , "Number of tasks" )
@@ -1073,6 +1092,8 @@ const (
10731092 flagUlimitAdd = "ulimit-add"
10741093 flagUlimitRemove = "ulimit-rm"
10751094 flagOomScoreAdj = "oom-score-adj"
1095+ flagSwapBytes = "memory-swap"
1096+ flagMemSwappiness = "memory-swappiness"
10761097)
10771098
10781099func toNetipAddrSlice (ips []string ) []netip.Addr {
0 commit comments