/* ------------------------------------------------------------------------ */ /* Copyright 2002-2024, 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. */ /* -------------------------------------------------------------------------*/ #ifndef IMAGE_H_ #define IMAGE_H_ #include "PoolSQL.h" #include "ImageTemplate.h" #include "ObjectCollection.h" #include "Snapshots.h" #include "BackupIncrements.h" class VirtualMachineDisk; /** * The Image class. */ class Image : public PoolObjectSQL { public: /** * Type of Images */ enum ImageType { OS = 0, /** < Base OS image */ CDROM = 1, /** < An ISO9660 image */ DATABLOCK = 2, /** < User persistent data device */ KERNEL = 3, /** < Kernel files */ RAMDISK = 4, /** < Initrd files */ CONTEXT = 5, /** < Context files */ BACKUP = 6, /** < VM Backup reference */ }; /** * Return the string representation of an ImageType * @param ob the type * @return the string */ static std::string type_to_str(ImageType ob) { switch (ob) { case OS: return "OS" ; break; case CDROM: return "CDROM" ; break; case DATABLOCK: return "DATABLOCK" ; break; case KERNEL: return "KERNEL" ; break; case RAMDISK: return "RAMDISK" ; break; case CONTEXT: return "CONTEXT" ; break; case BACKUP: return "BACKUP" ; break; default: return ""; } }; /** * Return the string representation of an ImageType * @param ob the type * @return the string */ static ImageType str_to_type(std::string& str_type); /** * Type of Disks (used by the VMM_MAD). Values: BLOCK, CDROM or * FILE */ enum DiskType { FILE = 0, /** < File-based disk */ CD_ROM = 1, /** < An ISO9660 disk */ BLOCK = 2, /** < Block-device disk */ RBD = 3, /** < CEPH RBD disk */ RBD_CDROM = 4, /** < CEPH RBD CDROM disk */ GLUSTER = 5, /** < Gluster Block Device */ GLUSTER_CDROM = 6, /** < Gluster CDROM Device Device */ SHEEPDOG = 7, /** < Sheepdog Block Device */ SHEEPDOG_CDROM = 8, /** < Sheepdog CDROM Device Device */ ISCSI = 9, /** < iSCSI Volume (Devices Datastore) */ NONE = 255 /** < No disk type, error situation */ }; /** * Return the string representation of a DiskType * @param ob the type * @return the string */ static std::string disk_type_to_str(DiskType ob) { switch (ob) { case FILE: return "FILE" ; break; case CD_ROM: return "CDROM" ; break; case BLOCK: return "BLOCK" ; break; case RBD: return "RBD" ; break; case RBD_CDROM: return "RBD_CDROM" ; break; case GLUSTER: return "GLUSTER" ; break; case GLUSTER_CDROM: return "GLUSTER_CDROM" ; break; case SHEEPDOG: return "SHEEPDOG" ; break; case SHEEPDOG_CDROM: return "SHEEPDOG_CDROM" ; break; case ISCSI: return "ISCSI" ; break; default: return ""; } }; /** * Return the string representation of a DiskType * @param s_disk_type string representing the DiskTypr * @return the DiskType (defaults to FILE) */ static DiskType str_to_disk_type(std::string& s_disk_type); /** * Image State */ enum ImageState { INIT = 0, /** < Initialization state */ READY = 1, /** < Image ready to use */ USED = 2, /** < Image in use */ DISABLED = 3, /** < Image can not be instantiated by a VM */ LOCKED = 4, /** < FS operation for the Image in process */ ERROR = 5, /** < Error state the operation FAILED*/ CLONE = 6, /** < Image is being cloned */ DELETE = 7, /** < DS is deleting the image */ USED_PERS = 8, /** < Image is in use and persistent */ LOCKED_USED = 9, /** < FS operation in progress, VMs waiting */ LOCKED_USED_PERS = 10 /** < FS operation in progress, VMs waiting. Persistent */ }; /** * Returns the string representation of an ImageState * @param state The state * @return the string representation */ static std::string state_to_str(ImageState state) { switch (state) { case INIT: return "INIT"; break; case READY: return "READY"; break; case USED: return "USED"; break; case DISABLED: return "DISABLED"; break; case LOCKED: return "LOCKED"; break; case ERROR: return "ERROR"; break; case CLONE: return "CLONE"; break; case DELETE: return "DELETE"; break; case USED_PERS: return "USED"; break; case LOCKED_USED: return "LOCKED_USED"; break; case LOCKED_USED_PERS: return "LOCKED_USED"; break; default: return ""; } }; static ImageState str_to_state(std::string& str_state); // ************************************************************************* // Image Public Methods // ************************************************************************* virtual ~Image() = default; /** * Function to print the Image object into a string in XML format * @param xml the resulting XML string * @return a reference to the generated string */ std::string& to_xml(std::string& xml) const override; /** * Rebuilds the object from an xml formatted string * @param xml_str The xml-formatted string * * @return 0 on success, -1 otherwise */ int from_xml(const std::string &xml_str) override; /** * Returns true if the image is persistent * @return true if the image is persistent */ bool is_persistent() const { return (persistent_img == 1); }; /** * @return true if the image is in a locked state */ bool is_locked() const { return state == LOCKED || state == LOCKED_USED || state == LOCKED_USED_PERS; }; /** * Check the PERSISTENT attribute in an image Template, if not set the * DEFAULT_IMAGE_PERSISTENT and DEFAULT_IMAGE_PERSISTENT_NEW are check in * user/group/oned.conf to set the attribute in the image. * @param image_template * @param uid of the user making the request * @param gid of the group of the user making the request * @param is_allocate true for one.image.allocate API Calls * @return true if the image is set to persistent, false otherwise */ static bool test_set_persistent(Template * image_template, int uid, int gid, bool is_allocate); /** * Returns the source path of the image * @return source of image */ const std::string& get_source() const { return source; } /** * Returns the original path of the image * @return path of image */ const std::string& get_path() const { return path; } /** * Returns the format of the image (defined for datablocks) * @return format */ const std::string& get_format() const { return format; } /** * Sets the format of the image */ void set_format(const std::string& _format) { format = _format; } /** * Returns the size of the image * @return size in MB */ long long get_size() const { return size_mb; } /** * Sets the source path of the image */ void set_source(const std::string& _source) { source = _source; } /** * Sets the size for the image */ void set_size(long long _size_mb) { size_mb = _size_mb; } /** * Returns the type of the image * @return type */ ImageType get_type() const { return type; } /** * Returns the image state * @return state of image */ ImageState get_state() const { return state; } /** * Sets the image state * @param state of image */ void set_state(ImageState _state); /** * Sets the previous state */ void set_prev_state() { prev_state = state; } /** * Test if the Image has changed state since last time prev state was set * @return true if state changed */ bool has_changed_state() const { return prev_state != state; } /** * Moves the image from the locked* states to ready, used, used_persistent */ void set_state_unlock(); /** * Return the ID of the image we are cloning this one from (if any) */ int get_cloning_id() const { return cloning_id; } /** * Sets the ID of the image we are cloning this one from (if any) */ void set_cloning_id(int id) { cloning_id = id; } /** * Clear the cloning state of the image */ void clear_cloning_id() { cloning_id = -1; } /* ---------------------------------------------------------------------- */ /* Access Image Counters (running vms and cloning operations ) */ /* ---------------------------------------------------------------------- */ int dec_running(int vm_id) { if ( vm_collection.del(vm_id) == 0 ) { running_vms--; } return running_vms; } int inc_running(int vm_id) { if ( vm_collection.add(vm_id) == 0 ) { running_vms++; } return running_vms; } int get_running() const { return running_vms; } const std::set& get_running_ids() const { return vm_collection.get_collection(); } int get_cloning() const { return cloning_ops; } int dec_cloning(PoolObjectSQL::ObjectType ot, int oid) { int rc = -1; if (ot == PoolObjectSQL::IMAGE) { rc = img_clone_collection.del(oid); } else //if (ot == PoolObjectSQL::MARKETPLACEAPP) { rc = app_clone_collection.del(oid); } if ( rc == 0 ) { cloning_ops--; } return cloning_ops; } int inc_cloning(PoolObjectSQL::ObjectType ot, int oid) { int rc = -1; if (ot == PoolObjectSQL::IMAGE) { rc = img_clone_collection.add(oid); } else //if (ot == PoolObjectSQL::MARKETPLACEAPP) { rc = app_clone_collection.add(oid); } if ( rc == 0 ) { cloning_ops++; } return cloning_ops; } /** * Sets the Image type. * * @param _type the new type. It will be transformed to upper case * @return 0 on success, -1 otherwise */ int set_type(std::string& _type, std::string& error); /** * Check if the image is used for saving_as a current one * @return true if the image will be used to save an existing image. */ bool is_saving() { return static_cast(obj_template.get())->is_saving(); } void clear_saving() { static_cast(obj_template.get())->clear_saving(); } /** * Set/Unset an image as persistent * @param persistent true to make an image persistent * @param error_str Returns the error reason, if any * * @return 0 on success */ int persistent(bool persis, std::string& error_str) { std::ostringstream oss; if ((snapshots.size() > 0) && !persis) { error_str = "Image has snapshots."; return -1; } switch (state) { case USED: case CLONE: case USED_PERS: case LOCKED_USED: case LOCKED_USED_PERS: oss << "Image cannot be in state " << state_to_str(state) <<"."; error_str = oss.str(); return -1; case INIT: case READY: case DISABLED: case LOCKED: case ERROR: case DELETE: if (persis == true) { persistent_img = 1; } else { persistent_img = 0; } break; } return 0; } /** * Modifies the given disk attribute adding the following attributes: * * SOURCE: the file-path. * * TARGET: will only be set if the Image's definition includes it. * * @param disk attribute for the VM template * @param img_type will be set to the used image's type * @param dev_prefix will be set to the defined dev_prefix, * or the default one * @param inherit_attrs Attributes to be inherited from the image template * into the disk * */ void disk_attribute(VirtualMachineDisk * disk, ImageType& img_type, std::string& dev_prefix, const std::vector& inherit_attrs); /** * Factory method for image templates */ std::unique_ptr