123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- package images
- import (
- "encoding/json"
- "fmt"
- "reflect"
- "time"
- "devel.mephi.ru/iacherepanov/openstack-gophercloud"
- "devel.mephi.ru/iacherepanov/openstack-gophercloud/internal"
- "devel.mephi.ru/iacherepanov/openstack-gophercloud/pagination"
- )
- // Image represents an image found in the OpenStack Image service.
- type Image struct {
- // ID is the image UUID.
- ID string `json:"id"`
- // Name is the human-readable display name for the image.
- Name string `json:"name"`
- // Status is the image status. It can be "queued" or "active"
- // See imageservice/v2/images/type.go
- Status ImageStatus `json:"status"`
- // Tags is a list of image tags. Tags are arbitrarily defined strings
- // attached to an image.
- Tags []string `json:"tags"`
- // ContainerFormat is the format of the container.
- // Valid values are ami, ari, aki, bare, and ovf.
- ContainerFormat string `json:"container_format"`
- // DiskFormat is the format of the disk.
- // If set, valid values are ami, ari, aki, vhd, vmdk, raw, qcow2, vdi,
- // and iso.
- DiskFormat string `json:"disk_format"`
- // MinDiskGigabytes is the amount of disk space in GB that is required to
- // boot the image.
- MinDiskGigabytes int `json:"min_disk"`
- // MinRAMMegabytes [optional] is the amount of RAM in MB that is required to
- // boot the image.
- MinRAMMegabytes int `json:"min_ram"`
- // Owner is the tenant ID the image belongs to.
- Owner string `json:"owner"`
- // Protected is whether the image is deletable or not.
- Protected bool `json:"protected"`
- // Visibility defines who can see/use the image.
- Visibility ImageVisibility `json:"visibility"`
- // Checksum is the checksum of the data that's associated with the image.
- Checksum string `json:"checksum"`
- // SizeBytes is the size of the data that's associated with the image.
- SizeBytes int64 `json:"size"`
- // Metadata is a set of metadata associated with the image.
- // Image metadata allow for meaningfully define the image properties
- // and tags.
- // See http://docs.openstack.org/developer/glance/metadefs-concepts.html.
- Metadata map[string]string `json:"metadata"`
- // Properties is a set of key-value pairs, if any, that are associated with
- // the image.
- Properties map[string]interface{} `json:"-"`
- // CreatedAt is the date when the image has been created.
- CreatedAt time.Time `json:"created_at"`
- // UpdatedAt is the date when the last change has been made to the image or
- // it's properties.
- UpdatedAt time.Time `json:"updated_at"`
- // File is the trailing path after the glance endpoint that represent the
- // location of the image or the path to retrieve it.
- File string `json:"file"`
- // Schema is the path to the JSON-schema that represent the image or image
- // entity.
- Schema string `json:"schema"`
- // VirtualSize is the virtual size of the image
- VirtualSize int64 `json:"virtual_size"`
- }
- func (r *Image) UnmarshalJSON(b []byte) error {
- type tmp Image
- var s struct {
- tmp
- SizeBytes interface{} `json:"size"`
- }
- err := json.Unmarshal(b, &s)
- if err != nil {
- return err
- }
- *r = Image(s.tmp)
- switch t := s.SizeBytes.(type) {
- case nil:
- r.SizeBytes = 0
- case float32:
- r.SizeBytes = int64(t)
- case float64:
- r.SizeBytes = int64(t)
- default:
- return fmt.Errorf("Unknown type for SizeBytes: %v (value: %v)", reflect.TypeOf(t), t)
- }
- // Bundle all other fields into Properties
- var result interface{}
- err = json.Unmarshal(b, &result)
- if err != nil {
- return err
- }
- if resultMap, ok := result.(map[string]interface{}); ok {
- delete(resultMap, "self")
- r.Properties = internal.RemainingKeys(Image{}, resultMap)
- }
- return err
- }
- type commonResult struct {
- gophercloud.Result
- }
- // Extract interprets any commonResult as an Image.
- func (r commonResult) Extract() (*Image, error) {
- var s *Image
- err := r.ExtractInto(&s)
- return s, err
- }
- // CreateResult represents the result of a Create operation. Call its Extract
- // method to interpret it as an Image.
- type CreateResult struct {
- commonResult
- }
- // UpdateResult represents the result of an Update operation. Call its Extract
- // method to interpret it as an Image.
- type UpdateResult struct {
- commonResult
- }
- // GetResult represents the result of a Get operation. Call its Extract
- // method to interpret it as an Image.
- type GetResult struct {
- commonResult
- }
- // DeleteResult represents the result of a Delete operation. Call its
- // ExtractErr method to interpret it as an Image.
- type DeleteResult struct {
- gophercloud.ErrResult
- }
- // ImagePage represents the results of a List request.
- type ImagePage struct {
- pagination.LinkedPageBase
- }
- // IsEmpty returns true if an ImagePage contains no Images results.
- func (r ImagePage) IsEmpty() (bool, error) {
- images, err := ExtractImages(r)
- return len(images) == 0, err
- }
- // NextPageURL uses the response's embedded link reference to navigate to
- // the next page of results.
- func (r ImagePage) NextPageURL() (string, error) {
- var s struct {
- Next string `json:"next"`
- }
- err := r.ExtractInto(&s)
- if err != nil {
- return "", err
- }
- if s.Next == "" {
- return "", nil
- }
- return nextPageURL(r.URL.String(), s.Next)
- }
- // ExtractImages interprets the results of a single page from a List() call,
- // producing a slice of Image entities.
- func ExtractImages(r pagination.Page) ([]Image, error) {
- var s struct {
- Images []Image `json:"images"`
- }
- err := (r.(ImagePage)).ExtractInto(&s)
- return s.Images, err
- }
|