Class: VCAP::Services::Base::AsyncJob::Package

Inherits:
Object
  • Object
show all
Includes:
Error
Defined in:
lib/base/job/package.rb

Constant Summary collapse

MANIFEST_FILE =
"manifest".freeze
CONTENT_FOLDER =
"content".freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Error

#failure, #internal_fail, #parse_msg, #success, #timeout_fail

Constructor Details

#initialize(zipfile, opts = {}) ⇒ Package

Returns a new instance of Package.



24
25
26
27
28
29
# File 'lib/base/job/package.rb', line 24

def initialize(zipfile, opts={})
  @zipfile = zipfile
  @files = {}
  @manifest = {}
  @filemode = opts[:mode] || 0644
end

Instance Attribute Details

#manifestObject

Returns the value of attribute manifest.



13
14
15
# File 'lib/base/job/package.rb', line 13

def manifest
  @manifest
end

Class Method Details

.load(path) ⇒ Object



16
17
18
19
20
21
# File 'lib/base/job/package.rb', line 16

def load path
  raise "File #{path} not exists." unless File.exists? path
  p = new(path)
  p.load_manifest
  p
end

Instance Method Details

#add_files(files) ⇒ Object



31
32
33
34
35
36
37
38
39
# File 'lib/base/job/package.rb', line 31

def add_files(files)
  files =  Array(files)
  files.each do |file|
    raise "File #{file} not found." unless File.exists? file
    raise "File #{file} is not readable." unless File.readable? file
    basename = File.basename file
    @files[basename] = file
  end
end

#load_manifestObject

read manifest in a zip file



105
106
107
108
109
110
# File 'lib/base/job/package.rb', line 105

def load_manifest
  zf = Zip::ZipFile.open(@zipfile)
  @manifest = VCAP.symbolize_keys(Yajl::Parser.parse(zf.read(MANIFEST_FILE)))
rescue Errno::ENOENT => e
  raise ServiceError.new(ServiceError::BAD_SERIALIZED_DATAFILE, "request. Missing manifest.")
end

#pack(force = nil) ⇒ Object

package files and manifest in zipfile. If force is true, we’ll try to delete the target zipfile if it already exists.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/base/job/package.rb', line 49

def pack(force=nil)
  if File.exists? @zipfile
    if force
      File.delete @zipfile
    else
      raise "File #{@zipfile} already exists."
    end
  end

  dirname = File.dirname(@zipfile)
  raise "Dir #{dirname} is not exists." unless File.exists? dirname
  raise "Dir #{dirname} is not writable." unless File.writable? dirname

  Zip::ZipFile.open(@zipfile, Zip::ZipFile::CREATE) do |zf|
    # manifest file
    zf.get_output_stream(MANIFEST_FILE) {|o| o << Yajl::Encoder.encode(@manifest)}

    @files.each do |f, path|
      zf.add("#{CONTENT_FOLDER}/#{f}", path)
    end
  end

  begin
    File.chmod(@filemode, @zipfile)
  rescue => e
    raise "Fail to change the mode of #{@zipfile} to #{@filemode.to_s(8)}: #{e}"
  end
end

#unpack(path) ⇒ Object

unpack the content to path and return extraced file list.



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/base/job/package.rb', line 79

def unpack path
  raise "File #{@zipfile} not exists." unless File.exists? @zipfile
  raise "unpack path: #{path} not found." unless Dir.exists? path
  raise "unpack path: #{path} is not writable." unless File.writable? path

  files = []
  Zip::ZipFile.foreach(@zipfile) do |entry|
    next if entry.to_s == MANIFEST_FILE
    entry_name = File.basename entry.to_s
    dst_path = File.join(path, entry_name)
    dirname = File.dirname(dst_path)
    FileUtils.mkdir_p(dirname) unless File.exists? dirname
    files << dst_path
    entry.extract(dst_path)
  end
  files.freeze
  yield files if block_given?
  files
rescue => e
  # auto cleanup if error raised.
  files.each{|f| File.delete f if File.exists? f} if files
  raise ServiceError.new(ServiceError::FILE_CORRUPTED) if e.is_a? Zlib::DataError
  raise e
end