Statistics
| Branch: | Tag: | Revision:

one / src / tm_mad / vcenter / delete @ 95fc9267

History | View | Annotate | Download (8.63 KB)

1
#!/usr/bin/env ruby
2

    
3
# ---------------------------------------------------------------------------- #
4
# Copyright 2002-2017, OpenNebula Project, OpenNebula Systems                  #
5
#                                                                              #
6
# Licensed under the Apache License, Version 2.0 (the "License"); you may      #
7
# not use this file except in compliance with the License. You may obtain      #
8
# a copy of the License at                                                     #
9
#                                                                              #
10
# http://www.apache.org/licenses/LICENSE-2.0                                   #
11
#                                                                              #
12
# Unless required by applicable law or agreed to in writing, software          #
13
# distributed under the License is distributed on an "AS IS" BASIS,            #
14
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.     #
15
# See the License for the specific language governing permissions and          #
16
# limitations under the License.                                               #
17
# ---------------------------------------------------------------------------- #
18

    
19
# DELETE <host:remote_system_ds/disk.i|host:remote_system_ds/> vmid dsid
20
#   - host is the target host to deploy the VM
21
#   - remote_system_ds is the path for the system datastore in the host
22
#   - vmid is the id of the VM
23
#   - dsid is the target datastore (0 is the system datastore)
24
# ---------------------------------------------------------------------------- #
25

    
26
ONE_LOCATION=ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION)
27

    
28
if !ONE_LOCATION
29
    RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
30
else
31
    RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
32
end
33

    
34
$: << RUBY_LIB_LOCATION
35
$: << File.dirname(__FILE__)
36

    
37
require 'vcenter_driver'
38

    
39
VM_PREFIX_DEFAULT = "one-$i-"
40

    
41
path = ARGV[0]
42
vmid = ARGV[1]
43
dsid = ARGV[2]
44

    
45
check_valid path, "path"
46
check_valid vmid, "vmid"
47
check_valid dsid, "dsid"
48

    
49
hostname, img_path = path.split(":")
50

    
51
# Get host ID
52
host = VCenterDriver::VIHelper.find_by_name(OpenNebula::HostPool, hostname)
53
host_id = host['ID']
54

    
55
# Get VM
56
one_vm = VCenterDriver::VIHelper.one_item(OpenNebula::VirtualMachine, vmid)
57
vm_ref = one_vm['DEPLOY_ID']
58

    
59
vm = nil
60

    
61
begin
62
    vi_client = VCenterDriver::VIClient.new_from_host(host_id)
63

    
64
    if !!vm_ref && !vm_ref.empty?
65
        vm = VCenterDriver::VirtualMachine.new_from_ref(vm_ref, vi_client)
66
    else
67
        vcenter_vm = VCenterDriver::VIHelper.find_vcenter_vm_by_name(one_vm, host, vi_client)
68

    
69
        # If no VM object retrieved, raise an exception
70
        raise "Could not find the undeployed VM in vCenter's inventory using it's name" if !vcenter_vm
71

    
72
        vm_ref = vcenter_vm._ref
73
        vm = VCenterDriver::VirtualMachine.new_from_ref(vm_ref, vi_client)
74
    end
75
rescue Exception => e
76
    vi_client.close_connection if vi_client
77

    
78
    STDERR.puts "Error obtaining the vCenter client and VM object."\
79
                " Reason: #{e.message}\n#{e.backtrace}"
80
    exit -1
81
end
82

    
83
if path.match(/disk\.\d+$/)
84
    # Detach and remove the disk (if it is not a CDROM)
85

    
86
    # Get DS ref
87
    dsid = img_path.split("/")[-3] # get dsid from path
88
    one_ds = VCenterDriver::VIHelper.one_item(OpenNebula::Datastore, dsid)
89
    ds_ref = one_ds['TEMPLATE/VCENTER_DS_REF']
90

    
91
    # Get disk info
92
    disk_id = img_path.split(".")[-1]
93
    disk = one_vm.retrieve_xmlelements("TEMPLATE/DISK[DISK_ID=#{disk_id}]").first
94

    
95
    begin
96
        if !vm.has_snapshots?
97

    
98
            vm.one_item = one_vm
99

    
100
            # Don't do a detach if unmanaged disks and state is terminate (EPILOG)
101
            unless one_vm["LCM_STATE"].to_i == 11 && disk["OPENNEBULA_MANAGED"] && disk["OPENNEBULA_MANAGED"].upcase == "NO"
102

    
103
                # Detach disk
104
                ds_ref, img_path = vm.detach_disk(disk)
105

    
106
                # If disk was already detached we have no way to remove it
107
                if ds_ref && img_path && !img_path.empty?
108
                    ds = VCenterDriver::Datastore.new_from_ref(ds_ref, vi_client)
109

    
110
                    # delete the disk if it's not a CDROM (CLONE=NO)
111
                    if disk["CLONE"].nil? || disk["CLONE"] == "YES"
112

    
113
                        search_params = ds.get_search_params(ds['name'],
114
                                                            File.dirname(img_path),
115
                                                            File.basename(img_path))
116

    
117
                        # Perform search task and return results
118
                        begin
119
                            search_task = ds['browser'].SearchDatastoreSubFolders_Task(search_params)
120
                            search_task.wait_for_completion
121

    
122
                            ds.delete_virtual_disk(img_path)
123
                            img_dir = File.dirname(img_path)
124
                            ds.rm_directory(img_dir) if ds.dir_empty?(img_dir)
125

    
126
                        rescue Exception => e
127
                            if !e.message.start_with?('FileNotFound')
128
                                raise e.message # Ignore FileNotFound
129
                            end
130
                        end
131
                    end
132
                end
133
            end
134
        end
135

    
136
    rescue Exception => e
137
        message = "Error delete virtual disk #{img_path} in datastore #{dsid}."\
138
                  " Reason: #{e.message}\n#{e.backtrace}"
139
        STDERR.puts error_message(message)
140
        exit -1
141
    ensure
142
        vi_client.close_connection if vi_client
143
    end
144
else
145
    # Remove the VM
146
    begin
147

    
148
        # All OpenNebula managed disks have been detached unless it has snapshots.
149
        # The VM may have still unmanaged disks that belong to the template
150
        # (OPENNEBULA_MANAGED disks). These disks will be deleted with the destroy
151
        # operation. If the user wants to save them, it can be done using the
152
        # disk-saveas operation.
153

    
154
        vm.poweroff_hard if vm.is_powered_on?
155

    
156
        # If the VM has snapshots the TM could not detach disks so we
157
        # will try to detach persistent disks once we have removed all snapshots
158
        # that way they won't be removed. If the vm has been marked as template
159
        # persistent disks shouldn't be detached
160
        vm.remove_all_snapshots if vm.has_snapshots?
161

    
162
        disks = one_vm.retrieve_xmlelements("TEMPLATE/DISK")
163
        if vm.has_snapshots? || vm.instantiated_as_persistent?
164
            disks.each do |d|
165
                if d["PERSISTENT"] == "YES"
166
                    vm.detach_disk(d)
167
                else
168
                    # Remove any disk that is not unmanaged from the VM if
169
                    # instantiate as persistent was set
170
                    if vm.instantiated_as_persistent? &&
171
                    (!d["OPENNEBULA_MANAGED"] || d["OPENNEBULA_MANAGED"].upcase != "NO")
172
                        vm.detach_disk(d)
173
                    end
174
                end
175
            end
176
        end
177

    
178
        # If the VM was instantiated to persistent keep the VM
179
        if vm.instantiated_as_persistent?
180

    
181
            # Remove the MAC addresses so they cannot be in conflict
182
            # with OpenNebula assigned mac addresses.
183

    
184
            # We detach all nics from the VM
185
            vm.detach_all_nics
186

    
187
            # We attach new NICs where the MAC address is assigned by vCenter
188
            nic_specs = []
189
            nics = one_vm.retrieve_xmlelements("TEMPLATE/NIC")
190
            nics.each do |nic|
191
                if (nic["OPENNEBULA_MANAGED"] && nic["OPENNEBULA_MANAGED"].upcase == "NO")
192
                    nic_specs << vm.calculate_add_nic_spec_autogenerate_mac(nic)
193
                end
194
            end
195

    
196
            # Reconfigure VM to add unmanaged nics
197
            spec_hash = {}
198
            spec_hash[:deviceChange] = nic_specs
199
            spec = RbVmomi::VIM.VirtualMachineConfigSpec(spec_hash)
200
            vm.item.ReconfigVM_Task(:spec => spec).wait_for_completion
201

    
202
            # Convert VM to template in vCenter
203
            vm.mark_as_template
204

    
205
            # Edit the Opennebula template
206
            one_client = OpenNebula::Client.new
207
            template_id = vm.one_item['TEMPLATE/TEMPLATE_ID']
208
            new_template = OpenNebula::Template.new_with_id(template_id, one_client)
209
            new_template.info
210

    
211
            # Update the template reference
212
            new_template.update("VCENTER_TEMPLATE_REF= #{vm.item._ref}", true)
213

    
214
        else
215
            # Destroy the VM and remaining disks
216
            vm.destroy
217
        end
218

    
219
    rescue Exception => e
220
        message = "Error unregistering vm #{vmid} (#{vm_ref})."\
221
                  " Reason: #{e.message}\n#{e.backtrace}"
222
        STDERR.puts error_message(message)
223
        exit -1
224
    ensure
225
        vi_client.close_connection if vi_client
226
    end
227
end