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/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
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ if __FILE__ == $0
4
+ lib = File.expand_path File.join('..', '..', 'lib'), $0
5
+ $:.insert 0, lib if File.file? File.join(lib, 'duck.rb')
6
+ end
7
+
8
+ require 'duck'
9
+ exit Duck::main(ARGV)
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
@@ -0,0 +1 @@
1
+ duck
data/files/etc/hosts ADDED
@@ -0,0 +1,2 @@
1
+ 127.0.0.1 localhost duckinstall
2
+ ::1 localhost
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,9 @@
1
+ #!/bin/sh
2
+
3
+ echo "Invocing INIT"
4
+
5
+ exec /sbin/init
6
+
7
+ # this will only be run if init cannot be run for some reason.
8
+ echo "System init failed, starting /bin/sh"
9
+ exec /bin/sh
@@ -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,14 @@
1
+ #!/bin/bash
2
+ # vim: filetype=sh
3
+ . /lib/libduck.sh
4
+ a_get_into target duck/target
5
+
6
+ policy_rcd=$target/usr/sbin/policy-rc.d
7
+
8
+ (
9
+ set -e
10
+ echo "#!/bin/bash"
11
+ echo "exit 101"
12
+ ) > $policy_rcd
13
+
14
+ chmod +x $policy_rcd
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+ . /lib/libduck.sh
3
+ a_get_into hostname hostname
4
+ a_get_into target duck/target
5
+
6
+ info "duckdb: Setting hostname in target"
7
+ echo $hostname > $target/etc/hostname
8
+
9
+ exit 0
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+ # vim: filetype=sh
3
+ . /lib/libduck.sh
4
+ a_get_into target duck/target
5
+
6
+ info "Removing policy-rc.d"
7
+
8
+ policy_rcd=$target/usr/sbin/policy-rc.d
9
+ rm -f $policy_rcd
@@ -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"