# HG changeset patch # User Marcus Granado # Date 1278519448 -3600 # Node ID 45dae0f9117b87944b3376e9be853f07ce79ea15 # Parent bcb4246f6c4b20269ab397d1b9c0c1e029d5dfa1 CP-1739: create XAPI datamodel stubs for PR-1031 (VM protection policy) Signed-off-by: Marcus Granado diff -r bcb4246f6c4b -r 45dae0f9117b ocaml/idl/datamodel.ml --- a/ocaml/idl/datamodel.ml +++ b/ocaml/idl/datamodel.ml @@ -60,6 +60,7 @@ let _vm = "VM" let _vm_metrics = "VM_metrics" let _vm_guest_metrics = "VM_guest_metrics" +let _vmpp = "VMPP" let _network = "network" let _vif = "VIF" let _vif_metrics = "VIF_metrics" @@ -148,6 +149,12 @@ | x::xs -> if x=in_product_since then "closed"::x::xs else go_through_release_order xs in go_through_release_order release_order +let cowley_release = + { internal=get_product_releases rel_cowley + ; opensource=get_oss_releases None + ; internal_deprecated_since=None + } + let midnight_ride_release = { internal=get_product_releases "midnight-ride" ; opensource=get_oss_releases None @@ -1265,9 +1272,10 @@ ~in_product_since: rel_orlando ~doc:"Snapshots the specified VM with quiesce, making a new VM. Snapshot automatically exploits the capabilities of the underlying storage repository in which the VM's disk images are stored (e.g. Copy on Write)." ~result: (Ref _vm, "The reference of the newly created VM.") - ~params:[ - Ref _vm, "vm", "The VM to be snapshotted"; - String, "new_name", "The name of the snapshotted VM" + ~versioned_params:[ + {param_type=Ref _vm; param_name="vm"; param_doc="The VM to be snapshotted"; param_release=orlando_release; param_default=None}; + {param_type=String ; param_name="new_name"; param_doc="The name of the snapshotted VM"; param_release=orlando_release; param_default=None}; + {param_type=Bool ; param_name="from_protection_policy"; param_doc="true if created by the protection policy"; param_release=cowley_release; param_default=(Some(VBool false))}; ] ~errs:[Api_errors.vm_bad_power_state; Api_errors.sr_full; Api_errors.operation_not_allowed; Api_errors.vm_snapshot_with_quiesce_failed; @@ -1296,9 +1304,10 @@ ~in_product_since: rel_orlando ~doc:"Snapshots the specified VM, making a new VM. Snapshot automatically exploits the capabilities of the underlying storage repository in which the VM's disk images are stored (e.g. Copy on Write)." ~result: (Ref _vm, "The reference of the newly created VM.") - ~params:[ - Ref _vm, "vm", "The VM to be snapshotted"; - String, "new_name", "The name of the snapshotted VM" + ~versioned_params:[ + {param_type=Ref _vm; param_name="vm"; param_doc="The VM to be snapshotted"; param_release=orlando_release; param_default=None}; + {param_type=String ; param_name="new_name"; param_doc="The name of the snapshotted VM"; param_release=orlando_release; param_default=None}; + {param_type=Bool ; param_name="from_protection_policy"; param_doc="true if created by the protection policy"; param_release=cowley_release; param_default=(Some(VBool false))}; ] ~errs:[Api_errors.vm_bad_power_state; Api_errors.sr_full; Api_errors.operation_not_allowed] ~allowed_roles:_R_VM_POWER_ADMIN @@ -1319,9 +1328,10 @@ ~in_product_since: rel_midnight_ride ~doc:"Checkpoints the specified VM, making a new VM. Checkpoint automatically exploits the capabilities of the underlying storage repository in which the VM's disk images are stored (e.g. Copy on Write) and saves the memory image as well." ~result: (Ref _vm, "The reference of the newly created VM.") - ~params:[ - Ref _vm, "vm", "The VM to be checkpointed"; - String, "new_name", "The name of the checkpointed VM" + ~versioned_params:[ + {param_type=Ref _vm; param_name="vm"; param_doc="The VM to be checkpointed"; param_release=midnight_ride_release; param_default=None}; + {param_type=String ; param_name="new_name"; param_doc="The name of the checkpointed VM"; param_release=midnight_ride_release; param_default=None}; + {param_type=Bool ; param_name="from_protection_policy"; param_doc="true if created by the protection policy"; param_release=cowley_release; param_default=(Some(VBool false))}; ] ~errs:[Api_errors.vm_bad_power_state; Api_errors.sr_full; Api_errors.operation_not_allowed; Api_errors.vm_checkpoint_suspend_failed; Api_errors.vm_checkpoint_resume_failed] @@ -3388,7 +3398,11 @@ ~name:"get_servertime" ~in_oss_since:None ~in_product_since:rel_orlando - ~params:[Ref _host, "host", "The host whose clock should be queried"] + ~versioned_params: + [ + {param_type=(Ref _host); param_name="host"; param_doc="The host whose clock should be queried"; param_release=orlando_release; param_default=None}; + {param_type=Bool; param_name="as_localtime"; param_doc="If the time returned should be in the server local timezone"; param_release=cowley_release; param_default=(Some (VBool false))}; + ] ~doc:"This call queries the host's clock for the current time" ~result:(DateTime, "The current time") ~allowed_roles:_R_READ_ONLY @@ -5686,6 +5700,8 @@ field ~writer_roles:_R_VM_POWER_ADMIN ~qualifier:DynamicRO ~in_product_since:rel_midnight_ride ~ty:(Set (Ref _vm)) "children" "List pointing to all the children of this VM"; field ~qualifier:DynamicRO ~in_product_since:rel_midnight_ride ~default_value:(Some (VMap [])) ~ty:(Map (String,String)) "bios_strings" "BIOS strings"; + field ~writer_roles:_R_VM_POWER_ADMIN ~qualifier:RW ~in_product_since:rel_cowley ~default_value:(Some (VRef (Ref.string_of Ref.null))) ~ty:(Ref _vmpp) "protection_policy" "Ref pointing to a protection policy for this VM"; + field ~writer_roles:_R_POOL_OP ~qualifier:StaticRO ~in_product_since:rel_cowley ~default_value:(Some (VBool false)) ~ty:Bool "is_snapshot_from_protection_policy" "true if this snapshot was created by the protection policy"; ]) () @@ -5745,6 +5761,72 @@ ] () +(* VM protection policy *) +let vmpp_protect_now = call ~flags:[`Session] + ~name:"protect_now" + ~in_oss_since:None + ~in_product_since:rel_cowley + ~params:[Ref _vmpp, "self", "The protection policy to execute";] + ~doc:"This call executes the protection policy immediately" + ~allowed_roles:_R_POOL_OP + () +let vmpp_archive_now = call ~flags:[`Session] + ~name:"archive_now" + ~in_oss_since:None + ~in_product_since:rel_cowley + ~params:[Ref _vm, "self", "The snapshot to archive";] + ~doc:"This call archives the snapshot provided as a parameter" + ~allowed_roles:_R_VM_POWER_ADMIN + () +let vmpp_test_archive_target = call ~flags:[`Session] + ~name:"test_archive_target" + ~in_oss_since:None + ~in_product_since:rel_cowley + ~params:[Ref _vmpp, "self", "The related protection policy"; + Map(String,String), "config", "Archive target config settings to test"; + ] + ~doc:"This call tests the archive target config settings" + ~allowed_roles:_R_POOL_OP + () +let vmpp_backup_type = Enum ("vmpp_backup_type", + [ + "snapshot", "The backup is a snapshot"; + "checkpoint", "The backup is a checkpoint"; + ]) +let vmpp_archive_type = Enum ("vmpp_archive_type", + [ + "always_after_backup", "Archive after backup"; + "never", "Never archive"; + "on_schedule", "Archive according to archive-schedule"; + ]) +let vmpp = + create_obj ~in_db:true ~in_product_since:rel_cowley ~in_oss_since:None ~internal_deprecated_since:None ~persist:PersistEverything ~gen_constructor_destructor:true ~name:_vmpp ~descr:"VM Protection Policy" + ~gen_events:true + ~doccomments:[] + ~messages_default_allowed_roles:_R_POOL_OP + ~messages:[ + vmpp_protect_now; + vmpp_archive_now; + vmpp_test_archive_target; + ] + ~contents:[ + uid _vmpp; + namespace ~name:"name" ~contents:(names None RW) (); + field ~qualifier:RW ~ty:Bool "is_policy_enabled" "enable or disable this policy" ~default_value:(Some (VBool true)); + field ~qualifier:RW ~ty:vmpp_backup_type "backup_type" "type of the backup sub-policy"; + field ~qualifier:RW ~ty:Int "backup_retention_value" "maximum number of backups that should be stored at any time" ~default_value:(Some (VInt 1L)); + field ~qualifier:RW ~ty:(Map (String,String)) "backup_schedule" "schedule of the backup containing 'frequency', 'hour', 'min', 'days'. Date/time-related information is in XenServer Local Timezone"; + field ~qualifier:RW ~ty:DateTime "backup_last_run_time" "time of the last backup" ~default_value:(Some(VDateTime(Date.of_float 0.))); + field ~qualifier:RW ~ty:vmpp_archive_type "archive_type" "type of the archive sub-policy" ~default_value:(Some (VEnum "never")); + field ~qualifier:RW ~ty:(Map (String,String)) "archive_target_config" "configuration for the archive, including its 'type' in {'cifs','nfs'}" ~default_value:(Some (VMap [])); + field ~qualifier:RW ~ty:(Map (String,String)) "archive_schedule" "schedule of the archive containing 'frequency', 'hour', 'min', 'days'. Date/time-related information is in XenServer Local Timezone" ~default_value:(Some (VMap [])); + field ~qualifier:RW ~ty:DateTime "archive_last_run_time" "time of the last archive" ~default_value:(Some(VDateTime(Date.of_float 0.))); + field ~qualifier:DynamicRO ~ty:(Set (Ref _vm)) "VMs" "all VMs attached to this protection policy"; + field ~qualifier:RW ~ty:Bool "is_alarm_enabled" "true if alarm is enabled for this policy" ~default_value:(Some (VBool false)); + field ~qualifier:RW ~ty:(Map (String,String)) "alarm_config" "configuration for the alarm" ~default_value:(Some (VMap [])); + ] + () + (** events handling: *) let event_operation = Enum ("event_operation", @@ -6016,6 +6098,7 @@ vm; vm_metrics; vm_guest_metrics; + vmpp; host; host_crashdump; host_patch; @@ -6099,6 +6182,8 @@ (_subject, "roles"), (_subject, "roles"); (*(_subject, "roles"), (_role, "subjects");*) (_role, "subroles"), (_role, "subroles"); + + (_vm, "protection_policy"), (_vmpp, "VMs"); ] (** the full api specified here *) @@ -6142,7 +6227,7 @@ or SR *) let expose_get_all_messages_for = [ _task; (* _alert; *) _host; _host_metrics; _hostcpu; _sr; _vm; _vm_metrics; _vm_guest_metrics; _network; _vif; _vif_metrics; _pif; _pif_metrics; _pbd; _vdi; _vbd; _vbd_metrics; _console; - _crashdump; _host_crashdump; _host_patch; _pool; _sm; _pool_patch; _bond; _vlan; _blob; _subject; _role; _secret ] + _crashdump; _host_crashdump; _host_patch; _pool; _sm; _pool_patch; _bond; _vlan; _blob; _subject; _role; _secret; _vmpp ] let no_task_id_for = [ _task; (* _alert; *) _event ] diff -r bcb4246f6c4b -r 45dae0f9117b ocaml/xapi/OMakefile --- a/ocaml/xapi/OMakefile +++ b/ocaml/xapi/OMakefile @@ -107,6 +107,7 @@ xapi_subject \ xapi_role \ audit_log \ + xapi_vmpp \ xapi_vm_lifecycle \ xapi_vm_clone \ xapi_vm_snapshot \ diff -r bcb4246f6c4b -r 45dae0f9117b ocaml/xapi/api_server.ml --- a/ocaml/xapi/api_server.ml +++ b/ocaml/xapi/api_server.ml @@ -34,6 +34,7 @@ end module VM_metrics = struct end module VM_guest_metrics = struct end + module VMPP = Xapi_vmpp module Host = Xapi_host module Host_crashdump = Xapi_host_crashdump diff -r bcb4246f6c4b -r 45dae0f9117b ocaml/xapi/cli_operations.ml --- a/ocaml/xapi/cli_operations.ml +++ b/ocaml/xapi/cli_operations.ml @@ -1432,7 +1432,7 @@ ~actions_after_shutdown:`destroy ~actions_after_reboot:`restart ~actions_after_crash:`destroy ~pV_bootloader:"" ~pV_kernel:"" ~pV_ramdisk:"" ~pV_args:"" ~pV_bootloader_args:"" ~pV_legacy_args:"" ~hVM_boot_policy:"" ~hVM_boot_params:[] ~hVM_shadow_multiplier:1. ~platform:[] ~pCI_bus:"" ~other_config:[] ~xenstore_data:[] ~recommendations:"" ~ha_always_run:false ~ha_restart_priority:"" - ~tags:[] in + ~tags:[] ~protection_policy:Ref.null ~is_snapshot_from_protection_policy:false in let uuid=Client.VM.get_uuid rpc session_id vm in printer (Cli_printer.PList [uuid]) @@ -2169,9 +2169,9 @@ printer (Cli_printer.PList (List.map (fun vm -> Client.VM.get_uuid rpc session_id vm) new_vms)) let vm_clone printer = vm_clone_aux Client.VM.clone "Cloned " printer true -let vm_snapshot printer = vm_clone_aux Client.VM.snapshot "Snapshotted " printer false -let vm_snapshot_with_quiesce printer = vm_clone_aux Client.VM.snapshot_with_quiesce "Snapshotted" printer false -let vm_checkpoint printer = vm_clone_aux Client.VM.checkpoint "Checkpointed " printer false +let vm_snapshot printer = vm_clone_aux (Client.VM.snapshot ~from_protection_policy:false) "Snapshotted " printer false +let vm_snapshot_with_quiesce printer = vm_clone_aux (Client.VM.snapshot_with_quiesce ~from_protection_policy:false) "Snapshotted" printer false +let vm_checkpoint printer = vm_clone_aux (Client.VM.checkpoint ~from_protection_policy:false) "Checkpointed " printer false let get_snapshot_uuid params = if List.mem_assoc "snapshot-uuid" params diff -r bcb4246f6c4b -r 45dae0f9117b ocaml/xapi/create_misc.ml --- a/ocaml/xapi/create_misc.ml +++ b/ocaml/xapi/create_misc.ml @@ -174,7 +174,9 @@ ~ha_restart_priority:"" ~ha_always_run:false ~recommendations:"" ~last_boot_CPU_flags:[] ~last_booted_record:"" ~guest_metrics:Ref.null ~metrics - ~bios_strings:[]; + ~bios_strings:[] ~protection_policy:Ref.null + ~is_snapshot_from_protection_policy:false + ; Xapi_vm_helpers.update_memory_overhead ~__context ~vm:domain_zero_ref and create_domain_zero_console_record ~__context ~domain_zero_ref = diff -r bcb4246f6c4b -r 45dae0f9117b ocaml/xapi/create_templates.ml --- a/ocaml/xapi/create_templates.ml +++ b/ocaml/xapi/create_templates.ml @@ -208,6 +208,8 @@ vM_tags = []; vM_bios_strings = []; + vM_protection_policy = Ref.null; + vM_is_snapshot_from_protection_policy = false; } let other_install_media_template memory = diff -r bcb4246f6c4b -r 45dae0f9117b ocaml/xapi/import_xva.ml --- a/ocaml/xapi/import_xva.ml +++ b/ocaml/xapi/import_xva.ml @@ -82,6 +82,7 @@ ~pV_args:"" ~pCI_bus:"" ~other_config:[] ~xenstore_data:[] ~recommendations:"" ~ha_always_run:false ~ha_restart_priority:"" ~tags:[] + ~protection_policy:Ref.null ~is_snapshot_from_protection_policy:false in TaskHelper.operate_on_db_task ~__context diff -r bcb4246f6c4b -r 45dae0f9117b ocaml/xapi/message_forwarding.ml --- a/ocaml/xapi/message_forwarding.ml +++ b/ocaml/xapi/message_forwarding.ml @@ -499,6 +499,7 @@ module Role = Local.Role module Task = Local.Task module Event = Local.Event + module VMPP = Local.VMPP (* module Alert = Local.Alert *) module Pool = struct @@ -844,9 +845,9 @@ (* -------------------------------------------------------------------------- *) (* don't forward create. this just makes a db record *) - let create ~__context ~name_label ~name_description ~user_version ~is_a_template ~affinity ~memory_target ~memory_static_max ~memory_dynamic_max ~memory_dynamic_min ~memory_static_min ~vCPUs_params ~vCPUs_max ~vCPUs_at_startup ~actions_after_shutdown ~actions_after_reboot ~actions_after_crash ~pV_bootloader ~pV_kernel ~pV_ramdisk ~pV_args ~pV_bootloader_args ~pV_legacy_args ~hVM_boot_policy ~hVM_boot_params ~hVM_shadow_multiplier ~platform ~pCI_bus ~other_config ~recommendations ~xenstore_data ~ha_always_run ~ha_restart_priority ~tags ~blocked_operations = + let create ~__context ~name_label ~name_description ~user_version ~is_a_template ~affinity ~memory_target ~memory_static_max ~memory_dynamic_max ~memory_dynamic_min ~memory_static_min ~vCPUs_params ~vCPUs_max ~vCPUs_at_startup ~actions_after_shutdown ~actions_after_reboot ~actions_after_crash ~pV_bootloader ~pV_kernel ~pV_ramdisk ~pV_args ~pV_bootloader_args ~pV_legacy_args ~hVM_boot_policy ~hVM_boot_params ~hVM_shadow_multiplier ~platform ~pCI_bus ~other_config ~recommendations ~xenstore_data ~ha_always_run ~ha_restart_priority ~tags ~blocked_operations ~protection_policy = info "VM.create: name_label = '%s' name_description = '%s'" name_label name_description; - Local.VM.create ~__context ~name_label ~name_description ~user_version ~is_a_template ~affinity ~memory_target ~memory_static_max ~memory_dynamic_max ~memory_dynamic_min ~memory_static_min ~vCPUs_params ~vCPUs_max ~vCPUs_at_startup ~actions_after_shutdown ~actions_after_reboot ~actions_after_crash ~pV_bootloader ~pV_kernel ~pV_ramdisk ~pV_args ~pV_bootloader_args ~pV_legacy_args ~hVM_boot_policy ~hVM_boot_params ~hVM_shadow_multiplier ~platform ~pCI_bus ~other_config ~recommendations ~xenstore_data ~ha_always_run ~ha_restart_priority ~tags ~blocked_operations + Local.VM.create ~__context ~name_label ~name_description ~user_version ~is_a_template ~affinity ~memory_target ~memory_static_max ~memory_dynamic_max ~memory_dynamic_min ~memory_static_min ~vCPUs_params ~vCPUs_max ~vCPUs_at_startup ~actions_after_shutdown ~actions_after_reboot ~actions_after_crash ~pV_bootloader ~pV_kernel ~pV_ramdisk ~pV_args ~pV_bootloader_args ~pV_legacy_args ~hVM_boot_policy ~hVM_boot_params ~hVM_shadow_multiplier ~platform ~pCI_bus ~other_config ~recommendations ~xenstore_data ~ha_always_run ~ha_restart_priority ~tags ~blocked_operations ~protection_policy (* don't forward destroy. this just deletes db record *) let destroy ~__context ~self = @@ -910,22 +911,22 @@ Db.VM.set_transportable_snapshot_id ~__context ~self:vm ~value:transportable_snapshot_id (* almost a copy of the clone function *) - let snapshot ~__context ~vm ~new_name = + let snapshot ~__context ~vm ~new_name ~from_protection_policy = info "VM.snapshot: VM = '%s'; new_name = '%s'" (vm_uuid ~__context vm) new_name; let task_id = Ref.string_of (Context.get_task_id __context) in - let local_fn = Local.VM.snapshot ~vm ~new_name in + let local_fn = Local.VM.snapshot ~vm ~new_name ~from_protection_policy in (* We mark the VM as snapshoting. We don't mark the disks; the implementation of the snapshot uses the API *) (* to snapshot and lock the individual VDIs. We don't give any atomicity guarantees here but we do prevent *) (* disk corruption. *) with_vm_operation ~__context ~self: vm ~doc:"VM.snapshot" ~op:`snapshot (fun () -> forward_to_access_srs ~local_fn ~__context ~vm - (fun session_id rpc -> Client.VM.snapshot rpc session_id vm new_name)) - - let snapshot_with_quiesce ~__context ~vm ~new_name = + (fun session_id rpc -> Client.VM.snapshot rpc session_id vm new_name from_protection_policy)) + + let snapshot_with_quiesce ~__context ~vm ~new_name ~from_protection_policy = info "VM.snapshot_with_quiesce: VM = '%s'; new_name = '%s'" (vm_uuid ~__context vm) new_name; let task_id = Ref.string_of (Context.get_task_id __context) in - let local_fn = Local.VM.snapshot_with_quiesce ~vm ~new_name in + let local_fn = Local.VM.snapshot_with_quiesce ~vm ~new_name ~from_protection_policy in (* We mark the VM as snapshoting. We don't mark the disks; the implementation of the snapshot uses the API *) (* to snapshot and lock the individual VDIs. We don't give any atomicity guarantees here but we do prevent *) (* disk corruption. *) @@ -937,12 +938,12 @@ then forward_vm_op else forward_to_access_srs in forward ~local_fn ~__context ~vm - (fun session_id rpc -> Client.VM.snapshot_with_quiesce rpc session_id vm new_name)) - - let checkpoint ~__context ~vm ~new_name = + (fun session_id rpc -> Client.VM.snapshot_with_quiesce rpc session_id vm new_name from_protection_policy)) + + let checkpoint ~__context ~vm ~new_name ~from_protection_policy = info "VM.checkpoint: VM = '%s'; new_name=' %s'" (vm_uuid ~__context vm) new_name; - let local_fn = Local.VM.checkpoint ~vm ~new_name in - let forward_fn session_id rpc = Client.VM.checkpoint rpc session_id vm new_name in + let local_fn = Local.VM.checkpoint ~vm ~new_name ~from_protection_policy in + let forward_fn session_id rpc = Client.VM.checkpoint rpc session_id vm new_name from_protection_policy in with_vm_operation ~__context ~self: vm ~doc:"VM.checkpoint" ~op:`checkpoint (fun () -> if Db.VM.get_power_state __context vm = `Running then @@ -2062,11 +2063,11 @@ (host_uuid ~__context host); Local.Host.compute_memory_overhead ~__context ~host - let get_servertime ~__context ~host = + let get_servertime ~__context ~host ~as_localtime = (* info "Host.get_servertime"; *) (* suppressed because the GUI calls this frequently and it isn't interesting for debugging *) - let local_fn = Local.Host.get_servertime ~host in + let local_fn = Local.Host.get_servertime ~host ~as_localtime in do_op_on ~local_fn ~__context ~host - (fun session_id rpc -> Client.Host.get_servertime rpc session_id host) + (fun session_id rpc -> Client.Host.get_servertime rpc session_id host as_localtime) let enable_binary_storage ~__context ~host = info "Host.enable_binary_storage: host = '%s'" (host_uuid ~__context host); diff -r bcb4246f6c4b -r 45dae0f9117b ocaml/xapi/quicktest.ml --- a/ocaml/xapi/quicktest.ml +++ b/ocaml/xapi/quicktest.ml @@ -463,8 +463,8 @@ debug test "Cloning suspended VM"; let vm' = Client.VM.clone !rpc session_id vm "clone-suspended-test" in debug test "Snapshoting the VM twice"; - let snap1 = Client.VM.snapshot !rpc session_id vm' "snap1" in - let snap2 = Client.VM.snapshot !rpc session_id vm' "snap2" in + let snap1 = Client.VM.snapshot !rpc session_id vm' "snap1" false in + let snap2 = Client.VM.snapshot !rpc session_id vm' "snap2" false in debug test "Comparing original, clone VIF configuration"; compare_vifs session_id test vm vm'; diff -r bcb4246f6c4b -r 45dae0f9117b ocaml/xapi/xapi_host.ml --- a/ocaml/xapi/xapi_host.ml +++ b/ocaml/xapi/xapi_host.ml @@ -921,7 +921,7 @@ Xapi_periodic_scheduler.add_to_queue "RRD backup" Xapi_periodic_scheduler.OneShot delay (fun () -> Monitor_rrds.backup ~save_stats_locally:(Pool_role.is_master ()) ()) -let get_servertime ~__context ~host = +let get_servertime ~__context ~host ~as_localtime = Date.of_float (Unix.gettimeofday ()) let enable_binary_storage ~__context ~host = diff -r bcb4246f6c4b -r 45dae0f9117b ocaml/xapi/xapi_host.mli --- a/ocaml/xapi/xapi_host.mli +++ b/ocaml/xapi/xapi_host.mli @@ -160,7 +160,7 @@ plugin:string -> fn:string -> args:(string * string) list -> string val sync_data : __context:Context.t -> host:API.ref_host -> unit val backup_rrds : __context:'a -> host:'b -> delay:float -> unit -val get_servertime : __context:'a -> host:'b -> Date.iso8601 +val get_servertime : __context:'a -> host:'b -> as_localtime:bool -> Date.iso8601 val enable_binary_storage : __context:Context.t -> host:[ `host ] Ref.t -> unit val disable_binary_storage : diff -r bcb4246f6c4b -r 45dae0f9117b ocaml/xapi/xapi_vm.ml --- a/ocaml/xapi/xapi_vm.ml +++ b/ocaml/xapi/xapi_vm.ml @@ -823,6 +823,8 @@ ~ha_restart_priority ~tags ~blocked_operations + ~protection_policy + ~is_snapshot_from_protection_policy : API.ref_VM = let gen_mac_seed () = Uuid.to_string (Uuid.make_uuid ()) in (* Add random mac_seed if there isn't one specified already *) @@ -865,6 +867,8 @@ ~ha_restart_priority ~tags ~blocked_operations + ~protection_policy + ~is_snapshot_from_protection_policy let destroy ~__context ~self = let parent = Db.VM.get_parent ~__context ~self in @@ -896,15 +900,15 @@ (* We do call wait_in_line for snapshot and snapshot_with_quiesce because the locks are taken at *) (* the VBD level (with pause/unpause mechanism *) -let snapshot ~__context ~vm ~new_name = +let snapshot ~__context ~vm ~new_name ~from_protection_policy = TaskHelper.set_cancellable ~__context; - Xapi_vm_snapshot.snapshot ~__context ~vm ~new_name + Xapi_vm_snapshot.snapshot ~__context ~vm ~new_name ~from_protection_policy (* Snapshot_with_quiesce triggers the VSS plugin which will then calls the VM.snapshot API call. *) (* Thus, to avoid dead-locks, do not put snapshot and snapshot_with_quiesce on the same waiting line *) -let snapshot_with_quiesce ~__context ~vm ~new_name = +let snapshot_with_quiesce ~__context ~vm ~new_name ~from_protection_policy = TaskHelper.set_cancellable ~__context; - Xapi_vm_snapshot.snapshot_with_quiesce ~__context ~vm ~new_name + Xapi_vm_snapshot.snapshot_with_quiesce ~__context ~vm ~new_name ~from_protection_policy (* As we will destroy the domain ourself, we grab the vm_lock here in order to tell the event thread to *) (* do not look at this domain. The message forwarding layer already checked that the VM reference we *) @@ -919,7 +923,7 @@ (* As the checkpoint operation modify the domain state, we take the vm_lock to do not let the event *) (* thread mess around with that. *) -let checkpoint ~__context ~vm ~new_name = +let checkpoint ~__context ~vm ~new_name ~from_protection_policy = if not (Features.is_enabled ~__context Features.Checkpoint) then raise (Api_errors.Server_error(Api_errors.license_restriction, [])) else begin @@ -928,7 +932,7 @@ (fun () -> TaskHelper.set_cancellable ~__context; Locking_helpers.with_lock vm - (fun token () -> Xapi_vm_snapshot.checkpoint ~__context ~vm ~new_name) + (fun token () -> Xapi_vm_snapshot.checkpoint ~__context ~vm ~new_name ~from_protection_policy) () ) end diff -r bcb4246f6c4b -r 45dae0f9117b ocaml/xapi/xapi_vm.mli --- a/ocaml/xapi/xapi_vm.mli +++ b/ocaml/xapi/xapi_vm.mli @@ -182,17 +182,20 @@ xenstore_data:(string * string) list -> ha_always_run:bool -> ha_restart_priority:string -> - tags:string list -> blocked_operations:'a -> API.ref_VM + tags:string list -> blocked_operations:'a -> + protection_policy:[ `VMPP ] Ref.t -> + is_snapshot_from_protection_policy:bool +-> API.ref_VM val destroy : __context:Context.t -> self:[ `VM ] Ref.t -> unit val clone : __context:Context.t -> vm:API.ref_VM -> new_name:string -> [ `VM ] Ref.t val snapshot : - __context:Context.t -> vm:API.ref_VM -> new_name:string -> [ `VM ] Ref.t + __context:Context.t -> vm:API.ref_VM -> new_name:string -> from_protection_policy:bool -> [ `VM ] Ref.t val snapshot_with_quiesce : - __context:Context.t -> vm:[ `VM ] Ref.t -> new_name:string -> [ `VM ] Ref.t + __context:Context.t -> vm:[ `VM ] Ref.t -> new_name:string -> from_protection_policy:bool -> [ `VM ] Ref.t val revert : __context:Context.t -> snapshot:[ `VM ] Ref.t -> unit val checkpoint : - __context:Context.t -> vm:API.ref_VM -> new_name:string -> [ `VM ] Ref.t + __context:Context.t -> vm:API.ref_VM -> new_name:string -> from_protection_policy:bool -> [ `VM ] Ref.t val copy : __context:Context.t -> vm:API.ref_VM -> new_name:string -> sr:API.ref_SR -> [ `VM ] Ref.t diff -r bcb4246f6c4b -r 45dae0f9117b ocaml/xapi/xapi_vm_clone.ml --- a/ocaml/xapi/xapi_vm_clone.ml +++ b/ocaml/xapi/xapi_vm_clone.ml @@ -307,7 +307,10 @@ ~ha_restart_priority:all.Db_actions.vM_ha_restart_priority ~ha_always_run:false ~tags:all.Db_actions.vM_tags - ~bios_strings:all.Db_actions.vM_bios_strings; + ~bios_strings:all.Db_actions.vM_bios_strings + ~protection_policy:Ref.null + ~is_snapshot_from_protection_policy:false + ; ref, uuid diff -r bcb4246f6c4b -r 45dae0f9117b ocaml/xapi/xapi_vm_helpers.ml --- a/ocaml/xapi/xapi_vm_helpers.ml +++ b/ocaml/xapi/xapi_vm_helpers.ml @@ -115,7 +115,8 @@ ~platform ~pCI_bus ~other_config ~xenstore_data ~recommendations ~ha_always_run ~ha_restart_priority ~tags - ~blocked_operations + ~blocked_operations ~protection_policy + ~is_snapshot_from_protection_policy : API.ref_VM = (* NB parameter validation is delayed until VM.start *) @@ -175,7 +176,10 @@ ~blobs:[] ~ha_restart_priority ~ha_always_run ~tags - ~bios_strings:[]; + ~bios_strings:[] + ~protection_policy:Ref.null + ~is_snapshot_from_protection_policy:false + ; Db.VM.set_power_state ~__context ~self:vm_ref ~value:`Halted; Xapi_vm_lifecycle.update_allowed_operations ~__context ~self:vm_ref; update_memory_overhead ~__context ~vm:vm_ref; diff -r bcb4246f6c4b -r 45dae0f9117b ocaml/xapi/xapi_vm_snapshot.ml --- a/ocaml/xapi/xapi_vm_snapshot.ml +++ b/ocaml/xapi/xapi_vm_snapshot.ml @@ -25,7 +25,7 @@ (*************************************************************************************************) (* Crash-consistant snapshot *) (*************************************************************************************************) -let snapshot ~__context ~vm ~new_name = +let snapshot ~__context ~vm ~new_name ~from_protection_policy = debug "Snapshot: begin"; TaskHelper.set_cancellable ~__context; let res = Xapi_vm_clone.clone Xapi_vm_clone.Disk_op_snapshot ~__context ~vm ~new_name in @@ -126,7 +126,7 @@ (* We fail if the guest does not support quiesce mode. Normally, that should be detected *) (* dynamically by the xapi_vm_lifecycle.update_allowed_operations call. *) -let snapshot_with_quiesce ~__context ~vm ~new_name = +let snapshot_with_quiesce ~__context ~vm ~new_name ~from_protection_policy = debug "snapshot_with_quiesce: begin"; let domid = Int64.to_int (Db.VM.get_domid ~__context ~self:vm) in let result = Vmopshelpers.with_xs (fun xs -> @@ -172,7 +172,7 @@ in List.filter aux (Db.VM.get_VBDs ~__context ~self:vm) -let checkpoint ~__context ~vm ~new_name = +let checkpoint ~__context ~vm ~new_name ~from_protection_policy = let power_state = Db.VM.get_power_state ~__context ~self:vm in with_xc_and_xs (fun xc xs -> let vbds = get_flushable_vbds ~__context vm in diff -r bcb4246f6c4b -r 45dae0f9117b ocaml/xapi/xapi_vmpp.ml --- /dev/null +++ b/ocaml/xapi/xapi_vmpp.ml @@ -0,0 +1,61 @@ +(* + * Copyright (C) 2006-2009 Citrix Systems Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + *) +module D = Debug.Debugger(struct let name="xapi" end) +open D + +(* + val protect_now : __context:Context.t -> self:ref_VMPP -> unit + val archive_now : __context:Context.t -> self:ref_VM -> unit + val test_archive_settings : + __context:Context.t -> settings:API.string_to_string_map -> unit + val create : + __context:Context.t -> + name_label:string -> + name_description:string -> + is_policy_enabled:bool -> + backup_type:API.vmpp_backup_type -> + backup_retention_value:int64 -> + backup_schedule:API.string_to_string_map -> + backup_last_run_time:API.datetime -> + archive_type:API.vmpp_archive_type -> + archive_target_config:API.string_to_string_map -> + archive_schedule:API.string_to_string_map -> + archive_last_run_time:API.datetime -> + is_alarm_enabled:bool -> + alarm_config:API.string_to_string_map -> API.ref_VMPP + val destroy : __context:Context.t -> self:API.ref_VMPP -> unit + +*) + +let create ~__context ~name_label ~name_description ~is_policy_enabled + ~backup_type ~backup_retention_value ~backup_schedule ~backup_last_run_time + ~archive_type ~archive_target_config ~archive_schedule ~archive_last_run_time + ~is_alarm_enabled ~alarm_config : API.ref_VMPP = + let ref=Ref.make() in + let uuid=Uuid.to_string (Uuid.make_uuid()) in + Db.VMPP.create ~__context ~ref ~uuid + ~name_label ~name_description ~is_policy_enabled + ~backup_type ~backup_retention_value + ~backup_schedule ~backup_last_run_time + ~archive_type ~archive_target_config + ~archive_schedule ~archive_last_run_time + ~is_alarm_enabled ~alarm_config; + ref + +let destroy ~__context ~self = + Db.VMPP.destroy ~__context ~self + +let protect_now ~__context ~self = () +let archive_now ~__context ~self = () +let test_archive_target ~__context ~self ~config = ()