func (command *commandCreate) HandleFlags(resource *handler.Resource) error { c := command.Ctx.CLIContext opts := &servers.CreateOpts{ ImageRef: c.String("image-id"), ImageName: c.String("image-name"), FlavorRef: c.String("flavor-id"), FlavorName: c.String("flavor-name"), AdminPass: c.String("admin-pass"), KeyPair: c.String("keypair"), } if c.IsSet("security-groups") { opts.SecurityGroups = strings.Split(c.String("security-groups"), ",") } if c.IsSet("user-data") { abs, err := filepath.Abs(c.String("user-data")) if err != nil { return err } userData, err := ioutil.ReadFile(abs) if err != nil { return err } opts.UserData = userData opts.ConfigDrive = true } if c.IsSet("networks") { netIDs := strings.Split(c.String("networks"), ",") networks := make([]osServers.Network, len(netIDs)) for i, netID := range netIDs { networks[i] = osServers.Network{ UUID: netID, } } opts.Networks = networks } if c.IsSet("metadata") { metadata, err := command.Ctx.CheckKVFlag("metadata") if err != nil { return err } opts.Metadata = metadata } if c.IsSet("block-device") { bfvMap, err := command.Ctx.CheckKVFlag("block-device") if err != nil { return err } sourceID, ok := bfvMap["source-id"] if !ok { return fmt.Errorf("The source-id key is required when using the --block-device flag.\n") } sourceTypeRaw, ok := bfvMap["source-type"] if !ok { return fmt.Errorf("The source-type key is required when using the --block-device flag.\n") } var sourceType osBFV.SourceType switch sourceTypeRaw { case "volume", "image", "snapshot": sourceType = osBFV.SourceType(sourceTypeRaw) default: return fmt.Errorf("Invalid value for source-type: %s. Options are: volume, image, snapshot.\n", sourceType) } bd := osBFV.BlockDevice{ SourceType: sourceType, UUID: sourceID, } if volumeSizeRaw, ok := bfvMap["volume-size"]; ok { volumeSize, err := strconv.ParseInt(volumeSizeRaw, 10, 16) if err != nil { return fmt.Errorf("Invalid value for volume-size: %d. Value must be an integer.\n", volumeSize) } bd.VolumeSize = int(volumeSize) } if deleteOnTerminationRaw, ok := bfvMap["delete-on-termination"]; ok { deleteOnTermination, err := strconv.ParseBool(deleteOnTerminationRaw) if err != nil { return fmt.Errorf("Invalid value for delete-on-termination: %v. Options are: true, false.\n", deleteOnTermination) } bd.DeleteOnTermination = deleteOnTermination } if bootIndexRaw, ok := bfvMap["boot-index"]; ok { bootIndex, err := strconv.ParseInt(bootIndexRaw, 10, 8) if err != nil { return fmt.Errorf("Invalid value for boot-index: %d. Value must be an integer.\n", bootIndex) } bd.BootIndex = int(bootIndex) } if destinationType, ok := bfvMap["destination-type"]; ok { if destinationType != "volume" && destinationType != "local" { return fmt.Errorf("Invalid value for destination-type: %s. Options are: volume, local.\n", destinationType) } bd.DestinationType = destinationType } opts.BlockDevice = []osBFV.BlockDevice{bd} } resource.Params = ¶msCreate{ opts: opts, } return nil }
func (command *commandCreate) HandleFlags(resource *handler.Resource) error { c := command.Ctx.CLIContext wait := false if c.IsSet("wait-for-completion") { wait = true } opts := &servers.CreateOpts{ ImageRef: c.String("image-id"), ImageName: c.String("image-name"), FlavorRef: c.String("flavor-id"), FlavorName: c.String("flavor-name"), AdminPass: c.String("admin-pass"), KeyPair: c.String("keypair"), } if c.IsSet("security-groups") { opts.SecurityGroups = strings.Split(c.String("security-groups"), ",") } if c.IsSet("user-data") { abs, err := filepath.Abs(c.String("user-data")) if err != nil { return err } userData, err := ioutil.ReadFile(abs) if err != nil { return err } opts.UserData = userData opts.ConfigDrive = true } if c.IsSet("personality") { filesToInjectMap, err := command.Ctx.CheckKVFlag("personality") if err != nil { return err } if len(filesToInjectMap) > 5 { return fmt.Errorf("A maximum of 5 files may be provided for the `personality` flag") } filesToInject := make(osServers.Personality, 0) for destinationPath, localPath := range filesToInjectMap { localAbsFilePath, err := filepath.Abs(localPath) if err != nil { return err } fileData, err := ioutil.ReadFile(localAbsFilePath) if err != nil { return err } if len(fileData)+len(destinationPath) > 1000 { return fmt.Errorf("The maximum length of a file-path-and-content pair for `personality` is 1000 bytes."+ " Current pair size: path (%s): %d, content: %d", len(destinationPath), len(fileData)) } filesToInject = append(filesToInject, &osServers.File{ Path: destinationPath, Contents: fileData, }) } opts.Personality = filesToInject } if c.IsSet("networks") { netIDs := strings.Split(c.String("networks"), ",") networks := make([]osServers.Network, len(netIDs)) for i, netID := range netIDs { networks[i] = osServers.Network{ UUID: netID, } } opts.Networks = networks } if c.IsSet("metadata") { metadata, err := command.Ctx.CheckKVFlag("metadata") if err != nil { return err } opts.Metadata = metadata } if c.IsSet("block-device") { bfvMap, err := command.Ctx.CheckKVFlag("block-device") if err != nil { return err } sourceID, ok := bfvMap["source-id"] if !ok { return fmt.Errorf("The source-id key is required when using the --block-device flag.\n") } sourceTypeRaw, ok := bfvMap["source-type"] if !ok { return fmt.Errorf("The source-type key is required when using the --block-device flag.\n") } var sourceType osBFV.SourceType switch sourceTypeRaw { case "volume", "image", "snapshot": sourceType = osBFV.SourceType(sourceTypeRaw) default: return fmt.Errorf("Invalid value for source-type: %s. Options are: volume, image, snapshot.\n", sourceType) } bd := osBFV.BlockDevice{ SourceType: sourceType, UUID: sourceID, } if volumeSizeRaw, ok := bfvMap["volume-size"]; ok { volumeSize, err := strconv.ParseInt(volumeSizeRaw, 10, 16) if err != nil { return fmt.Errorf("Invalid value for volume-size: %d. Value must be an integer.\n", volumeSize) } bd.VolumeSize = int(volumeSize) } if deleteOnTerminationRaw, ok := bfvMap["delete-on-termination"]; ok { deleteOnTermination, err := strconv.ParseBool(deleteOnTerminationRaw) if err != nil { return fmt.Errorf("Invalid value for delete-on-termination: %v. Options are: true, false.\n", deleteOnTermination) } bd.DeleteOnTermination = deleteOnTermination } if bootIndexRaw, ok := bfvMap["boot-index"]; ok { bootIndex, err := strconv.ParseInt(bootIndexRaw, 10, 8) if err != nil { return fmt.Errorf("Invalid value for boot-index: %d. Value must be an integer.\n", bootIndex) } bd.BootIndex = int(bootIndex) } if destinationType, ok := bfvMap["destination-type"]; ok { if destinationType != "volume" && destinationType != "local" { return fmt.Errorf("Invalid value for destination-type: %s. Options are: volume, local.\n", destinationType) } bd.DestinationType = destinationType } opts.BlockDevice = []osBFV.BlockDevice{bd} } resource.Params = ¶msCreate{ wait: wait, opts: opts, } return nil }