mprm 0.9.0
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.
- checksums.yaml +7 -0
- data/bin/mprm +82 -0
- data/lib/mprm.rb +13 -0
- data/lib/mprm/debian.rb +218 -0
- data/lib/mprm/repo.rb +57 -0
- data/lib/mprm/rpm.rb +301 -0
- data/lib/mprm/version.rb +3 -0
- data/templates/deb_release.erb +23 -0
- data/templates/filelists.xml.erb +6 -0
- data/templates/other.xml.erb +6 -0
- data/templates/primary.xml.erb +6 -0
- data/templates/repomd.xml.erb +7 -0
- metadata +99 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f52e3b7d9d1d577ec71b4586c8662444c8bdc480
|
4
|
+
data.tar.gz: 2d9eb4be9a2e97efe3e5498ec6033763bb3677d4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7c8389587a9d105b8cccf6d8f679e27658c805d207471542ffab4b897b5b22a150de32feff41e38c6b8b875c7a58b5c01ff2d02b2e7dfda7fe3c61d4760d9eb6
|
7
|
+
data.tar.gz: ba89fb38852568b28012f0272cae23a1ca74ee7032ce7bda50b34d4eae88ca2af8f561ecda7e3986e81b4c10048ddb1eb9a83a004cd8173ce25745716aea4207
|
data/bin/mprm
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'clamp'
|
4
|
+
require 'mprm'
|
5
|
+
|
6
|
+
class Main < Clamp::Command
|
7
|
+
option ["-v", "--version"], :flag, "Version information"
|
8
|
+
option ["-t", "--type"], "TYPE", "Type of repo to create"
|
9
|
+
option ["-p", "--path"], "PATH", "Path to repo location"
|
10
|
+
option ["-r", "--release"], "RELEASE", "OS version to create"
|
11
|
+
option ["-a", "--arch"], "ARCH", "Architecture of repo contents"
|
12
|
+
option ["-c", "--component"], "COMPONENT", "Component to create [DEB ONLY]"
|
13
|
+
option ["-l", "--label"], "LABEL", "Label for generated repository [DEB ONLY]"
|
14
|
+
option ["-o", "--origin"], "ORIGIN", "Origin for generated repository [DEB ONLY]"
|
15
|
+
option ["--nocache"], :flag, "Don't cache md5 sums [DEB ONLY]"
|
16
|
+
option ["-d", "--directory"], "DIRECTORY", "Move packages from directory to target", :default => false
|
17
|
+
option ["-e", "--recent"], :flag, "Snapshot the most recent unique packages", :default => false
|
18
|
+
option ["-k", "--gpg"], "GPG KEY", "Sign release files with this GPG key", :default => false
|
19
|
+
option ["-x", "--gpg_passphrase"], "GPG PASSPHRASE", "Passphrase for GPG key", :default => false
|
20
|
+
option ["-n", "--gpg_sign_algorithm"], "GPG SIGN ALGORITHM", "Digest algorithm to use for signing (e.g SHA1, SHA512, etc)", :default => "sha256"
|
21
|
+
|
22
|
+
def execute
|
23
|
+
if version?
|
24
|
+
puts "MPRM version: #{MPRM::VERSION}"
|
25
|
+
exit
|
26
|
+
end
|
27
|
+
|
28
|
+
unless type && path && release && arch
|
29
|
+
puts "Type, Path, Release and Arch are required arguments"
|
30
|
+
exit
|
31
|
+
end
|
32
|
+
|
33
|
+
if recent? && !snapshot
|
34
|
+
raise "--snapshot is required for --recent"
|
35
|
+
end
|
36
|
+
|
37
|
+
if type == "deb" && !component
|
38
|
+
raise "--deb option required for the --component option!"
|
39
|
+
end
|
40
|
+
|
41
|
+
r = MPRM::Repo.new
|
42
|
+
r.release = release
|
43
|
+
r.arch = arch
|
44
|
+
r.type = type
|
45
|
+
r.path = path
|
46
|
+
r.label = label
|
47
|
+
r.origin = origin
|
48
|
+
unless upload.nil?
|
49
|
+
r.upload = upload
|
50
|
+
end
|
51
|
+
unless gpg.nil?
|
52
|
+
r.gpg = gpg
|
53
|
+
r.gpg_passphrase = gpg_passphrase
|
54
|
+
r.gpg_sign_algorithm = gpg_sign_algorithm
|
55
|
+
end
|
56
|
+
unless accesskey.nil?
|
57
|
+
r.accesskey = accesskey
|
58
|
+
end
|
59
|
+
unless secretkey.nil?
|
60
|
+
r.secretkey = secretkey
|
61
|
+
end
|
62
|
+
unless snapshot.nil?
|
63
|
+
r.snapshot = snapshot
|
64
|
+
end
|
65
|
+
unless component.nil?
|
66
|
+
r.component = component
|
67
|
+
end
|
68
|
+
if recent?
|
69
|
+
r.recent = recent?
|
70
|
+
end
|
71
|
+
unless directory.nil?
|
72
|
+
r.directory = directory
|
73
|
+
end
|
74
|
+
if nocache?
|
75
|
+
r.nocache = nocache?
|
76
|
+
end
|
77
|
+
|
78
|
+
r.create
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
Main.run
|
data/lib/mprm.rb
ADDED
data/lib/mprm/debian.rb
ADDED
@@ -0,0 +1,218 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'zlib'
|
3
|
+
require 'erb'
|
4
|
+
require 'digest/md5'
|
5
|
+
require 'digest/sha1'
|
6
|
+
require 'digest/sha2'
|
7
|
+
require 'parallel'
|
8
|
+
require 'time'
|
9
|
+
require 'thread'
|
10
|
+
|
11
|
+
module Debian
|
12
|
+
def build_apt_repo(path, component, arch, release, label, origin, gpg, nocache)
|
13
|
+
release.each { |r|
|
14
|
+
component.each { |c|
|
15
|
+
arch.each { |a|
|
16
|
+
fpath = path + "/dists/" + r + "/" + c + "/" + "binary-" + a + "/"
|
17
|
+
pfpath = fpath + "Packages"
|
18
|
+
rfpath = fpath + "Release"
|
19
|
+
|
20
|
+
MPRM.logger.debug "Building Path: #{fpath}"
|
21
|
+
|
22
|
+
FileUtils.mkpath(fpath)
|
23
|
+
FileUtils.touch(pfpath)
|
24
|
+
FileUtils.touch(rfpath)
|
25
|
+
generate_packages_gz(fpath,pfpath,path,rfpath,r,c,a)
|
26
|
+
}
|
27
|
+
}
|
28
|
+
generate_release(path,r,component,arch,label,origin)
|
29
|
+
|
30
|
+
unless gpg == false
|
31
|
+
generate_release_gpg(path,r, gpg)
|
32
|
+
end
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
def move_apt_packages(path,component,arch,release,directory)
|
37
|
+
unless File.exist?(directory)
|
38
|
+
MPRM.logger.debug "ERROR: #{directory} doesn't exist... not doing anything\n"
|
39
|
+
return false
|
40
|
+
end
|
41
|
+
|
42
|
+
files_moved = []
|
43
|
+
release.each { |r|
|
44
|
+
component.each { |c|
|
45
|
+
arch.each { |a|
|
46
|
+
Dir.glob(directory + "/*.deb") do |file|
|
47
|
+
MPRM.logger.debug file
|
48
|
+
if file =~ /^.*#{a}.*\.deb$/i || file =~ /^.*all.*\.deb$/i || file =~ /^.*any.*\.deb$/i
|
49
|
+
if file =~ /^.*#{r}.*\.deb$/i
|
50
|
+
# Lets do this here to help mitigate packages like "asdf-123+wheezy.deb"
|
51
|
+
FileUtils.cp(file, "#{path}/dists/#{r}/#{c}/binary-#{a}/")
|
52
|
+
FileUtils.rm(file)
|
53
|
+
else
|
54
|
+
FileUtils.cp(file, "#{path}/dists/#{r}/#{c}/binary-#{a}/")
|
55
|
+
files_moved << file
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
files_moved.each do |f|
|
64
|
+
if File.exist?(f)
|
65
|
+
FileUtils.rm(f)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
# Regex?
|
69
|
+
#/^.*#{arch}.*\.deb$/i
|
70
|
+
end
|
71
|
+
|
72
|
+
def generate_packages_gz(fpath,pfpath,path,rfpath,r,c,a)
|
73
|
+
MPRM.logger.debug "Generating Packages: #{r} : #{c} : binary-#{a}"
|
74
|
+
|
75
|
+
npath = "dists/" + r + "/" + c + "/" + "binary-" + a + "/"
|
76
|
+
|
77
|
+
d = File.open(pfpath, "w+")
|
78
|
+
write_mutex = Mutex.new
|
79
|
+
|
80
|
+
Parallel.each(Dir.glob("#{fpath}*.deb"), in_threads: 5) do |deb|
|
81
|
+
algs = {
|
82
|
+
'md5' => Digest::MD5.new,
|
83
|
+
'sha1' => Digest::SHA1.new,
|
84
|
+
'sha256' => Digest::SHA256.new
|
85
|
+
}
|
86
|
+
sums = {
|
87
|
+
'md5' => '',
|
88
|
+
'sha1' => '',
|
89
|
+
'sha256' => ''
|
90
|
+
}
|
91
|
+
tdeb = File.basename(deb)
|
92
|
+
init_size = File.size(deb)
|
93
|
+
deb_contents = nil
|
94
|
+
|
95
|
+
FileUtils.mkdir_p "tmp/#{tdeb}/"
|
96
|
+
if not nocache
|
97
|
+
sums.keys.each do |s|
|
98
|
+
sum_path = "#{path}/dists/#{r}/#{c}/binary-#{a}/#{s}-results/#{tdeb}"
|
99
|
+
FileUtils.mkdir_p File.dirname(sum_path)
|
100
|
+
|
101
|
+
if File.exist?(sum_path)
|
102
|
+
stored_sum = File.read(sum_path)
|
103
|
+
sum = stored_sum unless nocache.nil?
|
104
|
+
end
|
105
|
+
|
106
|
+
unless sum
|
107
|
+
deb_contents ||= File.read(deb)
|
108
|
+
sum = algs[s].hexdigest(deb_contents)
|
109
|
+
end
|
110
|
+
|
111
|
+
sums[s] = sum
|
112
|
+
if nocache.nil?
|
113
|
+
File.open(sum_path, 'w') { |f| f.write(sum) }
|
114
|
+
elsif sum != stored_sum
|
115
|
+
MPRM.logger.debug "WARN: #{s}sum mismatch on #{deb}\n"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
`ar p #{deb} control.tar.gz | tar zx -C tmp/#{tdeb}/`
|
120
|
+
|
121
|
+
package_info = [
|
122
|
+
"Filename: #{npath}#{s3_compatible_encode(tdeb)}",
|
123
|
+
"MD5: #{sums['md5']}",
|
124
|
+
"SHA1: #{sums['sha1']}",
|
125
|
+
"SHA256: #{sums['sha256']}",
|
126
|
+
"Size: #{init_size}"
|
127
|
+
]
|
128
|
+
|
129
|
+
write_mutex.synchronize do
|
130
|
+
# Copy the control file data into the Packages list
|
131
|
+
d.write(File.read("tmp/#{tdeb}/control").gsub!(/\n+/, "\n"))
|
132
|
+
d.write(package_info.join("\n"))
|
133
|
+
d.write("\n\n") # blank line between package info in the Packages file
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
FileUtils.rmtree 'tmp/'
|
138
|
+
|
139
|
+
d.close
|
140
|
+
|
141
|
+
Zlib::GzipWriter.open(pfpath + ".gz") do |gz|
|
142
|
+
f = File.new(pfpath, "r")
|
143
|
+
f.each do |line|
|
144
|
+
gz.write(line)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def generate_release(path,release,component,arch,label,origin)
|
150
|
+
date = Time.now.utc
|
151
|
+
|
152
|
+
release_info = {}
|
153
|
+
unreasonable_array = ["Packages", "Packages.gz", "Release"]
|
154
|
+
component_ar = []
|
155
|
+
Dir.glob(path + "/dists/" + release + "/*").select { |f|
|
156
|
+
f.slice!(path + "/dists/" + release + "/")
|
157
|
+
unless f == "Release" or f == "Release.gpg"
|
158
|
+
component_ar << f
|
159
|
+
end
|
160
|
+
}
|
161
|
+
|
162
|
+
component_ar.each do |c|
|
163
|
+
arch.each do |ar|
|
164
|
+
unreasonable_array.each do |unr|
|
165
|
+
tmp_path = "#{path}/dists/#{release}/#{c}/binary-#{ar}"
|
166
|
+
tmp_hash = {}
|
167
|
+
filename = "#{c}/binary-#{ar}/#{unr}".chomp
|
168
|
+
|
169
|
+
byte_size = File.size("#{tmp_path}/#{unr}").to_s
|
170
|
+
file_contents = File.read("#{tmp_path}/#{unr}")
|
171
|
+
|
172
|
+
tmp_hash['size'] = byte_size
|
173
|
+
tmp_hash['md5'] = Digest::MD5.hexdigest(file_contents)
|
174
|
+
tmp_hash['sha1'] = Digest::SHA1.hexdigest(file_contents)
|
175
|
+
tmp_hash['sha256'] = Digest::SHA256.hexdigest(file_contents)
|
176
|
+
release_info[filename] = tmp_hash
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
template_dir = File.join(File.dirname(__FILE__), "..", "..", "templates")
|
183
|
+
erb = ERB.new(File.read("#{template_dir}/deb_release.erb"), nil, "-").result(binding)
|
184
|
+
|
185
|
+
File.open("#{path}/dists/#{release}/Release.tmp","wb") do |x|
|
186
|
+
x.puts erb
|
187
|
+
end
|
188
|
+
|
189
|
+
FileUtils.move("#{path}/dists/#{release}/Release.tmp", "#{path}/dists/#{release}/Release")
|
190
|
+
end
|
191
|
+
|
192
|
+
# We expect that GPG is installed and a key has already been made
|
193
|
+
def generate_release_gpg(path,release,gpg)
|
194
|
+
Dir.chdir("#{path}/dists/#{release}") do
|
195
|
+
if gpg_sign_algorithm.nil?
|
196
|
+
sign_algorithm = "none"
|
197
|
+
else
|
198
|
+
sign_algorithm = gpg_sign_algorithm
|
199
|
+
end
|
200
|
+
|
201
|
+
if gpg.nil?
|
202
|
+
sign_cmd = "gpg --digest-algo \"#{sign_algorithm}\" --yes --output Release.gpg -b Release"
|
203
|
+
elsif !gpg_passphrase.nil?
|
204
|
+
sign_cmd = "echo \'#{gpg_passphrase}\' | gpg --digest-algo \"#{sign_algorithm}\" -u #{gpg} --passphrase-fd 0 --yes --output Release.gpg -b Release"
|
205
|
+
else
|
206
|
+
sign_cmd = "gpg --digest-algo \"#{sign_algorithm}\" -u #{gpg} --yes --output Release.gpg -b Release"
|
207
|
+
end
|
208
|
+
MPRM.logger.debug "Exec: #{sign_cmd}"
|
209
|
+
MPRM.logger.debug `#{sign_cmd}`
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def s3_compatible_encode(str)
|
214
|
+
str.gsub(/[#\$&'\(\)\*\+,\/:;=\?@\[\]]/) { |x| x.each_byte.map { |b| '%' + b.to_s(16) }.join }
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
|
data/lib/mprm/repo.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'mprm/debian'
|
2
|
+
require 'mprm/rpm'
|
3
|
+
|
4
|
+
module MPRM
|
5
|
+
class Repo
|
6
|
+
include Debian
|
7
|
+
include Redhat
|
8
|
+
|
9
|
+
attr_accessor :path
|
10
|
+
attr_accessor :type
|
11
|
+
attr_accessor :component
|
12
|
+
attr_accessor :arch
|
13
|
+
attr_accessor :release
|
14
|
+
attr_accessor :label
|
15
|
+
attr_accessor :origin
|
16
|
+
attr_accessor :gpg
|
17
|
+
attr_accessor :gpg_passphrase
|
18
|
+
attr_accessor :gpg_sign_algorithm
|
19
|
+
attr_accessor :secretkey
|
20
|
+
attr_accessor :accesskey
|
21
|
+
attr_accessor :directory
|
22
|
+
attr_accessor :recent
|
23
|
+
attr_accessor :nocache
|
24
|
+
|
25
|
+
def create
|
26
|
+
if "#{@type}" == "deb"
|
27
|
+
parch,pcomponent,prelease = _parse_vars(arch,component,release)
|
28
|
+
if directory
|
29
|
+
build_apt_repo(path,pcomponent,parch,prelease,label,origin,gpg,nocache)
|
30
|
+
if move_apt_packages(path,pcomponent,parch,prelease,directory) == false
|
31
|
+
return
|
32
|
+
end
|
33
|
+
end
|
34
|
+
build_apt_repo(path,pcomponent,parch,prelease,label,origin,gpg,nocache)
|
35
|
+
elsif "#{@type}" == "rpm"
|
36
|
+
component = nil
|
37
|
+
parch,pcomponent,prelease = _parse_vars(arch,component,release)
|
38
|
+
if directory
|
39
|
+
build_rpm_repo(path,parch,prelease,gpg)
|
40
|
+
if move_rpm_packages(path,parch,prelease,directory) == false
|
41
|
+
return
|
42
|
+
end
|
43
|
+
end
|
44
|
+
build_rpm_repo(path,parch,prelease,gpg)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def _parse_vars(arch_ar,component_ar,release_ar)
|
49
|
+
arch_ar = arch.split(",")
|
50
|
+
if !component.nil?
|
51
|
+
component_ar = component.split(",")
|
52
|
+
end
|
53
|
+
release_ar = release.split(",")
|
54
|
+
[arch_ar,component_ar,release_ar]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/mprm/rpm.rb
ADDED
@@ -0,0 +1,301 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'parallel'
|
5
|
+
require 'digest'
|
6
|
+
require 'zlib'
|
7
|
+
require 'erb'
|
8
|
+
|
9
|
+
module Redhat
|
10
|
+
def build_rpm_repo(path,arch,release,gpg)
|
11
|
+
begin
|
12
|
+
require 'arr-pm'
|
13
|
+
rescue NameError, LoadError
|
14
|
+
MPRM.logger.debug "please install the `arr-pm` gem to support RPM packages"
|
15
|
+
end
|
16
|
+
|
17
|
+
arch.each do |a|
|
18
|
+
release.each do |r|
|
19
|
+
full_path = "#{path}/#{r}/#{a}/"
|
20
|
+
repo_path = "#{full_path}/repodata/"
|
21
|
+
|
22
|
+
if !File.exist?(full_path)
|
23
|
+
FileUtils.mkdir_p(full_path)
|
24
|
+
end
|
25
|
+
|
26
|
+
if !File.exist?(repo_path)
|
27
|
+
FileUtils.mkdir(repo_path)
|
28
|
+
end
|
29
|
+
|
30
|
+
pkgnum = 0
|
31
|
+
hpkgnum = {}
|
32
|
+
Dir.glob("#{full_path}/*.rpm").each do |file|
|
33
|
+
pkgnum = pkgnum + 1
|
34
|
+
hpkgnum.store(file, pkgnum)
|
35
|
+
end
|
36
|
+
|
37
|
+
primary_xml = []
|
38
|
+
filelists_xml = []
|
39
|
+
other_xml = []
|
40
|
+
package_count = 0
|
41
|
+
|
42
|
+
Parallel.each(Dir.glob("#{full_path}/*.rpm"), :in_threads => 5) do |file|
|
43
|
+
package_count = package_count + 1
|
44
|
+
time = Time.now
|
45
|
+
sha256sum = Digest::SHA256.file(file).hexdigest
|
46
|
+
rpm = RPM::File.new(file)
|
47
|
+
filesize = File.size?(file)
|
48
|
+
pkgmeta = Hash[*rpm.header.tags.collect { |t| [t.tag, t.value] }.inject([]) { |m,v| m + v }]
|
49
|
+
start_header = rpm.lead.length + rpm.signature.length
|
50
|
+
end_header = start_header + rpm.header.length
|
51
|
+
pkgnum = hpkgnum[file]
|
52
|
+
|
53
|
+
primary_xml << create_primary_xml(file, time, sha256sum, rpm, filesize, pkgmeta, start_header, end_header, pkgnum)
|
54
|
+
other_xml << create_other_xml(file, time, sha256sum, rpm, filesize, pkgmeta, start_header, end_header, pkgnum)
|
55
|
+
filelists_xml << create_filelists_xml(file, time, sha256sum, rpm, filesize, pkgmeta, start_header, end_header, pkgnum)
|
56
|
+
end
|
57
|
+
|
58
|
+
erb_files = %w{
|
59
|
+
primary
|
60
|
+
other
|
61
|
+
filelists
|
62
|
+
}
|
63
|
+
|
64
|
+
template_dir = File.join(File.dirname(__FILE__), "..", "..", "templates")
|
65
|
+
|
66
|
+
erb_files.each { |f|
|
67
|
+
erb = ERB.new(File.read("#{template_dir}/#{f}.xml.erb"), nil, "-").result(binding)
|
68
|
+
|
69
|
+
File.open("#{repo_path}/#{f}.xml","wb") do |x|
|
70
|
+
x.puts erb
|
71
|
+
end
|
72
|
+
}
|
73
|
+
|
74
|
+
xml_data_hash = {}
|
75
|
+
xml_data_hash = {
|
76
|
+
"filelists" => {
|
77
|
+
"xml" => "",
|
78
|
+
"gz" => "",
|
79
|
+
"size" => "",
|
80
|
+
"osize" => "",
|
81
|
+
},
|
82
|
+
"other" => {
|
83
|
+
"xml" => "",
|
84
|
+
"gz" => "",
|
85
|
+
"size" => "",
|
86
|
+
"osize" => "",
|
87
|
+
},
|
88
|
+
"primary" => {
|
89
|
+
"xml" => "",
|
90
|
+
"gz" => "",
|
91
|
+
"size" => "",
|
92
|
+
"osize" => "",
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
Dir.glob("#{repo_path}/*.gz") { |f|
|
97
|
+
FileUtils.rm(f)
|
98
|
+
}
|
99
|
+
|
100
|
+
erb_files.each { |file|
|
101
|
+
xml_data_hash[file]["osize"] = File.size?("#{repo_path}/#{file}.xml")
|
102
|
+
xml_data_hash[file]["xml"] = Digest::SHA256.file("#{repo_path}/#{file}.xml").hexdigest
|
103
|
+
|
104
|
+
Zlib::GzipWriter.open("#{repo_path}/#{file}.xml.gz") do |gz|
|
105
|
+
ff = File.new("#{repo_path}/#{file}.xml", "r")
|
106
|
+
ff.each do |line|
|
107
|
+
gz.write(line)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
xml_data_hash[file]["size"] = File.size?("#{repo_path}/#{file}.xml.gz")
|
112
|
+
xml_data_hash[file]["gz"] = Digest::SHA256.file("#{repo_path}/#{file}.xml.gz").hexdigest
|
113
|
+
|
114
|
+
FileUtils.rm("#{repo_path}/#{file}.xml")
|
115
|
+
FileUtils.mv("#{repo_path}/#{file}.xml.gz", "#{repo_path}/#{xml_data_hash[file]['gz']}-#{file}.xml.gz")
|
116
|
+
}
|
117
|
+
|
118
|
+
repomd_xml = []
|
119
|
+
timestamp = Time.now.to_i
|
120
|
+
|
121
|
+
repomd_xml << create_repomd_xml(xml_data_hash,timestamp)
|
122
|
+
erb_two = ERB.new(File.open("#{template_dir}/repomd.xml.erb", "r") { |file|
|
123
|
+
file.read
|
124
|
+
}).result(binding)
|
125
|
+
|
126
|
+
File.open("#{repo_path}/repomd.xml.tmp","wb") do |x|
|
127
|
+
x.puts erb_two
|
128
|
+
end
|
129
|
+
|
130
|
+
FileUtils.mv("#{repo_path}/repomd.xml.tmp", "#{repo_path}/repomd.xml")
|
131
|
+
|
132
|
+
unless gpg == false
|
133
|
+
# We expect that GPG is installed and a key has already been made
|
134
|
+
sign_cmd = "gpg -u #{gpg} --yes --detach-sign --armor #{repo_path}/repomd.xml"
|
135
|
+
MPRM.logger.debug "Exec: #{sign_cmd}"
|
136
|
+
MPRM.logger.debug `#{sign_cmd}`
|
137
|
+
end
|
138
|
+
|
139
|
+
MPRM.logger.debug "Built Yum repository for #{full_path}"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def move_rpm_packages(path,arch,release,directory)
|
145
|
+
unless File.exist?(directory)
|
146
|
+
MPRM.logger.debug "ERROR: #{directory} doesn't exist... not doing anything"
|
147
|
+
return false
|
148
|
+
end
|
149
|
+
|
150
|
+
files_moved = []
|
151
|
+
release.each { |r|
|
152
|
+
arch.each { |a|
|
153
|
+
Dir.glob(directory + "/*.rpm") do |file|
|
154
|
+
if file =~ /^.*#{a}.*\.rpm$/i || file =~ /^.*all.*\.rpm$/i || file =~ /^.*any.*\.rpm$/i
|
155
|
+
target_dir = "#{path}/#{r}/#{a}/"
|
156
|
+
FileUtils.mkpath(target_dir)
|
157
|
+
if file =~ /^.*#{r}.*\.rpm$/i
|
158
|
+
# Lets do this here to help mitigate packages like "asdf-123+rhel7.rpm"
|
159
|
+
FileUtils.cp(file, target_dir)
|
160
|
+
FileUtils.rm(file)
|
161
|
+
else
|
162
|
+
FileUtils.cp(file, target_dir)
|
163
|
+
files_moved << file
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
170
|
+
files_moved.each do |f|
|
171
|
+
if File.exist?(f)
|
172
|
+
FileUtils.rm(f)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def create_repomd_xml(xml_data_hash,timestamp)
|
178
|
+
repomd_meta = String.new
|
179
|
+
xml_data_hash.each_pair do |k,v|
|
180
|
+
repomd_meta <<
|
181
|
+
%Q(<data type="#{k}">
|
182
|
+
<checksum type="sha256">#{v["gz"]}</checksum>
|
183
|
+
<open-checksum type="sha256">#{v["xml"]}</open-checksum>
|
184
|
+
<location href="repodata/#{v["gz"]}-#{k}.xml.gz"/>
|
185
|
+
<timestamp>#{timestamp}</timestamp>
|
186
|
+
<size>#{v["size"]}</size>
|
187
|
+
<open-size>#{v["osize"]}</open-size>
|
188
|
+
</data>)
|
189
|
+
end
|
190
|
+
repomd_meta
|
191
|
+
end
|
192
|
+
|
193
|
+
def create_filelists_xml(file, time, sha256sum, rpm, filesize, pkgmeta, start_header, end_header, pkgnum)
|
194
|
+
init_filelists_data = String.new
|
195
|
+
init_filelists_data <<
|
196
|
+
%Q(<package pkgid="#{sha256sum}" name="#{pkgmeta[:name]}" arch="#{pkgmeta[:arch]}">
|
197
|
+
<version epoch="0" ver="#{pkgmeta[:version]}" rel="#{pkgmeta[:release]}"/>\n\n)
|
198
|
+
|
199
|
+
rpm.files.each do |filex|
|
200
|
+
init_filelists_data << %Q( <file>#{filex}</file>\n)
|
201
|
+
end
|
202
|
+
|
203
|
+
init_filelists_data <<
|
204
|
+
%Q(</package>)
|
205
|
+
init_filelists_data
|
206
|
+
end
|
207
|
+
|
208
|
+
def create_other_xml(file, time, sha256sum, rpm, filesize, pkgmeta, start_header, end_header, pkgnum)
|
209
|
+
init_other_data = String.new
|
210
|
+
init_other_data <<
|
211
|
+
%Q(<package pkgid="#{sha256sum}" name="#{pkgmeta[:name]}" arch="#{pkgmeta[:arch]}">
|
212
|
+
<version epoch="0" ver="#{pkgmeta[:version]}" rel="#{pkgmeta[:release]}"/>\n)
|
213
|
+
init_other_data <<
|
214
|
+
%Q(</package>)
|
215
|
+
|
216
|
+
init_other_data
|
217
|
+
end
|
218
|
+
|
219
|
+
def create_primary_xml(file, time, sha256sum, rpm, filesize, pkgmeta, start_header, end_header, pkgnum)
|
220
|
+
time = time.to_i
|
221
|
+
cut_file = File.basename(file)
|
222
|
+
|
223
|
+
init_primary_data = String.new
|
224
|
+
init_primary_data = %Q(<package type=\"rpm\">
|
225
|
+
<name>#{pkgmeta[:name]}</name>
|
226
|
+
<arch>#{pkgmeta[:arch]}</arch>
|
227
|
+
<version epoch=\"0\" ver=\"#{pkgmeta[:version]}\" rel=\"#{pkgmeta[:release]}\"/>
|
228
|
+
<checksum type=\"sha256\" pkgid=\"YES\">#{sha256sum}</checksum>
|
229
|
+
<summary>#{pkgmeta[:summary]}</summary>
|
230
|
+
<description>#{pkgmeta[:description]}</description>
|
231
|
+
<packager></packager>
|
232
|
+
<url>#{pkgmeta[:url]}</url>
|
233
|
+
<time file=\"#{time}\" build=\"#{time}\"/>
|
234
|
+
<size package=\"#{filesize}\" installed=\"\" archive=\"\"/>
|
235
|
+
<location href=\"#{cut_file}\"/>
|
236
|
+
<format>
|
237
|
+
<rpm:license>#{pkgmeta[:license]}</rpm:license>
|
238
|
+
<rpm:vendor/>
|
239
|
+
<rpm:group>#{pkgmeta[:group]}</rpm:group>
|
240
|
+
<rpm:buildhost>#{pkgmeta[:buildhost]}</rpm:buildhost>
|
241
|
+
<rpm:sourcerpm>#{pkgmeta[:sourcerpm]}</rpm:sourcerpm>\n)
|
242
|
+
# <rpm:header-range start=\"#{start_header}\" end=\"#{end_header}\"/ >\n)
|
243
|
+
|
244
|
+
provide_primary_data = String.new
|
245
|
+
if !rpm.provides.empty?
|
246
|
+
provide_primary_data << "<rpm:provides>\n"
|
247
|
+
rpm.provides.each do |prov|
|
248
|
+
name = prov[1]
|
249
|
+
prov[1].nil? ? flag = "" : flag = prov[1]
|
250
|
+
prov[2].nil? ? version = "" && release = "" : (version,release = prov[2].split(/-/))
|
251
|
+
provide_primary_data <<
|
252
|
+
"<rpm:entry name=\"#{name}\" flags=\"#{flag}\" epoch=\"0\" ver=\"#{version}\" rel=\"#{release}\"/>\n"
|
253
|
+
end
|
254
|
+
provide_primary_data << "</rpm:provides>\n"
|
255
|
+
end
|
256
|
+
|
257
|
+
init_primary_data << provide_primary_data
|
258
|
+
|
259
|
+
require_primary_data = String.new
|
260
|
+
if !rpm.requires.empty?
|
261
|
+
require_primary_data << "<rpm:requires>\n"
|
262
|
+
rpm.requires.each do |req|
|
263
|
+
next if req[0] =~ /^rpmlib/
|
264
|
+
name = req[0]
|
265
|
+
req[1].nil? ? flag = "" : flag = req[1]
|
266
|
+
req[2].nil? ? version = "" && release = "" : (version,release = req[2].split(/-/))
|
267
|
+
require_primary_data <<
|
268
|
+
"<rpm:entry name=\"#{name}\" flags=\"#{flag}\" epoch=\"0\" ver=\"#{version}\" rel=\"#{release}\"/>\n"
|
269
|
+
end
|
270
|
+
require_primary_data << "</rpm:requires>\n"
|
271
|
+
end
|
272
|
+
|
273
|
+
init_primary_data << require_primary_data
|
274
|
+
|
275
|
+
conflict_primary_data = String.new
|
276
|
+
if !rpm.conflicts.empty?
|
277
|
+
conflict_primary_data << "<rpm:conflicts>\n"
|
278
|
+
rpm.conflicts.each do |con|
|
279
|
+
name = con[0]
|
280
|
+
conflict_primary_data <<
|
281
|
+
"<rpm:entry name=\"#{name}\">\n"
|
282
|
+
end
|
283
|
+
conflict_primary_data << "</rpm:conflicts>\n"
|
284
|
+
end
|
285
|
+
|
286
|
+
init_primary_data << conflict_primary_data
|
287
|
+
|
288
|
+
files_primary_data = String.new
|
289
|
+
rpm.files.each do |filex|
|
290
|
+
files_primary_data <<
|
291
|
+
"<file>#{filex}</file>"
|
292
|
+
end
|
293
|
+
|
294
|
+
init_primary_data << files_primary_data
|
295
|
+
|
296
|
+
init_primary_data <<
|
297
|
+
%Q( </format>\n) + %Q(</package>)
|
298
|
+
|
299
|
+
init_primary_data
|
300
|
+
end
|
301
|
+
end
|
data/lib/mprm/version.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Date: <%= date.rfc2822 %>
|
2
|
+
Suite: <%= release %>
|
3
|
+
<% if origin -%>
|
4
|
+
Origin: <%= origin %>
|
5
|
+
<% end -%>
|
6
|
+
<% if label -%>
|
7
|
+
Label: <%= label %>
|
8
|
+
<% end -%>
|
9
|
+
MD5Sum:
|
10
|
+
d41d8cd98f00b204e9800998ecf8427e 0 Release
|
11
|
+
<% release_info.each_pair do |k,v| -%>
|
12
|
+
<%= "#{release_info[k]['md5']} #{release_info[k]['size']} #{k}" %>
|
13
|
+
<% end -%>
|
14
|
+
SHA1:
|
15
|
+
da39a3ee5e6b4b0d3255bfef95601890afd80709 0 Release
|
16
|
+
<% release_info.each_pair do |k,v| -%>
|
17
|
+
<%= "#{release_info[k]['sha1']} #{release_info[k]['size']} #{k}" %>
|
18
|
+
<% end -%>
|
19
|
+
SHA256:
|
20
|
+
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 Release
|
21
|
+
<% release_info.each_pair do |k,v| -%>
|
22
|
+
<%= "#{release_info[k]['sha256']} #{release_info[k]['size']} #{k}" %>
|
23
|
+
<% end -%>
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mprm
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brett Gailey
|
8
|
+
- Mike Perham
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2018-10-23 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: parallel
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.12'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.12'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: arr-pm
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 0.0.10
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 0.0.10
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: clamp
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 1.0.1
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 1.0.1
|
56
|
+
description: Mike's PRM (Package Repository Manager) is an OS-independent Package
|
57
|
+
Repository tool. It allows you to quickly build Debian and Yum Package Repositories.
|
58
|
+
email: mperham@gmail.com
|
59
|
+
executables:
|
60
|
+
- mprm
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- bin/mprm
|
65
|
+
- lib/mprm.rb
|
66
|
+
- lib/mprm/debian.rb
|
67
|
+
- lib/mprm/repo.rb
|
68
|
+
- lib/mprm/rpm.rb
|
69
|
+
- lib/mprm/version.rb
|
70
|
+
- templates/deb_release.erb
|
71
|
+
- templates/filelists.xml.erb
|
72
|
+
- templates/other.xml.erb
|
73
|
+
- templates/primary.xml.erb
|
74
|
+
- templates/repomd.xml.erb
|
75
|
+
homepage: https://github.com/mperham/prm
|
76
|
+
licenses:
|
77
|
+
- MIT
|
78
|
+
metadata: {}
|
79
|
+
post_install_message:
|
80
|
+
rdoc_options: []
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
requirements: []
|
94
|
+
rubyforge_project:
|
95
|
+
rubygems_version: 2.6.13
|
96
|
+
signing_key:
|
97
|
+
specification_version: 4
|
98
|
+
summary: Mike's Package Repository Manager
|
99
|
+
test_files: []
|