lxd/storage_volumes.go
func storagePoolVolumeTypeGet(d *Daemon, r *http.Request, volumeTypeName string) Response {
	project := projectParam(r)

	// Get the name of the storage volume.
	var volumeName string
	fields := strings.Split(mux.Vars(r)["name"], "/")

	if len(fields) == 3 && fields[1] == "snapshots" {
		// Handle volume snapshots
		volumeName = fmt.Sprintf("%s%s%s", fields[0], shared.SnapshotDelimiter, fields[2])
	} else if len(fields) > 1 {
		volumeName = fmt.Sprintf("%s%s%s", fields[0], shared.SnapshotDelimiter, fields[1])
	} else if len(fields) > 0 {
		// Handle volume
		volumeName = fields[0]
	} else {
		return BadRequest(fmt.Errorf("invalid storage volume %s", mux.Vars(r)["name"]))
	}

	// Get the name of the storage pool the volume is supposed to be
	// attached to.
	poolName := mux.Vars(r)["pool"]

	// Convert the volume type name to our internal integer representation.
	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
	if err != nil {
		return BadRequest(err)
	}
	// Check that the storage volume type is valid.
	if !shared.IntInSlice(volumeType, supportedVolumeTypes) {
		return BadRequest(fmt.Errorf("invalid storage volume type %s", volumeTypeName))
	}

	// Get the ID of the storage pool the storage volume is supposed to be
	// attached to.
	poolID, err := d.cluster.StoragePoolGetID(poolName)
	if err != nil {
		return SmartError(err)
	}

	response := ForwardedResponseIfTargetIsRemote(d, r)
	if response != nil {
		return response
	}

	response = ForwardedResponseIfVolumeIsRemote(d, r, poolID, volumeName, volumeType)
	if response != nil {
		return response
	}

	// Get the storage volume.
	_, volume, err := d.cluster.StoragePoolNodeVolumeGetType(volumeName, volumeType, poolID)
	if err != nil {
		return SmartError(err)
	}

	volumeUsedBy, err := storagePoolVolumeUsedByGet(d.State(), project, volume.Name, volume.Type)
	if err != nil {
		return SmartError(err)
	}
	volume.UsedBy = volumeUsedBy

	etag := []interface{}{volumeName, volume.Type, volume.Config}

	return SyncResponseETag(true, volume, etag)
}
func storagePoolVolumeTypeGet(d *Daemon, r *http.Request, volumeTypeName string) Response {
	project := projectParam(r)

	// Get the name of the storage volume.
	var volumeName string
	fields := strings.Split(mux.Vars(r)["name"], "/")

	if len(fields) == 3 && fields[1] == "snapshots" {
		// Handle volume snapshots
		volumeName = fmt.Sprintf("%s%s%s", fields[0], shared.SnapshotDelimiter, fields[2])
	} else if len(fields) > 1 {
		volumeName = fmt.Sprintf("%s%s%s", fields[0], shared.SnapshotDelimiter, fields[1])
	} else if len(fields) > 0 {
		// Handle volume
		volumeName = fields[0]
	} else {
		return BadRequest(fmt.Errorf("invalid storage volume %s", mux.Vars(r)["name"]))
	}

	// Get the name of the storage pool the volume is supposed to be
	// attached to.
	poolName := mux.Vars(r)["pool"]

	// Convert the volume type name to our internal integer representation.
	volumeType, err := storagePoolVolumeTypeNameToType(volumeTypeName)
	if err != nil {
		return BadRequest(err)
	}
	// Check that the storage volume type is valid.
	if !shared.IntInSlice(volumeType, supportedVolumeTypes) {
		return BadRequest(fmt.Errorf("invalid storage volume type %s", volumeTypeName))
	}

	// Get the ID of the storage pool the storage volume is supposed to be
	// attached to.
	poolID, err := d.cluster.StoragePoolGetID(poolName)
	if err != nil {
		return SmartError(err)
	}

	response := ForwardedResponseIfTargetIsRemote(d, r)
	if response != nil {
		return response
	}

	response = ForwardedResponseIfVolumeIsRemote(d, r, poolID, volumeName, volumeType)
	if response != nil {
		return response
	}

	// Get the storage volume.
	_, volume, err := d.cluster.StoragePoolNodeVolumeGetType(volumeName, volumeType, poolID)
	if err != nil {
		return SmartError(err)
	}

	volumeUsedBy, err := storagePoolVolumeUsedByGet(d.State(), project, volume.Name, volume.Type)
	if err != nil {
		return SmartError(err)
	}
	volume.UsedBy = volumeUsedBy

	etag := []interface{}{volumeName, volume.Type, volume.Config}

	return SyncResponseETag(true, volume, etag)
}
func storagePoolVolumeTypeGet ( d * Daemon , r * http . Request , volumeTypeName string ) Response { project := projectParam ( r ) // Get the name of the storage volume. var volumeName string fields := strings . Split ( mux . Vars ( r ) [ " " ] , " " ) if len ( fields ) == 3 && fields [ 1 ] == " " { // Handle volume snapshots volumeName = fmt . Sprintf ( " " , fields [ 0 ] , shared . SnapshotDelimiter , fields [ 2 ] ) } else if len ( fields ) > 1 { volumeName = fmt . Sprintf ( " " , fields [ 0 ] , shared . SnapshotDelimiter , fields [ 1 ] ) } else if len ( fields ) > 0 { // Handle volume volumeName = fields [ 0 ] } else { return BadRequest ( fmt . Errorf ( " " , mux . Vars ( r ) [ " " ] ) ) } // Get the name of the storage pool the volume is supposed to be // attached to. poolName := mux . Vars ( r ) [ " " ] // Convert the volume type name to our internal integer representation. volumeType , err := storagePoolVolumeTypeNameToType ( volumeTypeName ) if err != nil { return BadRequest ( err ) } // Check that the storage volume type is valid. if ! shared . IntInSlice ( volumeType , supportedVolumeTypes ) { return BadRequest ( fmt . Errorf ( " " , volumeTypeName ) ) } // Get the ID of the storage pool the storage volume is supposed to be // attached to. poolID , err := d . cluster . StoragePoolGetID ( poolName ) if err != nil { return SmartError ( err ) } response := ForwardedResponseIfTargetIsRemote ( d , r ) if response != nil { return response } response = ForwardedResponseIfVolumeIsRemote ( d , r , poolID , volumeName , volumeType ) if response != nil { return response } // Get the storage volume. _ , volume , err := d . cluster . StoragePoolNodeVolumeGetType ( volumeName , volumeType , poolID ) if err != nil { return SmartError ( err ) } volumeUsedBy , err := storagePoolVolumeUsedByGet ( d . State ( ) , project , volume . Name , volume . Type ) if err != nil { return SmartError ( err ) } volume . UsedBy = volumeUsedBy etag := [ ] interface { } { volumeName , volume . Type , volume . Config } return SyncResponseETag ( true , volume , etag ) }
// /1.0/storage-pools/{pool}/volumes/{type}/{name}
// Get storage volume of a given volume type on a given storage pool.
/ 1 . 0 / storage - pools / { pool } / volumes / { type } / { name } Get storage volume of a given volume type on a given storage pool .