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/README
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
duck
|
2
|
+
----
|
3
|
+
|
4
|
+
A minimalist installer system generator.
|
5
|
+
|
6
|
+
about
|
7
|
+
-----
|
8
|
+
|
9
|
+
Duck will help you generate installer system images setup as an initrd, similar
|
10
|
+
to how debian-installer works.
|
11
|
+
|
12
|
+
There are however a few goals with duck that are different.
|
13
|
+
|
14
|
+
* No memory restrictions (debian-installer is geared towards 32M)
|
15
|
+
* Less rigorous space restrictions
|
16
|
+
- No special packaging necessary, but encouraged: http://www.emdebian.org/
|
17
|
+
- No library stripping.
|
18
|
+
|
19
|
+
All in all, you get a slightly bigger installer image, but a lot more
|
20
|
+
flexibility.
|
21
|
+
|
22
|
+
usage
|
23
|
+
-----
|
24
|
+
|
25
|
+
Duck has two steps in creating an initrd.
|
26
|
+
|
27
|
+
setup - Setup base configuration.
|
28
|
+
|
29
|
+
build - Build the base system.
|
30
|
+
pack - Pack the resulting initrd.gz
|
31
|
+
|
32
|
+
For testing/tweaking there are two other commands available.
|
33
|
+
|
34
|
+
enter - Enter the chroot that is used to build the initrd.
|
35
|
+
qemu - Run the resulting initrd in a qemu-based virtual environment.
|
data/bin/duck
ADDED
data/duck.yaml
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
---
|
2
|
+
sources:
|
3
|
+
- url: "http://www.emdebian.org/grip"
|
4
|
+
suite: squeeze
|
5
|
+
components:
|
6
|
+
- main
|
7
|
+
- url: "http://ftp.se.debian.org/debian"
|
8
|
+
suite: squeeze
|
9
|
+
components:
|
10
|
+
- main
|
11
|
+
|
12
|
+
packages:
|
13
|
+
- binutils
|
14
|
+
- python-argparse
|
15
|
+
- python
|
16
|
+
- grub2
|
17
|
+
- iproute
|
18
|
+
- bind9-host
|
19
|
+
- isc-dhcp-client
|
20
|
+
- net-tools
|
21
|
+
- openssh-server
|
22
|
+
- pciutils
|
23
|
+
- psutils
|
24
|
+
- syslog-ng
|
25
|
+
- udev
|
26
|
+
- vim-tiny
|
27
|
+
- less
|
28
|
+
- strace
|
29
|
+
|
30
|
+
files:
|
31
|
+
# init file
|
32
|
+
- from: /*
|
33
|
+
to: /
|
34
|
+
- from: /sbin/*
|
35
|
+
to: /sbin/
|
36
|
+
mode: 0755
|
37
|
+
# configuration files
|
38
|
+
- from: /etc/*
|
39
|
+
to: /etc/
|
40
|
+
- from: /etc/dhclient-exit-hooks.d/*
|
41
|
+
to: /etc/dhcp/dhclient-exit-hooks.d/
|
42
|
+
mode: 0755
|
43
|
+
# installer library
|
44
|
+
- from: /lib/libduck.sh
|
45
|
+
to: /lib/
|
46
|
+
- from: /lib/python-duck/duck/*
|
47
|
+
to: /lib/python-duck/duck/
|
48
|
+
# installation steps
|
49
|
+
- from: /lib/duck.d/*
|
50
|
+
to: /lib/duck.d/
|
51
|
+
mode: 0755
|
52
|
+
# hooks
|
53
|
+
- from: /lib/duck-hooks.d/*
|
54
|
+
to: /lib/duck-hooks.d/
|
55
|
+
mode: 0755
|
56
|
+
|
57
|
+
fixes:
|
58
|
+
# file contains scripts that should be run to fix the target environment.
|
59
|
+
# scripts are located under <out>/fixes
|
60
|
+
- squeeze-fix
|
61
|
+
# disable initrd generation and grub setup for installed kernels.
|
62
|
+
- kernel-boot-fix
|
63
|
+
# remove persistent udev rules.
|
64
|
+
- clear-persistent-udev
|
65
|
+
|
66
|
+
services:
|
67
|
+
- name: hostname.sh
|
68
|
+
start: '00 S'
|
69
|
+
- name: mountkernfs.sh
|
70
|
+
start: '00 S'
|
71
|
+
- name: mountdevsubfs.sh
|
72
|
+
start: '00 S'
|
73
|
+
- name: udev
|
74
|
+
start: '00 S'
|
75
|
+
- name: syslog-ng
|
76
|
+
start: '00 2 3 4 5'
|
77
|
+
stop: '00 0 1 6'
|
78
|
+
|
79
|
+
keyring:
|
80
|
+
keyserver: "subkeys.pgp.net"
|
81
|
+
keys:
|
82
|
+
# debian archive keys
|
83
|
+
- "473041FA"
|
84
|
+
- "B98321F9"
|
85
|
+
# puppetlabs
|
86
|
+
- "4BD6EC30"
|
87
|
+
# other debian keys for older archives
|
88
|
+
- "30E974EE"
|
89
|
+
- "46925553"
|
90
|
+
- "55BE302B"
|
91
|
+
- "65FFB764"
|
92
|
+
- "6D849617"
|
93
|
+
- "97BB3B58"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
if [ "$reason" != BOUND ] && [ "$reason" != RENEW ] \
|
4
|
+
&& [ "$reason" != REBIND ] && [ "$reason" != REBOOT ]
|
5
|
+
then
|
6
|
+
return
|
7
|
+
fi
|
8
|
+
|
9
|
+
hostname=$(host $new_ip_address | cut -d ' ' -f 5)
|
10
|
+
hostname=${hostname%*.}
|
11
|
+
echo $hostname > /etc/hostname
|
12
|
+
|
13
|
+
# update the hostname
|
14
|
+
hostname $hostname
|
15
|
+
|
16
|
+
# restart syslog to use the correct hostname.
|
17
|
+
invoke-rc.d syslog-ng restart
|
data/files/etc/fstab
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# empty fstab
|
data/files/etc/hostname
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
duck
|
data/files/etc/hosts
ADDED
data/files/etc/inittab
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# The default runlevel.
|
2
|
+
id:2:initdefault:
|
3
|
+
# Boot-time system configuration/initialization script.
|
4
|
+
# This is run first except when booting in emergency (-b) mode.
|
5
|
+
si::sysinit:/etc/init.d/rcS
|
6
|
+
# What to do in single-user mode.
|
7
|
+
~~:S:wait:/sbin/sulogin
|
8
|
+
|
9
|
+
l0:0:wait:/etc/init.d/rc 0
|
10
|
+
l1:1:wait:/etc/init.d/rc 1
|
11
|
+
l2:2:wait:/etc/init.d/rc 2
|
12
|
+
l6:6:wait:/etc/init.d/rc 6
|
13
|
+
# Normally not reached, but fallthrough in case of emergency.
|
14
|
+
z6:6:respawn:/sbin/sulogin
|
15
|
+
# What to do when CTRL-ALT-DEL is pressed.
|
16
|
+
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
|
17
|
+
# What to do when the power fails/returns.
|
18
|
+
pf::powerwait:/etc/init.d/powerfail start
|
19
|
+
pn::powerfailnow:/etc/init.d/powerfail now
|
20
|
+
po::powerokwait:/etc/init.d/powerfail stop
|
21
|
+
|
22
|
+
1:23:respawn:/sbin/agetty -n -l /sbin/duckinstall 38400 tty1
|
23
|
+
2:23:respawn:/sbin/agetty -n -l /sbin/ducklogin 38400 tty2
|
24
|
+
3:23:respawn:/sbin/agetty -n -l /sbin/ducklogin 38400 tty3
|
25
|
+
4:23:respawn:/sbin/agetty -n -l /sbin/ducklogin 38400 tty4
|
data/files/etc/mtab
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# empty mtab
|
data/files/init
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
. /lib/libduck.sh
|
3
|
+
|
4
|
+
cat - <<ENDL
|
5
|
+
_
|
6
|
+
.-' '-.
|
7
|
+
.' '.
|
8
|
+
:-._o) (o_.-:
|
9
|
+
( / \ )
|
10
|
+
'-.' '.-'
|
11
|
+
'. .'
|
12
|
+
i\ /i
|
13
|
+
. : ' : .
|
14
|
+
"\. : : ./"
|
15
|
+
\\| |//
|
16
|
+
.' : : '.
|
17
|
+
.-' : : '-.
|
18
|
+
: i .' '. i :
|
19
|
+
: : : :
|
20
|
+
: .' '. :
|
21
|
+
:/ \:
|
22
|
+
'. .'
|
23
|
+
'-._________.-'
|
24
|
+
|
25
|
+
| You are Ducked! |
|
26
|
+
|
27
|
+
ENDL
|
28
|
+
|
29
|
+
echo "Installation starting in..."
|
30
|
+
echo "3,"
|
31
|
+
sleep 1
|
32
|
+
echo "2,"
|
33
|
+
sleep 1
|
34
|
+
echo "1,"
|
35
|
+
sleep 1
|
36
|
+
echo "NOW"
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
. /lib/libduck.sh
|
3
|
+
|
4
|
+
if [[ "$DUCK_MODE" == "testing" ]]; then
|
5
|
+
warning "Skipping network configuration, duck/mode=testing"
|
6
|
+
exit 0
|
7
|
+
fi
|
8
|
+
|
9
|
+
info "network: Setting up loopback interface"
|
10
|
+
|
11
|
+
info "network: lo: address"
|
12
|
+
ip addr add 127.0.0.1/8 dev lo || true
|
13
|
+
info "network: lo: route"
|
14
|
+
ip route add 127.0.0.0/8 dev lo || true
|
15
|
+
info "network: lo: link up"
|
16
|
+
ip link set lo up
|
17
|
+
|
18
|
+
info "network: eth0: Configuring using dhcp"
|
19
|
+
|
20
|
+
if ! dhclient eth0; then
|
21
|
+
error "Network setup failed"
|
22
|
+
exit 1
|
23
|
+
fi
|
24
|
+
|
25
|
+
info "network: eth0: link up"
|
26
|
+
|
27
|
+
# Set hostname from DHCP
|
28
|
+
a_set hostname $(hostname)
|
29
|
+
|
30
|
+
exit 0
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
. /lib/libduck.sh
|
3
|
+
a_get_into target duck/target
|
4
|
+
a_get_into suite debootstrap/suite
|
5
|
+
a_get_into mirror debootstrap/mirror
|
6
|
+
|
7
|
+
if [[ ! -d $target ]]; then
|
8
|
+
error "Target does not exist: $target"
|
9
|
+
exit 1
|
10
|
+
fi
|
11
|
+
|
12
|
+
debootstrap $suite $target $mirror
|
13
|
+
|
14
|
+
mount --bind /dev $target/dev
|
15
|
+
mount -t proc none $target/proc
|
16
|
+
mount -t sysfs none $target/sys
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
. /lib/libduck.sh
|
3
|
+
a_get_into reboot_enabled "reboot/enabled" "True"
|
4
|
+
|
5
|
+
if [[ "$DUCK_MODE" == "testing" ]]; then
|
6
|
+
warning "Not rebooting, duck/mode=testing"
|
7
|
+
exit 0
|
8
|
+
fi
|
9
|
+
|
10
|
+
info "Installation done, rebooting!"
|
11
|
+
|
12
|
+
if [[ "$reboot_enabled" == "True" ]]; then
|
13
|
+
reboot
|
14
|
+
else
|
15
|
+
info "Not rebooting, reboot/enabled=$reboot_enabled"
|
16
|
+
fi
|
17
|
+
|
18
|
+
exit 0
|
@@ -0,0 +1,152 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
set -e
|
3
|
+
|
4
|
+
# static variables
|
5
|
+
export DUCK_VERSION="0.1"
|
6
|
+
export DUCKDB_CONF="/duckdb.conf"
|
7
|
+
export DUCKDB_JSON="/duckdb.json"
|
8
|
+
# if this file exists, the installation loop should not run.
|
9
|
+
export INSTALLER_STATUS="/.installer_status"
|
10
|
+
# default logging location.
|
11
|
+
export DEFAULT_LOG="/var/log/duckinstall.log"
|
12
|
+
export DUCK_LOGIN="/sbin/ducklogin"
|
13
|
+
export DUCK_HOOKS="/lib/duck-hooks.d"
|
14
|
+
export DUCK_PYTHONLIB="/lib/python-duck"
|
15
|
+
export PYTHONPATH="$DUCK_PYTHONLIB"
|
16
|
+
|
17
|
+
invoke_hook() {
|
18
|
+
name=$1
|
19
|
+
shift
|
20
|
+
path=$DUCK_HOOKS/$name
|
21
|
+
[[ -x $path ]] && ( $path "$@" || true )
|
22
|
+
}
|
23
|
+
|
24
|
+
info() {
|
25
|
+
echo "INFO : $@";
|
26
|
+
invoke_hook log info "$@"
|
27
|
+
}
|
28
|
+
|
29
|
+
warning() {
|
30
|
+
echo "WARNING : $@";
|
31
|
+
invoke_hook log warning "$@"
|
32
|
+
}
|
33
|
+
|
34
|
+
error() {
|
35
|
+
echo "ERROR : $@";
|
36
|
+
invoke_hook log error "$@"
|
37
|
+
}
|
38
|
+
|
39
|
+
setup_duckdb() {
|
40
|
+
info "duckdb: Loading Static Variables"
|
41
|
+
|
42
|
+
if [[ -f $DUCKDB_CONF ]]; then
|
43
|
+
info "duckdb: Loading $DUCKDB_CONF"
|
44
|
+
duckdb url file://$DUCKDB_CONF
|
45
|
+
fi
|
46
|
+
|
47
|
+
if [[ -f $DUCKDB_JSON ]]; then
|
48
|
+
info "duckdb: Loading $DUCKDB_JSON"
|
49
|
+
duckdb url --json file://$DUCKDB_JSON
|
50
|
+
fi
|
51
|
+
|
52
|
+
info "duckdb: Loading /proc/cmdline"
|
53
|
+
|
54
|
+
if ! duckdb url --cmdline file:///proc/cmdline; then
|
55
|
+
error "duckdb: Failed to load kernel arguments"
|
56
|
+
return 1
|
57
|
+
fi
|
58
|
+
|
59
|
+
# Time to enable hooks.
|
60
|
+
duckdb set --json duck/hooks-enabled true
|
61
|
+
duckdb set --json duck/log-hook-enabled true
|
62
|
+
}
|
63
|
+
|
64
|
+
run_installer() {
|
65
|
+
if ! setup_duckdb; then
|
66
|
+
return 1
|
67
|
+
fi
|
68
|
+
|
69
|
+
for script in /lib/duck.d/[0-9][0-9]-*; do
|
70
|
+
[[ ! -x $script ]] && continue
|
71
|
+
|
72
|
+
info "Running: $script"
|
73
|
+
logger -t installer "running: $script"
|
74
|
+
|
75
|
+
if ! $script; then
|
76
|
+
error "Failed: $script"
|
77
|
+
return 1
|
78
|
+
fi
|
79
|
+
done
|
80
|
+
|
81
|
+
return 0
|
82
|
+
}
|
83
|
+
|
84
|
+
# Run a command in the target environment.
|
85
|
+
# required duckdb variables:
|
86
|
+
# - duck/target
|
87
|
+
in_target() {
|
88
|
+
# run chroot invocation inside of a subshell
|
89
|
+
# this allows us to override some useful environment variables
|
90
|
+
# at leisure.
|
91
|
+
|
92
|
+
a_get_into target duck/target
|
93
|
+
|
94
|
+
command="$@"
|
95
|
+
|
96
|
+
info "in-target: $command"
|
97
|
+
|
98
|
+
(
|
99
|
+
export DEBIAN_FRONTEND=noninteractive
|
100
|
+
export DEBCONF_NONINTERACTIVE_SEEN=true
|
101
|
+
export LC_ALL=C
|
102
|
+
export LANGUAGE=C
|
103
|
+
export LANG=C
|
104
|
+
exec chroot $target $command
|
105
|
+
)
|
106
|
+
|
107
|
+
return $?
|
108
|
+
}
|
109
|
+
|
110
|
+
|
111
|
+
# get single duckdb variable
|
112
|
+
# exports the RET variable containing the value of the requested variable
|
113
|
+
# or invokes 'exit 1' if it was unable to fetch the value from duckdb.
|
114
|
+
#
|
115
|
+
# a_get duck/mode
|
116
|
+
# duck_mode="$RET"
|
117
|
+
#
|
118
|
+
# duckdb supprts the notion of default values, in that case, two arguments
|
119
|
+
# should be provided, as follows.
|
120
|
+
#
|
121
|
+
# a_get duck/mode testing
|
122
|
+
# duck_mode="$RET"
|
123
|
+
a_get() {
|
124
|
+
export DUCK_RETURN=""
|
125
|
+
export DUCK_OK="no"
|
126
|
+
|
127
|
+
eval $(duckdb get --sh "$@")
|
128
|
+
|
129
|
+
if [[ "$DUCK_OK" != "yes" ]]; then
|
130
|
+
error "Missing required duckdb variable: $1"
|
131
|
+
exit 1
|
132
|
+
fi
|
133
|
+
|
134
|
+
export RET=$DUCK_RETURN
|
135
|
+
}
|
136
|
+
|
137
|
+
# This function was introduced because the common idiom of assigning RET
|
138
|
+
# resulted in code which was error prone.
|
139
|
+
a_get_into() {
|
140
|
+
name=$1
|
141
|
+
shift
|
142
|
+
a_get "$@"
|
143
|
+
export "$name"="$RET"
|
144
|
+
}
|
145
|
+
|
146
|
+
# set single duckdb variable
|
147
|
+
a_set() {
|
148
|
+
eval $(duckdb set "$@");
|
149
|
+
}
|
150
|
+
|
151
|
+
# Dynamic Variables
|
152
|
+
a_get_into DUCK_MODE duck/mode "testing"
|