github.com/emc-advanced-dev/unik@v0.0.0-20190717152701-a58d3e8e33b7/cmd/create-volume.go (about)

     1  package cmd
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"strings"
     7  
     8  	"github.com/sirupsen/logrus"
     9  	"github.com/spf13/cobra"
    10  
    11  	"github.com/emc-advanced-dev/pkg/errors"
    12  	"github.com/solo-io/unik/pkg/client"
    13  	unikos "github.com/solo-io/unik/pkg/os"
    14  )
    15  
    16  var data string
    17  var size int
    18  var volumeType string
    19  var rawVolume bool
    20  
    21  const (
    22  	VolTypeExt2 = "ext2"
    23  )
    24  
    25  var cvCmd = &cobra.Command{
    26  	Use:   "create-volume",
    27  	Short: "Create a unik-managed data volume",
    28  	Long: `Create a data volume which can be attached to and detached from
    29  unik-managed instances.
    30  
    31  Volumes can be created from a directory, which will copy the contents
    32  of the directory onto the voume. Empty volume can also be created.
    33  
    34  Volumes will persist after instances are deleted, allowing application data
    35  to be persisted beyond the lifecycle of individual instances.
    36  
    37  If specifying a data folder (with --data), specifying a size for the volume is
    38  not necessary. UniK will automatically size the volume to fit the data provided.
    39  A larger volume can be requested with the --size flag.
    40  
    41  If no data directory is provided, --size is a required parameter to specify the
    42  desired size for the empty volume to be createad.
    43  
    44  Volumes are created for a specific provider, specified with the --provider flag.
    45  Volumes can only be attached to instances of the same provider type.
    46  To see a list of available providers, run 'unik providers'
    47  
    48  Volume names must be unique. If a volume exists with the same name, you will be
    49  required to remove the volume with 'unik delete-volume' before the new volume
    50  can be created.
    51  
    52  --size parameter uses MB
    53  
    54  Example usage:
    55  	unik create-volume --name myVolume --data ./myApp/data --provider aws
    56  
    57  	# will create an EBS-backed AWS volume named myVolume using the data found in ./myApp/src,
    58  	# the size will be either 1GB (the default minimum size on AWS) or greater, if the size of the
    59  	volume is greater
    60  
    61  
    62  Another example (empty volume):
    63  	unik create-volume -name anotherVolume --size 500 -provider vsphere
    64  
    65  	# will create a 500mb sparse vmdk file and upload it to the vsphere datastore,
    66  	where it can be attached to a vsphere instance
    67  `,
    68  	Run: func(cmd *cobra.Command, args []string) {
    69  		if err := func() error {
    70  			if name == "" {
    71  				return errors.New("--name must be set", nil)
    72  			}
    73  			if data == "" && size == 0 {
    74  				return errors.New("either --data or --size must be set", nil)
    75  			}
    76  			if provider == "" {
    77  				return errors.New("--provider must be set", nil)
    78  			}
    79  			if volumeType == "" {
    80  				volumeType = VolTypeExt2
    81  			} else {
    82  				volumeType = strings.ToLower(volumeType)
    83  			}
    84  
    85  			if err := readClientConfig(); err != nil {
    86  				return err
    87  			}
    88  			if host == "" {
    89  				host = clientConfig.Host
    90  			}
    91  			logrus.WithFields(logrus.Fields{
    92  				"name":       name,
    93  				"data":       data,
    94  				"size":       size,
    95  				"provider":   provider,
    96  				"host":       host,
    97  				"volumeType": volumeType,
    98  			}).Infof("creating volume")
    99  			if data != "" {
   100  				dataTar, err := ioutil.TempFile("", "data.tar.gz.")
   101  				if err != nil {
   102  					logrus.WithError(err).Error("failed to create tmp tar file")
   103  				}
   104  				if false {
   105  					defer os.Remove(dataTar.Name())
   106  				}
   107  				if err := unikos.Compress(data, dataTar.Name()); err != nil {
   108  					return errors.New("failed to tar data", err)
   109  				}
   110  				data = dataTar.Name()
   111  				logrus.Infof("Data packaged as tarball: %s\n", dataTar.Name())
   112  			}
   113  
   114  			volume, err := client.UnikClient(host).Volumes().Create(name, data, provider, rawVolume, size, volumeType, noCleanup)
   115  
   116  			if err != nil {
   117  				return errors.New("creatinv volume image failed", err)
   118  			}
   119  			printVolumes(volume)
   120  			return nil
   121  		}(); err != nil {
   122  			logrus.Errorf("create-volume failed: %v", err)
   123  			os.Exit(-1)
   124  		}
   125  	},
   126  }
   127  
   128  func init() {
   129  	RootCmd.AddCommand(cvCmd)
   130  	cvCmd.Flags().StringVar(&name, "name", "", "<string,required> name to give the volume. must be unique")
   131  	cvCmd.Flags().StringVar(&data, "data", "", "<string,special> path to data folder (or file if --raw is provided). optional if --size is provided")
   132  	cvCmd.Flags().BoolVar(&rawVolume, "raw", false, "<bool,optional> if true then then data is expected to be a file that will be used as is. if false (default) data should point to a folder which will be turned into a volume.")
   133  	cvCmd.Flags().IntVar(&size, "size", 0, "<int,special> size to create volume in MB. optional if --data is provided")
   134  	cvCmd.Flags().StringVar(&provider, "provider", "", "<string,required> name of the target infrastructure to compile for")
   135  	cvCmd.Flags().StringVar(&volumeType, "type", "", "<string,optional> FS type of the volume. ext2 or FAT are supported. defaults to ext2")
   136  
   137  	cvCmd.Flags().BoolVar(&noCleanup, "no-cleanup", false, "<bool, optional> for debugging; do not clean up artifacts for volumes that fail to build")
   138  }