Exemplo n.º 1
0
// 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
}
Exemplo n.º 2
0
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)
}