last tested to work on arch
[distro-setup] / distro-begin
1 #!/bin/bash -l
2 # Copyright (C) 2016 Ian Kelling
3 # This program is under GPL v. 3 or later, see <http://www.gnu.org/licenses/>
4
5
6 # for bootstrapping a new machine
7
8 # to make ssh run better, first run this:
9 sudo bash -c 'source /a/c/repos/bash/.bashrc && source /a/bin/ssh-emacs-setup'
10
11
12 # see t.org for OS installer notes
13
14 # usage: $0 [OPTIONS] HOSTNAME
15
16 # tips:
17 # run any sudo command first so your pass is cached
18 # set the scrollback to unlimited in case something goes wrong
19
20 if [[ $EUID == 0 ]]; then
21 echo error: do not run as root
22 exit
23 fi
24
25 interactive=true # set this to true if running by hand in emacs
26 [[ $- == *i* ]] || interactive=false
27
28
29
30 if ! $interactive; then
31 set -x
32 set -e -o pipefail
33 fi
34 set -E
35 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR
36
37 headless=false
38 debian_stable=false
39 recompile=true
40 # for copying to a new data fs
41 bootstrapfs=false
42 while [[ $1 == -* ]]; do
43 case $1 in
44 # avoid some of the longer compilation steps,
45 # when we need to rerun because we had an error
46 -n) recompile=false; shift ;;
47 -b) boostrap_new_comp=true; shift ;;
48 esac
49 done
50
51 if [[ $1 ]]; then
52 host=$1
53 else
54 host=$HOSTNAME
55 fi
56
57 for f in iank-dev htpc treetowl x2 frodo; do
58 eval "$f() { [[ $host == $f ]]; }"
59 done
60 encrypted() { iank-dev || x2 || frodo ; }
61
62 shopt -s extglob
63 export GLOBIGNORE=*/.:*/..
64 umask 0002
65
66
67 ####### end command line parsing
68
69
70 if frodo; then
71 x=/usr/local/bin/iancryptsetup
72 sudo dd of=$x <<'EOF'
73 #!/bin/bash -x
74
75 # man systemd-cryptsetup-generator
76 #man systemd-cryptsetup
77 #man systemd-cryptsetup@.service
78
79 f=/tmp/iancryptsetup
80 ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null \
81 -T -i /p/cryptkeyssh/id_rsa ian@treetowl > $f || exit 0
82
83 # example of initial setup of a disk
84 #disk=/dev/sdg2
85 #echo YES|cryptsetup --verbose luksFormat $disk $f
86 ## copy $f into paste buffer, then enter memorized pass, which we can use
87 ## This is for the case of ssh not being available
88 #cryptsetup --verbose --verify-passphrase luksAddKey $disk
89
90 # initial keyfile can be generated like any random pass
91 # head -c 200 /dev/urandom | tr -cd '[:alnum:]' | head -c 80 > keyfile
92
93
94 data=(
95 b1d7f102-c7cd-40a0-bff0-2d498692b5a7 crypta7
96 80649f08-1977-441b-ad8f-246931571702 crypt02
97 3ae71d1a-dbd5-4cbe-afa2-c7529c0c4d31 crypt31
98 bd4bbf8e-35c1-48e5-bb15-106c1b47792b crypt2b
99 c061a929-54fe-4a47-939d-c008ba418246 crypt46
100 ec709a4b-1ba7-463f-a1cd-841cb40868f0 cryptf0
101 b9f2a980-f57c-4c58-9313-055da09d579c crypt9c
102 747b9932-aa98-4552-86ab-657d0ccd4fb0 cryptb0
103 afb44dd6-28ba-443b-9ca4-34dc2a95a213 crypt13
104 )
105 for ((i=0; i<${#data[@]}; i+=2)); do
106 cryptsetup luksOpen --key-file $f UUID=${data[i]} ${data[i+1]}
107 done
108 for x in a q /mnt/btrfs_root; do
109 mount /$x
110 done
111 #/a/bin/firefox-link
112 exit 0
113 EOF
114 sudo chmod +x $x
115 # todo, it needs to wait for networking
116 sudo dd of=/etc/systemd/system/iancrypt.service <<'EOF'
117 [Unit]
118 Description=iancrypt
119
120 [Service]
121 Type=oneshot
122 ExecStart=/usr/local/bin/iancryptsetup
123
124 [Install]
125 WantedBy=multi-user.target
126 EOF
127 sudo systemctl enable iancrypt.service
128 sudo systemctl restart iancrypt.service
129 fi
130
131
132
133 if iank-dev; then
134 desktop=$(ssh root@iankelling.org grep desktop /etc/hosts | grep -o "^.* ")
135 if $bootstrapfs; then
136 # for bootstrapping at a new job:
137 cp="scp $desktop:"
138 # for moving to a new hd, change $cp to move between filesystems
139 mkdir -p /a/bin
140 chown -R ian:ian /a
141 $cp/a/c /a
142 $cp/a/c/bin/{bash-programs-by-ian,distro-begin,distro-functions,input-setup.sh} /a/bin
143 echo -e \\n\\n\\n | ssh-keygen -t rsa
144 fi
145 fi
146
147 # example which will be usefull when redoing desktop
148 # if x2; then
149 # f=/etc/fstab
150 # line='/dev/mapper/fedora-a /a btrfs noatime 0 1'
151 # if ! grep -Fxq "$line" $f; then
152 # echo "$line" | sudo tee -a $f >/dev/null
153 # fi
154 # if ! mount | grep -q '^/dev/mapper/fedora-a'; then
155 # dir=/a
156 # sudo mkdir -p $dir
157 # sudo chown ian:ian $dir
158 # sudo mount $dir
159 # fi
160 # fi
161
162 # set noatime.
163 sudo sed -ri '/noatime/!s/(ext[234]|btrfs)[[:space:]]+/\1 noatime,/' /etc/fstab
164 sudo sed -ri '/noatime/s/relatime,?|defaults,?//g' /etc/fstab
165
166
167 # this script has been designed to be idempotent
168 # todo, it would be nice to cut down on some of the output
169 for x in /a/bin/bash-programs-by-ian/repos/{errhandle,tee-unique,lnf}/*-function; do
170 source $x;
171 done
172 set +e
173 $interactive || errcatch
174 source /a/bin/distro-functions/src/identify-distros
175 echo path:$PATH
176
177
178
179
180 if isfedora; then
181 # comment out line disallowing calling sudo in scripts
182 sudo sed -i 's/^Defaults *requiretty/#\0 # ian commented/' /etc/sudoers
183 # turn on magic sysrq commands for this boot cycle
184 echo 1 > sudo dd of=/proc/sys/kernel/sysrq
185 # selinux is not user friendly. Like, you enable samba, but you haven't run the magic selinux commands so it doesn't work
186 # and you have no idea why.
187 sudo sed -i 's/^\(SELINUX=\).*/\1disabled/' /etc/selinux/config
188 selinuxenabled && sudo setenforce 0
189 fi
190
191
192
193
194 # link files
195
196
197 lnf /a/c/* /a/bin ~
198
199 for x in /a/c/repos/bash/!(.git); do
200 lnf "$x" ~
201 sudo -i <<EOF
202 source /a/bin/bash-programs-by-ian/repos/lnf/lnf-function
203 lnf $x /root
204 EOF
205 done
206
207 echo path:$PATH
208
209 set +x
210 errallow
211 source ~/.bashrc
212 echo path:$PATH
213 $interactive || errcatch
214 $interactive || set -x
215
216
217 # passwordless sudo
218 tu /etc/sudoers <<'EOF'
219 ian ALL=(ALL) NOPASSWD: ALL
220 Defaults env_keep += SUDOD
221 EOF
222
223
224 # enable magic sysrq keys. debian docs say it is already enabled by default
225 isfedora && tu /etc/sysctl.conf 'kernel.sysrq = 1'
226
227
228
229 if isdebian; then
230 # add contrib non-free to sources for main
231 s sed -i 's/^\(deb.* main\).*/\1 contrib non-free/' /etc/apt/sources.list
232
233 # non-existent var, as Im not planning to use stable right now
234 if $debian_stable; then
235 code=$(debian-codename)
236 tu /etc/apt/sources.list <<EOF
237 deb http://mozilla.debian.net/ $code-backports iceweasel-release
238 deb-src http://mozilla.debian.net/ $code-backports iceweasel-release
239 EOF
240
241 # we change the mirror from the default, so we cant use tu
242 if ! grep -qP "^deb [^ ]+ $code-backports main contrib non-free" /etc/apt/sources.list; then
243 s tee -a /etc/apt/sources.list <<EOF
244 deb http://ftp.us.debian.org/debian/ $code-backports main contrib non-free
245 deb-src http://ftp.us.debian.org/debian/ $code-backports main contrib non-free
246 EOF
247 fi
248
249 p update
250 # take care of mozilla signing errors in previous command
251 pi pkg-mozilla-archive-keyring
252 else
253 sudo sed -ri 's!^( *[^ #]+ +[^ ]+ +)[[:alpha:]]+(.*)!\1testing\2!' \
254 /etc/apt/sources.list
255 pup
256 fi
257 # doesnt exist on ubuntu. ubuntu has a mirror type url to use instead.
258 pi netselect-apt
259 debian_pick_mirror
260 fi
261
262 if isarch; then
263 #https://wiki.archlinux.org/index.php/Arch_User_Repository#Installing_packages
264 sudo pacman -S --noconfirm --needed base-devel jq
265 # pacaur seems to be the best, although it + cower has a few minor bugs,
266 # its design goals seem good, so, going for it.
267
268 aurpi() {
269 for p in "$@"; do
270 tempdir=$(mktemp -d)
271 pushd $tempdir
272 aurex "$p"
273 makepkg -sri --skippgpcheck --noconfirm
274 popd
275 rm -rf $tempdir
276 done
277 }
278 aurpi cower pacaur
279
280 # this creates ~/.gnupg. addgnupghome is broken on arch.
281 gpg -k
282 # for aur, automatically dl & add gpg keys.
283 # Just the keyserver-options line goes in dirmngr.conf once
284 # this bug is fixed: https://bugs.gnupg.org/gnupg/issue2147
285 teeu ~/.gnupg/gpg.conf <<EOF
286 $(grep -o '^ *keyserver .*' ~/.gnupg/dirmngr.conf)
287 keyserver-options auto-key-retrieve
288 EOF
289 pi pacserve
290 x=$(mktemp); pacman.conf-insert_pacserve >$x
291 sudo dd of=/etc/pacman.conf if=$x; rm $x
292 sudo systemctl enable pacserve.service
293 sudo systemctl start pacserve.service
294 fi
295 pup
296 # strange error if just installing trash-cli: "pyalpm requires python",
297 # so I see that it requires python2, and installing that manually fixes it.
298 # I didn't see this on earlier installation, main thing which changed was
299 # pacserve, so not sure if it's related.
300 pi python2 trash-cli
301
302
303 ###### link files ###########
304 # convenient to just do all file linking in one place
305
306 lnf /a/* ~
307 s lnf /a/sdx{,d} /
308
309 # if it wasn't set already, we could set hostname here
310 #echo treetowl | s dd of=/etc/hostname
311 #s hostname -F /etc/hostname
312 #HOSTNAME=$(hostname)
313
314 #########################################
315 # NOTE: only /a needs to be mounted for creating links!
316 ###########################################
317
318 # todo: this is desktop specific. on work comp, mkdir /p/.editor-backups
319 # todo: reconcile ~/.ssh/config work/home
320 if encrypted; then
321 lnf -T /p/offlineimap ~/Maildir
322 lnf -T /p/News ~/News
323 s lnf -T /q/p /p
324 # don't use /* because I don't want to require it to be mounted
325 s lnf /q/root/.editor-backups /q/root/.undo-tree-history \
326 /q/root/.ssh /q/root/sasl_passwd /q/root/sasl_passwd.db /a/opt \
327 /a/c/.emacs.d ~/.unison /root
328
329 fi
330
331 for x in /a/c/repos/*/!(.git); do
332 [[ $x == */. || $x == */.. ]] && continue # workaround for ubuntu 14.04 bug
333 lnf "$x" ~
334 done
335
336 s lnf /a/c/.inputrc /a/c/.vim /a/c/.vimrc /a/c/.gvimrc /root
337
338 if [[ $HOSTNAME == htpc ]]; then
339 lnf -T /i/Videos ~/Downloads
340 fi
341
342 if encrypted; then
343 # for dovecot
344 lnf -T /i/mboxes ~/mail
345 fi
346
347
348 # basic needed packages
349 case $(distro-name) in
350 debian)
351 pi $( $debian_stable && e -t $code-backports ) iceweasel \
352 linux-image-amd64 firmware-linux-nonfree \
353 firmware-linux-free linux-headers-amd64
354 ;;&
355 ubuntu|debian)
356 pi xmacro gtk-redshift xinput
357 ;;&
358 fedora)
359 p -y groupinstall development-tools c-development books admin-tools
360 pi redshift-gtk
361 # debian has this package patched to work, upstream is dead
362 # tried using alien, pi alien, alien -r *.deb, rpm -Uhv *.rpm, got this error, so fuck it
363 # file /usr/bin from install of xmacro-0.3pre_20000911-7.x86_64 conflicts with file from package filesystem-3.2-19.fc20.x86_64
364 # http://packages.debian.org/source/sid/xmacro
365 pi patch libXtst-devel wget man-pages # what is the ubuntu equivalent to man-pages?
366 cd $(mktemp -d)
367 wget http://ftp.de.debian.org/debian/pool/main/x/xmacro/xmacro_0.3pre-20000911.orig.tar.gz
368 wget http://ftp.de.debian.org/debian/pool/main/x/xmacro/xmacro_0.3pre-20000911-6.diff.gz
369 ex *.gz
370 patch -p0 < xmacro_0.3pre-20000911-6.diff
371 cd xmacro-0.3pre-20000911.orig
372 make
373 sleep 1 # not sure why the following command couldn\'t find, so trying this
374 # no make install target
375 s cp -f xmacroplay xmacrorec xmacrorec2 /usr/local/bin
376 ;;&
377 arch)
378 # libxtst is missing dep https://aur.archlinux.org/packages/xmacro/#news
379 pi xorg-server redshift xorg-xinput pkgfile libxtst xmacro
380 # like apt-cache
381 s pkgfile --update
382 ;;&
383 esac
384
385 pi xbindkeys xkbset cryptsetup unison
386
387 # enables trim for volume delete, other rare commands.
388 sudo sed -ri 's/( *issue_discards\b).*/\1 = 1/' /etc/lvm/lvm.conf
389 if encrypted; then
390 if isdeb; then
391 sudo cp /usr/share/doc/util-linux/examples/fstrim.{service,timer} /etc/systemd/system
392 fi
393 # does weekly trim
394 sudo systemctl enable fstrim.timer
395
396 # relatime is default, but it still significantly increases writes
397 # in comparison because it writes on the first read after each
398 # write.
399 #
400 dirs=(/i /mnt/{1,2,3,4,5,6,7,8,9})
401 if ! frodo; then
402 dirs+=(/q)
403 fi
404 s mkdir -p ${dirs[@]}
405 s chown ian:ian ${dirs[@]}
406 # ssh and probably some other things care about parent directory
407 # ownership, and ssh doesn\'t allow any group writable parent
408 # directories, so we are forced to use a directory structure similar
409 # to home directories
410 s chown root:ian /q
411 s chmod 755 /q
412
413 if treetowl; then
414 # get uuids from blkid and lvdisplay
415 # at times Ive done this through the installer. not anymore
416 tu /etc/fstab<<'EOF'
417 /dev/mapper/cswap1 none swap sw 0 0
418 /dev/mapper/q /q ext4 noatime 0 2
419 UUID=3f7b31cd-f299-40b4-a86b-7604282e2715 /i btrfs noatime 0 2
420 UUID=3f7b31cd-f299-40b4-a86b-7604282e2715 /mnt/btrfs_root btrfs noatime,subvolid=0 0 2
421 EOF
422 s mkdir -p /mnt/btrfs_root
423 s dd of=/etc/crypttab <<'EOF'
424 # i used to use UUID=<uuid> from cryptsetup luksUUID /dev/mapper/ianvg1-q
425 # however, it doesn't work for lvm volumes when opening on the command line,
426 # So, just using the thing which works both ways.
427 q /dev/mapper/vg_treetowl00-lv01 none luks,discard,noauto
428 # based on cryptsetup's README.Debian, and FAQ
429 cswap1 /dev/mapper/vg_treetowl00-lv00 /dev/urandom swap,cipher=aes-cbc-essiv:sha256,size=256,hash=sha256,discard,noearly
430 EOF
431 s chmod 600 /etc/crypttab
432
433 s systemctl daemon-reload
434 s systemctl restart systemd-cryptsetup@q.service
435 s mount /q
436
437 s systemctl restart systemd-cryptsetup@cswap1.service
438 # old ways:
439 # s update-rc.d cryptdisks enable
440
441 # misc notes about when messing around with jessie:
442 # # this was useful on debian jessie:
443 # systemd-tty-ask-password-agent --query
444 # according to the broadcast message
445 # jessie also still had /etc/init.d/cryptdisks,
446 # which seemed to work only with reload, and it seems deprecated
447 # and cryptdisks_start q, also prolly deprecated
448
449 fi
450
451
452
453 # emacs dependencies.
454
455 # dunno why debian installed postfix with yum-builddep emacs
456 # but I will just explicitly install it here since
457 # I use it for sending mail in emacs.
458 if isdeb; then
459 s debconf-set-selections<<EOF
460 postfix postfix/main_mailer_type select Satellite system
461 postfix postfix/mailname string $host
462 postfix postfix/relayhost string [mail.messagingengine.com]:587
463 EOF
464 pi postfix
465 else
466 pi postfix
467 s postconf -v 'relayhost = [mail.messagingengine.com]:587'
468 s systemctl enable postfix
469 s systemctl start postfix
470 fi
471 fi
472
473 /a/bin/conflink
474
475
476 # work desktop doesnt need gpg stuff, but it doesnt hurt
477 s dd of=/etc/profile.d/environment.sh <<'EOF'
478 # IAN: EDIT THIS FROM /a/bin/distro-begin
479
480 if [ -f $HOME/path_add-function ]; then
481 . $HOME/path_add-function
482 path_add /usr/sbin /usr/local/sbin /sbin
483 path_add /a/bin /a/opt/bin $HOME/.cabal/bin
484
485 if [ -r /etc/alternatives/java_sdk ]; then
486 export JAVA_HOME=/etc/alternatives/java_sdk
487 path_add /etc/alternatives/java_sdk
488 fi
489 fi
490
491 export EDITOR="emacsclient"
492 # this makes emacsclient file/-c start a server instance if none is running,
493 # instead of some alternate editor logic
494 export ALTERNATE_EDITOR=""
495
496 # ubuntu starts gpg agent automatically with /etc/X11/Xsession.d/90gpg-agent.
497 # fedora doesn't, which left me to figure this out, and google was no help.
498 # fedora documentation is often quite bad :(
499 # This is mostly copied from that file.
500 # Main difference is that we eval the result of starting gpg-agent,
501 # while that file executes it through xsession specific var.
502 # Also make sourcing the pidfile make more sense.
503 # End result should be the same afaik.
504 # for gpg-agent to work when calling gpg from the command line,
505 # we need an environment variable that is setup via the eval.
506 # which is why we do this upon login, so it can propogate
507 # It is also written to the file $HOME/.gnupg/gpg-agent-info-$(hostname)
508 # I'm not aware if that is ever used, but just fyi.
509 # I also added the bit about xmessaging the stderr,
510 # because I'd like to know if the command fails
511 if [ -f /etc/fedora-release ]; then
512 : ${GNUPGHOME=$HOME/.gnupg}
513
514 GPGAGENT=/usr/bin/gpg-agent
515 PID_FILE="$GNUPGHOME/gpg-agent-info-$(hostname)"
516
517 if ! $GPGAGENT 2>/dev/null; then
518 temp="$(mktemp)"
519 eval "$($GPGAGENT --homedir /p/do-not-delete --daemon --sh --write-env-file=$PID_FILE 2>$temp)"
520 temperr="$(<"$temp")"
521 [ -n "$temperr" ] && xmessage "gpg-agent stderr: $temperr"
522 elif [ -r "$PID_FILE" ]; then
523 . "$PID_FILE"
524 export GPG_AGENT_INFO
525 fi
526 fi
527
528 # ubuntu has 002, debian has 022.
529 # from what I've read, benefit of 002 makes shared groups read/write.
530 # Security concern is where some unixes put everyone in a same group,
531 # so if you copy files there with exact perms, that is probably not
532 # what you want. I don't use a system like that, and I don't really care
533 # either way, but I'd prefer
534 # being able to sync file perms with ubuntu systems at work,
535 # and it's easier to change the debian one.
536
537 umask 002
538 EOF
539
540
541 if isarch; then
542 # install so it's build dependencies don't get removed.
543 x=$(mktemp -d)
544 pushd $x
545 aurex emacs-git
546 makepkg -si --noconfirm
547 popd
548 rm -rf $x
549 else
550 if $recompile; then
551 /a/bin/buildscripts/emacs
552 else
553 /a/bin/buildscripts/emacs -r
554 fi
555 fi
556
557 # todo, figure this out for arch if we ever try out gnome.
558 if ! isarch; then
559 # install for multiple display managers in case we use one
560 if isdeb; then
561 dir=/etc/gdm3
562 elif isfedora; then
563 # fedora didn\'t have the 3.
564 dir=/etc/gdm
565 fi
566 mkdir -p $dir/PostLogin
567 s command cp /a/bin/desktop-20-autostart.sh $dir/PostLogin/Default
568 s mkdir /etc/lightdm/lightdm.conf.d
569 s dd of=/etc/lightdm/lightdm.conf.d/12-ian.conf <<'EOF'
570 [SeatDefaults]
571 session-setup-script=/a/bin/desktop-20-autostart.sh
572 EOF
573 fi
574
575 if isubuntu; then
576 # disable crash report annoying crap
577 s dd of=/etc/default/apport <<<'enabled=0'
578 fi
579
580
581 pi ghc sakura
582 # todo, also note for work comp, scp opt/org-mode bin/build-scripts
583
584 # use the package manger version to install the cabal version
585 pi cabal-install
586 cabal update
587 PATH="$PATH:$HOME/.cabal/bin"
588
589 # trying out the distro's versions newer distros
590 if $debian_stable || isubuntu; then
591 # todo: on ubuntu 12.04, needed to install zlib1g-dev
592 cabal install cabal-install
593 pu cabal-install
594 # just guessed at this after getting /bin/ld cannot find -lHSmtl or something
595 t ~/.ghc
596
597
598 cabal update
599 # todo, work machine required some packages libx11-dev libxrandr-dev libxft2-dev
600 cabal install xmonad
601 cabal install xmonad-contrib
602 # work machine:
603 # pi tasksel. select openssh server, basic server, large font selection
604
605 #http://comments.gmane.org/gmane.comp.lang.haskell.xmonad/13871
606 cat <<'EOF'
607 manual steps required:
608 xfce, "Session and Startup" > "Application Autostart"
609 Add
610 Name: xmonad
611 Description: xmonad --replace
612 Command: delayed-xmonad
613 EOF
614
615 else
616 pi xmonad
617 if isarch; then
618 # for displaying error messages.
619 # optional dependency in arch, standard elsewhere.
620 pi xorg-xmessage xmonad-contrib xorg-xsetroot xorg-xinit
621
622 # https://wiki.archlinux.org/index.php/Xinitrc
623 cp /etc/X11/xinit/xinitrc ~/.xinitrc
624 sed -ri '/^ *twm\b/,$d' ~/.xinitrc
625 echo "source /a/bin/xinitrc" >> ~/.xinitrc
626 else
627 pi suckless-tools
628 fi
629 fi
630 pi dmenu