1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
|
#+TITLE: Balg02 Initial Setup Instructions
#+AUTHOR: Collin J. Doering
#+begin_abstract
This document details the initial setup of a genenetwork.org sponsored server hosted at the
University of Tennessee.
#+end_abstract
* Install Guix on debian to be used to bootstrap the Guix os installation
Optionally, the below steps can be completed within tmux or screen. Tmux was installed and
used in this case using the following.
#+begin_src shell
sudo apt update
sudo apt install tmux
tmux
#+end_src
Following the [[https://guix.gnu.org/manual/en/html_node/Binary-Installation.html][Binary Installation]] section from the Guix manual to install guix.
#+begin_src shell
sudo apt install -y guix
#+end_src
This installs the Debian's packaged version of Guix, which likely is older then what's
available upstream. As such, update our installation of Guix (following the [[https://guix.gnu.org/manual/en/html_node/Upgrading-Guix.html][Updating Guix]]
documentation specific to foreign distros').
#+begin_src shell
sudo -i guix pull
sudo systemctl restart guix-daemon.service
#+end_src
* Define Guix operating-system for the machine
See: [[file:balg02.scm][balg02.scm]]
** Bootloader configuration
For this installation, debian and its bootloader Grub will be left in place. Because we want
to retain Guix's interactions with Grub (eg. to allow for restoring from failed upgrades to
an earlier generation), we will have debian's Grub chainload Guix's Grub. To do so, we will
need to manually adjust Debians' Grub in order to add another menu entry, and set it as the
default menu item.
Below is a snippet from debian's ~/etc/default/grub~.
#+begin_src text
GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0,115200n8"
GRUB_CMDLINE_LINUX="console=tty1 console=ttyS0,115200n8"
GRUB_TERMINAL="console serial"
GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=1 --word=8 --parity=no --stop=1"
#+end_src
From this we extract the necessary guix bootloader configuration options (for serial).
- serial-unit :: 1
- serial-speed :: 115200
- terminal-inputs :: console serial
- terminal-outputs :: console serial
*** Manual modifications to Debian's Grub
:PROPERTIES:
:CUSTOM_ID: manual_modifications_to_debians_grub
:END:
Modify grub config on debian to add an additional (and default) option to chainload Guix
grub.
- Add a menuitem for Guix in ~/etc/grub.d/40_custom~, where ~<EFI-UUID>~ is replaced with the
efi partition UUID.
#+begin_src text
menuentry "Gnu Guix" {
insmod part_gpt
insmod search_fs_uuid
insmod chain
search --fs-uuid --no-floppy --set=root <EFI-UUID>
chainloader ($root)/EFI/Guix/grubx64.efi
}
#+end_src
- Modify ~/etc/default/grub~ setting ~GRUB_DEFAULT="Gnu Guix"~
- Run ~grub-mkconfig -o /boot/grub/grub.cfg~
** Network configuration
Using the a snippet taken from ~/etc/network/interfaces~ on the existing debian installation
(below), we can extract the necessary details to configure Guix's static-networking-service.
- Interface :: eno8303
- Address :: 216.37.76.55/24
- Gateway :: 216.37.76.1
- DNS Name Servers :: 216.37.64.2 216.37.64.3
- DNS Search :: genenetwork.org
#+begin_src text
# The primary network interface
allow-hotplug eno8303
iface eno8303 inet static
address 216.37.76.55/24
gateway 216.37.76.1
# dns-* options are implemented by the resolvconf package, if installed
dns-nameservers 216.37.64.2 216.37.64.3
dns-search genenetwork.org
#+end_src
** Disk Partitioning
:PROPERTIES:
:CUSTOM_ID: disk_partitioning
:END:
For this installation we are using ~/dev/sdb~ (a 1.5T ssd which is faster then the
alternative 3.6T ssd in the server).
First, we require a variety of tools to setup and partition the disk destined for Guix
installation. These could be installed on debian, however an alternative approach would be to
use Guix from debian as a package manager to temporarily provide the prerequisite tools. This
can be done using the shell spawned from the following command.
#+begin_src shell
guix shell parted btrfs-progs dosfstools
#+end_src
*** Create disk partition table and layout
#+begin_src bash
parted /dev/sda mklabel gpt
#+end_src
*** Create partitions
A simple™️ partition layout is used for this installation, consisting of an EFI ESP partition,
and the remaining disk partitions for use by btrfs, where btrfs subvolumes and a swapfile
will be used.
#+begin_src bash
parted /dev/sda mkpart primary fat32 0% 512MiB
parted /dev/sda mkpart primary 512MiB 100%
#+end_src
*** Create EFI partition
#+begin_src bash
parted /dev/sda set 1 esp on
mkfs.fat -F32 /dev/sda1
#+end_src
*** Create btrfs 'pool' (file-system) and subvolumes
**** Create btrfs file-system
#+begin_src bash
mkfs.btrfs --label root /dev/sda2
#+end_src
**** Create btrfs subvolumes
First mount the btrfs top-level file-system.
#+begin_src bash
mount /dev/sda2 /mnt
#+end_src
Then create the root subvolume, and a subvolume for swapfiles.
#+begin_src bash
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@swap
#+end_src
Unmount the top-level btrfs file-system.
#+begin_src bash
umount /mnt
#+end_src
Mount the root subvolume.
#+begin_src bash
mount -o subvol=@,compress=zstd /dev/sda2 /mnt
#+end_src
Create nested subvolumes for ~/gnu/store~ and ~/home~.
#+begin_src bash
mkdir -p /mnt/gnu
btrfs subvolume create /mnt/gnu/store
btrfs subvolume create /mnt/home
btrfs subvolume create /mnt/var
#+end_src
*** Create swap
#+begin_src bash
mkdir /mnt/swap
mount -o subvol=@swap /dev/sda2 /mnt/swap
btrfs filesystem mkswapfile --size 32g --uuid clear /swap/swapfile
#+end_src
*** Prepare ~/mnt~ for Guix installation
Create ~/boot/efi~ directory for UEFI boot and mount the ESP partition there.
#+begin_src bash
mkdir -p /mnt/boot/efi
mount /dev/sda1 /mnt/boot/efi
#+end_src
Both root and swap are already mounted and ready due to earlier steps.
** Testing
To test the configuration in a vm before deployment, the following can be used.
#+begin_src shell
$(guix time-machine -C channels.scm -- system vm -e '(@ (guix-na config balg02) %system)') -m 2G -smp 2 -nic user,model=virtio-net-pci
#+end_src
** Manual Testing of bootstrapping Guix from a Debian VM
To correctly test this deployment, a environment that mimics bal02g should be used. The
closest to this is a VM with debian installed, with an additional virtual disk to bootstrap
guix onto. This will enable validating bootloader changes required to chainboot Guix's Grub.
This testing could be automated, but was done manually as we do not expect to have to
bootstrap a system like this often.
*** Setup Debian VM
1. Using ~qemu~, ~libvirt~, ~virtualbox~, etc.. create a VM that boots using UEFI firmware.
1. Create an additional virtual disk that will be used to bootstrap Guix onto from Debian.
This disk should be ~>20GiB~.
2. Ensure that there is a serial device attached to the VM.
2. Install Debian 12 on the VM created during step 1 (this can be a minimal server
installation, no desktop, etc..).
1. It's worth noting that for some reason debian didn't setup a efi boot
entry for some reason. Not sure why. To create one I used:
#+begin_src shell
efibootmgr --create --disk /dev/vda -p 1 -L "Debian" -l "\EFI\debian\grub64.efi"
#+end_src
After which I would have adjusted the boot order with:
#+begin_src shell
efibootmgr -o X,Y,...
#+end_src
However, in my case it was not needed as the boot order had debian first.
3. Reboot VM; further configure Debian.
1. Enable serial for debian grub
Modify ~/etc/default/grub~, adjusting ~GRUB_TERMINAL~ and ~GRUB_CMDLINE_LINUX_DEFAULT~ as
follows.
#+begin_src text
GRUB_TERMINAL="console serial"
GRUB_CMDLINE_LINUX_DEFAULT="console=tty1 console=ttyS0,115200n8"
#+end_src
2. Enable getty over serial
#+begin_src shell
systemctl enable getty@ttyS0.service
systemctl start getty@ttyS0.service
#+end_src
*** Test Bootstrapping Gnu Guix from Debian
With the Debian VM setup, we can now apply the documented bootstrapping steps.
1. [[#disk_partitioning][Disk Partitioning]], but with disks adjusted to match the testing VM.
2. [[#bootstrap_guix][Bootstrap Guix]], ensure ~<EFI-UUID>~ matches the VM efi partition used for Guix.
3. [[#manual_modifications_to_debians_grub][Manual modifications to Debian's Grub]], again ensuring ~<EFI-UUID>~ matches the VM efi
partition used for Guix.
4. Reboot
Following rebooting the VM, its expected that:
- Debian Grub boots first, has "Gnu Guix" as its default selected option, which boots Guixs'
Grub.
- Serial access works for:
- Debian and Guix Grub/s
- Debian and Guix linux console
As this testing is occurring in a VM, its worth noting things that are NOT expected to to be
testable.
- The network interfaces are not going to match what is on balg02, so its expected that the
networking service will not be able to start.
* Bootstrap Guix
:PROPERTIES:
:CUSTOM_ID: bootstrap_guix
:END:
Using Guix on debian, bootstrap the machine using the configuration in [[*Define Guix operating-system for the machine][Define Guix
operating-system for the machine]].
** Configure Guix Channels
First, fetch the most recent channel file from the target machine.
#+begin_src shell
curl -O https://git.genenetwork.org/guix-north-america/plain/channels.scm
#+end_src
** Create and Bootstrap System
Create a ~bootstrap.scm~ file like below, but where ~<EFI-UUID>~ is replaced with the efi
partition UUID.
#+begin_src scheme
((@ (guix-na config balg02) balg02) "<EFI-UUID>")
#+end_src
Use ~guix system init ...~ to instantiate the system, but using guix time-machine to use
pinned dependencies.
#+begin_src shell
guix time-machine -C channels.scm -- system init bootstrap.scm /mnt
#+end_src
** Post Boostrapping
After guix has been bootstrapped, its useful to do an initial ~guix pull~ using the same
channels that were used during bootstrapping.
#+begin_src shell
guix pull -C /run/current-system/channels.scm
#+end_src
To ensure your shell refers to the correct guix after its been updated, run ~hash guix~.
|