Class: Deb::S3::Release

Inherits:
Object
  • Object
show all
Includes:
Utils
Defined in:
lib/deb/s3/release.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utils

access_policy, access_policy=, bucket, bucket=, debianize_op, encryption, encryption=, gpg_options, gpg_options=, prefix, prefix=, s3, s3=, s3_escape, s3_exists?, s3_path, s3_read, s3_remove, s3_store, safesystem, signing_key, signing_key=, template

Constructor Details

#initializeRelease

Returns a new instance of Release.



17
18
19
20
21
22
23
24
25
26
# File 'lib/deb/s3/release.rb', line 17

def initialize
  @origin = nil
  @suite = nil
  @codename = nil
  @architectures = []
  @components = []
  @cache_control = ""
  @files = {}
  @policy = :public_read
end

Instance Attribute Details

#architecturesObject

Returns the value of attribute architectures.



10
11
12
# File 'lib/deb/s3/release.rb', line 10

def architectures
  @architectures
end

#cache_controlObject

Returns the value of attribute cache_control.



12
13
14
# File 'lib/deb/s3/release.rb', line 12

def cache_control
  @cache_control
end

#codenameObject

Returns the value of attribute codename.



7
8
9
# File 'lib/deb/s3/release.rb', line 7

def codename
  @codename
end

#componentsObject

Returns the value of attribute components.



11
12
13
# File 'lib/deb/s3/release.rb', line 11

def components
  @components
end

#filesObject

Returns the value of attribute files.



14
15
16
# File 'lib/deb/s3/release.rb', line 14

def files
  @files
end

#originObject

Returns the value of attribute origin.



8
9
10
# File 'lib/deb/s3/release.rb', line 8

def origin
  @origin
end

#policyObject

Returns the value of attribute policy.



15
16
17
# File 'lib/deb/s3/release.rb', line 15

def policy
  @policy
end

#suiteObject

Returns the value of attribute suite.



9
10
11
# File 'lib/deb/s3/release.rb', line 9

def suite
  @suite
end

Class Method Details

.parse_release(str) ⇒ Object



42
43
44
45
46
# File 'lib/deb/s3/release.rb', line 42

def parse_release(str)
  rel = self.new
  rel.parse(str)
  rel
end

.retrieve(codename, origin = nil, suite = nil, cache_control = nil) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/deb/s3/release.rb', line 29

def retrieve(codename, origin=nil, suite=nil, cache_control=nil)
  if s = Deb::S3::Utils.s3_read("dists/#{codename}/Release")
    rel = self.parse_release(s)
  else
    rel = self.new
  end
  rel.codename = codename
  rel.origin = origin unless origin.nil?
  rel.suite = suite unless suite.nil?
  rel.cache_control = cache_control
  rel
end

Instance Method Details

#filenameObject



49
50
51
# File 'lib/deb/s3/release.rb', line 49

def filename
  "dists/#{@codename}/Release"
end

#generateObject



84
85
86
# File 'lib/deb/s3/release.rb', line 84

def generate
  template("release.erb").result(binding)
end

#parse(str) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/deb/s3/release.rb', line 53

def parse(str)
  parse = lambda do |field|
    value = str[/^#{field}: .*/]
    if value.nil?
      return nil
    else
      return value.split(": ",2).last
    end
  end

  # grab basic fields
  self.codename = parse.call("Codename")
  self.origin = parse.call("Origin") || nil
  self.suite = parse.call("Suite") || nil
  self.architectures = (parse.call("Architectures") || "").split(/\s+/)
  self.components = (parse.call("Components") || "").split(/\s+/)

  # find all the hashes
  str.scan(/^\s+([^\s]+)\s+(\d+)\s+(.+)$/).each do |(hash,size,name)|
    self.files[name] ||= { :size => size.to_i }
    case hash.length
    when 32
      self.files[name][:md5] = hash
    when 40
      self.files[name][:sha1] = hash
    when 64
      self.files[name][:sha256] = hash
    end
  end
end

#update_manifest(manifest) ⇒ Object



134
135
136
137
138
# File 'lib/deb/s3/release.rb', line 134

def update_manifest(manifest)
  self.components << manifest.component unless self.components.include?(manifest.component)
  self.architectures << manifest.architecture unless self.architectures.include?(manifest.architecture)
  self.files.merge!(manifest.files)
end

#validate_othersObject



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/deb/s3/release.rb', line 140

def validate_others
  to_apply = []
  self.components.each do |comp|
    %w(amd64 i386 armhf).each do |arch|
      next if self.files.has_key?("#{comp}/binary-#{arch}/Packages")

      m = Deb::S3::Manifest.new
      m.codename = self.codename
      m.component = comp
      m.architecture = arch
      if block_given?
        m.write_to_s3 { |f| yield f }
      else
        m.write_to_s3
      end
      to_apply << m
    end
  end

  to_apply.each { |m| self.update_manifest(m) }
end

#write_to_s3 {|self.filename| ... } ⇒ Object

Yields:



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/deb/s3/release.rb', line 88

def write_to_s3
  # validate some other files are present
  if block_given?
    self.validate_others { |f| yield f }
  else
    self.validate_others
  end

  # generate the Release file
  release_tmp = Tempfile.new("Release")
  release_tmp.puts self.generate
  release_tmp.close
  yield self.filename if block_given?
  s3_store(release_tmp.path, self.filename, 'text/plain; charset=utf-8', self.cache_control)

  # sign the file, if necessary
  if Deb::S3::Utils.signing_key
    key_param = Deb::S3::Utils.signing_key != "" ? "--default-key=#{Deb::S3::Utils.signing_key}" : ""
    if system("gpg -a #{key_param} --digest-algo SHA256 #{Deb::S3::Utils.gpg_options} -s --clearsign #{release_tmp.path}")
      local_file = release_tmp.path+".asc"
      remote_file = "dists/#{@codename}/InRelease"
      yield remote_file if block_given?
      raise "Unable to locate InRelease file" unless File.exists?(local_file)
      s3_store(local_file, remote_file, 'application/pgp-signature; charset=us-ascii', self.cache_control)
      File.unlink(local_file)
    else
      raise "Signing the InRelease file failed."
    end
    if system("gpg -a #{key_param} --digest-algo SHA256 #{Deb::S3::Utils.gpg_options} -b #{release_tmp.path}")
      local_file = release_tmp.path+".asc"
      remote_file = self.filename+".gpg"
      yield remote_file if block_given?
      raise "Unable to locate Release signature file" unless File.exists?(local_file)
      s3_store(local_file, remote_file, 'application/pgp-signature; charset=us-ascii', self.cache_control)
      File.unlink(local_file)
    else
      raise "Signing the Release file failed."
    end
  else
    # remove an existing Release.gpg, if it was there
    s3_remove(self.filename+".gpg")
  end

  release_tmp.unlink
end