diff --git a/include/ImageManager.h b/include/ImageManager.h index 4090f0f9be3..fb555d7a4ca 100644 --- a/include/ImageManager.h +++ b/include/ImageManager.h @@ -308,6 +308,15 @@ class ImageManager : public DriverManager> */ int flatten_snapshot(int iid, int sid, std::string& error); + /** + * Resizes an image to a new size (only upsize supported). + * @param iid id of image + * @param size new size in MiB (as string) + * @param error Error reason, if any + * @return 0 on success + */ + int resize_image(int iid, const std::string& size, std::string& error); + /** * Flattens the backup chain by commiting changes to first (full) backup * @param iid id of image @@ -423,6 +432,8 @@ class ImageManager : public DriverManager> void _restore(std::unique_ptr msg); + void _resize(std::unique_ptr msg); + static void _log(std::unique_ptr msg); /** diff --git a/include/ProtocolMessages.h b/include/ProtocolMessages.h index cf0a7bfe612..8164fcc475c 100644 --- a/include/ProtocolMessages.h +++ b/include/ProtocolMessages.h @@ -62,6 +62,7 @@ enum class ImageManagerMessages : unsigned short int SNAP_FLATTEN, RESTORE, INCREMENT_FLATTEN, + RESIZE, LOG, ENUM_MAX }; diff --git a/install.sh b/install.sh index 4274cea8c5e..51886342524 100755 --- a/install.sh +++ b/install.sh @@ -1620,6 +1620,7 @@ DATASTORE_DRIVER_DUMMY_SCRIPTS="src/datastore_mad/remotes/dummy/cp \ src/datastore_mad/remotes/dummy/snap_delete \ src/datastore_mad/remotes/dummy/snap_revert \ src/datastore_mad/remotes/dummy/snap_flatten \ + src/datastore_mad/remotes/dummy/resize \ src/datastore_mad/remotes/dummy/rm \ src/datastore_mad/remotes/dummy/restore \ src/datastore_mad/remotes/dummy/export" @@ -1632,6 +1633,7 @@ DATASTORE_DRIVER_FS_SCRIPTS="src/datastore_mad/remotes/fs/cp \ src/datastore_mad/remotes/fs/snap_delete \ src/datastore_mad/remotes/fs/snap_revert \ src/datastore_mad/remotes/fs/snap_flatten \ + src/datastore_mad/remotes/fs/resize \ src/datastore_mad/remotes/fs/rm \ src/datastore_mad/remotes/fs/export" @@ -1646,6 +1648,7 @@ DATASTORE_DRIVER_CEPH_SCRIPTS="src/datastore_mad/remotes/ceph/cp \ src/datastore_mad/remotes/ceph/snap_delete \ src/datastore_mad/remotes/ceph/snap_revert \ src/datastore_mad/remotes/ceph/snap_flatten \ + src/datastore_mad/remotes/ceph/resize \ src/datastore_mad/remotes/ceph/ceph_utils.sh \ src/datastore_mad/remotes/ceph/export" @@ -1659,6 +1662,7 @@ DATASTORE_DRIVER_DEV_SCRIPTS="src/datastore_mad/remotes/dev/cp \ src/datastore_mad/remotes/dev/snap_delete \ src/datastore_mad/remotes/dev/snap_revert \ src/datastore_mad/remotes/dev/snap_flatten \ + src/datastore_mad/remotes/dev/resize \ src/datastore_mad/remotes/dev/clone" DATASTORE_DRIVER_ISCSI_SCRIPTS="src/datastore_mad/remotes/iscsi_libvirt/cp \ @@ -1669,6 +1673,7 @@ DATASTORE_DRIVER_ISCSI_SCRIPTS="src/datastore_mad/remotes/iscsi_libvirt/cp \ src/datastore_mad/remotes/iscsi_libvirt/snap_delete \ src/datastore_mad/remotes/iscsi_libvirt/snap_revert \ src/datastore_mad/remotes/iscsi_libvirt/snap_flatten \ + src/datastore_mad/remotes/iscsi_libvirt/resize \ src/datastore_mad/remotes/iscsi_libvirt/clone" DATASTORE_DRIVER_RSYNC_SCRIPTS="src/datastore_mad/remotes/rsync/cp \ @@ -1679,6 +1684,7 @@ DATASTORE_DRIVER_RSYNC_SCRIPTS="src/datastore_mad/remotes/rsync/cp \ src/datastore_mad/remotes/rsync/snap_delete \ src/datastore_mad/remotes/rsync/snap_revert \ src/datastore_mad/remotes/rsync/snap_flatten \ + src/datastore_mad/remotes/rsync/resize \ src/datastore_mad/remotes/rsync/rm \ src/datastore_mad/remotes/rsync/backup \ src/datastore_mad/remotes/rsync/backup_cancel \ @@ -1695,6 +1701,7 @@ DATASTORE_DRIVER_RESTIC_SCRIPTS="src/datastore_mad/remotes/restic/cp \ src/datastore_mad/remotes/restic/snap_delete \ src/datastore_mad/remotes/restic/snap_revert \ src/datastore_mad/remotes/restic/snap_flatten \ + src/datastore_mad/remotes/restic/resize \ src/datastore_mad/remotes/restic/clone \ src/datastore_mad/remotes/restic/restore \ src/datastore_mad/remotes/restic/restic.rb \ @@ -1712,6 +1719,7 @@ DATASTORE_DRIVER_VIRTIOFS_SCRIPTS="src/datastore_mad/remotes/virtiofs/clone \ src/datastore_mad/remotes/virtiofs/snap_delete \ src/datastore_mad/remotes/virtiofs/snap_flatten \ src/datastore_mad/remotes/virtiofs/snap_revert \ + src/datastore_mad/remotes/virtiofs/resize \ src/datastore_mad/remotes/virtiofs/stat" DATASTORE_DRIVER_ETC_SCRIPTS="src/datastore_mad/remotes/datastore.conf" diff --git a/share/shell/bash_completion b/share/shell/bash_completion index bf1c8e92c54..73b6bbc2165 100755 --- a/share/shell/bash_completion +++ b/share/shell/bash_completion @@ -440,7 +440,7 @@ _oneimage() { fi opts="create clone delete persistent nonpersistent update enable chtype disable chgrp chown chmod rename snapshot-delete snapshot-revert - snapshot-flatten list show top lock unlock orphans restore" + snapshot-flatten resize list show top lock unlock orphans restore" cmd=oneimage if [ "$COMP_CWORD" == 1 ]; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) diff --git a/src/cli/oneimage b/src/cli/oneimage index bd7a0181f82..e38d28358d3 100755 --- a/src/cli/oneimage +++ b/src/cli/oneimage @@ -160,6 +160,10 @@ CommandParser::CmdParser.new(ARGV) do helper.retrieve_snapshot_id(@current_image, arg) end + set :format, :size, 'Image size in MiB' do |arg| + OpenNebulaHelper.size_in_mb(arg) + end + ######################################################################## # Commands ######################################################################## @@ -426,6 +430,24 @@ CommandParser::CmdParser.new(ARGV) do end end + resize_desc = <<-EOT.unindent + Resizes an image. The image must be in READY state and only + upsizing is supported (the new size must be greater than the + current size). + + The size can be specified with the following suffixes: + - T: TiB + - G: GiB + - M: MiB + Default unit is MiB. + EOT + + command :resize, resize_desc, :imageid, :size do + helper.perform_action(args[0], options, 'resizing image') do |o| + o.resize(args[1].to_s) + end + end + restore_desc = <<-EOT.unindent Restore a backup image. It will restore the associated VM template to the VM template pool and the disk images to the selected image datastore. diff --git a/src/datastore_mad/one_datastore.rb b/src/datastore_mad/one_datastore.rb index 64f6fd41716..4f30bbbd0de 100755 --- a/src/datastore_mad/one_datastore.rb +++ b/src/datastore_mad/one_datastore.rb @@ -61,7 +61,8 @@ class DatastoreDriver < OpenNebulaDriver :snap_revert => 'SNAP_REVERT', :snap_flatten=> 'SNAP_FLATTEN', :restore => 'RESTORE', - :increment_flatten => 'INCREMENT_FLATTEN' + :increment_flatten => 'INCREMENT_FLATTEN', + :resize => 'RESIZE' } # Default System datastores for OpenNebula, override in oned.conf @@ -87,7 +88,8 @@ def initialize(ds_type, sys_ds_type, options = {}) ACTION[:snap_delete] => nil, ACTION[:snap_revert] => nil, ACTION[:snap_flatten] => nil, - ACTION[:restore] => nil + ACTION[:restore] => nil, + ACTION[:resize] => nil } }.merge!(options) @@ -124,6 +126,7 @@ def initialize(ds_type, sys_ds_type, options = {}) register_action(ACTION[:snap_flatten].to_sym, method('snap_flatten')) register_action(ACTION[:restore].to_sym, method('restore')) register_action(ACTION[:increment_flatten].to_sym, method('increment_flatten')) + register_action(ACTION[:resize].to_sym, method('resize')) end ############################################################################ @@ -185,6 +188,11 @@ def increment_flatten(id, drv_message) do_image_action(id, ds, :increment_flatten, drv_message) end + def resize(id, drv_message) + ds, _sys = get_ds_type(drv_message) + do_image_action(id, ds, :resize, drv_message) + end + private def available?(ds, id, action) diff --git a/src/datastore_mad/remotes/ceph/resize b/src/datastore_mad/remotes/ceph/resize new file mode 100755 index 00000000000..fd8efdecf8b --- /dev/null +++ b/src/datastore_mad/remotes/ceph/resize @@ -0,0 +1,97 @@ +#!/bin/bash + +# -------------------------------------------------------------------------- # +# Copyright 2002-2025, OpenNebula Project, OpenNebula Systems # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +############################################################################### +# This script is used to resize a persistent image in a Ceph datastore +############################################################################### + +# -------- Set up the environment to source common tools & conf ------------ + +if [ -z "${ONE_LOCATION}" ]; then + LIB_LOCATION=/usr/lib/one +else + LIB_LOCATION=$ONE_LOCATION/lib +fi + +. $LIB_LOCATION/sh/scripts_common.sh + +DRIVER_PATH=$(dirname $0) + +source ${DRIVER_PATH}/../libfs.sh +source ${DRIVER_PATH}/../../etc/datastore/ceph/ceph.conf + +# -------- Get image and datastore arguments from OpenNebula core ------------ + +DRV_ACTION=`cat -` +ID=$1 + +XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" + +unset i XPATH_ELEMENTS + +while IFS= read -r -d '' element; do + XPATH_ELEMENTS[i++]="$element" +done < <($XPATH /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/BRIDGE_LIST \ + /DS_DRIVER_ACTION_DATA/IMAGE/SOURCE \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/CEPH_USER \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/CEPH_KEY \ + /DS_DRIVER_ACTION_DATA/DATASTORE/TEMPLATE/CEPH_CONF \ + /DS_DRIVER_ACTION_DATA/EXTRA_DATA/SIZE) + +unset i + +BRIDGE_LIST="${XPATH_ELEMENTS[i++]}" +RBD_SRC="${XPATH_ELEMENTS[i++]}" +CEPH_USER="${XPATH_ELEMENTS[i++]}" +CEPH_KEY="${XPATH_ELEMENTS[i++]}" +CEPH_CONF="${XPATH_ELEMENTS[i++]}" +SIZE="${XPATH_ELEMENTS[i++]}" + +if [ -z "$SIZE" ]; then + error_message "Missing SIZE in driver message." + exit -1 +fi + +DST_HOST=`get_destination_host $ID` + +if [ -z "$DST_HOST" ]; then + error_message "Datastore template missing 'BRIDGE_LIST' attribute." + exit -1 +fi + +if [ -n "$CEPH_USER" ]; then + RBD="$RBD --id ${CEPH_USER}" +fi + +if [ -n "$CEPH_KEY" ]; then + RBD="$RBD --keyfile ${CEPH_KEY}" +fi + +if [ -n "$CEPH_CONF" ]; then + RBD="$RBD --conf ${CEPH_CONF}" +fi + +RESIZE_CMD=$(cat < current size */ + /* */ + /* The write lock (ipool->get) is held through quota reservation, driver */ + /* message send, and state update to LOCKED. This prevents concurrent */ + /* resize requests from passing the READY check simultaneously. */ + /* ---------------------------------------------------------------------- */ + + auto img = ipool->get(iid); + + if ( img == nullptr ) + { + error = "Image does not exist"; + return -1; + } + + int ds_id = img->get_ds_id(); + + string ds_data; + + if (auto ds = dspool->get_ro(ds_id)) + { + ds->decrypt(); + + ds->to_xml(ds_data); + } + else + { + error = "Datastore no longer exists"; + return -1; + } + + if ( img->get_type() != Image::OS && img->get_type() != Image::DATABLOCK ) + { + error = "Only images of type OS and DATABLOCK can be resized"; + return -1; + } + + if (img->get_state() != Image::READY) + { + error = "Cannot resize image in state " + Image::state_to_str(img->get_state()); + return -1; + } + + long long new_size = 0; + long long cur_size = img->get_size(); + + istringstream iss(size); + iss >> new_size; + + if (iss.fail() || !iss.eof() || new_size <= 0) + { + error = "Invalid size value: " + size; + return -1; + } + + if (new_size <= cur_size) + { + ostringstream oss; + oss << "New size (" << new_size + << " MiB) must be greater than current size (" << cur_size << " MiB)"; + error = oss.str(); + return -1; + } + + /* ---------------------------------------------------------------------- */ + /* Prepare driver message before quota check so that all allocations */ + /* happen before quota is reserved. After quota_check, only */ + /* non-throwing operations remain (template update, write, state set). */ + /* ---------------------------------------------------------------------- */ + + long long delta = new_size - cur_size; + + string img_tmpl; + string extra_data = "" + to_string(new_size) + ""; + string drv_msg(format_message(img->to_xml(img_tmpl), ds_data, extra_data)); + + /* ---------------------------------------------------------------------- */ + /* Check datastore quota for the size delta */ + /* ---------------------------------------------------------------------- */ + + int uid = img->get_uid(); + int gid = img->get_gid(); + + Template quota_tmpl; + + quota_tmpl.add("DATASTORE", ds_id); + quota_tmpl.add("SIZE", delta); + quota_tmpl.add("IMAGES", 0); + + if ( !Quotas::quota_check(Quotas::DATASTORE, uid, gid, "a_tmpl, error) ) + { + return -1; + } + + /* ---------------------------------------------------------------------- */ + /* Send action to driver and lock the image */ + /* ---------------------------------------------------------------------- */ + + img->replace_template_attribute("RESIZE_DELTA", delta); + + image_msg_t msg(ImageManagerMessages::RESIZE, "", iid, drv_msg); + + imd->write(msg); + + img->set_state(Image::LOCKED); + + ipool->update(img.get()); + + return 0; +} diff --git a/src/image/ImageManagerProtocol.cc b/src/image/ImageManagerProtocol.cc index b2b0b8c6e3a..2d70ee920c8 100644 --- a/src/image/ImageManagerProtocol.cc +++ b/src/image/ImageManagerProtocol.cc @@ -844,6 +844,107 @@ void ImageManager::_snap_flatten(unique_ptr msg) /* -------------------------------------------------------------------------- */ +void ImageManager::_resize(unique_ptr msg) +{ + NebulaLog::dddebug("ImM", "_resize: " + msg->payload()); + + auto image = ipool->get(msg->oid()); + + if ( !image ) + { + return; + } + + int ds_id = image->get_ds_id(); + int uid = image->get_uid(); + int gid = image->get_gid(); + + long long resize_delta = 0; + image->get_template_attribute("RESIZE_DELTA", resize_delta); + image->remove_template_attribute("RESIZE_DELTA"); + + bool success = false; + + if (msg->status() == "SUCCESS") + { + long long new_size = 0; + + istringstream iss(msg->payload()); + iss >> new_size >> std::ws; + + long long cur_size = image->get_size(); + + if (!iss.fail() && iss.eof() && new_size > 0 && new_size > cur_size) + { + image->set_size(new_size); + success = true; + } + else + { + ostringstream oss; + + if (new_size > 0 && new_size <= cur_size) + { + oss << "Error resizing image: driver returned size (" + << new_size << " MiB) not greater than current (" + << cur_size << " MiB)"; + } + else + { + oss << "Error resizing image: driver returned invalid size"; + } + + image->set_template_error_message(oss.str()); + + NebulaLog::log("ImM", Log::ERROR, oss); + } + } + else + { + ostringstream oss; + oss << "Error resizing image"; + + const auto& info = msg->payload(); + + if (!info.empty() && (info[0] != '-')) + { + oss << ": " << info; + } + + image->set_template_error_message(oss.str()); + + NebulaLog::log("ImM", Log::ERROR, oss); + } + + image->set_state_unlock(); + + ipool->update(image.get()); + + image.reset(); + + if (success) + { + monitor_datastore(ds_id); + } + else if (resize_delta > 0) + { + Template quotas; + + quotas.add("DATASTORE", ds_id); + quotas.add("SIZE", resize_delta); + quotas.add("IMAGES", 0); + + Quotas::ds_del(uid, gid, "as); + } + else + { + NebulaLog::log("ImM", Log::WARNING, + "Cannot rollback resize quota: RESIZE_DELTA attribute missing"); + } +} + +/* -------------------------------------------------------------------------- */ + void ImageManager::_restore(unique_ptr msg) { NebulaLog::dddebug("ImM", "_restore: " + msg->payload()); diff --git a/src/oca/go/src/goca/api/image/image.pb.go b/src/oca/go/src/goca/api/image/image.pb.go index d19846f5ef2..3a176eed3bf 100644 --- a/src/oca/go/src/goca/api/image/image.pb.go +++ b/src/oca/go/src/goca/api/image/image.pb.go @@ -31,7 +31,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.32.0 -// protoc v3.21.12 +// protoc v6.33.4 // source: image.proto package image @@ -1155,6 +1155,69 @@ func (x *SnapshotFlattenRequest) GetSnapshotId() int32 { return 0 } +type ResizeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SessionId string `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"` + Oid int32 `protobuf:"varint,2,opt,name=oid,proto3" json:"oid,omitempty"` + Size string `protobuf:"bytes,3,opt,name=size,proto3" json:"size,omitempty"` +} + +func (x *ResizeRequest) Reset() { + *x = ResizeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_image_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResizeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResizeRequest) ProtoMessage() {} + +func (x *ResizeRequest) ProtoReflect() protoreflect.Message { + mi := &file_image_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResizeRequest.ProtoReflect.Descriptor instead. +func (*ResizeRequest) Descriptor() ([]byte, []int) { + return file_image_proto_rawDescGZIP(), []int{16} +} + +func (x *ResizeRequest) GetSessionId() string { + if x != nil { + return x.SessionId + } + return "" +} + +func (x *ResizeRequest) GetOid() int32 { + if x != nil { + return x.Oid + } + return 0 +} + +func (x *ResizeRequest) GetSize() string { + if x != nil { + return x.Size + } + return "" +} + type RestoreRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1169,7 +1232,7 @@ type RestoreRequest struct { func (x *RestoreRequest) Reset() { *x = RestoreRequest{} if protoimpl.UnsafeEnabled { - mi := &file_image_proto_msgTypes[16] + mi := &file_image_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1182,7 +1245,7 @@ func (x *RestoreRequest) String() string { func (*RestoreRequest) ProtoMessage() {} func (x *RestoreRequest) ProtoReflect() protoreflect.Message { - mi := &file_image_proto_msgTypes[16] + mi := &file_image_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1195,7 +1258,7 @@ func (x *RestoreRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreRequest.ProtoReflect.Descriptor instead. func (*RestoreRequest) Descriptor() ([]byte, []int) { - return file_image_proto_rawDescGZIP(), []int{16} + return file_image_proto_rawDescGZIP(), []int{17} } func (x *RestoreRequest) GetSessionId() string { @@ -1240,7 +1303,7 @@ type PoolInfoRequest struct { func (x *PoolInfoRequest) Reset() { *x = PoolInfoRequest{} if protoimpl.UnsafeEnabled { - mi := &file_image_proto_msgTypes[17] + mi := &file_image_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1253,7 +1316,7 @@ func (x *PoolInfoRequest) String() string { func (*PoolInfoRequest) ProtoMessage() {} func (x *PoolInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_image_proto_msgTypes[17] + mi := &file_image_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1266,7 +1329,7 @@ func (x *PoolInfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PoolInfoRequest.ProtoReflect.Descriptor instead. func (*PoolInfoRequest) Descriptor() ([]byte, []int) { - return file_image_proto_rawDescGZIP(), []int{17} + return file_image_proto_rawDescGZIP(), []int{18} } func (x *PoolInfoRequest) GetSessionId() string { @@ -1419,90 +1482,99 @@ var file_image_proto_rawDesc = []byte{ 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6f, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, - 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x49, 0x64, 0x22, 0x71, 0x0a, 0x0e, 0x52, 0x65, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6f, 0x69, 0x64, 0x12, 0x13, 0x0a, - 0x05, 0x64, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x64, 0x73, - 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x70, 0x74, 0x5f, 0x74, 0x6d, 0x70, 0x6c, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x54, 0x6d, 0x70, 0x6c, 0x22, 0x79, 0x0a, - 0x0f, 0x50, 0x6f, 0x6f, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, - 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x66, 0x6c, 0x61, 0x67, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x11, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x46, 0x6c, 0x61, 0x67, - 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, - 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x11, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x32, 0x81, 0x08, 0x0a, 0x0c, 0x49, 0x6d, 0x61, - 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x37, 0x0a, 0x08, 0x41, 0x6c, 0x6c, - 0x6f, 0x63, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, - 0x65, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x49, 0x44, 0x12, 0x33, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x18, 0x2e, 0x6f, - 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x30, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, - 0x16, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x58, 0x4d, 0x4c, 0x12, 0x33, 0x0a, 0x06, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x12, 0x18, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, - 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x33, - 0x0a, 0x06, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, - 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x49, 0x44, 0x12, 0x31, 0x0a, 0x05, 0x43, 0x68, 0x6d, 0x6f, 0x64, 0x12, 0x17, 0x2e, 0x6f, - 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x68, 0x6d, 0x6f, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x31, 0x0a, 0x05, 0x43, 0x68, 0x6f, 0x77, 0x6e, 0x12, - 0x17, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x68, 0x6f, 0x77, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x2f, 0x0a, 0x04, 0x4c, 0x6f, 0x63, - 0x6b, 0x12, 0x16, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x4c, 0x6f, - 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x33, 0x0a, 0x06, 0x55, 0x6e, - 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x18, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, - 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, - 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, - 0x31, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x12, 0x17, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, - 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x49, 0x44, 0x12, 0x33, 0x0a, 0x06, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x18, 0x2e, 0x6f, - 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x3b, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x73, 0x69, - 0x73, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, - 0x65, 0x2e, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x49, 0x64, 0x22, 0x54, 0x0a, 0x0d, 0x52, 0x65, + 0x73, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6f, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, + 0x22, 0x71, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, + 0x6f, 0x69, 0x64, 0x12, 0x13, 0x0a, 0x05, 0x64, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x04, 0x64, 0x73, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x70, 0x74, 0x5f, + 0x74, 0x6d, 0x70, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x54, + 0x6d, 0x70, 0x6c, 0x22, 0x79, 0x0a, 0x0f, 0x50, 0x6f, 0x6f, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, + 0x66, 0x6c, 0x61, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x11, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x10, 0x0a, 0x03, + 0x65, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x11, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x32, 0xb6, + 0x08, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, + 0x37, 0x0a, 0x08, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x6f, 0x6e, + 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x33, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x12, 0x18, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, + 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x30, 0x0a, + 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, + 0x65, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, + 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x58, 0x4d, 0x4c, 0x12, + 0x33, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x18, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, + 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x49, 0x44, 0x12, 0x33, 0x0a, 0x06, 0x43, 0x68, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, - 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x68, 0x74, 0x79, 0x70, + 0x73, 0x65, 0x49, 0x44, 0x12, 0x33, 0x0a, 0x06, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, + 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x43, 0x0a, 0x0e, 0x53, 0x6e, 0x61, - 0x70, 0x73, 0x68, 0x6f, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x20, 0x2e, 0x6f, 0x6e, - 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, - 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x43, - 0x0a, 0x0e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, - 0x12, 0x20, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x6e, 0x61, - 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x49, 0x44, 0x12, 0x45, 0x0a, 0x0f, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x46, - 0x6c, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x12, 0x21, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, - 0x67, 0x65, 0x2e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x46, 0x6c, 0x61, 0x74, 0x74, - 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x36, 0x0a, 0x07, 0x52, 0x65, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x19, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, - 0x65, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x10, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x58, - 0x4d, 0x4c, 0x12, 0x38, 0x0a, 0x08, 0x50, 0x6f, 0x6f, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, - 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x50, 0x6f, 0x6f, 0x6c, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x6f, 0x6e, 0x65, - 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x58, 0x4d, 0x4c, 0x42, 0x39, 0x5a, 0x37, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x70, 0x65, 0x6e, 0x4e, - 0x65, 0x62, 0x75, 0x6c, 0x61, 0x2f, 0x6f, 0x6e, 0x65, 0x2f, 0x73, 0x72, 0x63, 0x2f, 0x6f, 0x63, - 0x61, 0x2f, 0x67, 0x6f, 0x2f, 0x73, 0x72, 0x63, 0x2f, 0x67, 0x6f, 0x63, 0x61, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x31, 0x0a, 0x05, 0x43, 0x68, 0x6d, + 0x6f, 0x64, 0x12, 0x17, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x43, + 0x68, 0x6d, 0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, + 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x31, 0x0a, 0x05, + 0x43, 0x68, 0x6f, 0x77, 0x6e, 0x12, 0x17, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, + 0x65, 0x2e, 0x43, 0x68, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, + 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, + 0x2f, 0x0a, 0x04, 0x4c, 0x6f, 0x63, 0x6b, 0x12, 0x16, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x2e, 0x4c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, + 0x12, 0x33, 0x0a, 0x06, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x18, 0x2e, 0x6f, 0x6e, 0x65, + 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x31, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x12, 0x17, + 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x33, 0x0a, 0x06, 0x45, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x12, 0x18, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x45, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, + 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x3b, 0x0a, + 0x0a, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x2e, 0x6f, 0x6e, + 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x50, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x33, 0x0a, 0x06, 0x43, 0x68, + 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, + 0x2e, 0x43, 0x68, 0x74, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, + 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, + 0x43, 0x0a, 0x0e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x12, 0x20, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x6e, + 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x49, 0x44, 0x12, 0x43, 0x0a, 0x0e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, + 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x12, 0x20, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x2e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x65, 0x76, 0x65, 0x72, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x45, 0x0a, 0x0f, 0x53, 0x6e, 0x61, + 0x70, 0x73, 0x68, 0x6f, 0x74, 0x46, 0x6c, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x12, 0x21, 0x2e, 0x6f, + 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, + 0x74, 0x46, 0x6c, 0x61, 0x74, 0x74, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49, 0x44, + 0x12, 0x33, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x18, 0x2e, 0x6f, 0x6e, 0x65, + 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x49, 0x44, 0x12, 0x36, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x12, 0x19, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x65, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x6f, 0x6e, + 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x58, 0x4d, 0x4c, 0x12, 0x38, 0x0a, + 0x08, 0x50, 0x6f, 0x6f, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, + 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x50, 0x6f, 0x6f, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x6f, 0x6e, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x58, 0x4d, 0x4c, 0x42, 0x39, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x70, 0x65, 0x6e, 0x4e, 0x65, 0x62, 0x75, 0x6c, 0x61, + 0x2f, 0x6f, 0x6e, 0x65, 0x2f, 0x73, 0x72, 0x63, 0x2f, 0x6f, 0x63, 0x61, 0x2f, 0x67, 0x6f, 0x2f, + 0x73, 0x72, 0x63, 0x2f, 0x67, 0x6f, 0x63, 0x61, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1517,7 +1589,7 @@ func file_image_proto_rawDescGZIP() []byte { return file_image_proto_rawDescData } -var file_image_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_image_proto_msgTypes = make([]protoimpl.MessageInfo, 19) var file_image_proto_goTypes = []interface{}{ (*AllocateRequest)(nil), // 0: one.image.AllocateRequest (*DeleteRequest)(nil), // 1: one.image.DeleteRequest @@ -1535,10 +1607,11 @@ var file_image_proto_goTypes = []interface{}{ (*SnapshotDeleteRequest)(nil), // 13: one.image.SnapshotDeleteRequest (*SnapshotRevertRequest)(nil), // 14: one.image.SnapshotRevertRequest (*SnapshotFlattenRequest)(nil), // 15: one.image.SnapshotFlattenRequest - (*RestoreRequest)(nil), // 16: one.image.RestoreRequest - (*PoolInfoRequest)(nil), // 17: one.image.PoolInfoRequest - (*shared.ResponseID)(nil), // 18: one.ResponseID - (*shared.ResponseXML)(nil), // 19: one.ResponseXML + (*ResizeRequest)(nil), // 16: one.image.ResizeRequest + (*RestoreRequest)(nil), // 17: one.image.RestoreRequest + (*PoolInfoRequest)(nil), // 18: one.image.PoolInfoRequest + (*shared.ResponseID)(nil), // 19: one.ResponseID + (*shared.ResponseXML)(nil), // 20: one.ResponseXML } var file_image_proto_depIdxs = []int32{ 0, // 0: one.image.ImageService.Allocate:input_type -> one.image.AllocateRequest @@ -1557,28 +1630,30 @@ var file_image_proto_depIdxs = []int32{ 13, // 13: one.image.ImageService.SnapshotDelete:input_type -> one.image.SnapshotDeleteRequest 14, // 14: one.image.ImageService.SnapshotRevert:input_type -> one.image.SnapshotRevertRequest 15, // 15: one.image.ImageService.SnapshotFlatten:input_type -> one.image.SnapshotFlattenRequest - 16, // 16: one.image.ImageService.Restore:input_type -> one.image.RestoreRequest - 17, // 17: one.image.ImageService.PoolInfo:input_type -> one.image.PoolInfoRequest - 18, // 18: one.image.ImageService.Allocate:output_type -> one.ResponseID - 18, // 19: one.image.ImageService.Delete:output_type -> one.ResponseID - 19, // 20: one.image.ImageService.Info:output_type -> one.ResponseXML - 18, // 21: one.image.ImageService.Update:output_type -> one.ResponseID - 18, // 22: one.image.ImageService.Rename:output_type -> one.ResponseID - 18, // 23: one.image.ImageService.Chmod:output_type -> one.ResponseID - 18, // 24: one.image.ImageService.Chown:output_type -> one.ResponseID - 18, // 25: one.image.ImageService.Lock:output_type -> one.ResponseID - 18, // 26: one.image.ImageService.Unlock:output_type -> one.ResponseID - 18, // 27: one.image.ImageService.Clone:output_type -> one.ResponseID - 18, // 28: one.image.ImageService.Enable:output_type -> one.ResponseID - 18, // 29: one.image.ImageService.Persistent:output_type -> one.ResponseID - 18, // 30: one.image.ImageService.Chtype:output_type -> one.ResponseID - 18, // 31: one.image.ImageService.SnapshotDelete:output_type -> one.ResponseID - 18, // 32: one.image.ImageService.SnapshotRevert:output_type -> one.ResponseID - 18, // 33: one.image.ImageService.SnapshotFlatten:output_type -> one.ResponseID - 19, // 34: one.image.ImageService.Restore:output_type -> one.ResponseXML - 19, // 35: one.image.ImageService.PoolInfo:output_type -> one.ResponseXML - 18, // [18:36] is the sub-list for method output_type - 0, // [0:18] is the sub-list for method input_type + 16, // 16: one.image.ImageService.Resize:input_type -> one.image.ResizeRequest + 17, // 17: one.image.ImageService.Restore:input_type -> one.image.RestoreRequest + 18, // 18: one.image.ImageService.PoolInfo:input_type -> one.image.PoolInfoRequest + 19, // 19: one.image.ImageService.Allocate:output_type -> one.ResponseID + 19, // 20: one.image.ImageService.Delete:output_type -> one.ResponseID + 20, // 21: one.image.ImageService.Info:output_type -> one.ResponseXML + 19, // 22: one.image.ImageService.Update:output_type -> one.ResponseID + 19, // 23: one.image.ImageService.Rename:output_type -> one.ResponseID + 19, // 24: one.image.ImageService.Chmod:output_type -> one.ResponseID + 19, // 25: one.image.ImageService.Chown:output_type -> one.ResponseID + 19, // 26: one.image.ImageService.Lock:output_type -> one.ResponseID + 19, // 27: one.image.ImageService.Unlock:output_type -> one.ResponseID + 19, // 28: one.image.ImageService.Clone:output_type -> one.ResponseID + 19, // 29: one.image.ImageService.Enable:output_type -> one.ResponseID + 19, // 30: one.image.ImageService.Persistent:output_type -> one.ResponseID + 19, // 31: one.image.ImageService.Chtype:output_type -> one.ResponseID + 19, // 32: one.image.ImageService.SnapshotDelete:output_type -> one.ResponseID + 19, // 33: one.image.ImageService.SnapshotRevert:output_type -> one.ResponseID + 19, // 34: one.image.ImageService.SnapshotFlatten:output_type -> one.ResponseID + 19, // 35: one.image.ImageService.Resize:output_type -> one.ResponseID + 20, // 36: one.image.ImageService.Restore:output_type -> one.ResponseXML + 20, // 37: one.image.ImageService.PoolInfo:output_type -> one.ResponseXML + 19, // [19:38] is the sub-list for method output_type + 0, // [0:19] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name @@ -1783,7 +1858,7 @@ func file_image_proto_init() { } } file_image_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RestoreRequest); i { + switch v := v.(*ResizeRequest); i { case 0: return &v.state case 1: @@ -1795,6 +1870,18 @@ func file_image_proto_init() { } } file_image_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RestoreRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_image_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PoolInfoRequest); i { case 0: return &v.state @@ -1813,7 +1900,7 @@ func file_image_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_image_proto_rawDesc, NumEnums: 0, - NumMessages: 18, + NumMessages: 19, NumExtensions: 0, NumServices: 1, }, diff --git a/src/oca/go/src/goca/api/image/image_grpc.pb.go b/src/oca/go/src/goca/api/image/image_grpc.pb.go index e4c18ba6d79..d1fb667faba 100644 --- a/src/oca/go/src/goca/api/image/image_grpc.pb.go +++ b/src/oca/go/src/goca/api/image/image_grpc.pb.go @@ -1,4 +1,38 @@ +// -------------------------------------------------------------------------- + +// Copyright 2002-2025, OpenNebula Project, OpenNebula Systems + +// + +// Licensed under the Apache License, Version 2.0 (the "License"); you may + +// not use this file except in compliance with the License. You may obtain + +// a copy of the License at + +// + +// http://www.apache.org/licenses/LICENSE-2.0 + +// + +// Unless required by applicable law or agreed to in writing, software + +// distributed under the License is distributed on an "AS IS" BASIS, + +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +// See the License for the specific language governing permissions and + +// limitations under the License. + +// -------------------------------------------------------------------------- + // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v6.33.4 +// source: image.proto package image @@ -12,8 +46,31 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 +const ( + ImageService_Allocate_FullMethodName = "/one.image.ImageService/Allocate" + ImageService_Delete_FullMethodName = "/one.image.ImageService/Delete" + ImageService_Info_FullMethodName = "/one.image.ImageService/Info" + ImageService_Update_FullMethodName = "/one.image.ImageService/Update" + ImageService_Rename_FullMethodName = "/one.image.ImageService/Rename" + ImageService_Chmod_FullMethodName = "/one.image.ImageService/Chmod" + ImageService_Chown_FullMethodName = "/one.image.ImageService/Chown" + ImageService_Lock_FullMethodName = "/one.image.ImageService/Lock" + ImageService_Unlock_FullMethodName = "/one.image.ImageService/Unlock" + ImageService_Clone_FullMethodName = "/one.image.ImageService/Clone" + ImageService_Enable_FullMethodName = "/one.image.ImageService/Enable" + ImageService_Persistent_FullMethodName = "/one.image.ImageService/Persistent" + ImageService_Chtype_FullMethodName = "/one.image.ImageService/Chtype" + ImageService_SnapshotDelete_FullMethodName = "/one.image.ImageService/SnapshotDelete" + ImageService_SnapshotRevert_FullMethodName = "/one.image.ImageService/SnapshotRevert" + ImageService_SnapshotFlatten_FullMethodName = "/one.image.ImageService/SnapshotFlatten" + ImageService_Resize_FullMethodName = "/one.image.ImageService/Resize" + ImageService_Restore_FullMethodName = "/one.image.ImageService/Restore" + ImageService_PoolInfo_FullMethodName = "/one.image.ImageService/PoolInfo" +) + // ImageServiceClient is the client API for ImageService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. @@ -34,6 +91,7 @@ type ImageServiceClient interface { SnapshotDelete(ctx context.Context, in *SnapshotDeleteRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) SnapshotRevert(ctx context.Context, in *SnapshotRevertRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) SnapshotFlatten(ctx context.Context, in *SnapshotFlattenRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) + Resize(ctx context.Context, in *ResizeRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) Restore(ctx context.Context, in *RestoreRequest, opts ...grpc.CallOption) (*shared.ResponseXML, error) PoolInfo(ctx context.Context, in *PoolInfoRequest, opts ...grpc.CallOption) (*shared.ResponseXML, error) } @@ -48,7 +106,7 @@ func NewImageServiceClient(cc grpc.ClientConnInterface) ImageServiceClient { func (c *imageServiceClient) Allocate(ctx context.Context, in *AllocateRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) { out := new(shared.ResponseID) - err := c.cc.Invoke(ctx, "/one.image.ImageService/Allocate", in, out, opts...) + err := c.cc.Invoke(ctx, ImageService_Allocate_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -57,7 +115,7 @@ func (c *imageServiceClient) Allocate(ctx context.Context, in *AllocateRequest, func (c *imageServiceClient) Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) { out := new(shared.ResponseID) - err := c.cc.Invoke(ctx, "/one.image.ImageService/Delete", in, out, opts...) + err := c.cc.Invoke(ctx, ImageService_Delete_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -66,7 +124,7 @@ func (c *imageServiceClient) Delete(ctx context.Context, in *DeleteRequest, opts func (c *imageServiceClient) Info(ctx context.Context, in *InfoRequest, opts ...grpc.CallOption) (*shared.ResponseXML, error) { out := new(shared.ResponseXML) - err := c.cc.Invoke(ctx, "/one.image.ImageService/Info", in, out, opts...) + err := c.cc.Invoke(ctx, ImageService_Info_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -75,7 +133,7 @@ func (c *imageServiceClient) Info(ctx context.Context, in *InfoRequest, opts ... func (c *imageServiceClient) Update(ctx context.Context, in *UpdateRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) { out := new(shared.ResponseID) - err := c.cc.Invoke(ctx, "/one.image.ImageService/Update", in, out, opts...) + err := c.cc.Invoke(ctx, ImageService_Update_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -84,7 +142,7 @@ func (c *imageServiceClient) Update(ctx context.Context, in *UpdateRequest, opts func (c *imageServiceClient) Rename(ctx context.Context, in *RenameRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) { out := new(shared.ResponseID) - err := c.cc.Invoke(ctx, "/one.image.ImageService/Rename", in, out, opts...) + err := c.cc.Invoke(ctx, ImageService_Rename_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -93,7 +151,7 @@ func (c *imageServiceClient) Rename(ctx context.Context, in *RenameRequest, opts func (c *imageServiceClient) Chmod(ctx context.Context, in *ChmodRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) { out := new(shared.ResponseID) - err := c.cc.Invoke(ctx, "/one.image.ImageService/Chmod", in, out, opts...) + err := c.cc.Invoke(ctx, ImageService_Chmod_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -102,7 +160,7 @@ func (c *imageServiceClient) Chmod(ctx context.Context, in *ChmodRequest, opts . func (c *imageServiceClient) Chown(ctx context.Context, in *ChownRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) { out := new(shared.ResponseID) - err := c.cc.Invoke(ctx, "/one.image.ImageService/Chown", in, out, opts...) + err := c.cc.Invoke(ctx, ImageService_Chown_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -111,7 +169,7 @@ func (c *imageServiceClient) Chown(ctx context.Context, in *ChownRequest, opts . func (c *imageServiceClient) Lock(ctx context.Context, in *LockRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) { out := new(shared.ResponseID) - err := c.cc.Invoke(ctx, "/one.image.ImageService/Lock", in, out, opts...) + err := c.cc.Invoke(ctx, ImageService_Lock_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -120,7 +178,7 @@ func (c *imageServiceClient) Lock(ctx context.Context, in *LockRequest, opts ... func (c *imageServiceClient) Unlock(ctx context.Context, in *UnlockRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) { out := new(shared.ResponseID) - err := c.cc.Invoke(ctx, "/one.image.ImageService/Unlock", in, out, opts...) + err := c.cc.Invoke(ctx, ImageService_Unlock_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -129,7 +187,7 @@ func (c *imageServiceClient) Unlock(ctx context.Context, in *UnlockRequest, opts func (c *imageServiceClient) Clone(ctx context.Context, in *CloneRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) { out := new(shared.ResponseID) - err := c.cc.Invoke(ctx, "/one.image.ImageService/Clone", in, out, opts...) + err := c.cc.Invoke(ctx, ImageService_Clone_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -138,7 +196,7 @@ func (c *imageServiceClient) Clone(ctx context.Context, in *CloneRequest, opts . func (c *imageServiceClient) Enable(ctx context.Context, in *EnableRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) { out := new(shared.ResponseID) - err := c.cc.Invoke(ctx, "/one.image.ImageService/Enable", in, out, opts...) + err := c.cc.Invoke(ctx, ImageService_Enable_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -147,7 +205,7 @@ func (c *imageServiceClient) Enable(ctx context.Context, in *EnableRequest, opts func (c *imageServiceClient) Persistent(ctx context.Context, in *PersistentRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) { out := new(shared.ResponseID) - err := c.cc.Invoke(ctx, "/one.image.ImageService/Persistent", in, out, opts...) + err := c.cc.Invoke(ctx, ImageService_Persistent_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -156,7 +214,7 @@ func (c *imageServiceClient) Persistent(ctx context.Context, in *PersistentReque func (c *imageServiceClient) Chtype(ctx context.Context, in *ChtypeRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) { out := new(shared.ResponseID) - err := c.cc.Invoke(ctx, "/one.image.ImageService/Chtype", in, out, opts...) + err := c.cc.Invoke(ctx, ImageService_Chtype_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -165,7 +223,7 @@ func (c *imageServiceClient) Chtype(ctx context.Context, in *ChtypeRequest, opts func (c *imageServiceClient) SnapshotDelete(ctx context.Context, in *SnapshotDeleteRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) { out := new(shared.ResponseID) - err := c.cc.Invoke(ctx, "/one.image.ImageService/SnapshotDelete", in, out, opts...) + err := c.cc.Invoke(ctx, ImageService_SnapshotDelete_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -174,7 +232,7 @@ func (c *imageServiceClient) SnapshotDelete(ctx context.Context, in *SnapshotDel func (c *imageServiceClient) SnapshotRevert(ctx context.Context, in *SnapshotRevertRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) { out := new(shared.ResponseID) - err := c.cc.Invoke(ctx, "/one.image.ImageService/SnapshotRevert", in, out, opts...) + err := c.cc.Invoke(ctx, ImageService_SnapshotRevert_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -183,7 +241,16 @@ func (c *imageServiceClient) SnapshotRevert(ctx context.Context, in *SnapshotRev func (c *imageServiceClient) SnapshotFlatten(ctx context.Context, in *SnapshotFlattenRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) { out := new(shared.ResponseID) - err := c.cc.Invoke(ctx, "/one.image.ImageService/SnapshotFlatten", in, out, opts...) + err := c.cc.Invoke(ctx, ImageService_SnapshotFlatten_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *imageServiceClient) Resize(ctx context.Context, in *ResizeRequest, opts ...grpc.CallOption) (*shared.ResponseID, error) { + out := new(shared.ResponseID) + err := c.cc.Invoke(ctx, ImageService_Resize_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -192,7 +259,7 @@ func (c *imageServiceClient) SnapshotFlatten(ctx context.Context, in *SnapshotFl func (c *imageServiceClient) Restore(ctx context.Context, in *RestoreRequest, opts ...grpc.CallOption) (*shared.ResponseXML, error) { out := new(shared.ResponseXML) - err := c.cc.Invoke(ctx, "/one.image.ImageService/Restore", in, out, opts...) + err := c.cc.Invoke(ctx, ImageService_Restore_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -201,7 +268,7 @@ func (c *imageServiceClient) Restore(ctx context.Context, in *RestoreRequest, op func (c *imageServiceClient) PoolInfo(ctx context.Context, in *PoolInfoRequest, opts ...grpc.CallOption) (*shared.ResponseXML, error) { out := new(shared.ResponseXML) - err := c.cc.Invoke(ctx, "/one.image.ImageService/PoolInfo", in, out, opts...) + err := c.cc.Invoke(ctx, ImageService_PoolInfo_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -228,6 +295,7 @@ type ImageServiceServer interface { SnapshotDelete(context.Context, *SnapshotDeleteRequest) (*shared.ResponseID, error) SnapshotRevert(context.Context, *SnapshotRevertRequest) (*shared.ResponseID, error) SnapshotFlatten(context.Context, *SnapshotFlattenRequest) (*shared.ResponseID, error) + Resize(context.Context, *ResizeRequest) (*shared.ResponseID, error) Restore(context.Context, *RestoreRequest) (*shared.ResponseXML, error) PoolInfo(context.Context, *PoolInfoRequest) (*shared.ResponseXML, error) mustEmbedUnimplementedImageServiceServer() @@ -285,6 +353,9 @@ func (UnimplementedImageServiceServer) SnapshotRevert(context.Context, *Snapshot func (UnimplementedImageServiceServer) SnapshotFlatten(context.Context, *SnapshotFlattenRequest) (*shared.ResponseID, error) { return nil, status.Errorf(codes.Unimplemented, "method SnapshotFlatten not implemented") } +func (UnimplementedImageServiceServer) Resize(context.Context, *ResizeRequest) (*shared.ResponseID, error) { + return nil, status.Errorf(codes.Unimplemented, "method Resize not implemented") +} func (UnimplementedImageServiceServer) Restore(context.Context, *RestoreRequest) (*shared.ResponseXML, error) { return nil, status.Errorf(codes.Unimplemented, "method Restore not implemented") } @@ -300,8 +371,8 @@ type UnsafeImageServiceServer interface { mustEmbedUnimplementedImageServiceServer() } -func RegisterImageServiceServer(s *grpc.Server, srv ImageServiceServer) { - s.RegisterService(&_ImageService_serviceDesc, srv) +func RegisterImageServiceServer(s grpc.ServiceRegistrar, srv ImageServiceServer) { + s.RegisterService(&ImageService_ServiceDesc, srv) } func _ImageService_Allocate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { @@ -314,7 +385,7 @@ func _ImageService_Allocate_Handler(srv interface{}, ctx context.Context, dec fu } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/one.image.ImageService/Allocate", + FullMethod: ImageService_Allocate_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ImageServiceServer).Allocate(ctx, req.(*AllocateRequest)) @@ -332,7 +403,7 @@ func _ImageService_Delete_Handler(srv interface{}, ctx context.Context, dec func } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/one.image.ImageService/Delete", + FullMethod: ImageService_Delete_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ImageServiceServer).Delete(ctx, req.(*DeleteRequest)) @@ -350,7 +421,7 @@ func _ImageService_Info_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/one.image.ImageService/Info", + FullMethod: ImageService_Info_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ImageServiceServer).Info(ctx, req.(*InfoRequest)) @@ -368,7 +439,7 @@ func _ImageService_Update_Handler(srv interface{}, ctx context.Context, dec func } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/one.image.ImageService/Update", + FullMethod: ImageService_Update_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ImageServiceServer).Update(ctx, req.(*UpdateRequest)) @@ -386,7 +457,7 @@ func _ImageService_Rename_Handler(srv interface{}, ctx context.Context, dec func } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/one.image.ImageService/Rename", + FullMethod: ImageService_Rename_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ImageServiceServer).Rename(ctx, req.(*RenameRequest)) @@ -404,7 +475,7 @@ func _ImageService_Chmod_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/one.image.ImageService/Chmod", + FullMethod: ImageService_Chmod_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ImageServiceServer).Chmod(ctx, req.(*ChmodRequest)) @@ -422,7 +493,7 @@ func _ImageService_Chown_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/one.image.ImageService/Chown", + FullMethod: ImageService_Chown_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ImageServiceServer).Chown(ctx, req.(*ChownRequest)) @@ -440,7 +511,7 @@ func _ImageService_Lock_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/one.image.ImageService/Lock", + FullMethod: ImageService_Lock_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ImageServiceServer).Lock(ctx, req.(*LockRequest)) @@ -458,7 +529,7 @@ func _ImageService_Unlock_Handler(srv interface{}, ctx context.Context, dec func } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/one.image.ImageService/Unlock", + FullMethod: ImageService_Unlock_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ImageServiceServer).Unlock(ctx, req.(*UnlockRequest)) @@ -476,7 +547,7 @@ func _ImageService_Clone_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/one.image.ImageService/Clone", + FullMethod: ImageService_Clone_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ImageServiceServer).Clone(ctx, req.(*CloneRequest)) @@ -494,7 +565,7 @@ func _ImageService_Enable_Handler(srv interface{}, ctx context.Context, dec func } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/one.image.ImageService/Enable", + FullMethod: ImageService_Enable_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ImageServiceServer).Enable(ctx, req.(*EnableRequest)) @@ -512,7 +583,7 @@ func _ImageService_Persistent_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/one.image.ImageService/Persistent", + FullMethod: ImageService_Persistent_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ImageServiceServer).Persistent(ctx, req.(*PersistentRequest)) @@ -530,7 +601,7 @@ func _ImageService_Chtype_Handler(srv interface{}, ctx context.Context, dec func } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/one.image.ImageService/Chtype", + FullMethod: ImageService_Chtype_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ImageServiceServer).Chtype(ctx, req.(*ChtypeRequest)) @@ -548,7 +619,7 @@ func _ImageService_SnapshotDelete_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/one.image.ImageService/SnapshotDelete", + FullMethod: ImageService_SnapshotDelete_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ImageServiceServer).SnapshotDelete(ctx, req.(*SnapshotDeleteRequest)) @@ -566,7 +637,7 @@ func _ImageService_SnapshotRevert_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/one.image.ImageService/SnapshotRevert", + FullMethod: ImageService_SnapshotRevert_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ImageServiceServer).SnapshotRevert(ctx, req.(*SnapshotRevertRequest)) @@ -584,7 +655,7 @@ func _ImageService_SnapshotFlatten_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/one.image.ImageService/SnapshotFlatten", + FullMethod: ImageService_SnapshotFlatten_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ImageServiceServer).SnapshotFlatten(ctx, req.(*SnapshotFlattenRequest)) @@ -592,6 +663,24 @@ func _ImageService_SnapshotFlatten_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } +func _ImageService_Resize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ResizeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ImageServiceServer).Resize(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ImageService_Resize_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ImageServiceServer).Resize(ctx, req.(*ResizeRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _ImageService_Restore_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RestoreRequest) if err := dec(in); err != nil { @@ -602,7 +691,7 @@ func _ImageService_Restore_Handler(srv interface{}, ctx context.Context, dec fun } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/one.image.ImageService/Restore", + FullMethod: ImageService_Restore_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ImageServiceServer).Restore(ctx, req.(*RestoreRequest)) @@ -620,7 +709,7 @@ func _ImageService_PoolInfo_Handler(srv interface{}, ctx context.Context, dec fu } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/one.image.ImageService/PoolInfo", + FullMethod: ImageService_PoolInfo_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(ImageServiceServer).PoolInfo(ctx, req.(*PoolInfoRequest)) @@ -628,7 +717,10 @@ func _ImageService_PoolInfo_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } -var _ImageService_serviceDesc = grpc.ServiceDesc{ +// ImageService_ServiceDesc is the grpc.ServiceDesc for ImageService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ImageService_ServiceDesc = grpc.ServiceDesc{ ServiceName: "one.image.ImageService", HandlerType: (*ImageServiceServer)(nil), Methods: []grpc.MethodDesc{ @@ -696,6 +788,10 @@ var _ImageService_serviceDesc = grpc.ServiceDesc{ MethodName: "SnapshotFlatten", Handler: _ImageService_SnapshotFlatten_Handler, }, + { + MethodName: "Resize", + Handler: _ImageService_Resize_Handler, + }, { MethodName: "Restore", Handler: _ImageService_Restore_Handler, diff --git a/src/oca/go/src/goca/client.go b/src/oca/go/src/goca/client.go index c9749a1c365..6fb62a826a5 100644 --- a/src/oca/go/src/goca/client.go +++ b/src/oca/go/src/goca/client.go @@ -693,6 +693,10 @@ func (c *Client) ImageSnapshotFlatten(ctx context.Context, id, snap_id int) (*Re return c.CallContext(ctx, "one.image.snapshotflatten", id, snap_id) } +func (c *Client) ImageResize(ctx context.Context, id int, newSize string) (*Response, error) { + return c.CallContext(ctx, "one.image.resize", id, newSize) +} + func (c *Client) ImageRestore(ctx context.Context, id, dsid int, opt_tmpl string) (*Response, error) { return c.CallContext(ctx, "one.image.restore", id, dsid, opt_tmpl) } diff --git a/src/oca/go/src/goca/controller.go b/src/oca/go/src/goca/controller.go index 0cfdca43596..d4bc9f42d4d 100644 --- a/src/oca/go/src/goca/controller.go +++ b/src/oca/go/src/goca/controller.go @@ -134,6 +134,7 @@ type RPCCaller interface { ImageSnapshotDelete(ctx context.Context, id, snap_id int) (*Response, error) ImageSnapshotRevert(ctx context.Context, id, snap_id int) (*Response, error) ImageSnapshotFlatten(ctx context.Context, id, snap_id int) (*Response, error) + ImageResize(ctx context.Context, id int, newSize string) (*Response, error) ImageRestore(ctx context.Context, id, dsid int, opt_tmpl string) (*Response, error) ImagePoolInfo(ctx context.Context, filter, start, end int) (*Response, error) diff --git a/src/oca/go/src/goca/grpc_client.go b/src/oca/go/src/goca/grpc_client.go index 4ba12bf0891..f71d18916e1 100644 --- a/src/oca/go/src/goca/grpc_client.go +++ b/src/oca/go/src/goca/grpc_client.go @@ -1145,6 +1145,16 @@ func (c *GRPCClient) ImageSnapshotFlatten(ctx context.Context, id, snapID int) ( return &Response{status: true, bodyInt: int(res.Oid)}, nil } +func (c *GRPCClient) ImageResize(ctx context.Context, id int, newSize string) (*Response, error) { + client := image.NewImageServiceClient(c.conn) + req := &image.ResizeRequest{SessionId: c.token, Oid: int32(id), Size: newSize} + res, err := client.Resize(ctx, req) + if err != nil { + return MakeErrorResponse(err) + } + return &Response{status: true, bodyInt: int(res.Oid)}, nil +} + func (c *GRPCClient) ImageRestore(ctx context.Context, id, dsid int, optTmpl string) (*Response, error) { client := image.NewImageServiceClient(c.conn) req := &image.RestoreRequest{SessionId: c.token, Oid: int32(id), DsId: int32(dsid), OptTmpl: optTmpl} diff --git a/src/oca/go/src/goca/image.go b/src/oca/go/src/goca/image.go index c876ea64c6c..5bbdf00bc29 100644 --- a/src/oca/go/src/goca/image.go +++ b/src/oca/go/src/goca/image.go @@ -319,6 +319,20 @@ func (ic *ImageController) DeleteContext(ctx context.Context) error { return err } +// Resize resizes the image to a new size. +// * newSize: new size in MiB +func (ic *ImageController) Resize(newSize string) error { + return ic.ResizeContext(context.Background(), newSize) +} + +// ResizeContext resizes the image to a new size. +// * ctx: context for cancelation +// * newSize: new size in MiB +func (ic *ImageController) ResizeContext(ctx context.Context, newSize string) error { + _, err := ic.c.Client.ImageResize(ctx, ic.ID, newSize) + return err +} + // Restore restores a VM backup. // * ds_id: target Datastore ID // * tmpl: template with optional arguments (NAME, NO_IP, NO_NIC, INCREMENT_ID, DISK_ID). diff --git a/src/oca/go/src/goca/image_test.go b/src/oca/go/src/goca/image_test.go index 256cfb3c617..10e5a899b1a 100644 --- a/src/oca/go/src/goca/image_test.go +++ b/src/oca/go/src/goca/image_test.go @@ -237,6 +237,62 @@ func (s *ImageSuite) TestSnapshots(c *C) { c.Assert(err.Error(), Matches, ".*does not exist.*") } +func (s *ImageSuite) TestResize(c *C) { + // Wait Image is ready + imageC := testCtrl.Image(s.ID) + wait := WaitResource(ImageExpectState(imageC, "READY")) + c.Assert(wait, Equals, true) + + // Get initial size to make test independent of fixture + image, err := imageC.Info(false) + c.Assert(err, IsNil) + curSize := image.Size + + // Resize to same size should fail (must be strictly greater) + err = imageC.Resize(fmt.Sprintf("%d", curSize)) + c.Assert(err, NotNil) + c.Assert(err.Error(), Matches, ".*greater than current.*") + + // Resize with invalid input should fail + err = imageC.Resize("abc") + c.Assert(err, NotNil) + c.Assert(err.Error(), Matches, ".*Invalid size.*") + + // Resize with empty string should fail + err = imageC.Resize("") + c.Assert(err, NotNil) + c.Assert(err.Error(), Matches, ".*Invalid size.*") + + // Resize with trailing garbage should fail (not silently truncate) + err = imageC.Resize("100abc") + c.Assert(err, NotNil) + c.Assert(err.Error(), Matches, ".*Invalid size.*") + + // Resize with zero should fail + err = imageC.Resize("0") + c.Assert(err, NotNil) + c.Assert(err.Error(), Matches, ".*Invalid size.*") + + // Resize with negative number should fail + err = imageC.Resize("-1") + c.Assert(err, NotNil) + c.Assert(err.Error(), Matches, ".*Invalid size.*") + + // Successful resize to larger size + newSize := curSize + 1 + err = imageC.Resize(fmt.Sprintf("%d", newSize)) + c.Assert(err, IsNil) + + // Wait for image to return to READY state after async resize + wait = WaitResource(ImageExpectState(imageC, "READY")) + c.Assert(wait, Equals, true) + + // Verify the new size + image, err = imageC.Info(false) + c.Assert(err, IsNil) + c.Assert(image.Size, Equals, newSize) +} + func (s *ImageSuite) TestRestore(c *C) { imageC := testCtrl.Image(s.ID) err := imageC.Restore(1, "") diff --git a/src/oca/ruby/opennebula/image.rb b/src/oca/ruby/opennebula/image.rb index 041ea0d9340..ff7ed24503b 100644 --- a/src/oca/ruby/opennebula/image.rb +++ b/src/oca/ruby/opennebula/image.rb @@ -40,6 +40,7 @@ class Image < PoolElement :snapshotdelete => "image.snapshotdelete", :snapshotrevert => "image.snapshotrevert", :snapshotflatten => "image.snapshotflatten", + :resize => "image.resize", :restore => "image.restore", :lock => "image.lock", :unlock => "image.unlock" @@ -263,6 +264,15 @@ def snapshot_flatten(snap_id) call(IMAGE_METHODS[:snapshotflatten], @pe_id, snap_id) end + # Resizes an image to a new size (only upsize supported) + # + # @param size [String] New size in MiB + # + # @return [nil, OpenNebula::Error] nil in case of success or Error + def resize(size) + call(IMAGE_METHODS[:resize], @pe_id, size.to_s) + end + # Restore the VM backup stored by the image # # @param dst_id [Integer] Datastore destination ID diff --git a/src/rm/api/ImageAPI.cc b/src/rm/api/ImageAPI.cc index 39f9f1cdc22..b7f11ea9a57 100644 --- a/src/rm/api/ImageAPI.cc +++ b/src/rm/api/ImageAPI.cc @@ -590,6 +590,30 @@ Request::ErrorCode ImageAPI::snapshot_flatten(int oid, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +Request::ErrorCode ImageAPI::resize(int oid, + const std::string& size, + RequestAttributes& att) +{ + ImageManager* imagem = Nebula::instance().get_imagem(); + + if ( auto ec = basic_authorization(oid, att); ec != Request::SUCCESS ) + { + return ec; + } + + int rc = imagem->resize_image(oid, size, att.resp_msg); + + if ( rc < 0 ) + { + return Request::ACTION; + } + + return Request::SUCCESS; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + Request::ErrorCode ImageAPI::restore(int oid, int ds_id, const std::string& opt_tmpl, diff --git a/src/rm/api/ImageAPI.h b/src/rm/api/ImageAPI.h index 9ca1d59e799..f889abfc5e5 100644 --- a/src/rm/api/ImageAPI.h +++ b/src/rm/api/ImageAPI.h @@ -79,6 +79,10 @@ class ImageAPI : public SharedAPI int snap_id, RequestAttributes& att); + Request::ErrorCode resize(int oid, + const std::string& size, + RequestAttributes& att); + Request::ErrorCode restore(int oid, int ds_id, const std::string& opt_tmpl, diff --git a/src/rm/grpc/ImageServiceGRPC.cc b/src/rm/grpc/ImageServiceGRPC.cc index 6a1e8b5c272..f979052d607 100644 --- a/src/rm/grpc/ImageServiceGRPC.cc +++ b/src/rm/grpc/ImageServiceGRPC.cc @@ -132,6 +132,13 @@ grpc::Status ImageService::SnapshotFlatten(grpc::ServerContext* context, return ImageSnapshotFlattenGRPC().execute(context, request, response); } +grpc::Status ImageService::Resize(grpc::ServerContext* context, + const one::image::ResizeRequest* request, + one::ResponseID* response) +{ + return ImageResizeGRPC().execute(context, request, response); +} + grpc::Status ImageService::Restore(grpc::ServerContext* context, const one::image::RestoreRequest* request, one::ResponseXML* response) @@ -437,6 +444,23 @@ void ImageSnapshotFlattenGRPC::request_execute(const google::protobuf::Message* /* ------------------------------------------------------------------------- */ +void ImageResizeGRPC::request_execute(const google::protobuf::Message* _request, + google::protobuf::Message* _response, + RequestAttributesGRPC& att) +{ + auto request = static_cast(_request); + + int oid = request->oid(); + + auto ec = resize(oid, + request->size(), + att); + + response(ec, oid, att); +} + +/* ------------------------------------------------------------------------- */ + void ImageRestoreGRPC::request_execute(const google::protobuf::Message* _request, google::protobuf::Message* _response, RequestAttributesGRPC& att) diff --git a/src/rm/grpc/ImageServiceGRPC.h b/src/rm/grpc/ImageServiceGRPC.h index 51d9b9e4fea..2f1933676f5 100644 --- a/src/rm/grpc/ImageServiceGRPC.h +++ b/src/rm/grpc/ImageServiceGRPC.h @@ -94,6 +94,10 @@ class ImageService final : public one::image::ImageService::Service const one::image::SnapshotFlattenRequest* request, one::ResponseID* response) override; + grpc::Status Resize(grpc::ServerContext* context, + const one::image::ResizeRequest* request, + one::ResponseID* response) override; + grpc::Status Restore(grpc::ServerContext* context, const one::image::RestoreRequest* request, one::ResponseXML* response) override; @@ -346,6 +350,21 @@ class ImageSnapshotFlattenGRPC : public RequestGRPC, public ImageAPI /* ------------------------------------------------------------------------- */ +class ImageResizeGRPC : public RequestGRPC, public ImageAPI +{ +public: + ImageResizeGRPC() : + RequestGRPC("one.image.resize", "/one.image.ImageService/Resize"), + ImageAPI(static_cast(*this)) + {} + + void request_execute(const google::protobuf::Message* _request, + google::protobuf::Message* _response, + RequestAttributesGRPC& att) override; +}; + +/* ------------------------------------------------------------------------- */ + class ImageRestoreGRPC : public RequestGRPC, public ImageAPI { public: diff --git a/src/rm/grpc/proto/image.proto b/src/rm/grpc/proto/image.proto index 7f2d4f04998..92ac2d9c82f 100644 --- a/src/rm/grpc/proto/image.proto +++ b/src/rm/grpc/proto/image.proto @@ -145,6 +145,13 @@ message SnapshotFlattenRequest int32 snapshot_id = 3; } +message ResizeRequest +{ + string session_id = 1; + int32 oid = 2; + string size = 3; // New size in MiB as integer string, must be > current size +} + message RestoreRequest { string session_id = 1; @@ -195,6 +202,8 @@ service ImageService rpc SnapshotFlatten (one.image.SnapshotFlattenRequest) returns (one.ResponseID); + rpc Resize (one.image.ResizeRequest) returns (one.ResponseID); + rpc Restore (one.image.RestoreRequest) returns (one.ResponseXML); rpc PoolInfo (one.image.PoolInfoRequest) returns (one.ResponseXML); diff --git a/src/rm/xml-rpc/ImageXRPC.cc b/src/rm/xml-rpc/ImageXRPC.cc index 697fa0ff34f..3eca0137f62 100644 --- a/src/rm/xml-rpc/ImageXRPC.cc +++ b/src/rm/xml-rpc/ImageXRPC.cc @@ -276,6 +276,21 @@ void ImageSnapshotFlattenXRPC::request_execute(xmlrpc_c::paramList const& paramL /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void ImageResizeXRPC::request_execute(xmlrpc_c::paramList const& paramList, + RequestAttributesXRPC& att) +{ + int oid = paramList.getInt(1); + + auto ec = resize(oid, + paramList.getString(2), // size in MiB + att); + + response(ec, oid, att); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void ImageRestoreXRPC::request_execute(xmlrpc_c::paramList const& paramList, RequestAttributesXRPC& att) { diff --git a/src/rm/xml-rpc/ImageXRPC.h b/src/rm/xml-rpc/ImageXRPC.h index 703c4abd902..c9edd05c07c 100644 --- a/src/rm/xml-rpc/ImageXRPC.h +++ b/src/rm/xml-rpc/ImageXRPC.h @@ -296,6 +296,23 @@ class ImageSnapshotFlattenXRPC: public RequestXRPC, public ImageAPI /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ +class ImageResizeXRPC: public RequestXRPC, public ImageAPI +{ +public: + ImageResizeXRPC() + : RequestXRPC("one.image.resize", + "Resizes an Image. Size is an integer string in MiB", + "A:sis") + , ImageAPI(static_cast(*this)) + {} + + void request_execute(xmlrpc_c::paramList const& _paramList, + RequestAttributesXRPC& att) override; +}; + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + class ImageRestoreXRPC: public RequestXRPC, public ImageAPI { public: diff --git a/src/rm/xml-rpc/RequestManagerXRPC.cc b/src/rm/xml-rpc/RequestManagerXRPC.cc index 101ad3183ef..5e073a6ca6d 100644 --- a/src/rm/xml-rpc/RequestManagerXRPC.cc +++ b/src/rm/xml-rpc/RequestManagerXRPC.cc @@ -608,6 +608,7 @@ void RequestManagerXRPC::register_xml_methods() xmlrpc_c::methodPtr image_snap_delete(new ImageSnapshotDeleteXRPC()); xmlrpc_c::methodPtr image_snap_revert(new ImageSnapshotRevertXRPC()); xmlrpc_c::methodPtr image_snap_flatten(new ImageSnapshotFlattenXRPC()); + xmlrpc_c::methodPtr image_resize(new ImageResizeXRPC()); xmlrpc_c::methodPtr image_restore(new ImageRestoreXRPC()); xmlrpc_c::methodPtr imagepool_info(new ImagePoolInfoXRPC()); @@ -628,6 +629,7 @@ void RequestManagerXRPC::register_xml_methods() RequestManagerRegistry.addMethod("one.image.snapshotdelete", image_snap_delete); RequestManagerRegistry.addMethod("one.image.snapshotrevert", image_snap_revert); RequestManagerRegistry.addMethod("one.image.snapshotflatten", image_snap_flatten); + RequestManagerRegistry.addMethod("one.image.resize", image_resize); RequestManagerRegistry.addMethod("one.image.restore", image_restore); RequestManagerRegistry.addMethod("one.imagepool.info", imagepool_info);