// Create requests a server to be provisioned to the user in the current tenant. func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult { var res CreateResult reqBody, err := opts.ToServerCreateMap() if err != nil { res.Err = err return res } // If ImageRef isn't provided, use ImageName to ascertain the image ID. if reqBody["server"].(map[string]interface{})["imageRef"].(string) == "" { imageName := reqBody["server"].(map[string]interface{})["imageName"].(string) if imageName == "" { res.Err = &ErrNeitherImageIDNorImageNameProvided{ &gophercloud.InvalidInputError{ BaseError: gophercloud.BaseError{ Function: "servers.Create", }, Argument: "ImageRef/ImageName", }, } return res } imageID, err := images.IDFromName(client, imageName) if err != nil { res.Err = err return res } reqBody["server"].(map[string]interface{})["imageRef"] = imageID } delete(reqBody["server"].(map[string]interface{}), "imageName") // If FlavorRef isn't provided, use FlavorName to ascertain the flavor ID. if reqBody["server"].(map[string]interface{})["flavorRef"].(string) == "" { flavorName := reqBody["server"].(map[string]interface{})["flavorName"].(string) if flavorName == "" { res.Err = &ErrNeitherFlavorIDNorFlavorNameProvided{ &gophercloud.InvalidInputError{ BaseError: gophercloud.BaseError{ Function: "servers.Create", }, Argument: "FlavorRef/FlavorName", }, } return res } flavorID, err := flavors.IDFromName(client, flavorName) if err != nil { res.Err = err return res } reqBody["server"].(map[string]interface{})["flavorRef"] = flavorID } delete(reqBody["server"].(map[string]interface{}), "flavorName") _, res.Err = client.Post(listURL(client), reqBody, &res.Body, &gophercloud.RequestOpts{ ErrorContext: &ServerError{}, }) return res }
func (command *commandCreate) Execute(resource *handler.Resource) { opts := resource.Params.(*paramsCreate).opts var server *osServers.Server var err error if len(opts.BlockDevice) > 0 { server, err = bfv.Create(command.Ctx.ServiceClient, opts).Extract() } else { server, err = servers.Create(command.Ctx.ServiceClient, opts).Extract() } handleErr: if err != nil { switch err.(type) { case *osServers.ErrNeitherImageIDNorImageNameProvided: err = errors.New("One and only one of the --image-id and the --image-name flags must be provided.") case *osServers.ErrNeitherFlavorIDNorFlavorNameProvided: err = errors.New("One and only one of the --flavor-id and the --flavor-name flags must be provided.") case *gophercloud.ErrErrorAfterReauthentication: err = err.(*gophercloud.ErrErrorAfterReauthentication).UnexpectedResponseCodeError goto handleErr case *gophercloud.UnexpectedResponseCodeError: switch err.(*gophercloud.UnexpectedResponseCodeError).Actual { case 403: imageID := opts.ImageRef if imageID == "" { id, err := osImages.IDFromName(command.Ctx.ServiceClient, opts.ImageName) if err != nil { resource.Err = err return } imageID = id } flavorLabel := "id" flavorID := opts.FlavorRef if flavorID == "" { flavorLabel = "name" flavorID = opts.FlavorName } err = fmt.Errorf(strings.Join([]string{"The flavor you've chosen has a disk size of 0, so an image can't be created on it directly.\n", "To boot with this flavor, creating a 100 GB volume and not deleting that volume when the server is deleted, run this command:\n", fmt.Sprintf("rack servers instance create --name %s --flavor-%s %s \\", opts.Name, flavorLabel, flavorID), fmt.Sprintf("--block-device \"source-type=image,source-id=%s,volume-size=100,destination-type=volume,delete-on-termination=false\"\n", imageID), "For more information please run: rack servers instance create --help", }, "\n")) } } resource.Err = err return } resource.Result = serverSingle(server) }