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

     1  package flagparser
     2  
     3  import (
     4  	"github.com/docker/swarmkit/api"
     5  	"github.com/spf13/cobra"
     6  )
     7  
     8  // ParseAddCapability validates capabilities passed on the command line
     9  func ParseAddCapability(cmd *cobra.Command, spec *api.ServiceSpec, flagName string) error {
    10  	flags := cmd.Flags()
    11  
    12  	if !flags.Changed(flagName) {
    13  		return nil
    14  	}
    15  
    16  	add, err := flags.GetStringSlice(flagName)
    17  	if err != nil {
    18  		return err
    19  	}
    20  
    21  	container := spec.Task.GetContainer()
    22  	if container == nil {
    23  		return nil
    24  	}
    25  
    26  	// Index adds so we don't have to double loop
    27  	addIndex := make(map[string]bool, len(add))
    28  	for _, v := range add {
    29  		addIndex[v] = true
    30  	}
    31  
    32  	// Check if any of the adds are in drop so we can remove them from the drop list.
    33  	var evict []int
    34  	for i, v := range container.CapabilityDrop {
    35  		if addIndex[v] {
    36  			evict = append(evict, i)
    37  		}
    38  	}
    39  	for n, i := range evict {
    40  		container.CapabilityDrop = append(container.CapabilityDrop[:i-n], container.CapabilityDrop[i-n+1:]...)
    41  	}
    42  
    43  	// De-dup the list to be added
    44  	for _, v := range container.CapabilityAdd {
    45  		if addIndex[v] {
    46  			delete(addIndex, v)
    47  			continue
    48  		}
    49  	}
    50  
    51  	for cap := range addIndex {
    52  		container.CapabilityAdd = append(container.CapabilityAdd, cap)
    53  	}
    54  
    55  	return nil
    56  }
    57  
    58  // ParseDropCapability validates capabilities passed on the command line
    59  func ParseDropCapability(cmd *cobra.Command, spec *api.ServiceSpec, flagName string) error {
    60  	flags := cmd.Flags()
    61  
    62  	if !flags.Changed(flagName) {
    63  		return nil
    64  	}
    65  
    66  	drop, err := flags.GetStringSlice(flagName)
    67  	if err != nil {
    68  		return err
    69  	}
    70  
    71  	container := spec.Task.GetContainer()
    72  	if container == nil {
    73  		return nil
    74  	}
    75  
    76  	// Index removals so we don't have to double loop
    77  	dropIndex := make(map[string]bool, len(drop))
    78  	for _, v := range drop {
    79  		dropIndex[v] = true
    80  	}
    81  
    82  	// Check if any of the adds are in add so we can remove them from the add list.
    83  	var evict []int
    84  	for i, v := range container.CapabilityAdd {
    85  		if dropIndex[v] {
    86  			evict = append(evict, i)
    87  		}
    88  	}
    89  	for n, i := range evict {
    90  		container.CapabilityAdd = append(container.CapabilityAdd[:i-n], container.CapabilityAdd[i-n+1:]...)
    91  	}
    92  
    93  	// De-dup the list to be dropped
    94  	for _, v := range container.CapabilityDrop {
    95  		if dropIndex[v] {
    96  			delete(dropIndex, v)
    97  			continue
    98  		}
    99  	}
   100  
   101  	for cap := range dropIndex {
   102  		container.CapabilityDrop = append(container.CapabilityDrop, cap)
   103  	}
   104  
   105  	return nil
   106  }