duck-installer 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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"