github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/cmd/swarmctl/service/flagparser/resource.go (about)

     1  package flagparser
     2  
     3  import (
     4  	"fmt"
     5  	"math/big"
     6  
     7  	"github.com/docker/go-units"
     8  	"github.com/docker/swarmkit/api"
     9  	"github.com/docker/swarmkit/api/genericresource"
    10  	"github.com/spf13/pflag"
    11  )
    12  
    13  func parseResourceCPU(flags *pflag.FlagSet, resources *api.Resources, name string) error {
    14  	cpu, err := flags.GetString(name)
    15  	if err != nil {
    16  		return err
    17  	}
    18  
    19  	nanoCPUs, ok := new(big.Rat).SetString(cpu)
    20  	if !ok {
    21  		return fmt.Errorf("invalid cpu: %s", cpu)
    22  	}
    23  	cpuRat := new(big.Rat).Mul(nanoCPUs, big.NewRat(1e9, 1))
    24  	if !cpuRat.IsInt() {
    25  		return fmt.Errorf("CPU value cannot have more than 9 decimal places: %s", cpu)
    26  	}
    27  	resources.NanoCPUs = cpuRat.Num().Int64()
    28  	return nil
    29  }
    30  
    31  func parseResourceMemory(flags *pflag.FlagSet, resources *api.Resources, name string) error {
    32  	memory, err := flags.GetString(name)
    33  	if err != nil {
    34  		return err
    35  	}
    36  
    37  	bytes, err := units.RAMInBytes(memory)
    38  	if err != nil {
    39  		return err
    40  	}
    41  
    42  	resources.MemoryBytes = bytes
    43  	return nil
    44  }
    45  
    46  func parseResource(flags *pflag.FlagSet, spec *api.ServiceSpec) error {
    47  	if flags.Changed("memory-reservation") {
    48  		if spec.Task.Resources == nil {
    49  			spec.Task.Resources = &api.ResourceRequirements{}
    50  		}
    51  		if spec.Task.Resources.Reservations == nil {
    52  			spec.Task.Resources.Reservations = &api.Resources{}
    53  		}
    54  		if err := parseResourceMemory(flags, spec.Task.Resources.Reservations, "memory-reservation"); err != nil {
    55  			return err
    56  		}
    57  	}
    58  
    59  	if flags.Changed("memory-limit") {
    60  		if spec.Task.Resources == nil {
    61  			spec.Task.Resources = &api.ResourceRequirements{}
    62  		}
    63  		if spec.Task.Resources.Limits == nil {
    64  			spec.Task.Resources.Limits = &api.Resources{}
    65  		}
    66  		if err := parseResourceMemory(flags, spec.Task.Resources.Limits, "memory-limit"); err != nil {
    67  			return err
    68  		}
    69  	}
    70  
    71  	if flags.Changed("cpu-reservation") {
    72  		if spec.Task.Resources == nil {
    73  			spec.Task.Resources = &api.ResourceRequirements{}
    74  		}
    75  		if spec.Task.Resources.Reservations == nil {
    76  			spec.Task.Resources.Reservations = &api.Resources{}
    77  		}
    78  		if err := parseResourceCPU(flags, spec.Task.Resources.Reservations, "cpu-reservation"); err != nil {
    79  			return err
    80  		}
    81  	}
    82  
    83  	if flags.Changed("cpu-limit") {
    84  		if spec.Task.Resources == nil {
    85  			spec.Task.Resources = &api.ResourceRequirements{}
    86  		}
    87  		if spec.Task.Resources.Limits == nil {
    88  			spec.Task.Resources.Limits = &api.Resources{}
    89  		}
    90  		if err := parseResourceCPU(flags, spec.Task.Resources.Limits, "cpu-limit"); err != nil {
    91  			return err
    92  		}
    93  	}
    94  
    95  	if flags.Changed("generic-resources") {
    96  		if spec.Task.Resources == nil {
    97  			spec.Task.Resources = &api.ResourceRequirements{}
    98  		}
    99  		if spec.Task.Resources.Reservations == nil {
   100  			spec.Task.Resources.Reservations = &api.Resources{}
   101  		}
   102  
   103  		cmd, err := flags.GetString("generic-resources")
   104  		if err != nil {
   105  			return err
   106  		}
   107  		spec.Task.Resources.Reservations.Generic, err = genericresource.ParseCmd(cmd)
   108  		if err != nil {
   109  			return err
   110  		}
   111  		err = genericresource.ValidateTask(spec.Task.Resources.Reservations)
   112  		if err != nil {
   113  			return err
   114  		}
   115  	}
   116  
   117  	if flags.Changed("ulimit") {
   118  		container := spec.Task.GetContainer()
   119  		if container == nil {
   120  			return nil
   121  		}
   122  
   123  		ulimits, err := flags.GetStringSlice("ulimit")
   124  		if err != nil {
   125  			return err
   126  		}
   127  
   128  		container.Ulimits = make([]*api.ContainerSpec_Ulimit, len(ulimits))
   129  
   130  		for i, ulimit := range ulimits {
   131  			parsed, err := units.ParseUlimit(ulimit)
   132  			if err != nil {
   133  				return err
   134  			}
   135  
   136  			container.Ulimits[i] = &api.ContainerSpec_Ulimit{
   137  				Name: parsed.Name,
   138  				Soft: parsed.Soft,
   139  				Hard: parsed.Hard,
   140  			}
   141  		}
   142  	}
   143  
   144  	return nil
   145  }