pandler 0.0.1
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/.gitignore +23 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +47 -0
- data/Rakefile +10 -0
- data/Vagrantfile +33 -0
- data/bin/pandle +8 -0
- data/etc/yum/pandler.py +52 -0
- data/lib/pandler.rb +8 -0
- data/lib/pandler/chroot.rb +229 -0
- data/lib/pandler/cli.rb +40 -0
- data/lib/pandler/version.rb +3 -0
- data/lib/pandler/yumfile.rb +26 -0
- data/lib/pandler/yumrepo.rb +240 -0
- data/pandler.gemspec +24 -0
- data/spec/pandler/chroot_spec.rb +93 -0
- data/spec/pandler/cli_spec.rb +20 -0
- data/spec/pandler/yumfile_spec.rb +20 -0
- data/spec/pandler/yumrepo_spec.rb +152 -0
- data/spec/pandler_spec.rb +8 -0
- data/spec/resources/yumrepo/pandler-test-0.0.1-1.x86_64.rpm +0 -0
- data/spec/resources/yumrepo/pandler-test-a-0.0.1-1.x86_64.rpm +0 -0
- data/spec/resources/yumrepo/pandler-test-a-0.0.2-1.x86_64.rpm +0 -0
- data/spec/resources/yumrepo/pandler-test-dep-a-0.0.1-1.x86_64.rpm +0 -0
- data/spec/resources/yumrepo/pandler-test-dep-b-0.0.1-1.x86_64.rpm +0 -0
- data/spec/resources/yumrepo/pandler-test-dep-required-0.0.1-1.x86_64.rpm +0 -0
- data/spec/resources/yumrepo/pandler-test-dep-required-required-0.0.1-1.x86_64.rpm +0 -0
- data/spec/resources/yumrepo/repodata/09267893997a9b34726567132f642093ebd2a4b5e65096a6562efc3a29106723-other.xml.gz +0 -0
- data/spec/resources/yumrepo/repodata/596e9069dad80db19e7ba4c36b3df1e52583231b95bfa61186408c77520a213a-primary.xml.gz +0 -0
- data/spec/resources/yumrepo/repodata/7dd30f881bb1b1cbd723a5fa9d996b96805e25015b56140c99a444bf248c4260-other.sqlite.bz2 +0 -0
- data/spec/resources/yumrepo/repodata/8e6f832a8605163914b5aaf46e42daeaad10f9785d202c6c99c9d903354b3194-filelists.xml.gz +0 -0
- data/spec/resources/yumrepo/repodata/a810cd5676bb578a196231dae1f37179241630f6745a3d33691279ff61bfe175-primary.sqlite.bz2 +0 -0
- data/spec/resources/yumrepo/repodata/ad696c5b02dadaef085b16712ce0464ae0d4c102b3ccf1ce0f14e371a119463a-filelists.sqlite.bz2 +0 -0
- data/spec/resources/yumrepo/repodata/repomd.xml +55 -0
- data/spec/spec_helper.rb +82 -0
- data/vagrant_file.sh +30 -0
- metadata +156 -0
data/lib/pandler/cli.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require "pandler"
|
2
|
+
require "thor"
|
3
|
+
|
4
|
+
class Pandler::CLI < Thor
|
5
|
+
class_option :yumfile, :type => :string, :aliases => "-f", :desc => "Default: Yumfile"
|
6
|
+
|
7
|
+
def initialize(args=[], options={}, config={})
|
8
|
+
super
|
9
|
+
@chroot = Pandler::Chroot.new
|
10
|
+
@yumrepo = Pandler::Yumrepo.new
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "version", "Display pandler version"
|
14
|
+
map ["-v", "--version"] => :version
|
15
|
+
def version
|
16
|
+
puts Pandler::VERSION
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "install", "Install"
|
20
|
+
def install
|
21
|
+
@chroot.init
|
22
|
+
@yumrepo.createrepo
|
23
|
+
@chroot.install(*@yumrepo.install_pkgs)
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "list", "List"
|
27
|
+
def list
|
28
|
+
puts @chroot.list
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "clean", "Clean"
|
32
|
+
def clean
|
33
|
+
@chroot.clean
|
34
|
+
end
|
35
|
+
|
36
|
+
desc "exec", "Execute"
|
37
|
+
def exec(*cmd)
|
38
|
+
@chroot.execute(*cmd)
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Pandler::Yumfile
|
2
|
+
attr_reader :repos, :rpms
|
3
|
+
|
4
|
+
def initialize(filename)
|
5
|
+
@repos = {}
|
6
|
+
@rpms = []
|
7
|
+
load_file(filename) if File.exists? filename
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def load_file(filename)
|
13
|
+
contents = File.read(filename)
|
14
|
+
instance_eval(contents, filename, 1)
|
15
|
+
@rpms.sort!
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def repo(name, url)
|
20
|
+
@repos[name] = url
|
21
|
+
end
|
22
|
+
|
23
|
+
def rpm(name)
|
24
|
+
@rpms.push(name)
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,240 @@
|
|
1
|
+
require "erb"
|
2
|
+
require "open3"
|
3
|
+
require "yaml"
|
4
|
+
|
5
|
+
class Hash
|
6
|
+
def to_yaml( opts = {} )
|
7
|
+
YAML::quick_emit( object_id, opts ) do |out|
|
8
|
+
out.map( taguri, to_yaml_style ) do |map|
|
9
|
+
sort.each do |k, v|
|
10
|
+
map.add( k, v )
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Pandler::Yumrepo
|
18
|
+
attr_reader :base_dir, :repo_dir, :yumfile_path, :lockfile_path
|
19
|
+
def initialize(args = {})
|
20
|
+
@base_dir = args[:base_dir] || File.expand_path("pandler")
|
21
|
+
@repo_dir = args[:repo_dir] || File.join(base_dir, "yumrepo")
|
22
|
+
@yumfile_path = args[:yumfile_path] || File.expand_path("Yumfile")
|
23
|
+
@lockfile_path = args[:lockfile_path] || yumfile_path + ".lock"
|
24
|
+
|
25
|
+
@cache_dir = File.join(base_dir, "yumcache")
|
26
|
+
@yum_log = File.join(@cache_dir, "/var/lib/yum/pandler.log")
|
27
|
+
FileUtils.mkdir_p base_dir
|
28
|
+
FileUtils.mkdir_p repo_dir
|
29
|
+
FileUtils.mkdir_p @cache_dir
|
30
|
+
|
31
|
+
@yumfile = Pandler::Yumfile.new(yumfile_path)
|
32
|
+
@lockfile = read_lockfile
|
33
|
+
end
|
34
|
+
|
35
|
+
def createrepo
|
36
|
+
setup_dirs
|
37
|
+
setup_files
|
38
|
+
yum_download
|
39
|
+
write_lockfile
|
40
|
+
symlink_pkgs
|
41
|
+
run_cmd("createrepo", "-v", repo_dir)
|
42
|
+
end
|
43
|
+
|
44
|
+
def install_pkgs
|
45
|
+
specs.sort_by { |package, spec| spec["name"] }.map { |package, spec| package }
|
46
|
+
end
|
47
|
+
|
48
|
+
def specs
|
49
|
+
@specs
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def run_cmd(*cmd)
|
55
|
+
ret = Kernel.system(*cmd)
|
56
|
+
raise "command failed(ret: #{ret}) '#{cmd.join(" ")}'" unless ret
|
57
|
+
end
|
58
|
+
|
59
|
+
def repos
|
60
|
+
@yumfile.repos
|
61
|
+
end
|
62
|
+
|
63
|
+
def rpms
|
64
|
+
@yumfile.rpms
|
65
|
+
end
|
66
|
+
|
67
|
+
def read_lockfile
|
68
|
+
File.exists?(lockfile_path) ? YAML.load_file(lockfile_path) : nil
|
69
|
+
end
|
70
|
+
|
71
|
+
def write_lockfile
|
72
|
+
open(@lockfile_path, "w") do |f|
|
73
|
+
YAML.dump({
|
74
|
+
"repos" => repos,
|
75
|
+
"rpms" => rpms,
|
76
|
+
"specs" => specs,
|
77
|
+
}, f)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def yum_download
|
82
|
+
run_cmd(*yum("install", *download_pkgs))
|
83
|
+
update_specs
|
84
|
+
end
|
85
|
+
|
86
|
+
def download_pkgs
|
87
|
+
pkgs = []
|
88
|
+
if @lockfile.nil?
|
89
|
+
pkgs = rpms
|
90
|
+
else
|
91
|
+
pkgs = @lockfile["specs"].keys
|
92
|
+
new_pkgs = rpms - @lockfile["rpms"]
|
93
|
+
removed_pkgs = @lockfile["rpms"] - rpms
|
94
|
+
|
95
|
+
if new_pkgs.size > 0
|
96
|
+
pkgs += new_pkgs
|
97
|
+
end
|
98
|
+
|
99
|
+
if removed_pkgs.size > 0
|
100
|
+
removed_pkgs.each do |rm|
|
101
|
+
rm_package = ""
|
102
|
+
@lockfile["specs"].each { |package, spec| rm_package = package if spec["name"] == rm }
|
103
|
+
rpms_package = []
|
104
|
+
rpms.each { |name| @lockfile["specs"].each { |package, spec| rpms_package.push package if spec["name"] == name } }
|
105
|
+
@lockfile["specs"].each do |package, spec|
|
106
|
+
if spec["comesfrom"].include? rm_package
|
107
|
+
if spec["comesfrom"].select { |pkg| rpms_package.include?(pkg) or pkg == rm_package } == [rm_package]
|
108
|
+
pkgs.delete(package)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
pkgs
|
116
|
+
end
|
117
|
+
|
118
|
+
def update_specs
|
119
|
+
@specs = read_yum_log
|
120
|
+
solve_comesfrom
|
121
|
+
end
|
122
|
+
|
123
|
+
def read_yum_log
|
124
|
+
results = {}
|
125
|
+
File.open(@yum_log).each_line do |log|
|
126
|
+
data = Hash[log.chomp.split("\t").map{|f| f.split(":", 2)}]
|
127
|
+
if results.has_key? data["package"]
|
128
|
+
results[data["package"]]["relatedto"].push data["relatedto"]
|
129
|
+
else
|
130
|
+
package = data.delete("package")
|
131
|
+
data["relatedto"] = [data["relatedto"]] if data.has_key?("relatedto")
|
132
|
+
results[package] = data
|
133
|
+
end
|
134
|
+
end
|
135
|
+
results
|
136
|
+
end
|
137
|
+
|
138
|
+
def solve_comesfrom
|
139
|
+
@specs.each do |package, spec|
|
140
|
+
checked_pkg = {}
|
141
|
+
@specs[package]["comesfrom"] = comesfrom(package, checked_pkg)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def comesfrom(pkgs, checked_pkg)
|
146
|
+
rpm_list = []
|
147
|
+
pkgs.each do |pkg|
|
148
|
+
next if checked_pkg[pkg]
|
149
|
+
|
150
|
+
checked_pkg[pkg] = true
|
151
|
+
spec = @specs[pkg]
|
152
|
+
|
153
|
+
rpm_list.push pkg if rpms.include?(@specs[pkg]["name"])
|
154
|
+
if spec.has_key? "relatedto"
|
155
|
+
spec["relatedto"].each do |related|
|
156
|
+
rpm_list.push related if rpms.include?(@specs[related]["name"])
|
157
|
+
end
|
158
|
+
rpm_list += comesfrom(spec["relatedto"], checked_pkg)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
rpm_list.uniq
|
162
|
+
end
|
163
|
+
|
164
|
+
def yum(*args)
|
165
|
+
cmd = ["yum", "--disableplugin=*", "--enableplugin=pandler"]
|
166
|
+
cmd += ["--installroot", @cache_dir, *args]
|
167
|
+
cmd
|
168
|
+
end
|
169
|
+
|
170
|
+
def symlink_pkgs
|
171
|
+
Dir.chdir(repo_dir) do
|
172
|
+
pkgs = Dir.glob("../yumcache/var/cache/yum/**/packages/*.rpm")
|
173
|
+
FileUtils.mkdir_p repo_dir
|
174
|
+
FileUtils.ln_s(pkgs, ".", { :force => true })
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def setup_dirs
|
179
|
+
dirs = [
|
180
|
+
'/var/lib/rpm',
|
181
|
+
'/var/lib/yum',
|
182
|
+
'/var/log',
|
183
|
+
'/var/lock/rpm',
|
184
|
+
'/var/cache/yum',
|
185
|
+
'/tmp',
|
186
|
+
'/var/tmp',
|
187
|
+
'/etc/yum.repos.d',
|
188
|
+
'/etc/yum',
|
189
|
+
'/etc/yum/plugin',
|
190
|
+
'/etc/yum/pluginconf.d',
|
191
|
+
]
|
192
|
+
dirs.each do |dir|
|
193
|
+
FileUtils.mkdir_p(File.join(@cache_dir, dir))
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def setup_files
|
198
|
+
open(File.join(@cache_dir, "/etc/yum/yum.conf"), "w") { |f| f.write yum_conf }
|
199
|
+
open(File.join(@cache_dir, "/etc/yum/pluginconf.d/pandler.conf"), "w") { |f| f.write plugin_conf }
|
200
|
+
FileUtils.cp(yum_plugin_path, File.join(@cache_dir, "/etc/yum/plugin"))
|
201
|
+
end
|
202
|
+
|
203
|
+
def yum_plugin_path
|
204
|
+
File.expand_path("../../../etc/yum/pandler.py", __FILE__)
|
205
|
+
end
|
206
|
+
|
207
|
+
def yum_conf
|
208
|
+
content = ERB.new <<-EOF
|
209
|
+
[main]
|
210
|
+
cachedir=/var/cache/yum
|
211
|
+
debuglevel=1
|
212
|
+
reposdir=/dev/null
|
213
|
+
logfile=/var/log/yum.log
|
214
|
+
retries=20
|
215
|
+
obsoletes=1
|
216
|
+
gpgcheck=0
|
217
|
+
assumeyes=1
|
218
|
+
syslog_ident=pandler
|
219
|
+
syslog_device=
|
220
|
+
plugins=1
|
221
|
+
pluginpath=<%= @cache_dir %>/etc/yum/plugin
|
222
|
+
pluginconfpath=<%= @cache_dir %>/etc/yum/pluginconf.d
|
223
|
+
<% repos.each { |repo, url| %>
|
224
|
+
[<%= repo %>]
|
225
|
+
name=<%= repo %>
|
226
|
+
enabled=1
|
227
|
+
baseurl=<%= url %>
|
228
|
+
<% } %>
|
229
|
+
EOF
|
230
|
+
content.result(binding)
|
231
|
+
end
|
232
|
+
|
233
|
+
def plugin_conf
|
234
|
+
content = <<-EOF
|
235
|
+
[main]
|
236
|
+
enabled=1
|
237
|
+
EOF
|
238
|
+
content
|
239
|
+
end
|
240
|
+
end
|
data/pandler.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'pandler/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "pandler"
|
8
|
+
gem.version = Pandler::VERSION
|
9
|
+
gem.authors = ["Ryosuke IWANAGA"]
|
10
|
+
gem.email = ["riywo.jp@gmail.com"]
|
11
|
+
gem.description = %q{Manage your packages with chroot}
|
12
|
+
gem.summary = %q{Yumfile}
|
13
|
+
gem.homepage = "https://github.com/riywo/pandler"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency 'thor', '>= 0.13.6'
|
21
|
+
|
22
|
+
gem.add_development_dependency 'rake', '>= 0.9.2.2'
|
23
|
+
gem.add_development_dependency 'rspec'
|
24
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require "pathname"
|
2
|
+
|
3
|
+
describe Pandler::Chroot do
|
4
|
+
include TempDirHelper
|
5
|
+
before :all do
|
6
|
+
# @base_dir = File.expand_path("../../../.spec_cache", __FILE__)
|
7
|
+
yumrepo = "file://" + File.expand_path("../../resources/yumrepo", __FILE__)
|
8
|
+
@chroot = Pandler::Chroot.new(:yumrepo => yumrepo)
|
9
|
+
end
|
10
|
+
|
11
|
+
subject { @chroot }
|
12
|
+
its(:root_dir) { should eq "#{@chroot.base_dir}/root" }
|
13
|
+
|
14
|
+
describe "chroot file path" do
|
15
|
+
subject { @chroot.real_path("/") }
|
16
|
+
it { should eq @chroot.root_dir + "/" }
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "init" do
|
20
|
+
before(:all) { @chroot.init }
|
21
|
+
it "should create directories" do
|
22
|
+
[
|
23
|
+
'/var/lib/rpm',
|
24
|
+
'/var/lib/yum',
|
25
|
+
'/var/lib/dbus',
|
26
|
+
'/var/log',
|
27
|
+
'/var/lock/rpm',
|
28
|
+
'/var/cache/yum',
|
29
|
+
'/etc/rpm',
|
30
|
+
'/tmp',
|
31
|
+
'/tmp/ccache',
|
32
|
+
'/var/tmp',
|
33
|
+
'/etc/yum.repos.d',
|
34
|
+
'/etc/yum',
|
35
|
+
'/proc',
|
36
|
+
'/sys',
|
37
|
+
].each do |path|
|
38
|
+
Pathname(@chroot.real_path(path)).should exist
|
39
|
+
end
|
40
|
+
end
|
41
|
+
it "should create files" do
|
42
|
+
[
|
43
|
+
'/etc/mtab',
|
44
|
+
'/etc/fstab',
|
45
|
+
'/var/log/yum.log',
|
46
|
+
'/etc/yum/yum.conf',
|
47
|
+
'/etc/yum.conf',
|
48
|
+
'/etc/resolv.conf',
|
49
|
+
'/etc/hosts',
|
50
|
+
].each do |path|
|
51
|
+
Pathname(@chroot.real_path(path)).should exist
|
52
|
+
end
|
53
|
+
end
|
54
|
+
it "should create devs" do
|
55
|
+
[
|
56
|
+
'/dev/null',
|
57
|
+
'/dev/full',
|
58
|
+
'/dev/zero',
|
59
|
+
'/dev/random',
|
60
|
+
'/dev/urandom',
|
61
|
+
'/dev/tty',
|
62
|
+
'/dev/console',
|
63
|
+
'/dev/stdin',
|
64
|
+
'/dev/stdout',
|
65
|
+
'/dev/stderr',
|
66
|
+
'/dev/fd',
|
67
|
+
# '/dev/ptmx',
|
68
|
+
].each do |path|
|
69
|
+
Pathname(@chroot.real_path(path)).should exist
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "install first time" do
|
75
|
+
before(:all) { @chroot.install("pandler-test-0.0.1-1.x86_64", "pandler-test-a-0.0.1-1.x86_64") }
|
76
|
+
it "should execute /pandler-test" do
|
77
|
+
Kernel.system("chroot", @chroot.root_dir, "/pandler-test").should be_true
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "exec /pandler-test" do
|
82
|
+
subject { capture_stdout { @chroot.execute("/pandler-test") } }
|
83
|
+
it { should eq "pandler test\n" }
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "install second time" do
|
87
|
+
before(:all) { @chroot.install("pandler-test-0.0.1-1.x86_64") }
|
88
|
+
subject { @chroot.installed_pkgs }
|
89
|
+
it { should eq ["pandler-test-0.0.1-1.x86_64"] }
|
90
|
+
end
|
91
|
+
|
92
|
+
after(:all) { @chroot.clean }
|
93
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
describe Pandler::CLI do
|
2
|
+
include TempDirHelper
|
3
|
+
include PandleHelper
|
4
|
+
describe "version" do
|
5
|
+
it "displays gem version" do
|
6
|
+
pandle("version").chomp.should == Pandler::VERSION
|
7
|
+
end
|
8
|
+
|
9
|
+
it "displays gem version on shortcut command" do
|
10
|
+
pandle("-v").chomp.should == Pandler::VERSION
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
=begin
|
15
|
+
describe "exec echo 'test'" do
|
16
|
+
subject { pandle("exec echo 'test'") }
|
17
|
+
it { should eq "test\n" }
|
18
|
+
end
|
19
|
+
=end
|
20
|
+
end
|