duck-installer 0.2.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/LICENSE +674 -0
- data/README +35 -0
- data/bin/duck +9 -0
- data/duck.yaml +93 -0
- data/files/etc/dhclient-exit-hooks.d/hostname +17 -0
- data/files/etc/fstab +1 -0
- data/files/etc/hostname +1 -0
- data/files/etc/hosts +2 -0
- data/files/etc/inittab +25 -0
- data/files/etc/mtab +1 -0
- data/files/init +9 -0
- data/files/lib/duck.d/00-splash +36 -0
- data/files/lib/duck.d/02-setup-network +30 -0
- data/files/lib/duck.d/40-debootstrap +16 -0
- data/files/lib/duck.d/41-add-policy-rc.d +14 -0
- data/files/lib/duck.d/41-update-hostname +9 -0
- data/files/lib/duck.d/98-remove-policy-rc.d +9 -0
- data/files/lib/duck.d/99-reboot +18 -0
- data/files/lib/libduck.sh +152 -0
- data/files/lib/python-duck/duck/__init__.py +2 -0
- data/files/lib/python-duck/duck/db.py +48 -0
- data/files/lib/python-duck/duck/log.py +5 -0
- data/files/sbin/duckdb +212 -0
- data/files/sbin/duckinstall +21 -0
- data/files/sbin/ducklogin +3 -0
- data/fixes/clear-persistent-udev +10 -0
- data/fixes/kernel-boot-fix +53 -0
- data/fixes/squeeze-fix +14 -0
- data/lib/duck.rb +191 -0
- data/lib/duck/build.rb +395 -0
- data/lib/duck/chroot_utils.rb +51 -0
- data/lib/duck/enter.rb +20 -0
- data/lib/duck/logging.rb +31 -0
- data/lib/duck/module_helper.rb +56 -0
- data/lib/duck/pack.rb +42 -0
- data/lib/duck/qemu.rb +34 -0
- data/lib/duck/spawn_utils.rb +83 -0
- data/lib/duck/version.rb +3 -0
- metadata +103 -0
data/lib/duck/logging.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Logging
|
4
|
+
def log
|
5
|
+
@log ||= Logging.logger_for(self.class.name)
|
6
|
+
end
|
7
|
+
|
8
|
+
@loggers = {}
|
9
|
+
@log_level = Logger::INFO
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def logger_for(name)
|
13
|
+
@loggers[name] ||= setup_logger_for(name)
|
14
|
+
end
|
15
|
+
|
16
|
+
def setup_logger_for(name)
|
17
|
+
log = Logger.new(STDOUT)
|
18
|
+
log.progname = name
|
19
|
+
log.level = @log_level
|
20
|
+
log
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_level(level)
|
24
|
+
@loggers.each do |key, value|
|
25
|
+
value.level = level
|
26
|
+
end
|
27
|
+
|
28
|
+
@log_level = level
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module ModuleHelper
|
2
|
+
class StepError < Exception
|
3
|
+
end
|
4
|
+
|
5
|
+
class Step
|
6
|
+
attr_accessor :name, :disable_hook
|
7
|
+
|
8
|
+
def initialize(name, params={})
|
9
|
+
@name = name
|
10
|
+
@disable_hook = params[:disable_hook] || false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def step(name, params={})
|
16
|
+
@steps << Step.new(name, params)
|
17
|
+
end
|
18
|
+
|
19
|
+
def steps
|
20
|
+
@steps
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.included(mod)
|
25
|
+
mod.extend ClassMethods
|
26
|
+
mod.instance_variable_set :@steps, []
|
27
|
+
end
|
28
|
+
|
29
|
+
def pre_hook(name); end
|
30
|
+
def post_hook(name); end
|
31
|
+
def final_hook(); end
|
32
|
+
|
33
|
+
def execute
|
34
|
+
self.class.steps.each do |step|
|
35
|
+
name = step.name.to_s.gsub '_', '-'
|
36
|
+
|
37
|
+
log.info "#{name}: running"
|
38
|
+
pre_hook name unless step.disable_hook
|
39
|
+
|
40
|
+
begin
|
41
|
+
self.method(step.name).call
|
42
|
+
rescue StepError
|
43
|
+
log.error "#{name}: #{$!}"
|
44
|
+
return
|
45
|
+
end
|
46
|
+
|
47
|
+
post_hook name unless step.disable_hook
|
48
|
+
log.info "#{name}: done"
|
49
|
+
end
|
50
|
+
|
51
|
+
final_hook
|
52
|
+
|
53
|
+
# run fixes for finalizing the setup.
|
54
|
+
return 0
|
55
|
+
end
|
56
|
+
end
|
data/lib/duck/pack.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'duck/chroot_utils'
|
2
|
+
require 'duck/logging'
|
3
|
+
|
4
|
+
module Duck
|
5
|
+
class Pack
|
6
|
+
include ChrootUtils
|
7
|
+
include Logging
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
@target = options[:target]
|
11
|
+
@original_target = @target
|
12
|
+
@target_min = "#{@target}.min"
|
13
|
+
@chroot_env = options[:env]
|
14
|
+
@initrd = options[:initrd]
|
15
|
+
@no_minimize = options[:no_minimize]
|
16
|
+
@keep_minimized = options[:keep_minimized]
|
17
|
+
end
|
18
|
+
|
19
|
+
def minimize_target
|
20
|
+
log.info "Minimizing Target"
|
21
|
+
spawn ['rm', '-rf', @target_min] if File.directory? @target_min
|
22
|
+
spawn ['cp', '-a', @target, @target_min]
|
23
|
+
|
24
|
+
@target = @target_min
|
25
|
+
|
26
|
+
in_apt_get "clean"
|
27
|
+
in_shell "rm -rf /var/lib/{apt,dpkg} /usr/share/{doc,man} /var/cache"
|
28
|
+
end
|
29
|
+
|
30
|
+
def execute
|
31
|
+
minimize_target unless @no_minimize
|
32
|
+
|
33
|
+
Dir.chdir @target
|
34
|
+
log.info "Packing #{@target} into #{@initrd}"
|
35
|
+
shell "find . | cpio -o -H newc | gzip > #{@initrd}"
|
36
|
+
|
37
|
+
spawn ['rm', '-r', '-f', @target] unless @keep_minimized
|
38
|
+
|
39
|
+
log.info "Done building initramfs image: #{@initrd}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/duck/qemu.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'duck/spawn_utils'
|
2
|
+
|
3
|
+
module Duck
|
4
|
+
class Qemu
|
5
|
+
include SpawnUtils
|
6
|
+
include Logging
|
7
|
+
|
8
|
+
def initialize(options)
|
9
|
+
@target = options[:target]
|
10
|
+
@kernel = options[:kernel]
|
11
|
+
@initrd = options[:initrd]
|
12
|
+
@append = options[:append]
|
13
|
+
raise "No kernel specified" unless @kernel
|
14
|
+
raise "Specified kernel does not exist: #{@kernel}" unless File.file? @kernel
|
15
|
+
raise "No initrd specified" unless @initrd
|
16
|
+
raise "Specified initrd does not exist: #{@initrd}" unless File.file? @initrd
|
17
|
+
end
|
18
|
+
|
19
|
+
def execute
|
20
|
+
append = 'console=ttyS0 duck/mode=testing'
|
21
|
+
append = "#{append} #{@append}" if @append
|
22
|
+
|
23
|
+
opts = ['-serial', 'stdio', '-m', '1024', '-append', append]
|
24
|
+
|
25
|
+
args = [
|
26
|
+
'-kernel', @kernel,
|
27
|
+
'-initrd', @initrd,
|
28
|
+
] + opts
|
29
|
+
|
30
|
+
log.info "Executing QEMU on #{@initrd}"
|
31
|
+
qemu *args
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module SpawnUtils
|
2
|
+
SH = 'sh'
|
3
|
+
DEBOOTSTRAP = 'debootstrap'
|
4
|
+
GPG = 'gpg'
|
5
|
+
QEMU = 'qemu-system-x86_64'
|
6
|
+
|
7
|
+
class ExitError < Exception
|
8
|
+
attr_accessor :exitcode
|
9
|
+
|
10
|
+
def initialize(message, exitcode=1)
|
11
|
+
@exitcode = exitcode
|
12
|
+
super message
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def spawn(args, options={})
|
17
|
+
env = options[:env] || {}
|
18
|
+
|
19
|
+
repr = args.map do |i|
|
20
|
+
if i.nil?
|
21
|
+
'<nil>'
|
22
|
+
elsif i.include? ' '
|
23
|
+
"\"#{i}\""
|
24
|
+
else
|
25
|
+
i
|
26
|
+
end
|
27
|
+
end.join " "
|
28
|
+
|
29
|
+
log.debug "exec: #{repr}"
|
30
|
+
|
31
|
+
stdin_r = nil
|
32
|
+
stdout_w = nil
|
33
|
+
|
34
|
+
if options[:input_file]
|
35
|
+
stdin_r = options[:input_file]
|
36
|
+
end
|
37
|
+
|
38
|
+
if options[:output_file]
|
39
|
+
stdout_w = options[:output_file]
|
40
|
+
end
|
41
|
+
|
42
|
+
child_pid = fork do
|
43
|
+
ENV.update env
|
44
|
+
$stdin.reopen stdin_r unless stdin_r.nil?
|
45
|
+
$stdout.reopen stdout_w unless stdout_w.nil?
|
46
|
+
exec *args
|
47
|
+
exit 255
|
48
|
+
end
|
49
|
+
|
50
|
+
Process.wait child_pid
|
51
|
+
exit_status = $?.exitstatus
|
52
|
+
|
53
|
+
if exit_status != 0
|
54
|
+
raise ExitError.new "#{repr}: Subprocess returned non-zero exit status #{exit_status}"
|
55
|
+
end
|
56
|
+
|
57
|
+
exit_status
|
58
|
+
end
|
59
|
+
|
60
|
+
def shell(command)
|
61
|
+
spawn [SH, '-c', command]
|
62
|
+
end
|
63
|
+
|
64
|
+
def debootstrap(suite, target, options={})
|
65
|
+
# Extra arguments have to be early when running debootstrap.
|
66
|
+
args = Array.new(options[:extra] || [])
|
67
|
+
args << suite << target
|
68
|
+
args << options[:mirror] if options.include? :mirror
|
69
|
+
spawn [DEBOOTSTRAP] + args
|
70
|
+
end
|
71
|
+
|
72
|
+
def gpg(args, options={})
|
73
|
+
gpg_args = []
|
74
|
+
gpg_args << "--homedir" << options[:homedir] if options[:homedir]
|
75
|
+
gpg_args << "--keyserver" << options[:keyserver] if options[:keyserver]
|
76
|
+
gpg_args += args
|
77
|
+
spawn [GPG] + gpg_args
|
78
|
+
end
|
79
|
+
|
80
|
+
def qemu(*args)
|
81
|
+
spawn [QEMU] + args
|
82
|
+
end
|
83
|
+
end
|
data/lib/duck/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: duck-installer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- John-John Tedro
|
9
|
+
- Nathan Ferch
|
10
|
+
- Martin Parm
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
date: 2013-05-08 00:00:00.000000000 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rspec
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ! '>='
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '0'
|
24
|
+
type: :development
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
none: false
|
28
|
+
requirements:
|
29
|
+
- - ! '>='
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: '0'
|
32
|
+
description: Duck takes a configuration and generates a bootable initramfs that gives
|
33
|
+
over to a minimalistic installation environment based on (em)debian.
|
34
|
+
email:
|
35
|
+
- johnjohn.tedro@gmail.com
|
36
|
+
executables:
|
37
|
+
- duck
|
38
|
+
extensions: []
|
39
|
+
extra_rdoc_files: []
|
40
|
+
files:
|
41
|
+
- lib/duck.rb
|
42
|
+
- lib/duck/pack.rb
|
43
|
+
- lib/duck/spawn_utils.rb
|
44
|
+
- lib/duck/logging.rb
|
45
|
+
- lib/duck/version.rb
|
46
|
+
- lib/duck/build.rb
|
47
|
+
- lib/duck/qemu.rb
|
48
|
+
- lib/duck/chroot_utils.rb
|
49
|
+
- lib/duck/module_helper.rb
|
50
|
+
- lib/duck/enter.rb
|
51
|
+
- files/init
|
52
|
+
- files/lib/python-duck/duck/log.py
|
53
|
+
- files/lib/python-duck/duck/__init__.py
|
54
|
+
- files/lib/python-duck/duck/db.py
|
55
|
+
- files/lib/duck.d/41-add-policy-rc.d
|
56
|
+
- files/lib/duck.d/99-reboot
|
57
|
+
- files/lib/duck.d/40-debootstrap
|
58
|
+
- files/lib/duck.d/02-setup-network
|
59
|
+
- files/lib/duck.d/41-update-hostname
|
60
|
+
- files/lib/duck.d/98-remove-policy-rc.d
|
61
|
+
- files/lib/duck.d/00-splash
|
62
|
+
- files/lib/libduck.sh
|
63
|
+
- files/sbin/ducklogin
|
64
|
+
- files/sbin/duckdb
|
65
|
+
- files/sbin/duckinstall
|
66
|
+
- files/etc/fstab
|
67
|
+
- files/etc/hosts
|
68
|
+
- files/etc/hostname
|
69
|
+
- files/etc/dhclient-exit-hooks.d/hostname
|
70
|
+
- files/etc/mtab
|
71
|
+
- files/etc/inittab
|
72
|
+
- fixes/squeeze-fix
|
73
|
+
- fixes/clear-persistent-udev
|
74
|
+
- fixes/kernel-boot-fix
|
75
|
+
- LICENSE
|
76
|
+
- README
|
77
|
+
- duck.yaml
|
78
|
+
- bin/duck
|
79
|
+
homepage: http://github.com/udoprog/duck
|
80
|
+
licenses: []
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.3.6
|
97
|
+
requirements: []
|
98
|
+
rubyforge_project: duck
|
99
|
+
rubygems_version: 1.8.23
|
100
|
+
signing_key:
|
101
|
+
specification_version: 3
|
102
|
+
summary: Tool for generating a minimalistic initramfs installer system
|
103
|
+
test_files: []
|