From 1e9e52138d7ab6f1f44948d25ad6cbfc062a6b28 Mon Sep 17 00:00:00 2001 From: Vlastimil Holer <vholer@opennebula.org> Date: Tue, 29 Aug 2017 17:28:48 +0200 Subject: [PATCH] F #1310: Added support for multiple deployment modes. This commit adds support of SSH mode for a Ceph datastore. Author: Vlastimil Holer <vholer@opennebula.org> Author: juanmont <jjmontiel@opennebula.org> (cherry picked from commit 8ab9c02102e2e7f72c4835aa819bab49c229ef45) --- include/PoolObjectSQL.h | 6 + include/VirtualMachineDisk.h | 21 +++- share/etc/oned.conf | 3 +- src/datastore/Datastore.cc | 98 +++++++++++++++- .../form-panels/create/wizard-tabs/storage.js | 75 +++++++++++- .../create/wizard-tabs/storage/disk-tab.js | 1 + .../create/wizard-tabs/storage/html.hbs | 17 +++ src/tm_mad/ceph/clone | 66 +++++++---- src/tm_mad/ceph/cpds | 55 +++++++-- src/tm_mad/ceph/delete | 26 +++-- src/tm_mad/ceph/ln | 36 ++++-- src/tm_mad/ceph/mvds | 107 +++++++++++++++++- src/tm_mad/ceph/resize | 15 ++- src/tm_mad/ceph/snap_create | 9 +- src/tm_mad/ceph/snap_create_live | 9 +- src/tm_mad/ceph/snap_delete | 9 +- src/tm_mad/ceph/snap_revert | 9 +- src/vm/VirtualMachine.cc | 41 +++++-- src/vm/VirtualMachineDisk.cc | 67 ++++++++++- 19 files changed, 594 insertions(+), 76 deletions(-) diff --git a/include/PoolObjectSQL.h b/include/PoolObjectSQL.h index d5a0caa131..b1759cdd74 100644 --- a/include/PoolObjectSQL.h +++ b/include/PoolObjectSQL.h @@ -376,6 +376,12 @@ public: */ template<typename T> bool get_template_attribute(const char * name, T& value) const + { + return obj_template->get(name,value); + } + + template<typename T> + bool get_template_attribute(const string& name, T& value) const { return obj_template->get(name,value); } diff --git a/include/VirtualMachineDisk.h b/include/VirtualMachineDisk.h index 41634ef420..b4f39133e2 100644 --- a/include/VirtualMachineDisk.h +++ b/include/VirtualMachineDisk.h @@ -162,6 +162,11 @@ public: */ int get_image_id(int &id, int uid); + /** + * Return the TM_MAD_SYSTEM attribute + */ + std::string get_tm_mad_system(); + /* ---------------------------------------------------------------------- */ /* Image Manager Interface */ /* ---------------------------------------------------------------------- */ @@ -320,6 +325,13 @@ public: */ void datastore_sizes(int& ds_id, long long& img_sz, long long& sys_sz); + /** + * Update the TYPE and DISK_TYPE attributes based on the system DS + * name + * @param ds_name of the system ds tm_mad + */ + void set_types(const string& ds_name); + private: Snapshots * snapshots; @@ -478,13 +490,15 @@ public: * Get all disk images for this Virtual Machine * @param vm_id of the VirtualMachine * @param uid of owner + * @param tm_mad_sys tm_mad_sys mode to deploy the disks * @param disks list of DISK Attribute in VirtualMachine Template * @param context attribute, 0 if none * @param error_str Returns the error reason, if any * @return 0 if success */ - int get_images(int vm_id, int uid, vector<Attribute *> disks, - VectorAttribute * context, std::string& error_str); + int get_images(int vm_id, int uid, const std::string& tm_mad_sys, + vector<Attribute *> disks, VectorAttribute * context, + std::string& error_str); /** * Release the images in the disk set @@ -562,7 +576,8 @@ public: * @return Pointer to the new disk or 0 in case of error */ VirtualMachineDisk * set_up_attach(int vmid, int uid, int cluster_id, - VectorAttribute * vdisk, VectorAttribute * vcontext, string& error); + VectorAttribute * vdisk, const std::string& tsys, + VectorAttribute * vcontext, string& error); /* ---------------------------------------------------------------------- */ /* Save as Interface */ diff --git a/share/etc/oned.conf b/share/etc/oned.conf index 72fa1459b2..82cb872cf8 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -1091,7 +1091,8 @@ TM_MAD_CONF = [ TM_MAD_CONF = [ NAME = "ceph", LN_TARGET = "NONE", CLONE_TARGET = "SELF", SHARED = "YES", - DS_MIGRATE = "NO", DRIVER = "raw", ALLOW_ORPHANS="yes" + DS_MIGRATE = "NO", DRIVER = "raw", ALLOW_ORPHANS="yes", TM_MAD_SYSTEM = "ssh", + LN_TARGET_SSH = "SYSTEM", CLONE_TARGET_SSH = "SYSTEM", DISK_TYPE_SSH = "FILE" ] TM_MAD_CONF = [ diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index def084789a..77d197cdc4 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -101,7 +101,7 @@ void Datastore::disk_attribute( VirtualMachineDisk * disk, const vector<string>& inherit_attrs) { - string st; + string st, tm_mad; string inherit_val; string current_val; string type; @@ -116,14 +116,46 @@ void Datastore::disk_attribute( disk->replace("CLUSTER_ID", one_util::join(cluster_ids, ',')); - get_template_attribute("CLONE_TARGET", st); + tm_mad = disk->get_tm_mad_system(); + + if (!tm_mad.empty()) + { + string tm_mad_t = one_util::trim(tm_mad); + tm_mad = one_util::toupper(tm_mad_t); + } + + if (!tm_mad.empty()) + { + get_template_attribute("CLONE_TARGET_" + tm_mad, st); + + if (st.empty()) + { + get_template_attribute("CLONE_TARGET", st); + } + } + else + { + get_template_attribute("CLONE_TARGET", st); + } if(!st.empty()) { disk->replace("CLONE_TARGET", st); } - get_template_attribute("LN_TARGET", st); + if (!tm_mad.empty()) + { + get_template_attribute("LN_TARGET_" + tm_mad, st); + + if (st.empty()) + { + get_template_attribute("LN_TARGET", st); + } + } + else + { + get_template_attribute("LN_TARGET", st); + } if(!st.empty()) { @@ -141,7 +173,16 @@ void Datastore::disk_attribute( } } - if (disk->is_volatile()) + if (!tm_mad.empty()) + { + get_template_attribute("DISK_TYPE_" + tm_mad, st); + + if (!st.empty()) + { + disk->set_types(st); + } + } + else if (disk->is_volatile()) { disk->replace("DISK_TYPE", Image::disk_type_to_str(get_disk_type())); } @@ -280,9 +321,10 @@ int Datastore::set_tm_mad(string &tm_mad, string &error_str) { const VectorAttribute* vatt; - string st; + std::vector<std::string> modes; ostringstream oss; + std::stringstream ss; if ( Nebula::instance().get_tm_conf_attribute(tm_mad, vatt) != 0 ) { @@ -327,6 +369,52 @@ int Datastore::set_tm_mad(string &tm_mad, string &error_str) } else { + string st = vatt->vector_value("TM_MAD_SYSTEM"); + + if (!st.empty()) + { + std::vector<std::string>::iterator it; + + replace_template_attribute("TM_MAD_SYSTEM", st); + + modes = one_util::split(st, ',', true); + + string s; + + for (it = modes.begin() ; it != modes.end(); ++it) + { + string tm_mad_t = one_util::trim(*it); + string tm_mad = one_util::toupper(tm_mad_t); + + st = vatt->vector_value("LN_TARGET_" + tm_mad); + + if (check_tm_target_type(st) == -1) + { + goto error; + } + + replace_template_attribute("LN_TARGET_" + tm_mad, st); + + st = vatt->vector_value("CLONE_TARGET_" + tm_mad); + + if (check_tm_target_type(st) == -1) + { + goto error; + } + + replace_template_attribute("CLONE_TARGET_" + tm_mad, st); + + st = vatt->vector_value("DISK_TYPE_" + tm_mad); + + if (st.empty()) + { + goto error; + } + + replace_template_attribute("DISK_TYPE_" + tm_mad, st); + } + } + st = vatt->vector_value("LN_TARGET"); if (check_tm_target_type(st) == -1) diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage.js index 7f168e40a8..cfc94b27fe 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage.js +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage.js @@ -26,6 +26,7 @@ define(function(require) { var WizardFields = require('utils/wizard-fields'); var DiskTab = require('./storage/disk-tab'); var UniqueId = require('utils/unique-id'); + var OpenNebula = require('opennebula'); /* TEMPLATES @@ -111,7 +112,7 @@ define(function(require) { } function _retrieve(context) { - var templateJSON = {}; + var templateJSON = WizardFields.retrieve(context); var disksJSON = []; var diskJSON; $.each(this.diskTabObjects, function(id, diskTab) { @@ -131,6 +132,14 @@ define(function(require) { function _fill(context, templateJSON) { var that = this; var disks = templateJSON.DISK + var modes = []; + var groupDropdownOptions = '<option value=></option>'; + + var tmpl_tm_mad_system; + if (templateJSON.TM_MAD_SYSTEM){ + tmpl_tm_mad_system = templateJSON.TM_MAD_SYSTEM; + } + if (disks instanceof Array) { $.each(disks, function(diskId, diskJSON) { if (diskId > 0) { @@ -139,11 +148,75 @@ define(function(require) { var diskTab = that.diskTabObjects[that.numberOfDisks]; var diskContext = $('#' + diskTab.diskTabId, context); + OpenNebula.Image.show({ + timeout: true, + data : { + name: diskJSON.IMAGE, + uname: diskJSON.IMAGE_UNAME + }, + success: function(request, obj_file){ + OpenNebula.Datastore.show({ + data : { + id: obj_file.IMAGE.DATASTORE_ID + }, + timeout: true, + success: function(request, ds){ + var tm_mad_system = ds.DATASTORE.TEMPLATE.TM_MAD_SYSTEM; + if (tm_mad_system) { + tm_mad_system.split(",").map(function(item) { + var i = item.trim(); + if(modes.indexOf(i) === -1){ + modes.push(i); + groupDropdownOptions += '<option elem_id="'+i+'" value="'+i+'">'+i+'</option>'; + } + }); + $('select#TM_MAD_SYSTEM', context).html(groupDropdownOptions); + if ( tmpl_tm_mad_system ){ + $('select#TM_MAD_SYSTEM', context).val(tmpl_tm_mad_system); + } + } + } + }); + } + }); diskTab.fill(diskContext, diskJSON); }); } else if (disks instanceof Object) { var diskTab = that.diskTabObjects[that.numberOfDisks]; var diskContext = $('#' + diskTab.diskTabId, context); + + OpenNebula.Image.show({ + timeout: true, + data : { + name: disks.IMAGE, + uname: disks.IMAGE_UNAME + }, + success: function(request, obj_file){ + OpenNebula.Datastore.show({ + data : { + id: obj_file.IMAGE.DATASTORE_ID + }, + timeout: true, + success: function(request, ds){ + var tm_mad_system = ds.DATASTORE.TEMPLATE.TM_MAD_SYSTEM; + if (tm_mad_system) { + tm_mad_system.split(",").map(function(item) { + var i = item.trim(); + if(modes.indexOf(i) === -1){ + modes.push(i); + groupDropdownOptions += '<option elem_id="'+i+'" value="'+i+'">'+i+'</option>'; + } + }); + $('select#TM_MAD_SYSTEM', context).html(groupDropdownOptions); + if ( tmpl_tm_mad_system ){ + $('select#TM_MAD_SYSTEM', context).val(tmpl_tm_mad_system); + } + } + } + }); + } + }); + diskTab.fill(diskContext, disks); } diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage/disk-tab.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage/disk-tab.js index 75081e498d..d06386e027 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage/disk-tab.js +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage/disk-tab.js @@ -218,6 +218,7 @@ define(function(require) { } this.imageTable.selectResourceTableSelect(selectedResources); + } else if (templateJSON.IMAGE != undefined && templateJSON.IMAGE_UNAME != undefined) { var selectedResources = { names : { diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage/html.hbs b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage/html.hbs index 73a90a85c8..9ac62cc8d5 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage/html.hbs +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage/html.hbs @@ -13,6 +13,23 @@ {{! See the License for the specific language governing permissions and }} {{! limitations under the License. }} {{! -------------------------------------------------------------------------- }} +<div class="row"> + <div class="medium-2 columns"></div> + <div class="medium-10 columns"> + <fieldset> + <legend>{{tr "Deployment Requirements"}}</legend> + <div class="row"> + <div class="medium-12 columns"> + <label for="TM_MAD_SYSTEM"> + {{tr "Deploy Mode"}} + </label> + <select wizard_field="TM_MAD_SYSTEM" id="TM_MAD_SYSTEM" name="TM_MAD_SYSTEM"> + </select> + </div> + </div> + </fieldset> + </div> +</div> <div class="row collapse"> <div class="medium-2 columns"> <ul class="tabs vertical" id="{{linksContainerId}}" data-tabs> diff --git a/src/tm_mad/ceph/clone b/src/tm_mad/ceph/clone index fd1507da0f..ac1325a673 100755 --- a/src/tm_mad/ceph/clone +++ b/src/tm_mad/ceph/clone @@ -51,6 +51,9 @@ CEPH_UTILS=${DRIVER_PATH}/../../datastore/ceph/ceph_utils.sh DST_HOST=`arg_host $DST` SRC_PATH=`arg_path $SRC` +DST_PATH=`arg_path $DST` + +DST_DIR=`dirname $DST_PATH` DISK_ID=$(echo $DST|awk -F. '{print $NF}') RBD_DST="${SRC_PATH}-${VM_ID}-${DISK_ID}" @@ -65,18 +68,20 @@ unset i j XPATH_ELEMENTS while IFS= read -r -d '' element; do XPATH_ELEMENTS[i++]="$element" - done < <(onevm show -x $VM_ID| $XPATH \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_USER \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_KEY \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_CONF \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/SIZE \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/ORIGINAL_SIZE) +done < <(onevm show -x $VM_ID| $XPATH \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_USER \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_KEY \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_CONF \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/SIZE \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/ORIGINAL_SIZE \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/TYPE ) CEPH_USER="${XPATH_ELEMENTS[j++]}" CEPH_KEY="${XPATH_ELEMENTS[j++]}" CEPH_CONF="${XPATH_ELEMENTS[j++]}" SIZE="${XPATH_ELEMENTS[j++]}" ORIGINAL_SIZE="${XPATH_ELEMENTS[j++]}" +TYPE="${XPATH_ELEMENTS[j++]}" #------------------------------------------------------------------------------- # Clone the image and create @snap if it does not exists @@ -94,26 +99,49 @@ if [ -n "$CEPH_CONF" ]; then RBD="$RBD --conf ${CEPH_CONF}" fi -CLONE_CMD=$(cat <<EOF - RBD="${RBD}" +if [ "${TYPE}" = 'FILE' ]; then + ssh_make_path $DST_HOST $DST_DIR - $RBD info $RBD_DST >/dev/null 2>&1 && exit 0 + CLONE_CMD=$(cat <<EOF + RBD="${RBD}" - rbd_make_snap $SRC_PATH + rbd_make_snap $SRC_PATH - set -e -o pipefail + set -e -o pipefail - if [ "\$(rbd_format $SRC_PATH)" = "2" ]; then - $RBD clone "$SRC_PATH@snap" $RBD_DST - else - $RBD copy $SRC_PATH $RBD_DST - fi + if [ "\$(rbd_format $SRC_PATH)" = "2" ]; then + $RBD export "$SRC_PATH@snap" $DST_PATH + else + $RBD export $SRC_PATH $DST_PATH + fi - if [ -n "$ORIGINAL_SIZE" -a "$SIZE" -gt "$ORIGINAL_SIZE" ]; then - $RBD resize $RBD_DST --size $SIZE - fi + if [ -n "$ORIGINAL_SIZE" -a "$SIZE" -gt "$ORIGINAL_SIZE" ]; then + qemu-img resize ${DST_PATH} ${SIZE}M + fi EOF ) +else + CLONE_CMD=$(cat <<EOF + RBD="${RBD}" + + $RBD info $RBD_DST >/dev/null 2>&1 && exit 0 + + rbd_make_snap $SRC_PATH + + set -e -o pipefail + + if [ "\$(rbd_format $SRC_PATH)" = "2" ]; then + $RBD clone "$SRC_PATH@snap" $RBD_DST + else + $RBD copy $SRC_PATH $RBD_DST + fi + + if [ -n "$ORIGINAL_SIZE" -a "$SIZE" -gt "$ORIGINAL_SIZE" ]; then + $RBD resize $RBD_DST --size $SIZE + fi +EOF +) +fi ssh_exec_and_log_stdin "$DST_HOST" "$CLONE_CMD" "$CEPH_UTILS" \ "Error cloning $SRC_PATH to $RBD_DST in $DST_HOST" diff --git a/src/tm_mad/ceph/cpds b/src/tm_mad/ceph/cpds index 8c93696be7..20be7ce2ee 100755 --- a/src/tm_mad/ceph/cpds +++ b/src/tm_mad/ceph/cpds @@ -43,6 +43,7 @@ DRIVER_PATH=$(dirname $0) source $TMCOMMON source ${DRIVER_PATH}/../../datastore/ceph/ceph.conf +source ${DRIVER_PATH}/../../vmm/kvm/kvmrc CEPH_UTILS=${DRIVER_PATH}/../../datastore/ceph/ceph_utils.sh @@ -50,6 +51,7 @@ CEPH_UTILS=${DRIVER_PATH}/../../datastore/ceph/ceph_utils.sh # Set dst path and dir #------------------------------------------------------------------------------- +SRC_PATH=`arg_path $SRC` SRC_HOST=`arg_host $SRC` RBD_SRC=`arg_path $SRC` @@ -66,17 +68,21 @@ unset i j XPATH_ELEMENTS while IFS= read -r -d '' element; do XPATH_ELEMENTS[i++]="$element" done < <(onevm show -x $VM_ID| $XPATH \ + /VM/DEPLOY_ID \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/SOURCE \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CLONE \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_USER \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_KEY \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_CONF) + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_CONF \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/TYPE ) +DEPLOY_ID="${XPATH_ELEMENTS[j++]}" RBD_SRC="${XPATH_ELEMENTS[j++]}" CLONE="${XPATH_ELEMENTS[j++]}" CEPH_USER="${XPATH_ELEMENTS[j++]}" CEPH_KEY="${XPATH_ELEMENTS[j++]}" CEPH_CONF="${XPATH_ELEMENTS[j++]}" +TYPE="${XPATH_ELEMENTS[j++]}" #------------------------------------------------------------------------------- # Copy Image back to the datastore @@ -100,25 +106,50 @@ if [ -n "$CEPH_CONF" ]; then RBD="$RBD --conf ${CEPH_CONF}" fi -COPY_CMD=$(cat <<EOF - RBD="${RBD}" +if [ "$RBD_FORMAT" = "2" ]; then + FORMAT_OPT="--image-format 2" +fi +if [ "${TYPE}" = 'FILE' ]; then if [ "$SNAP_ID" != "-1" ]; then - rbd_check_2 $RBD_DST + error_message "$script_name: Operation not supported on disk type ${TYPE} with snapshots" + exit 1 + fi - RBD_DST=\$(rbd_find_snap $RBD_DST $SNAP_ID) - - if [ -z "\$RBD_DST" ]; then - echo "Target RBD not found." >&2 + COPY_CMD=$(cat <<EOF + if virsh -c $LIBVIRT_URI domfsfreeze $DEPLOY_ID ; then + trap "virsh -c $LIBVIRT_URI domfsthaw $DEPLOY_ID" EXIT TERM INT HUP + elif virsh -c $LIBVIRT_URI suspend $DEPLOY_ID; then + trap "virsh -c $LIBVIRT_URI resume $DEPLOY_ID" EXIT TERM INT HUP + else + echo "Could not domfsfreeze or suspend domain" >&2 exit 1 fi - RBD_DST=\$RBD_DST@$SNAP_ID - fi - - $RBD copy $RBD_DST $DST + $RBD import $FORMAT_OPT $SRC_PATH $DST EOF ) +else + COPY_CMD=$(cat <<EOF + RBD="${RBD}" + + if [ "$SNAP_ID" != "-1" ]; then + rbd_check_2 $RBD_DST + + RBD_DST=\$(rbd_find_snap $RBD_DST $SNAP_ID) + + if [ -z "\$RBD_DST" ]; then + echo "Target RBD not found." >&2 + exit 1 + fi + + RBD_DST=\$RBD_DST@$SNAP_ID + fi + + $RBD copy $RBD_DST $DST +EOF +) +fi ssh_exec_and_log_stdin "$SRC_HOST" "$COPY_CMD" "$CEPH_UTILS" \ "Error cloning $RBD_DST to $DST in $SRC_HOST" diff --git a/src/tm_mad/ceph/delete b/src/tm_mad/ceph/delete index 1d9e76f796..84ae76100b 100755 --- a/src/tm_mad/ceph/delete +++ b/src/tm_mad/ceph/delete @@ -115,7 +115,8 @@ done < <(onevm show -x $VM_ID | $XPATH \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_USER \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_KEY \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_CONF \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/POOL_NAME) + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/POOL_NAME \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/TYPE ) SRC="${XPATH_ELEMENTS[j++]}" CLONE="${XPATH_ELEMENTS[j++]}" @@ -123,6 +124,7 @@ CEPH_USER="${XPATH_ELEMENTS[j++]}" CEPH_KEY="${XPATH_ELEMENTS[j++]}" CEPH_CONF="${XPATH_ELEMENTS[j++]}" POOL_NAME="${XPATH_ELEMENTS[j++]:-$POOL_NAME}" +TYPE="${XPATH_ELEMENTS[j++]}" # No need to delete no cloned images if [ "$CLONE" = "NO" ]; then @@ -157,20 +159,24 @@ fi log "Deleting $DST_PATH" -DELETE_CMD=$(cat <<EOF - RBD="${RBD}" +if [ "${TYPE}" = 'FILE' ]; then + exit 0 +else + DELETE_CMD=$(cat <<EOF + RBD="${RBD}" - if [ "\$(rbd_format $RBD_SRC)" = "2" ]; then - rbd_rm_r \$(rbd_top_parent $RBD_SRC) + if [ "\$(rbd_format $RBD_SRC)" = "2" ]; then + rbd_rm_r \$(rbd_top_parent $RBD_SRC) - if [ -n "$RBD_SNAP" ]; then - rbd_rm_snap $SRC $RBD_SNAP + if [ -n "$RBD_SNAP" ]; then + rbd_rm_snap $SRC $RBD_SNAP + fi + else + $RBD rm $RBD_SRC fi - else - $RBD rm $RBD_SRC - fi EOF ) +fi ssh_exec_and_log_stdin "$DST_HOST" "$DELETE_CMD" "$CEPH_UTILS" \ "Error deleting $RBD_SRC in $DST_HOST" diff --git a/src/tm_mad/ceph/ln b/src/tm_mad/ceph/ln index 669eaeab1a..63fd9276a4 100755 --- a/src/tm_mad/ceph/ln +++ b/src/tm_mad/ceph/ln @@ -56,6 +56,9 @@ DISK_ID=$(echo $DST|awk -F. '{print $NF}') #------------------------------------------------------------------------------- SRC_PATH=`arg_path $SRC` +DST_PATH=`arg_path $DST` + +DST_DIR=`dirname $DST_PATH` XPATH="${DRIVER_PATH}/../../datastore/xpath.rb --stdin" @@ -63,14 +66,16 @@ unset i j XPATH_ELEMENTS while IFS= read -r -d '' element; do XPATH_ELEMENTS[i++]="$element" - done < <(onevm show -x $VM_ID| $XPATH \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_USER \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_KEY \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_CONF) +done < <(onevm show -x $VM_ID| $XPATH \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_USER \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_KEY \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_CONF \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/TYPE ) CEPH_USER="${XPATH_ELEMENTS[j++]}" CEPH_KEY="${XPATH_ELEMENTS[j++]}" CEPH_CONF="${XPATH_ELEMENTS[j++]}" +TYPE="${XPATH_ELEMENTS[j++]}" #------------------------------------------------------------------------------- # Remove any @snap in image (non persistent -> persistnet) @@ -88,13 +93,28 @@ if [ -n "$CEPH_CONF" ]; then RBD="$RBD --conf ${CEPH_CONF}" fi -CLONE_CMD=$(cat <<EOF - RBD="${RBD}" +if [ "${TYPE}" = 'FILE' ]; then + ssh_make_path $DST_HOST $DST_DIR - rbd_rm_snap $SRC_PATH + LN_CMD=$(cat <<EOF + RBD="${RBD}" + + rbd_rm_snap $SRC_PATH + + set -e -o pipefail + + $RBD export $SRC_PATH $DST_PATH EOF ) +else + LN_CMD=$(cat <<EOF + RBD="${RBD}" -ssh_exec_and_log_stdin "$DST_HOST" "$CLONE_CMD" "$CEPH_UTILS" \ + rbd_rm_snap $SRC_PATH +EOF +) +fi + +ssh_exec_and_log_stdin "$DST_HOST" "$LN_CMD" "$CEPH_UTILS" \ "Error cloning $SRC_PATH to $RBD_DST in $DST_HOST" exit 0 diff --git a/src/tm_mad/ceph/mvds b/src/tm_mad/ceph/mvds index fed6dd2fe6..aaa5d1442f 100755 --- a/src/tm_mad/ceph/mvds +++ b/src/tm_mad/ceph/mvds @@ -16,4 +16,109 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -exit 0 +# mvds host:remote_system_ds/disk.i fe:SOURCE vmid dsid +# - fe is the front-end hostname +# - SOURCE is the path of the disk image in the form DS_BASE_PATH/disk +# - host is the target host to deploy the VM +# - remote_system_ds is the path for the system datastore in the host +# - vmid is the id of the VM +# - dsid is the target datastore (0 is the system datastore) + +SRC=$1 +DST=$2 +VMID=$3 +DSID=$4 + +#-------------------------------------------------------------------------------- + +if [ -z "${ONE_LOCATION}" ]; then + TMCOMMON=/var/lib/one/remotes/tm/tm_common.sh + LIB_LOCATION=/usr/lib/one +else + TMCOMMON=$ONE_LOCATION/var/remotes/tm/tm_common.sh + LIB_LOCATION=$ONE_LOCATION/lib +fi + +DRIVER_PATH=$(dirname $0) + +source $TMCOMMON +source ${DRIVER_PATH}/../../datastore/ceph/ceph.conf + +CEPH_UTILS=${DRIVER_PATH}/../../datastore/ceph/ceph_utils.sh + +#------------------------------------------------------------------------------- +# Set dst path and dir +#------------------------------------------------------------------------------- + +SRC_PATH=`arg_path $SRC` +SRC_HOST=`arg_host $SRC` +RBD_SRC=`arg_path $SRC` + +#------------------------------------------------------------------------------- +# Get Image information +#------------------------------------------------------------------------------- + +DISK_ID=$(echo "$RBD_SRC" | $AWK -F. '{print $NF}') + +XPATH="${DRIVER_PATH}/../../datastore/xpath.rb --stdin" + +unset i j XPATH_ELEMENTS + +while IFS= read -r -d '' element; do + XPATH_ELEMENTS[i++]="$element" +done < <(onevm show -x $VMID| $XPATH \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/SOURCE \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CLONE \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_USER \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_KEY \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_CONF \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/TYPE \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/SIZE \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/ORIGINAL_SIZE ) + +RBD_SRC="${XPATH_ELEMENTS[j++]}" +CLONE="${XPATH_ELEMENTS[j++]}" +CEPH_USER="${XPATH_ELEMENTS[j++]}" +CEPH_KEY="${XPATH_ELEMENTS[j++]}" +CEPH_CONF="${XPATH_ELEMENTS[j++]}" +TYPE="${XPATH_ELEMENTS[j++]}" +SIZE="${XPATH_ELEMENTS[j++]}" +ORIGINAL_SIZE="${XPATH_ELEMENTS[j++]}" + +#------------------------------------------------------------------------------- +# Copy Image back to the datastore +#------------------------------------------------------------------------------- + +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 + +if [ "${TYPE}" = 'FILE' ]; then + MVDS_CMD=$(cat <<EOF + RBD="${RBD}" + + set -e -o pipefail + + if [ -n "$ORIGINAL_SIZE" -a "$SIZE" -gt "$ORIGINAL_SIZE" ]; then + $RBD resize $RBD_SRC --size $SIZE + fi + + $SUDO $RBD map $RBD_SRC + trap "$SUDO $RBD unmap /dev/rbd/$RBD_SRC" EXIT TERM INT HUP + $DD if=$SRC_PATH of=/dev/rbd/$RBD_SRC bs=64k +EOF +) +else + exit 0 +fi + +ssh_exec_and_log_stdin "$SRC_HOST" "$MVDS_CMD" "$CEPH_UTILS" \ + "Error copying $RBD_SRC to $DST in $SRC_HOST" #?? diff --git a/src/tm_mad/ceph/resize b/src/tm_mad/ceph/resize index 249ec6f048..fc1d12848d 100755 --- a/src/tm_mad/ceph/resize +++ b/src/tm_mad/ceph/resize @@ -64,7 +64,8 @@ done < <(onevm show -x $VM_ID| $XPATH \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_KEY \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_CONF \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/PERSISTENT \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/POOL_NAME ) + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/POOL_NAME \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/TYPE ) RBD_SRC="${XPATH_ELEMENTS[j++]}" CEPH_USER="${XPATH_ELEMENTS[j++]}" @@ -72,6 +73,7 @@ CEPH_KEY="${XPATH_ELEMENTS[j++]}" CEPH_CONF="${XPATH_ELEMENTS[j++]}" PERSISTENT="${XPATH_ELEMENTS[j++]}" POOL_NAME="${XPATH_ELEMENTS[j++]:-$POOL_NAME}" +TYPE="${XPATH_ELEMENTS[j++]}" if [ -n "${RBD_SRC}" ]; then if [ "${PERSISTENT}" = 'YES' ]; then @@ -99,10 +101,17 @@ if [ -n "$CEPH_CONF" ]; then RBD="$RBD --conf ${CEPH_CONF}" fi -RESIZE_CMD=$(cat <<EOF - $RBD resize --size ${SIZE} $RBD_DST +if [ "${TYPE}" = 'FILE' ]; then + RESIZE_CMD=$(cat <<EOF + ${QEMU_IMG} resize "${SRC_PATH}" "${SIZE}M" EOF ) +else + RESIZE_CMD=$(cat <<EOF + $RBD resize --size ${SIZE} $RBD_DST +EOF +) +fi ssh_exec_and_log_stdin "$SRC_HOST" "$RESIZE_CMD" "$CEPH_UTILS" \ "Error resizing disk $RBD_DST" diff --git a/src/tm_mad/ceph/snap_create b/src/tm_mad/ceph/snap_create index e4f09e4f0c..5adeb2f929 100755 --- a/src/tm_mad/ceph/snap_create +++ b/src/tm_mad/ceph/snap_create @@ -64,13 +64,15 @@ done < <(onevm show -x $VM_ID| $XPATH \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CLONE \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_USER \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_KEY \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_CONF) + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_CONF \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/TYPE ) RBD_SRC="${XPATH_ELEMENTS[j++]}" CLONE="${XPATH_ELEMENTS[j++]}" CEPH_USER="${XPATH_ELEMENTS[j++]}" CEPH_KEY="${XPATH_ELEMENTS[j++]}" CEPH_CONF="${XPATH_ELEMENTS[j++]}" +TYPE="${XPATH_ELEMENTS[j++]}" if [ "$CLONE" = "NO" ]; then RBD_DST="${RBD_SRC}" @@ -94,6 +96,11 @@ if [ -n "$CEPH_CONF" ]; then RBD="$RBD --conf ${CEPH_CONF}" fi +if [ "${TYPE}" != 'RBD' ]; then + error_message "$script_name: Operation not supported on disk type ${TYPE}" + exit 1 +fi + SNAP_CREATE_CMD=$(cat <<EOF set -e -o pipefail diff --git a/src/tm_mad/ceph/snap_create_live b/src/tm_mad/ceph/snap_create_live index ec645b610e..9ff45c1e8d 100755 --- a/src/tm_mad/ceph/snap_create_live +++ b/src/tm_mad/ceph/snap_create_live @@ -66,7 +66,8 @@ done < <(onevm show -x $VM_ID| $XPATH \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CLONE \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_USER \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_KEY \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_CONF) + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_CONF \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/TYPE ) DEPLOY_ID="${XPATH_ELEMENTS[j++]}" RBD_SRC="${XPATH_ELEMENTS[j++]}" @@ -74,6 +75,7 @@ CLONE="${XPATH_ELEMENTS[j++]}" CEPH_USER="${XPATH_ELEMENTS[j++]}" CEPH_KEY="${XPATH_ELEMENTS[j++]}" CEPH_CONF="${XPATH_ELEMENTS[j++]}" +TYPE="${XPATH_ELEMENTS[j++]}" if [ "$CLONE" = "NO" ]; then RBD_DST="${RBD_SRC}" @@ -97,6 +99,11 @@ if [ -n "$CEPH_CONF" ]; then RBD="$RBD --conf ${CEPH_CONF}" fi +if [ "${TYPE}" != 'RBD' ]; then + error_message "$script_name: Operation not supported on disk type ${TYPE}" + exit 1 +fi + SNAP_CREATE_CMD=$(cat <<EOF set -e -o pipefail diff --git a/src/tm_mad/ceph/snap_delete b/src/tm_mad/ceph/snap_delete index 7b7e0c16bf..28387858cc 100755 --- a/src/tm_mad/ceph/snap_delete +++ b/src/tm_mad/ceph/snap_delete @@ -64,13 +64,15 @@ done < <(onevm show -x $VM_ID| $XPATH \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CLONE \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_USER \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_KEY \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_CONF) + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_CONF \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/TYPE ) RBD_SRC="${XPATH_ELEMENTS[j++]}" CLONE="${XPATH_ELEMENTS[j++]}" CEPH_USER="${XPATH_ELEMENTS[j++]}" CEPH_KEY="${XPATH_ELEMENTS[j++]}" CEPH_CONF="${XPATH_ELEMENTS[j++]}" +TYPE="${XPATH_ELEMENTS[j++]}" if [ "$CLONE" = "NO" ]; then RBD_DST="${RBD_SRC}" @@ -96,6 +98,11 @@ if [ -n "$CEPH_CONF" ]; then RBD="$RBD --conf ${CEPH_CONF}" fi +if [ "${TYPE}" != 'RBD' ]; then + error_message "$script_name: Operation not supported on disk type ${TYPE}" + exit 1 +fi + SNAP_DELETE_CMD=$(cat <<EOF RBD="${RBD}" diff --git a/src/tm_mad/ceph/snap_revert b/src/tm_mad/ceph/snap_revert index f65f7b7cfd..89677089ca 100755 --- a/src/tm_mad/ceph/snap_revert +++ b/src/tm_mad/ceph/snap_revert @@ -64,13 +64,15 @@ done < <(onevm show -x $VM_ID| $XPATH \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CLONE \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_USER \ /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_KEY \ - /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_CONF) + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/CEPH_CONF \ + /VM/TEMPLATE/DISK[DISK_ID=$DISK_ID]/TYPE ) RBD_SRC="${XPATH_ELEMENTS[j++]}" CLONE="${XPATH_ELEMENTS[j++]}" CEPH_USER="${XPATH_ELEMENTS[j++]}" CEPH_KEY="${XPATH_ELEMENTS[j++]}" CEPH_CONF="${XPATH_ELEMENTS[j++]}" +TYPE="${XPATH_ELEMENTS[j++]}" if [ "$CLONE" = "NO" ]; then RBD_DST="${RBD_SRC}" @@ -109,6 +111,11 @@ if [ -n "$CEPH_CONF" ]; then RBD="$RBD --conf ${CEPH_CONF}" fi +if [ "${TYPE}" != 'RBD' ]; then + error_message "$script_name: Operation not supported on disk type ${TYPE}" + exit 1 +fi + SNAP_REVERT_CMD=$(cat <<EOF RBD="${RBD}" diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 97b81898cb..3261d9bdca 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -504,7 +504,7 @@ int VirtualMachine::select(SqlDB * db) return rc; } - //Get History Records. + //Get History Records. if( hasHistory() ) { last_seq = history->seq; @@ -1400,6 +1400,7 @@ error_common: int VirtualMachine::automatic_requirements(set<int>& cluster_ids, string& error_str) { + string tm_mad_system; ostringstream oss; set<string> clouds; @@ -1451,21 +1452,28 @@ int VirtualMachine::automatic_requirements(set<int>& cluster_ids, obj_template->add("AUTOMATIC_REQUIREMENTS", oss.str()); + oss.str(""); + + if ( obj_template->get("TM_MAD_SYSTEM", tm_mad_system) ) + { + oss << "(TM_MAD = " << one_util::trim(tm_mad_system) << ") & "; + } + // Set automatic System DS requirements if ( !cluster_ids.empty() ) { - oss.str(""); - set<int>::iterator i = cluster_ids.begin(); - oss << "\"CLUSTERS/ID\" @> " << *i; + oss << "(\"CLUSTERS/ID\" @> " << *i; for (++i; i != cluster_ids.end(); i++) { oss << " | \"CLUSTERS/ID\" @> " << *i; } + oss << ")"; + obj_template->add("AUTOMATIC_DS_REQUIREMENTS", oss.str()); } @@ -2129,7 +2137,7 @@ int VirtualMachine::from_xml(const string &xml_str) // ------------------------------------------------------------------------- int last_seq; - if ( xpath(last_seq,"/VM/HISTORY_RECORDS/HISTORY/SEQ", -1) == 0 && + if ( xpath(last_seq,"/VM/HISTORY_RECORDS/HISTORY/SEQ", -1) == 0 && last_seq != -1 ) { history_records.resize(last_seq + 1); @@ -2677,7 +2685,19 @@ int VirtualMachine::get_disk_images(string& error_str) context = static_cast<VectorAttribute * >(acontext_disks[0]); } - return disks.get_images(oid, uid, adisks, context, error_str); + // ------------------------------------------------------------------------- + // Deployment mode for the VM disks + // ------------------------------------------------------------------------- + std::string tm_mad_sys; + + if ( user_obj_template->get("TM_MAD_SYSTEM", tm_mad_sys) == true ) + { + user_obj_template->erase("TM_MAD_SYSTEM"); + + obj_template->add("TM_MAD_SYSTEM", tm_mad_sys); + } + + return disks.get_images(oid, uid, tm_mad_sys, adisks, context, error_str); } /* -------------------------------------------------------------------------- */ @@ -2711,7 +2731,14 @@ int VirtualMachine::set_up_attach_disk(VirtualMachineTemplate * tmpl, string& er VirtualMachineDisk * new_disk; - new_disk = disks.set_up_attach(oid, uid, get_cid(), new_vdisk, context, err); + // ------------------------------------------------------------------------- + // Deployment mode for the VM disks + // ------------------------------------------------------------------------- + std::string tm_mad_sys; + + obj_template->get("TM_MAD_SYSTEM", tm_mad_sys); + + new_disk = disks.set_up_attach(oid, uid, get_cid(), new_vdisk, tm_mad_sys, context, err); if ( new_disk == 0 ) { diff --git a/src/vm/VirtualMachineDisk.cc b/src/vm/VirtualMachineDisk.cc index 6a16425201..3d55b894d8 100644 --- a/src/vm/VirtualMachineDisk.cc +++ b/src/vm/VirtualMachineDisk.cc @@ -140,6 +140,21 @@ int VirtualMachineDisk::get_image_id(int &id, int uid) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +string VirtualMachineDisk::get_tm_mad_system() +{ + std::string tm_mad_system; + + if (vector_value("TM_MAD_SYSTEM", tm_mad_system) != 0) + { + return ""; + } + + return tm_mad_system; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void VirtualMachineDisk::extended_info(int uid) { ImagePool * ipool = Nebula::instance().get_ipool(); @@ -504,6 +519,37 @@ void VirtualMachineDisk::clear_resize(bool restore) clear_resize(); } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void VirtualMachineDisk::set_types(const string& ds_name) +{ + string type = vector_value("TYPE"); + + switch(Image::str_to_disk_type(type)) + { + case Image::RBD_CDROM: + case Image::GLUSTER_CDROM: + case Image::SHEEPDOG_CDROM: + case Image::CD_ROM: + if (ds_name != "FILE" && ds_name != "ISCSI" && ds_name != "NONE") + { + replace("TYPE", ds_name+"_CDROM"); + } + else + { + replace("TYPE", "CDROM"); + } + break; + + default: + replace("TYPE", ds_name); + break; + } + + replace("DISK_TYPE", ds_name); +} + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -662,7 +708,7 @@ void VirtualMachineDisks::assign_disk_targets( /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int VirtualMachineDisks::get_images(int vm_id, int uid, +int VirtualMachineDisks::get_images(int vm_id, int uid, const std::string& tsys, vector<Attribute *> disks, VectorAttribute * vcontext, std::string& error_str) { @@ -695,6 +741,15 @@ int VirtualMachineDisks::get_images(int vm_id, int uid, // --------------------------------------------------------------------- VirtualMachineDisk * disk = new VirtualMachineDisk(vdisk, disk_id); + if ( !tsys.empty() ) + { + disk->replace("TM_MAD_SYSTEM", tsys); + } + else + { + disk->remove("TM_MAD_SYSTEM"); + } + if ( ipool->acquire_disk(vm_id, disk, disk_id, image_type, dev_prefix, uid, image_id, &snapshots, error_str) != 0 ) { @@ -959,7 +1014,7 @@ int VirtualMachineDisks::set_attach(int id) /* -------------------------------------------------------------------------- */ VirtualMachineDisk * VirtualMachineDisks::set_up_attach(int vmid, int uid, - int cluster_id, VectorAttribute * vdisk, VectorAttribute * vcontext, + int cluster_id, VectorAttribute * vdisk, const std::string& tsys, VectorAttribute * vcontext, string& error) { set<string> used_targets; @@ -1083,6 +1138,14 @@ VirtualMachineDisk * VirtualMachineDisks::set_up_attach(int vmid, int uid, // ------------------------------------------------------------------------- disk->set_attach(); + if ( !tsys.empty() ) + { + disk->replace("TM_MAD_SYSTEM", tsys); + } + else + { + disk->remove("TM_MAD_SYSTEM"); + } add_attribute(disk, disk->get_disk_id());