This repository has been archived by the owner on Aug 28, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
bootstrap.yml
299 lines (254 loc) · 8.68 KB
/
bootstrap.yml
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
# Copyright © 2019 4km3
# https://github.com/orgs/4km3/people
# This file is part of archify.
# archify is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# archify is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with archify. If not, see <https://www.gnu.org/licenses/>.
# SPDX-License-Identifier: GPL-3.0-or-later
---
- name: Bootstrap Arch Linux
tags: bootstrap
hosts: bootstrap
gather_facts: no
vars:
sudoers_config: "%wheel ALL=(ALL) NOPASSWD: ALL"
home: "{{ lookup('env', 'HOME') }}"
user: "{{ lookup('env', 'USER') }}"
pubkey: "{{ home }}/.ssh/keys.d/id_ed25519-{{ user }}@{{ ansible_host }}.pub"
key: "{{ lookup('file', pubkey) }}"
pre_tasks:
- name: Fix .ssh/known_hosts
local_action:
module: known_hosts
name: "{{ item }}"
state: absent
loop:
- "{{ ansible_host }}"
- "{{ lookup('dig', ansible_host) }}"
- name: Add target host ssh pubkey fingerprint to our known_hosts
local_action:
module: known_hosts
name: "{{ ansible_host }}"
key: "{{ lookup('pipe', 'ssh-keyscan -t ed25519 ' + ansible_host) }}"
- name: Ensure time is set correctly
shell: timedatectl set-ntp true
- name: Identify main block device
shell: >
lsblk --nodeps --exclude 7 --sort HOTPLUG --output NAME,HOTPLUG --noheadings | awk '/0$/ { print $1; exit }'
# Note: use the following line instead to force a specific device
#echo -n sdb
register: lsblk_output
- name: Determine if p prefix is needed for main block device parts
set_fact:
target_block_device_part_prefix: p
when: "'nvme' in lsblk_output.stdout"
- name: Export main block device as a fact
set_fact:
target_block_device: /dev/{{ lsblk_output.stdout }}
target_block_device_base: /dev/{{ lsblk_output.stdout }}{{ target_block_device_part_prefix | default() }}
- name: Export volumes as a fact
set_fact:
esp_volume: "{{ target_block_device_base }}1"
swap_volume: "{{ target_block_device_base }}2"
root_volume: "{{ target_block_device_base }}3"
- name: Clear stale EFI boot entries
command:
efibootmgr -B -b "{{ item }}"
loop: "{{ range(0, 6)|list }}"
ignore_errors: yes
- name: Ensure no container is running on /mnt
ignore_errors: yes
command:
machinectl poweroff target-on-mnt
args:
warn: false
- name: Ensure no fs is mounted
ignore_errors: yes
command:
umount -R /mnt
- name: Ensure no crypto device is open
ignore_errors: yes
command:
cryptsetup luksClose arch
when: want_fde is defined and want_fde
roles:
- pacman
- role: partition
main_block_device: "{{ target_block_device }}"
main_block_device_base: "{{ target_block_device_base }}"
- role: encryption
when: want_fde is defined and want_fde
main_block_device_base: "{{ root_volume }}"
- role: filesystems
filesystems_esp_volume: "{{ esp_volume }}"
filesystems_swap_volume: "{{ swap_volume }}"
filesystems_root_volume: "{{ root_volume }}"
tasks:
- name: Mount main block device on /mnt
mount:
name: /mnt
src: "{{ root_volume }}"
fstype: btrfs
#opts: noatime,discard,ssd,autodefrag,compress=lzo,space_cache
opts: noatime,ssd,autodefrag,compress=lzo,space_cache
state: mounted
- name: Create btrfs subvolumes
command:
btrfs subvolume create {{ item }}
args:
chdir: /mnt
creates: /mnt/{{ item }}
loop:
- '@'
- '@home'
- name: Umount /mnt
mount:
path: /mnt
src: "{{ root_volume }}"
fstype: btrfs
state: unmounted
- name: Mount root subvolume on /mnt
mount:
path: /mnt
src: "{{ root_volume }}"
fstype: btrfs
#opts: noatime,discard,ssd,autodefrag,compress=lzo,space_cache,subvol=@
opts: noatime,ssd,nodiscard,autodefrag,compress=lzo,space_cache,subvol=@
state: mounted
- name: Mount boot subvolume on /mnt/boot
mount:
path: /mnt/boot
src: "{{ esp_volume }}"
fstype: vfat
opts: rw,noatime,fmask=0133,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro
state: mounted
- name: Mount home subvolume on /mnt/home
mount:
path: /mnt/home
src: "{{ root_volume }}"
fstype: btrfs
#opts: noatime,discard,ssd,autodefrag,compress=lzo,space_cache,subvol=@home
opts: noatime,ssd,nodiscard,autodefrag,compress=lzo,space_cache,subvol=@home
state: mounted
- name: pacstrap, create main user
command: "{{ item }}"
loop:
- pacstrap /mnt base base-devel intel-ucode linux linux-lts linux-firmware python openssh btrfs-progs fish vi
- rm -f /mnt/etc/localtime /mnt/etc/locale.conf
- systemd-firstboot --root=/mnt --locale=en_US.UTF-8 --timezone=Europe/Madrid --hostname={{ hostvars[inventory_hostname]['ansible_host'] }} --setup-machine-id
- bootctl --path /mnt/boot install
- cp -a /mnt/etc/fstab /mnt/etc/fstab.orig
- arch-chroot /mnt useradd -m -G wheel,log -s /usr/bin/fish {{ user }}
ignore_errors: yes
args:
warn: no
- name: Populate /mnt/etc/fstab
shell: genfstab -t PARTUUID -p /mnt >> /mnt/etc/fstab
- name: Enable no-password sudo for users in wheel group
lineinfile:
dest: /mnt/etc/sudoers.d/wheel-nopasswd
line: "{{ sudoers_config }}"
create: yes
state: present
- name: Create main user on the live instance, so that subsequent call to authorized_key will work under /mnt
user:
name: "{{ user }}"
createhome: no
- name: Add main user pubkey to its ~/.ssh/authorized_keys
authorized_key:
user: "{{ user }}"
key: "{{ key }}"
path: "/mnt/home/{{ user }}/.ssh/authorized_keys"
manage_dir: yes
- name: Copy OpenSSH server keys to /mnt
shell: cp -a /etc/ssh/ssh_host_* /mnt/etc/ssh
- name: Bootstrap Arch Linux | Configure systemd-boot
hosts: bootstrap
tags: bootstrap
gather_facts: no
roles:
- role: systemd-boot
systemd_boot_main_block_device: "{{ target_block_device }}"
- name: Bootstrap Arch Linux | Run new system in a container
tags: bootstrap
hosts: bootstrap
gather_facts: no
# accelerate: true
tasks:
- name: Install tmux
pacman:
name: tmux
update_cache: yes
- name: Disable sshd
systemd:
name: sshd
state: stopped
- name: Enable sshd on /mnt
command:
arch-chroot /mnt systemctl enable sshd
- name: Boot new system on /mnt on a container
command:
/usr/bin/tmux new-session -s local -n container -d systemd-nspawn --boot --directory=/mnt --machine=target-on-mnt
# Terminate:
# "/usr/bin/tmux send-keys -t local:container C-] C-] C-]"
- name: Setup Arch Linux
tags: bootstrap
hosts: all:!bootstrap
gather_facts: yes
vars_prompt:
- name: main_user_password
prompt: Enter your password
encrypt: "sha512_crypt"
private: yes
confirm: yes
- name: main_user_passphrase
prompt: Enter your passphrase
private: yes
confirm: yes
pre_tasks:
- name: Wait for container to become reachable
wait_for_connection:
- name: Gather facts
setup:
roles:
- role: credentials
user_password: "{{ main_user_password }}"
user_passphrase: "{{ main_user_passphrase }}"
- base
- name: Reboot host
tags: bootstrap
hosts: bootstrap
gather_facts: no
tasks:
- name: Terminate container on /mnt
command:
machinectl poweroff target-on-mnt
args:
warn: false
- name: Ensure no fs is mounted
ignore_errors: yes
command:
umount -R /mnt
- name: Close crypto device
ignore_errors: yes
command:
cryptsetup luksClose arch
when: want_fde is defined and want_fde
- name: Reboot server
reboot:
reboot_timeout: 0
ignore_errors: yes
- name: Wait for host to become reachable
tags: bootstrap
hosts: all:!bootstrap
gather_facts: no
tasks:
- name: Wait for connection
wait_for_connection: