/* -------------------------------------------------------------------------- */ /* 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 BACKUP_JOB_H_ #define BACKUP_JOB_H_ #include "PoolObjectSQL.h" #include "ObjectXML.h" #include "ObjectCollection.h" /** * The BackuJob class, it organize backups of multiple VMs * * The schema is as follows: * <BACKUPJOB> * * <!-- PoolObjectSQL attributes --> * * <PRIORITY> Of this backup job. BJ with higher priority are scheduled first * <SCHED_ACTIONS> List of associated scheduled action * <ID> * <UPDATED_VMS> VMs with all backups up to date * <ID> * <OUTDATED_VMS> VMs that need a backup * <ID> * <BACKING_UP_VMS> VMs with an ongoing backup operation * <ID> * <ERROR_VMS> VMs that fail the last backup operation * <ID> * <LAST_BACKUP_TIME> Last time the backup job was triggered * <LAST_BACKUP_DURATION> Time to backup all VMs int the backup job * <TEMPLATE> * <KEEP_LAST> Just keep the last N backups * <BACKUP_VOLATILE> Backup volatile disks or not * <FS_FREEZE> FS freeze operation to perform on the VM * <MODE> Backup mode * <BACKUP_VMS> comma separated list of VMs to backup, order is implicit * <DATASTORE_ID> The dastore ID used to store the active backups * <EXECUTION> */ class BackupJob : public PoolObjectSQL { public: // ************************************************************************* // Priority Limits // ************************************************************************* static const int MAX_PRIO; static const int MIN_PRIO; static const int MAX_USER_PRIO; // ************************************************************************* // Backup modes // ************************************************************************* enum Execution { SEQUENTIAL = 0, /** < Backup VMs one by one */ PARALLEL = 1, /** < Backup all VMs in parallel */ }; static std::string execution_to_str(Execution exec) { switch (exec) { case SEQUENTIAL: return "SEQUENTIAL"; case PARALLEL: return "PARALLEL"; default: return ""; } }; static Execution str_to_execution(std::string& str_exec) { Execution exec = SEQUENTIAL; one_util::toupper(str_exec); if ( str_exec == "SEQUENTIAL" ) { exec = SEQUENTIAL; } else if ( str_exec == "PARALLEL" ) { exec = PARALLEL; } return exec; }; /** * Function to print the BackuJob 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 { return to_xml_extended(xml, false); } std::string& to_xml_extended(std::string& xml, bool do_sa) const; /** * Starts execution of the Backup Job * Add VMs to WAITING_VMS list, the backup of individual VMs * is managed by Scheduled Action Manager */ int execute(std::string& error); /** * Cancel pending Backup Job action, clear the waiting and pending list */ void cancel(); /** * Retry Backup Job, move VMs from error list to outdated */ void retry(); /** * Returns VMs waiting for a backup, the order define the priority */ std::vector<int> backup_vms() const { std::string vms_str; std::vector<int> vms; get_template_attribute("BACKUP_VMS", vms_str); one_util::split(vms_str, ',', vms); return vms; } /** * Returns VMs waiting for a backup, the order define the priority */ const std::set<int>& outdated() const { return _outdated.get_collection(); } /** * Returns VMs that are currently being backed up */ const std::set<int>& backing_up() const { return _backing_up.get_collection(); } /** * Get priority */ int priority() const { return _priority; } /** * Set priority */ void priority(int pr) { if ( pr >= MIN_PRIO && pr <= MAX_PRIO ) { _priority = pr; } } /** * Returns execution mode: SEQUENTIAL or PARALLEL */ Execution exec_mode() const; /** * Returns Datastore ID, where to backup the VMs */ int ds_id() const; /** * Returns the 'reset' attribute for the Backup Config */ int reset() const; /** * VM backup started, move the VM from waiting to pending list */ void backup_started(int vm_id); /** * Remove Virtual Machine from outdated and VMS list */ void remove_vm(int vm_id); /** * VM backup finished, remove it from backing_up list */ void backup_finished(int vm_id, bool success); /** * Add Virtual Machine to error_vms list */ void add_error(int vm_id); /** * Return Backup Config in format for Virtual Machine */ void get_backup_config(Template &tmpl); /** * Get IDs of the associated scheduled actions */ ObjectCollection& sched_actions() { return _sched_actions; } const ObjectCollection& sched_actions() const { return _sched_actions; } /** * Replace template for this object. Object should be updated * after calling this method * @param tmpl_str new contents * @param keep_restricted If true, the restricted attributes of the * current template will override the new template * @param error string describing the error if any * @return 0 on success */ int replace_template(const std::string& tmpl_str, bool keep_restricted, std::string& error) override; /** * Append new attributes to the *user template*. * @param tmpl_str new contents * @param keep_restricted If true, the restricted attributes of the * current template will override the new template * @param error string describing the error if any * @return 0 on success */ int append_template(const std::string& tmpl_str, bool keep_restricted, std::string& error) override; friend class BackupJobPool; friend class PoolSQL; protected: /** * Child classes can process the new template set with replace_template or * append_template with this method * @param error string describing the error if any * @return 0 on success */ int post_update_template(std::string& error, Template *_old_tmpl) override { remove_template_attribute("NAME"); remove_template_attribute("PRIORITY"); remove_template_attribute("SCHED_ACTION"); return parse(error); } // ************************************************************************* // Database implementation // ************************************************************************* /** * Bootstraps the database table(s) associated to the Backup Jobs * @return 0 on success */ static int bootstrap(SqlDB * db); /** * Writes the BackupJob to the DB * @param db pointer to the database. * @return 0 on success. */ int insert(SqlDB * db, std::string& error_str) override; /** * Updates the BackupJob record * @param db pointer to the database. * @return 0 on success. */ int update(SqlDB * db) override; /** * Execute an INSERT or REPLACE Sql query. * @param db The SQL DB * @param replace Execute an INSERT or a REPLACE * @return 0 on success */ int insert_replace(SqlDB *db, bool replace, std::string& error_str); private: /** * Priority for this backup job [0, 99] */ int _priority; /** * Associated scheduled action for this backup job */ ObjectCollection _sched_actions; /** * These collections stores the collection of VMs in the Virtual * Networks and manages the update process * - updated VMs with not pending backups * - outdated VMs that need backup * - backing_up VMs with an ongoing backup operation * - error VMs that fail the last backup operation */ ObjectCollection _updated; ObjectCollection _outdated; ObjectCollection _backing_up; ObjectCollection _error; /** * Time stats for the last backup action (start - epoch, duration - sec) */ time_t _last_time; time_t _last_duration; /** * @param uid * @param id * @param uname * @param gname * @param umask * @param tmpl */ BackupJob(int uid, int gid, const std::string& uname, const std::string& gname, int umask, std::unique_ptr<Template> templ); /** * Factory method for Hook templates */ std::unique_ptr<Template> get_new_template() const override { return std::make_unique<Template>(true); } /* * Parse configuration attributes for the backup operation * - KEEP_LAST * - BACKUP_VOLATILE * - FSFREEZE * - MODE * - BACKUP_VMS * * This method also updates the VMs collections removing those VMs no longer * present in BACKUP_VMS */ int parse(std::string& error); /** * 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; /** * Check if the VM belongs only to one Backup Job. * Assign Backup Job ID to added Virtual Machines, remove ID for removed VMs. * @param vms_new_str New value of BACKUP_VMS attribute * @param vms_old_str Old value of BACKUP_VMS attribute * @param error string describing the error if any * @return 0 on success, -1 otherwise */ int process_backup_vms(const std::string& vms_new_str, const std::string& vms_old_str, std::string& error); /** * Remove Backup Job ID from Virtual Machines listed in BACKUP_VMS attribute */ void remove_id_from_vms(); /** * Remove Backup Job ID from Virtual Machines * @param vms Virtual Machine IDs to remove the Backup Job ID */ void remove_id_from_vms(const std::set<unsigned int>& vms); }; #endif /*BACKUP_JOB_H_*/