Revision 40086e5c src/vmm_mad/exec/one_vmm_exec.rb

View differences:

src/vmm_mad/exec/one_vmm_exec.rb
888 888
    # DISKSNAPSHOTCREATE action, takes a snapshot of a disk
889 889
    #
890 890
    def disk_snapshot_create(id, drv_message)
891
        action   = ACTION[:disk_snapshot_create]
892
        xml_data = decode(drv_message)
893

  
891
        snap_action  = prepare_snap_action(id, drv_message, ACTION[:disk_snapshot_create])
892
        action       = snap_action[:action]
893
        strategy     = snap_action[:strategy]
894
        drv_message  = snap_action[:drv_message]
895
        target       = snap_action[:target]
896
        target_index = snap_action[:target_index]
897
        xml_data     = snap_action[:xml_data]
898

  
899
        # Get TM command
894 900
        tm_command = ensure_xpath(xml_data, id, action, 'TM_COMMAND') || return
895 901
        tm_rollback= xml_data.elements['TM_COMMAND_ROLLBACK'].text.strip
896 902

  
897
        target_xpath = "VM/TEMPLATE/DISK[DISK_SNAPSHOT_ACTIVE='YES']/TARGET"
898
        target       = ensure_xpath(xml_data, id, action, target_xpath) ||return
899

  
900
        target_index = target.downcase[-1..-1].unpack('c').first - 97
901

  
902
        if @options[:detach_snap]
903
          disk   = xml_data.elements[target_xpath].parent
904
          attach = REXML::Element.new('ATTACH')
905

  
906
          attach.add_text('YES')
907
          disk.add(attach)
908

  
909
          drv_message = Base64.encode64(xml_data.to_s)
910
        end
911

  
912
        action = VmmAction.new(self, id, :disk_snapshot_create, drv_message)
913

  
914
        vmm_driver_path = 'VM/HISTORY_RECORDS/HISTORY/VMMMAD'
915
        tm_driver_path = "VM/TEMPLATE/DISK[DISK_SNAPSHOT_ACTIVE='YES']/TM_MAD"
916

  
917
        vmm_driver = ensure_xpath(xml_data, id, action, vmm_driver_path) ||
918
            return
919
        tm_driver = ensure_xpath(xml_data, id, action, tm_driver_path) ||
920
            return
921

  
922
        # live_snapshots option is an array of VM and TM pairs
923
        # For example "kvm-qcow2". If found then only TM action is called.
924
        # Extra actions (suspend or attach) will be skipped
925
        live_snapshot = @options[:live_snapshots].include? "#{vmm_driver}-#{tm_driver}"
926

  
927
        if @options[:detach_snap]
928
          pre_action = :detach_disk
929
          pre_params = [:deploy_id, :disk_target_path, target, target_index]
930

  
931
          post_action = :attach_disk
932
          post_params = [:deploy_id, :disk_target_path, target, target_index,
933
                         drv_message]
903
        # Build the process
904
        if strategy == :live
905
            tm_command_split = tm_command.split
906
            tm_command_split[0] += "_LIVE"
907

  
908
            steps = [
909
                {
910
                    :driver     => :tm,
911
                    :action     => :tm_snap_create_live,
912
                    :parameters => tm_command_split,
913
                    :no_fail    => true
914
                }
915
            ]
934 916
        else
935
          pre_action = :save
936
          pre_params = [:deploy_id, :checkpoint_file, :host]
937

  
938
          post_action = :restore
939
          post_params = [:checkpoint_file, :host, :deploy_id]
940
        end
941

  
942
        steps = []
917
            if strategy == :detach
918
                pre_action = :detach_disk
919
                pre_params = [:deploy_id, :disk_target_path, target, target_index]
920

  
921
                post_action = :attach_disk
922
                post_params = [:deploy_id, :disk_target_path, target, target_index,
923
                               drv_message]
924
            else # suspend
925
                pre_action = :save
926
                pre_params = [:deploy_id, :checkpoint_file, :host]
927

  
928
                post_action = :restore
929
                post_params = [:checkpoint_file, :host, :deploy_id]
930
            end
943 931

  
944
        if !live_snapshot
945
            # Save VM state / detach the disk
946
            steps << {
947
                :driver     => :vmm,
948
                :action     => pre_action,
949
                :parameters => pre_params
950
            }
951
        end
952

  
953
        # Do the snapshot
954
        steps << {
955
            :driver     => :tm,
956
            :action     => :tm_snap_create,
957
            :parameters => tm_command.split,
958
            :no_fail    => true
959
        }
960

  
961
        if !live_snapshot
962
            # Restore VM / attach the disk
963
            steps << {
964
                :driver     => :vmm,
965
                :action     => post_action,
966
                :parameters => post_params,
967
                :fail_actions => [
968
                    {
969
                        :driver     => :tm,
970
                        :action     => :tm_snap_delete,
971
                        :parameters => tm_rollback.split
972
                    }
973
                ]
974
            }
932
            steps = [
933
                {
934
                    :driver     => :vmm,
935
                    :action     => pre_action,
936
                    :parameters => pre_params
937
                },
938
                {
939
                    :driver     => :tm,
940
                    :action     => :tm_snap_create,
941
                    :parameters => tm_command.split,
942
                    :no_fail    => true
943
                },
944
                {
945
                    :driver     => :vmm,
946
                    :action     => post_action,
947
                    :parameters => post_params,
948
                    :fail_actions => [
949
                        {
950
                            :driver     => :tm,
951
                            :action     => :tm_snap_delete,
952
                            :parameters => tm_rollback.split
953
                        }
954
                    ]
955
                }
956
            ]
975 957
        end
976 958

  
977 959
        action.run(steps)
......
981 963
    # DISKSNAPSHOTREVERT action, takes a snapshot of a disk
982 964
    #
983 965
    def disk_snapshot_revert(id, drv_message)
984
        action   = ACTION[:disk_snapshot_revert]
985
        xml_data = decode(drv_message)
986

  
966
        snap_action  = prepare_snap_action(id, drv_message, ACTION[:disk_snapshot_revert])
967
        action       = snap_action[:action]
968
        strategy     = @options[:snapshots_strategy]
969
        drv_message  = snap_action[:drv_message]
970
        target       = snap_action[:target]
971
        target_index = snap_action[:target_index]
972
        xml_data     = snap_action[:xml_data]
973

  
974
        # Get TM command
987 975
        tm_command = ensure_xpath(xml_data, id, action, 'TM_COMMAND') || return
988 976

  
989
        target_xpath = "VM/TEMPLATE/DISK[DISK_SNAPSHOT_ACTIVE='YES']/TARGET"
990
        target       = ensure_xpath(xml_data, id, action, target_xpath) ||return
991

  
992
        target_index = target.downcase[-1..-1].unpack('c').first - 97
993

  
994
        if @options[:detach_snap]
995
            disk   = xml_data.elements[target_xpath].parent
996
            attach = REXML::Element.new('ATTACH')
997

  
998
            attach.add_text('YES')
999
            disk.add(attach)
1000

  
1001
            drv_message = Base64.encode64(xml_data.to_s)
1002
        end
1003

  
1004
        action = VmmAction.new(self, id, :disk_snapshot_revert, drv_message)
1005

  
1006
        if @options[:detach_snap]
977
        # Build the process
978
        if strategy == :detach
1007 979
          pre_action = :detach_disk
1008 980
          pre_params = [:deploy_id, :disk_target_path, target, target_index]
1009 981

  
1010 982
          post_action = :attach_disk
1011 983
          post_params = [:deploy_id, :disk_target_path, target, target_index,
1012 984
                         drv_message]
1013
        else
985
        else # suspend
1014 986
          pre_action = :save
1015 987
          pre_params = [:deploy_id, :checkpoint_file, :host]
1016 988

  
......
1042 1014

  
1043 1015
        action.run(steps)
1044 1016
    end
1017

  
1045 1018
private
1046 1019

  
1047 1020
    def ensure_xpath(xml_data, id, action, xpath)
......
1056 1029
        end
1057 1030
    end
1058 1031

  
1032
    def prepare_snap_action(id, drv_message, action)
1033
        xml_data = decode(drv_message)
1034

  
1035
        # Make sure disk target has been defined
1036
        target_xpath = "VM/TEMPLATE/DISK[DISK_SNAPSHOT_ACTIVE='YES']/TARGET"
1037
        target       = ensure_xpath(xml_data, id, action, target_xpath) || return
1038
        target_index = target.downcase[-1..-1].unpack('c').first - 97
1039

  
1040
        # Always send ATTACH='YES' for the selected target in case it will end
1041
        # up being a 'detach' strategy
1042
        disk   = xml_data.elements[target_xpath].parent
1043
        attach = REXML::Element.new('ATTACH')
1044

  
1045
        attach.add_text('YES')
1046
        disk.add(attach)
1047

  
1048
        drv_message = Base64.encode64(xml_data.to_s)
1049
        action = VmmAction.new(self, id, :disk_snapshot_create, drv_message)
1050

  
1051
        # Determine the strategy
1052
        vmm_driver_path = 'VM/HISTORY_RECORDS/HISTORY/VMMMAD'
1053
        tm_driver_path  = "VM/TEMPLATE/DISK[DISK_SNAPSHOT_ACTIVE='YES']/TM_MAD"
1054

  
1055
        vmm_driver = ensure_xpath(xml_data, id, action, vmm_driver_path) || return
1056
        tm_driver  = ensure_xpath(xml_data, id, action, tm_driver_path)  || return
1057

  
1058
        strategy = @options[:snapshots_strategy]
1059
        if @options[:live_snapshots] && LIVE_DISK_SNAPSHOTS.include?("#{vmm_driver}-#{tm_driver}")
1060
            strategy = :live
1061
        end
1062

  
1063
        {
1064
            :action       => action,
1065
            :strategy     => strategy,
1066
            :drv_message  => drv_message,
1067
            :target       => target,
1068
            :target_index => target_index,
1069
            :xml_data     => xml_data
1070
        }
1071
    end
1059 1072
end
1060 1073

  
1061 1074
################################################################################
......
1064 1077
#
1065 1078
################################################################################
1066 1079

  
1080
LIVE_DISK_SNAPSHOTS = ENV['LIVE_DISK_SNAPSHOTS'].split rescue []
1081

  
1067 1082
opts = GetoptLong.new(
1068
    [ '--retries',        '-r', GetoptLong::OPTIONAL_ARGUMENT ],
1069
    [ '--threads',        '-t', GetoptLong::OPTIONAL_ARGUMENT ],
1070
    [ '--local',          '-l', GetoptLong::REQUIRED_ARGUMENT ],
1071
    [ '--shell',          '-s', GetoptLong::REQUIRED_ARGUMENT ],
1072
    [ '--parallel',       '-p', GetoptLong::NO_ARGUMENT ],
1073
    [ '--detach-snap',    '-d', GetoptLong::NO_ARGUMENT ],
1074
    [ '--live-snapshots', '-i', GetoptLong::REQUIRED_ARGUMENT ]
1083
    [ '--retries',           '-r', GetoptLong::OPTIONAL_ARGUMENT ],
1084
    [ '--threads',           '-t', GetoptLong::OPTIONAL_ARGUMENT ],
1085
    [ '--local',             '-l', GetoptLong::REQUIRED_ARGUMENT ],
1086
    [ '--shell',             '-s', GetoptLong::REQUIRED_ARGUMENT ],
1087
    [ '--parallel',          '-p', GetoptLong::NO_ARGUMENT ],
1088
    [ '--live-snapshots',    '-i', GetoptLong::NO_ARGUMENT ],
1089
    [ '--default-snapshots', '-d', GetoptLong::REQUIRED_ARGUMENT ]
1075 1090
)
1076 1091

  
1077
hypervisor    = ''
1078
retries       = 0
1079
threads       = 15
1080
shell         = 'bash'
1081
local_actions = {}
1082
single_host   = true
1083
detach_snap   = false
1084
live_snapshots= ['kvm-qcow2']
1092
hypervisor         = ''
1093
retries            = 0
1094
threads            = 15
1095
shell              = 'bash'
1096
local_actions      = {}
1097
single_host        = true
1098
live_snapshots     = false
1099
snapshots_strategy = :suspend # Either :detach or :suspend
1085 1100

  
1086 1101
begin
1087 1102
    opts.each do |opt, arg|
1088 1103
        case opt
1089 1104
            when '--retries'
1090
                retries   = arg.to_i
1105
                retries = arg.to_i
1091 1106
            when '--threads'
1092
                threads   = arg.to_i
1107
                threads = arg.to_i
1093 1108
            when '--local'
1094
                local_actions=OpenNebulaDriver.parse_actions_list(arg)
1109
                local_actions = OpenNebulaDriver.parse_actions_list(arg)
1095 1110
            when '--shell'
1096
                shell   = arg
1111
                shell = arg
1097 1112
            when '--parallel'
1098 1113
                single_host = false
1099
            when '--detach-snap'
1100
                detach_snap = true
1114
            when '--default-snapshots'
1115
                snapshots_strategy = arg.to_sym
1101 1116
            when '--live-snapshots'
1102
                live_snapshots = arg.split(',')
1117
                live_snapshots = true
1103 1118
        end
1104 1119
    end
1105 1120
rescue Exception => e
......
1113 1128
end
1114 1129

  
1115 1130
exec_driver = ExecDriver.new(hypervisor,
1116
                :concurrency => threads,
1117
                :retries => retries,
1118
                :local_actions => local_actions,
1119
                :shell => shell,
1120
                :single_host => single_host,
1121
                :detach_snap => detach_snap,
1122
                :live_snapshots => live_snapshots)
1131
                :concurrency        => threads,
1132
                :retries            => retries,
1133
                :local_actions      => local_actions,
1134
                :shell              => shell,
1135
                :single_host        => single_host,
1136
                :snapshots_strategy => snapshots_strategy,
1137
                :live_snapshots     => live_snapshots)
1123 1138

  
1124 1139
exec_driver.start_driver

Also available in: Unified diff