github.com/drycc/workflow-cli@v1.5.3-0.20240322092846-d4ee25983af9/cmd/volumes.go (about)

     1  package cmd
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  
     7  	"github.com/drycc/controller-sdk-go/api"
     8  	"github.com/drycc/controller-sdk-go/volumes"
     9  	"sigs.k8s.io/yaml"
    10  )
    11  
    12  // VolumesList list volumes in the application
    13  func (d *DryccCmd) VolumesList(appID string, results int) error {
    14  	s, appID, err := load(d.ConfigFile, appID)
    15  
    16  	if err != nil {
    17  		return err
    18  	}
    19  
    20  	if results == defaultLimit {
    21  		results = s.Limit
    22  	}
    23  	//fmt.Println("-----app-----", appID)  # debug
    24  	volumes, count, err := volumes.List(s.Client, appID, results)
    25  	if d.checkAPICompatibility(s.Client, err) != nil {
    26  		return err
    27  	}
    28  
    29  	if count == 0 {
    30  		d.Println("Could not find any volume.")
    31  	} else {
    32  		printVolumes(d, volumes)
    33  	}
    34  	return nil
    35  }
    36  
    37  // VolumesInfo get volume in the application
    38  func (d *DryccCmd) VolumesInfo(appID, name string) error {
    39  	s, appID, err := load(d.ConfigFile, appID)
    40  
    41  	if err != nil {
    42  		return err
    43  	}
    44  
    45  	volume, err := volumes.Get(s.Client, appID, name)
    46  	if d.checkAPICompatibility(s.Client, err) != nil {
    47  		return err
    48  	}
    49  	table := d.getDefaultFormatTable([]string{})
    50  	table.Append([]string{"UUID:", volume.UUID})
    51  	table.Append([]string{"Name:", volume.Name})
    52  	table.Append([]string{"Owner:", volume.Owner})
    53  	table.Append([]string{"Type:", volume.Type})
    54  	// table append path
    55  	table.Append([]string{"Path:"})
    56  	path, err := yaml.Marshal(volume.Path)
    57  	if err != nil {
    58  		return err
    59  	}
    60  	table.Append([]string{"", string(path)})
    61  	// table append parameters
    62  	table.Append([]string{"Parameters:"})
    63  	parameters, err := yaml.Marshal(volume.Parameters)
    64  	if err != nil {
    65  		return err
    66  	}
    67  	table.Append([]string{"", string(parameters)})
    68  	table.Append([]string{"Created: ", volume.Created})
    69  	table.Append([]string{"Updated: ", volume.Updated})
    70  	table.Render()
    71  	return nil
    72  }
    73  
    74  // VolumesCreate create a volume for the application
    75  func (d *DryccCmd) VolumesCreate(appID, name, vType, size string, parameters map[string]interface{}) error {
    76  	s, appID, err := load(d.ConfigFile, appID)
    77  
    78  	if err != nil {
    79  		return err
    80  	}
    81  	regex := regexp.MustCompile("^([1-9][0-9]*[gG])$")
    82  	if !regex.MatchString(size) {
    83  		return fmt.Errorf(`%s doesn't fit format #unit
    84  Examples: 2G 2g`, size)
    85  	}
    86  
    87  	d.Printf("Creating %s to %s... ", name, appID)
    88  
    89  	quit := progress(d.WOut)
    90  	volume := api.Volume{
    91  		Name:       name,
    92  		Size:       size,
    93  		Type:       vType,
    94  		Parameters: parameters,
    95  	}
    96  	_, err = volumes.Create(s.Client, appID, volume)
    97  	quit <- true
    98  	<-quit
    99  	if d.checkAPICompatibility(s.Client, err) != nil {
   100  		return err
   101  	}
   102  
   103  	d.Println("done")
   104  	return nil
   105  }
   106  
   107  // VolumesExpand create a volume for the application
   108  func (d *DryccCmd) VolumesExpand(appID, name, size string) error {
   109  	s, appID, err := load(d.ConfigFile, appID)
   110  
   111  	if err != nil {
   112  		return err
   113  	}
   114  	regex := regexp.MustCompile("^([1-9][0-9]*[gG])$")
   115  	if !regex.MatchString(size) {
   116  		return fmt.Errorf(`%s doesn't fit format #unit
   117  Examples: 2G 2g`, size)
   118  	}
   119  
   120  	d.Printf("Expand %s to %s... ", name, appID)
   121  
   122  	quit := progress(d.WOut)
   123  	volume := api.Volume{
   124  		Name: name,
   125  		Size: size,
   126  	}
   127  	_, err = volumes.Expand(s.Client, appID, volume)
   128  	quit <- true
   129  	<-quit
   130  	if d.checkAPICompatibility(s.Client, err) != nil {
   131  		return err
   132  	}
   133  
   134  	d.Println("done")
   135  	return nil
   136  }
   137  
   138  // VolumesDelete delete a volume from the application
   139  func (d *DryccCmd) VolumesDelete(appID, name string) error {
   140  	s, appID, err := load(d.ConfigFile, appID)
   141  
   142  	if err != nil {
   143  		return err
   144  	}
   145  
   146  	d.Printf("Deleting %s from %s... ", name, appID)
   147  
   148  	quit := progress(d.WOut)
   149  	err = volumes.Delete(s.Client, appID, name)
   150  	quit <- true
   151  	<-quit
   152  	if d.checkAPICompatibility(s.Client, err) != nil {
   153  		return err
   154  	}
   155  
   156  	d.Println("done")
   157  	return nil
   158  }
   159  
   160  // VolumesMount mount a volume to process of the application
   161  func (d *DryccCmd) VolumesMount(appID string, name string, volumeVars []string) error {
   162  	s, appID, err := load(d.ConfigFile, appID)
   163  
   164  	if err != nil {
   165  		return err
   166  	}
   167  
   168  	volumeMap, err := parseVolume(volumeVars)
   169  	if err != nil {
   170  		return err
   171  	}
   172  
   173  	d.Print("Mounting volume... ")
   174  
   175  	quit := progress(d.WOut)
   176  	volumeObj := api.Volume{Path: volumeMap}
   177  	_, err = volumes.Mount(s.Client, appID, name, volumeObj)
   178  	quit <- true
   179  	<-quit
   180  	if d.checkAPICompatibility(s.Client, err) != nil {
   181  		return err
   182  	}
   183  
   184  	d.Print("done\n")
   185  	d.Print("The pods should be restart, please check the pods up or not.\n")
   186  
   187  	return nil
   188  }
   189  
   190  // VolumesUnmount unmount a volume from process of the application
   191  func (d *DryccCmd) VolumesUnmount(appID string, name string, volumeVars []string) error {
   192  	s, appID, err := load(d.ConfigFile, appID)
   193  
   194  	if err != nil {
   195  		return err
   196  	}
   197  
   198  	valuesMap := make(map[string]interface{})
   199  	for _, volumeVar := range volumeVars {
   200  		valuesMap[volumeVar] = nil
   201  	}
   202  
   203  	d.Print("Unmounting volume... ")
   204  
   205  	quit := progress(d.WOut)
   206  	volumeObj := api.Volume{Path: valuesMap}
   207  	_, err = volumes.Mount(s.Client, appID, name, volumeObj)
   208  	quit <- true
   209  	<-quit
   210  	if d.checkAPICompatibility(s.Client, err) != nil {
   211  		return err
   212  	}
   213  
   214  	d.Print("done\n")
   215  	d.Print("The pods should be restart, please check the pods up or not.\n")
   216  
   217  	return nil
   218  }
   219  
   220  func parseVolume(volumeVars []string) (map[string]interface{}, error) {
   221  	volumeMap := make(map[string]interface{})
   222  
   223  	regex := regexp.MustCompile(`^([A-z_]+[A-z0-9_]*)=([\s\S]*)$`)
   224  	for _, volume := range volumeVars {
   225  		if regex.MatchString(volume) {
   226  			captures := regex.FindStringSubmatch(volume)
   227  			volumeMap[captures[1]] = captures[2]
   228  		} else {
   229  			return nil, fmt.Errorf("'%s' does not match the pattern 'key=var', ex: MODE=test", volume)
   230  		}
   231  	}
   232  
   233  	return volumeMap, nil
   234  }
   235  
   236  // printVolumes format volume data
   237  func printVolumes(d *DryccCmd, volumes api.Volumes) {
   238  	table := d.getDefaultFormatTable([]string{"NAME", "OWNER", "TYPE", "PTYPE", "PATH", "SIZE"})
   239  	for _, volume := range volumes {
   240  		if len(volume.Path) > 0 {
   241  			for _, key := range *sortKeys(volume.Path) {
   242  				table.Append([]string{volume.Name, volume.Owner, volume.Type, key, fmt.Sprintf("%v", volume.Path[key]), volume.Size})
   243  			}
   244  		} else {
   245  			table.Append([]string{volume.Name, volume.Owner, volume.Type, "", "", volume.Size})
   246  		}
   247  	}
   248  	table.Render()
   249  }