Class: VCenterDriver::FileHelper

Inherits:
Object
  • Object
show all
Defined in:
lib/file_helper.rb

Overview

Class FileHelper

Class Method Summary collapse

Class Method Details

.download_vmdks(files_to_download, url_prefix, temp_folder, ds) ⇒ Object



230
231
232
233
234
235
236
237
238
239
# File 'lib/file_helper.rb', line 230

def self.download_vmdks(files_to_download, url_prefix, temp_folder, ds)
    # Download files
    url_prefix += '/'

    VCenterDriver::VIClient.in_silence do
        files_to_download.each do |file|
            ds.download_file(url_prefix + file, temp_folder + file)
        end
    end
end

.dump_vmdk_tar_gz(vcenter_url, ds) ⇒ Object

Receives a VMDK descriptor or file, downloads all related files, creates a tar.gz and dumps it in stdout



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
# File 'lib/file_helper.rb', line 243

def self.dump_vmdk_tar_gz(vcenter_url, ds)
    image_source = vcenter_url.host + vcenter_url.path
    if ds.descriptor?(image_source)
        files_to_download =
            get_all_filenames_in_descriptor(
                vcenter_url,
                ds
            )

        descriptor_name = File.basename vcenter_url.path
        temp_folder = VAR_LOCATION + '/vcenter/' + descriptor_name + '/'
        unless File.directory?(temp_folder)
            FileUtils
                .mkdir_p(
                    temp_folder
                )
        end

        image_path = File.dirname(vcenter_url.host+vcenter_url.path)
        download_vmdks(files_to_download, image_path, temp_folder, ds)

        # Create tar.gz
        rs = system(
            "cd #{temp_folder} \&& tar czf #{descriptor_name}.tar.gz \
            #{files_to_download.join(' ')} > /dev/null 2>&1"
        )
        unless rs
            FileUtils.rm_rf temp_folder
            raise "Error creating tar file for #{descriptor_name}"
        end

        # Cat file to stdout
        rs = system("cat #{temp_folder + descriptor_name}.tar.gz")
        unless rs
            FileUtils.rm_rf temp_folder
            raise "Error reading tar for #{descriptor_name}"
        end

        # Delete tar.gz
        rs = system(
            "cd #{temp_folder} \
            && rm #{descriptor_name}.tar.gz #{
                files_to_download
                .join(' ')}"
        )
        unless rs
            FileUtils.rm_rf temp_folder
            raise "Error removing tar for #{descriptor_name}"
        end
    else
        # Setting "." as the source will read from the stdin
        VCenterDriver::VIClient.in_stderr_silence do
            descriptor_name = File.basename vcenter_url.path
            file_to_download = [vcenter_url.path]
            temp_folder =
                VAR_LOCATION + '/vcenter/' + descriptor_name + '/'

            unless File
                   .directory?(
                       temp_folder + File
                       .dirname(
                           vcenter_url
                           .path
                       ) + '/'
                   )
                FileUtils
                    .mkdir_p(temp_folder + File
                    .dirname(
                        vcenter_url
                        .path
                    ) + '/')
            end

            download_vmdks(
                file_to_download,
                vcenter_url.host,
                temp_folder,
                ds
            )

            temp_folder += File.dirname(vcenter_url.path)

            # Create tar.gz
            rs = system(
                "cd #{temp_folder} && tar czf #{descriptor_name}.tar.gz\
                 #{descriptor_name} > /dev/null 2>&1"
            )
            unless rs
                (
                    FileUtils
                    .rm_rf(
                        temp_folder
                    )
                    raise "Error creating tar \
                    file for #{descriptor_name}")
            end

            # Cat file to stdout
            rs = system(
                "cat #{temp_folder + '/' + descriptor_name}.tar.gz"
            )
            unless rs
                (
                    FileUtils
                    .rm_rf(
                        temp_folder
                    )
                    raise "Error reading tar for #{descriptor_name}")
            end # rubocop:disable Style/Semicolon

            # Delete tar.gz
            rs = system(
                "cd #{temp_folder} \
                && rm #{descriptor_name}.tar.gz #{descriptor_name}"
            )
            unless rs
                (
                    FileUtils
                    .rm_rf(
                        temp_folder
                    )
                    raise "Error removing tar for #{descriptor_name}")
            end # rubocop:disable Style/Semicolon
        end
    end
end

.escape_path(path) ⇒ Object



191
192
193
# File 'lib/file_helper.rb', line 191

def self.escape_path(path)
    path.gsub(' ', '%20')
end

.from_s3?(file) ⇒ Boolean

Returns:

  • (Boolean)


84
85
86
# File 'lib/file_helper.rb', line 84

def self.from_s3?(file)
    file.match(%r{^s3?://})
end

.get_all_filenames_in_descriptor(descriptor_url, ds) ⇒ Object

Recursively downloads vmdk related files and returns filenames



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/file_helper.rb', line 200

def self.get_all_filenames_in_descriptor(descriptor_url, ds)
    descriptor_filename = File.basename descriptor_url.path
    # Build array of files to download
    files_to_download = [descriptor_filename]
    image_source = descriptor_url.host + descriptor_url.path
    descriptor_content = ds.get_text_file image_source
    flat_files = descriptor_content.select {|l| l.start_with?('RW') }
    flat_files.each do |file|
        # Get the filename from lines of type
        # RW 2048000 VMFS "filename-flat.vdmdk"
        file_to_download = file.split(' ')[3][1..-2]
        files_to_download << file_to_download
        image_path =
            File
            .dirname(
                descriptor_url.host+descriptor_url.path
            )
        next unless ds.descriptor?(
            image_path + '/' + file_to_download
        )

        files_to_download <<
            download_all_filenames_in_descriptor(
                image_path + '/' + file_to_download
            )
    end

    files_to_download
end

.get_img_name(disk, vm_id, _vm_name, instantiate_as_persistent = false) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/file_helper.rb', line 43

def self.get_img_name(
    disk,
    vm_id,
    _vm_name,
    instantiate_as_persistent = false
)
    if disk['PERSISTENT'] == 'YES' || disk['TYPE'] == 'CDROM'
        disk['SOURCE']
    else
        disk_id = disk['DISK_ID']
        if disk['SOURCE']
            if instantiate_as_persistent &&
               disk['OPENNEBULA_MANAGED'] &&
               disk['OPENNEBULA_MANAGED'].upcase == 'NO'
                disk['SOURCE'] # Treat this disk as if was persistent
            else
                image_name = disk['SOURCE'].split('.').first
                "#{image_name}-#{vm_id}-#{disk_id}.vmdk"
            end
        else
            ds_volatile_dir =
                disk['VCENTER_DS_VOLATILE_DIR'] || 'one-volatile'
            "#{ds_volatile_dir}/#{vm_id}/one-#{vm_id}-#{disk_id}.vmdk"
        end
    end
end

.get_img_name_from_path(path, vm_id, disk_id) ⇒ Object

REMOVE: no need to change…



71
72
73
74
# File 'lib/file_helper.rb', line 71

def self.get_img_name_from_path(path, vm_id, disk_id)
    # NOTE: This will probably fail if the basename contains '.'
    "#{path.split('.').first}-#{vm_id}-#{disk_id}.vmdk"
end

.get_type(file) ⇒ Object



100
101
102
103
104
105
106
107
# File 'lib/file_helper.rb', line 100

def self.get_type(file)
    type = `file -P bytes=256 -b --mime-type #{file}`
    if $?.exitstatus != 0 # rubocop:disable Style/SpecialGlobalVars
        STDERR.puts "Can not read file #{file}"
        exit(-1)
    end
    type.strip
end

.iso?(file) ⇒ Boolean

Returns:

  • (Boolean)


94
95
96
97
98
# File 'lib/file_helper.rb', line 94

def self.iso?(file)
    type = `file #{file}`

    type.include? 'ISO'
end

.needs_unpack?(file_path) ⇒ Boolean

Returns:

  • (Boolean)


109
110
111
112
113
# File 'lib/file_helper.rb', line 109

def self.needs_unpack?(file_path)
    type = get_type(file_path)
    type.gsub!(%r{^application/(x-)?}, '')
    ['bzip2', 'gzip', 'tar'].include?(type)
end

.remote?(file) ⇒ Boolean

Returns:

  • (Boolean)


80
81
82
# File 'lib/file_helper.rb', line 80

def self.remote?(file)
    file.match(%r{^https?://}) || file.match(%r{^s3?://})
end

.remote_or_needs_unpack?(file) ⇒ Boolean

Returns:

  • (Boolean)


76
77
78
# File 'lib/file_helper.rb', line 76

def self.remote_or_needs_unpack?(file)
    !remote?(file).nil? || needs_unpack?(file)
end

.sanitize(text) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/file_helper.rb', line 30

def self.sanitize(text)
    # Bad as defined by wikipedia:
    # https://en.wikipedia.org/wiki/Filename in
    # Reserved_characters_and_words
    # Also have to escape the backslash
    bad_chars = ['/', '\\', '?', '%', '*', ':',
                 '|', '"', '<', '>', '.', ' ']
    bad_chars.each do |bad_char|
        text.gsub!(bad_char, '_')
    end
    text
end

.unescape_path(path) ⇒ Object



195
196
197
# File 'lib/file_helper.rb', line 195

def self.unescape_path(path)
    path.gsub('%20', ' ')
end

.vcenter_file_info(file_path) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/file_helper.rb', line 115

def self.vcenter_file_info(file_path)
    if File.directory?(file_path)
        files = Dir["#{file_path}/*.vmdk"]
        found = false
        count = 0
        last  = nil

        files.each do |f|
            if get_type(f).strip == 'text/plain'
                file_path = f
                found = true
                break
            else
                count += 1
                last = f
            end
        end

        if !found
            if count == 1
                file_path = last
                found = true
            else
                STDERR.puts 'Could not find vmdk'
                exit(-1)
            end
        end
    end

    case get_type(file_path).strip
    when 'application/octet-stream'
        {
            :type   => :standalone,
            :file   => file_path,
            :dir    => File.dirname(file_path)
        }
    when 'application/x-iso9660-image'
        {
            :type   => :standalone,
            :file   => file_path,
            :dir    => File.dirname(file_path),
            :extension => '.iso'
        }
    when 'text/plain'
        info = {
            :type   => :flat,
            :file   => file_path,
            :dir    => File.dirname(file_path)
        }

        files_list = []
        descriptor = File.read(file_path).split("\n")
        flat_files = descriptor.select {|l| l.start_with?('RW') }

        flat_files.each do |f|
            files_list <<
                info[:dir] +
                '/' +
                f
                .split(' ')[3]
                .chomp
                .chomp('"')
                .reverse
                .chomp('"')
                .reverse
        end

        info[:flat_files] = files_list

        info
    else
        STDERR.puts 'Unrecognized file type'
        exit(-1)
    end
end

.vmdk?(file) ⇒ Boolean

Returns:

  • (Boolean)


88
89
90
91
92
# File 'lib/file_helper.rb', line 88

def self.vmdk?(file)
    type = `file #{file}`

    type.include? 'VMware'
end