prm 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/prm +8 -1
- data/lib/prm/repo.rb +212 -9
- metadata +18 -4
data/bin/prm
CHANGED
@@ -10,7 +10,7 @@ rescue LoadError
|
|
10
10
|
require 'prm'
|
11
11
|
end
|
12
12
|
|
13
|
-
version_info = "0.1.
|
13
|
+
version_info = "0.1.3"
|
14
14
|
|
15
15
|
class Main < Clamp::Command
|
16
16
|
option ["-t", "--type"], "TYPE", "Type of repo to create", :required => true
|
@@ -22,10 +22,14 @@ class Main < Clamp::Command
|
|
22
22
|
option ["--secretkey"], "SECRET KEY", "DHO/S3 Secret Key", :default => false
|
23
23
|
option ["-d", "--directory"], "DIRECTORY", "Move packages from directory to target", :default => false
|
24
24
|
option ["-s", "--snapshot"], "COMPONENT", "Creates a snapshot of a component", :default => false
|
25
|
+
option ["-e", "--recent"], :flag, "Snapshot the most recent unique packages"
|
25
26
|
option ["-k", "--gpg"], :flag, "Sign release files with users GPG key", :default => false
|
26
27
|
option ["-g", "--generate"], :flag , "Generate new repository"
|
27
28
|
|
28
29
|
def execute
|
30
|
+
if recent? && !snapshot
|
31
|
+
raise "--snapshot is required for --recent\n"
|
32
|
+
end
|
29
33
|
r = PRM::Repo.new
|
30
34
|
r.component = component
|
31
35
|
r.release = release
|
@@ -44,6 +48,9 @@ class Main < Clamp::Command
|
|
44
48
|
unless snapshot.nil?
|
45
49
|
r.snapshot = snapshot
|
46
50
|
end
|
51
|
+
if recent?
|
52
|
+
r.recent = recent?
|
53
|
+
end
|
47
54
|
unless directory.nil?
|
48
55
|
r.directory = directory
|
49
56
|
end
|
data/lib/prm/repo.rb
CHANGED
@@ -2,11 +2,155 @@ require 'rubygems'
|
|
2
2
|
require 'fileutils'
|
3
3
|
require 'zlib'
|
4
4
|
require 'digest/md5'
|
5
|
+
require 'digest/sha2'
|
5
6
|
require 'erb'
|
6
7
|
require 'find'
|
7
8
|
require 'thread'
|
8
9
|
require 'peach'
|
9
10
|
require 'aws/s3'
|
11
|
+
require 'arr-pm'
|
12
|
+
|
13
|
+
module Redhat
|
14
|
+
def build_rpm_repo(path,arch,release,gpg,silent)
|
15
|
+
release.each { |r|
|
16
|
+
arch.each { |a|
|
17
|
+
orgpath = path
|
18
|
+
path = path + "/repodata/"
|
19
|
+
FileUtils.mkpath(path)
|
20
|
+
timestamp = Time.now.to_i
|
21
|
+
package_hash = Hash.new
|
22
|
+
|
23
|
+
template_dir = File.join(File.dirname(__FILE__), "..", "..", "templates")
|
24
|
+
|
25
|
+
erb_files = %w{
|
26
|
+
filelists
|
27
|
+
other
|
28
|
+
primary
|
29
|
+
}
|
30
|
+
|
31
|
+
Dir.glob("#{orgpath}/*.rpm").peach do |rpm|
|
32
|
+
sha256sum = ''
|
33
|
+
sha256_path = "#{orgpath}/sha256_results"
|
34
|
+
unless File.directory?(sha256_path)
|
35
|
+
FileUtils.mkdir(sha256_path)
|
36
|
+
end
|
37
|
+
trpm = rpm.split('/').last
|
38
|
+
if File.exists?("#{sha256_path}/#{trpm}")
|
39
|
+
file = File.open("#{sha256_path}/#{trpm}", 'r')
|
40
|
+
sha256sum = file.read
|
41
|
+
file.close
|
42
|
+
else
|
43
|
+
sha256sum = Digest::SHA256.file(rpm).hexdigest
|
44
|
+
File.open("#{sha256_path}/#{trpm}", 'w') { |file| file.write(sha256sum) }
|
45
|
+
end
|
46
|
+
|
47
|
+
nrpm = RPM::File.new(rpm)
|
48
|
+
sheader = nrpm.lead.length + nrpm.signature.length
|
49
|
+
eheader = sheader + nrpm.header.length
|
50
|
+
|
51
|
+
info = Hash[*nrpm.header.tags.collect { |t| [t.tag, t.value] }.inject([]) { |m,v| m + v }]
|
52
|
+
package_hash[trpm] = {
|
53
|
+
"sha256" => sha256sum,
|
54
|
+
"name" => info[:name],
|
55
|
+
"arch" => info[:arch],
|
56
|
+
"version" => info[:version],
|
57
|
+
"release" => info[:release],
|
58
|
+
"start_header" => sheader,
|
59
|
+
"end_header" => eheader,
|
60
|
+
"files" => nrpm.files,
|
61
|
+
"license" => info[:license],
|
62
|
+
"vendor" => info[:vendor],
|
63
|
+
"buildtime" => info[:buildtime],
|
64
|
+
"buildhost" => info[:buildhost],
|
65
|
+
"requires" => nrpm.requires,
|
66
|
+
"conflicts" => nrpm.conflicts,
|
67
|
+
"provides" => nrpm.provides,
|
68
|
+
"epoch" => info[:epochnum],
|
69
|
+
"sourcerpm" => info[:sourcerpm],
|
70
|
+
"buildtime" => info[:buildtime],
|
71
|
+
"installtime" => info[:installtime],
|
72
|
+
"url" => info[:url],
|
73
|
+
"summary" => info[:summary],
|
74
|
+
"description" => info[:description],
|
75
|
+
"packager" => info[:packager],
|
76
|
+
"size" => info[:size],
|
77
|
+
"longsize" => info[:longsize],
|
78
|
+
"filesizes" => info[:filesizes]
|
79
|
+
}
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
xml_hash = Hash.new()
|
84
|
+
xml_hash = {
|
85
|
+
"filelists" => {
|
86
|
+
"xml" => "",
|
87
|
+
"gz" => "",
|
88
|
+
"size" => "",
|
89
|
+
"osize" => "",
|
90
|
+
},
|
91
|
+
"other" => {
|
92
|
+
"xml" => "",
|
93
|
+
"gz" => "",
|
94
|
+
"size" => "",
|
95
|
+
"osize" => "",
|
96
|
+
},
|
97
|
+
"primary" => {
|
98
|
+
"xml" => "",
|
99
|
+
"gz" => "",
|
100
|
+
"size" => "",
|
101
|
+
"osize" => "",
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
erb_files.each { |f|
|
106
|
+
erb = ERB.new(File.open("#{template_dir}/#{f}.xml.erb") { |file|
|
107
|
+
file.read
|
108
|
+
}).result(binding)
|
109
|
+
|
110
|
+
release_file = File.new("#{path}/#{f}.xml.tmp","wb")
|
111
|
+
release_file.puts erb
|
112
|
+
release_file.close
|
113
|
+
|
114
|
+
Zlib::GzipWriter.open("#{path}/#{f}.xml.tmp.gz") do |gz|
|
115
|
+
ff = File.new("#{path}/#{f}.xml.tmp", "r")
|
116
|
+
ff.each do |line|
|
117
|
+
gz.write(line)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
}
|
121
|
+
|
122
|
+
erb_files.each { |f|
|
123
|
+
xml_hash[f]["gz"] = Digest::SHA256.file("#{path}/#{f}.xml.tmp.gz").hexdigest
|
124
|
+
xml_hash[f]["xml"] = Digest::SHA256.file("#{path}/#{f}.xml.tmp").hexdigest
|
125
|
+
xml_hash[f]["size"] = File.size?("#{path}/#{f}.xml.tmp.gz")
|
126
|
+
xml_hash[f]["osize"] = File.size?("#{path}/#{f}.xml.tmp")
|
127
|
+
}
|
128
|
+
|
129
|
+
erb_two = ERB.new(File.open("#{template_dir}/repomd.xml.erb") { |file|
|
130
|
+
file.read
|
131
|
+
}).result(binding)
|
132
|
+
|
133
|
+
r_file = File.new("#{path}/repomd.xml.tmp","wb")
|
134
|
+
r_file.puts erb_two
|
135
|
+
r_file.close
|
136
|
+
|
137
|
+
Dir.glob("#{path}/*.gz") do |f|
|
138
|
+
if f =~ /gz$/
|
139
|
+
unless f =~ /tmp\.gz$/
|
140
|
+
FileUtils.rm(f)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
erb_files.each { |f|
|
146
|
+
FileUtils.move("#{path}/#{f}.xml.tmp.gz", "#{path}/" + xml_hash[f]["gz"] + "-#{f}.xml.gz")
|
147
|
+
FileUtils.rm("#{path}/#{f}.xml.tmp")
|
148
|
+
}
|
149
|
+
FileUtils.move("#{path}/repomd.xml.tmp", "#{path}/repomd.xml")
|
150
|
+
}
|
151
|
+
}
|
152
|
+
end
|
153
|
+
end
|
10
154
|
|
11
155
|
module Debian
|
12
156
|
def build_apt_repo(path, component, arch, release, gpg, silent)
|
@@ -183,7 +327,7 @@ module Debian
|
|
183
327
|
end
|
184
328
|
|
185
329
|
module SNAP
|
186
|
-
def snapshot_to(path,component,release,snapname,type)
|
330
|
+
def snapshot_to(path,component,release,snapname,type,recent)
|
187
331
|
if type != "deb"
|
188
332
|
puts "Only deb supported"
|
189
333
|
return
|
@@ -194,7 +338,15 @@ module SNAP
|
|
194
338
|
now = time.strftime("%Y-%m-%d-%H-%M")
|
195
339
|
new_snap = "#{snapname}-#{now}"
|
196
340
|
|
197
|
-
|
341
|
+
|
342
|
+
component.each do |c|
|
343
|
+
if !File.exists?("#{path}/dists/#{r}/#{c}")
|
344
|
+
puts "Component doesn't exist! To snapshot you need to have an existing component\n"
|
345
|
+
return
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
if File.exists?("#{path}/dists/#{r}/#{snapname}") && !File.symlink?("#{path}/dists/#{r}/#{snapname}")
|
198
350
|
puts "Snapshot target is a filesystem, remove it or rename your snap target"
|
199
351
|
return
|
200
352
|
end
|
@@ -203,9 +355,56 @@ module SNAP
|
|
203
355
|
Dir.mkdir("#{path}/dists/#{r}/#{new_snap}")
|
204
356
|
end
|
205
357
|
|
206
|
-
|
207
|
-
|
208
|
-
|
358
|
+
if File.exists?("#{path}/dists/#{r}/#{snapname}")
|
359
|
+
FileUtils.rm("#{path}/dists/#{r}/#{snapname}")
|
360
|
+
end
|
361
|
+
|
362
|
+
if recent
|
363
|
+
component.each do |c|
|
364
|
+
arch.each do |a|
|
365
|
+
source_dir = "#{path}/dists/#{r}/#{c}/binary-#{a}"
|
366
|
+
target_dir = "#{path}/dists/#{r}/#{new_snap}/binary-#{a}"
|
367
|
+
pfiles = Dir.glob("#{source_dir}/*").sort_by { |f| File.mtime(f) }
|
368
|
+
|
369
|
+
package_hash = Hash.new
|
370
|
+
pfiles.each do |p|
|
371
|
+
file = p.split(/[_]/)
|
372
|
+
mtime = File.mtime(p)
|
373
|
+
date_in_mil = mtime.to_f
|
374
|
+
|
375
|
+
if !package_hash.has_key?(file[0])
|
376
|
+
package_hash[file[0]] = { "name" => p, "time" => date_in_mil }
|
377
|
+
else
|
378
|
+
if date_in_mil > package_hash[file[0]]["time"]
|
379
|
+
package_hash[file[0]] = { "name" => p, "time" => date_in_mil }
|
380
|
+
end
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
if !File.exists?(target_dir)
|
385
|
+
FileUtils.mkdir_p(target_dir)
|
386
|
+
end
|
387
|
+
|
388
|
+
package_hash.each do |key,value|
|
389
|
+
value["name"].each do |k|
|
390
|
+
target_file = k.split("/").last
|
391
|
+
FileUtils.cp(k, "#{target_dir}/#{target_file}")
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
end
|
396
|
+
|
397
|
+
FileUtils.ln_s "#{new_snap}", "#{path}/dists/#{r}/#{snapname}", :force => true
|
398
|
+
puts "Created #{snapname} snapshot of #{component} with --recent flag\n"
|
399
|
+
end
|
400
|
+
else
|
401
|
+
FileUtils.cp_r(Dir["#{path}/dists/#{r}/#{component}/*"], "#{path}/dists/#{r}/#{new_snap}")
|
402
|
+
if File.exists?("#{path}/dists/#{r}/#{snapname}")
|
403
|
+
FileUtils.rm("#{path}/dists/#{r}/#{snapname}")
|
404
|
+
end
|
405
|
+
FileUtils.ln_s "#{new_snap}", "#{path}/dists/#{r}/#{snapname}", :force => true
|
406
|
+
puts "Created #{snapname} snapshot of #{component}\n"
|
407
|
+
end
|
209
408
|
end
|
210
409
|
end
|
211
410
|
end
|
@@ -265,6 +464,7 @@ module PRM
|
|
265
464
|
include Debian
|
266
465
|
include DHO
|
267
466
|
include SNAP
|
467
|
+
include Redhat
|
268
468
|
|
269
469
|
attr_accessor :path
|
270
470
|
attr_accessor :type
|
@@ -276,13 +476,13 @@ module PRM
|
|
276
476
|
attr_accessor :accesskey
|
277
477
|
attr_accessor :snapshot
|
278
478
|
attr_accessor :directory
|
479
|
+
attr_accessor :recent
|
279
480
|
|
280
481
|
def create
|
281
|
-
parch,pcomponent,prelease = _parse_vars(arch,component,release)
|
282
|
-
|
283
482
|
if "#{@type}" == "deb"
|
483
|
+
parch,pcomponent,prelease = _parse_vars(arch,component,release)
|
284
484
|
if snapshot
|
285
|
-
snapshot_to(path,pcomponent,prelease,snapshot,type)
|
485
|
+
snapshot_to(path,pcomponent,prelease,snapshot,type,recent)
|
286
486
|
else
|
287
487
|
if directory
|
288
488
|
silent = true
|
@@ -297,7 +497,10 @@ module PRM
|
|
297
497
|
elsif "#{@type}" == "sync"
|
298
498
|
sync_to_dho(path, accesskey, secretkey,pcomponent,prelease)
|
299
499
|
elsif "#{@type}" == "rpm"
|
300
|
-
|
500
|
+
component = "test"
|
501
|
+
parch,prelease = _parse_vars(arch,component,release)
|
502
|
+
silent = false
|
503
|
+
build_rpm_repo(path,parch,prelease,gpg,silent)
|
301
504
|
end
|
302
505
|
end
|
303
506
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 29
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 3
|
10
|
+
version: 0.1.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Brett Gailey
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2013-
|
18
|
+
date: 2013-07-15 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -60,6 +60,20 @@ dependencies:
|
|
60
60
|
version: "0"
|
61
61
|
type: :runtime
|
62
62
|
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: arr-pm
|
65
|
+
prerelease: false
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
type: :runtime
|
76
|
+
version_requirements: *id004
|
63
77
|
description: PRM (Package Repository Manager) is an Operating System independent Package Repository tool. PRM supports Repository syncing to DreamObjects
|
64
78
|
email: brett.gailey@dreamhost.com
|
65
79
|
executables:
|