nixos configurations
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

247 lines
6.7 KiB

4 months ago
4 months ago
  1. #!/usr/bin/env bash
  2. # Change into script dir.
  3. cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null || exit
  4. nixosDir=$(pwd)
  5. # Defaults
  6. defaultHostname="nixos"
  7. defaultSwap="8G"
  8. defaultName="grmrgecko"
  9. defaultDescription="James Coleman"
  10. defaultGitName="GRMrGecko"
  11. defaultGitEmail="grmrgecko@gmail.com"
  12. # A simple function to print an array.
  13. CHOICE=0
  14. chooseOpts() {
  15. local opts i
  16. CHOICE=-1
  17. opts=("$@")
  18. # Keep an index to properly index the options.
  19. i=0
  20. echo
  21. # For each option, print it and increment the index.
  22. for opt in "${opts[@]}"; do
  23. echo "$i) $opt"
  24. i=$((i+1))
  25. done
  26. # Ask for their choice.
  27. echo
  28. echo -n "Enter choice: "
  29. read -r CHOICE
  30. # Check inputted index range.
  31. if ((CHOICE >= ${#opts[@]} || CHOICE < 0)); then
  32. echo "Invalid range"
  33. chooseOpts "$@"
  34. fi
  35. }
  36. # A looping function to choose Y or N.
  37. chooseYN() {
  38. local default=""
  39. if [[ "$1" =~ \[.*([YN]).*\] ]]; then
  40. default=${BASH_REMATCH[1]}
  41. fi
  42. echo -n "$1: "
  43. read -r CHOICE
  44. [[ -z $CHOICE ]] && CHOICE=$default
  45. if [[ "$CHOICE" =~ ^[yY]$ ]]; then
  46. CHOICE="y"
  47. elif [[ "$CHOICE" =~ ^[nN]$ ]]; then
  48. CHOICE="n"
  49. else
  50. chooseYN "$1"
  51. fi
  52. }
  53. # Determine video drivers based on PCI devices.
  54. videoDrivers="unknown"
  55. pciRaw=$(lspci | grep -E 'VGA')
  56. if [[ "$pciRaw" =~ QXL ]]; then
  57. videoDrivers="qxl"
  58. elif [[ "$pciRaw" =~ NVIDIA ]]; then
  59. videoDrivers="nvidia"
  60. elif [[ "$pciRaw" =~ AMD ]]; then
  61. videoDrivers="amdgpu"
  62. fi
  63. # Get the packages souce, rather its unstable or stable.
  64. PACKAGESOPTS=(
  65. "stable"
  66. "unstable"
  67. )
  68. echo "Packages source"
  69. chooseOpts "${PACKAGESOPTS[@]}"
  70. PACKAGES=${PACKAGESOPTS[$CHOICE]}
  71. # Get the profile for this system.
  72. PROFILEOPTS=()
  73. # Build profile list from profiles directory.
  74. for profile in ./profiles/*.nix; do
  75. PROFILEOPTS+=("$(basename "${profile%.*}")")
  76. done
  77. echo "Choose your profile"
  78. chooseOpts "${PROFILEOPTS[@]}"
  79. PROFILE=${PROFILEOPTS[$CHOICE]}
  80. # Get the hostname.
  81. echo -n "Choose hostname [$defaultHostname]: "
  82. read -r hostName
  83. [[ -z $hostName ]] && hostName=$defaultHostname
  84. # Determine default disk.
  85. diskDefault=""
  86. [[ -e /dev/sda ]] && diskDefault="/dev/sda"
  87. [[ -e /dev/vda ]] && diskDefault="/dev/vda"
  88. echo
  89. echo "Select a disk from the list below:"
  90. # List disks to allow a choice to be made without stopping
  91. # configuration and verifying available disks.
  92. lsblk -o PATH,ID-LINK,SIZE -t
  93. echo
  94. echo -n "Choose disk (/dev/disk/by-id/{ID-LINK}) [$diskDefault]: "
  95. read -r disk
  96. # If selected disk is none, use the default disk determined above.
  97. [[ -z $disk ]] && disk=$diskDefault
  98. # Get the swap size.
  99. echo -n "Swap size [$defaultSwap]: "
  100. read -r swapSize
  101. [[ -z $swapSize ]] && swapSize=$defaultSwap
  102. # Determine if we should LUKS encrypt the disk.
  103. luks="false"
  104. chooseYN "Use LUKS Encryption? [N/y]"
  105. if [[ "$CHOICE" == "y" ]]; then
  106. luks="true"
  107. # Get a password from the user, with confirmation to ensure
  108. # we are not setting a typo.
  109. while true; do
  110. echo -n "Enter your luks encryption passphrase: "
  111. read -r -s luksPasswd
  112. echo -n "Confirm your luks encryption passphrase: "
  113. read -r -s confirmLuksPasswd
  114. if [[ "$luksPasswd" == "$confirmLuksPasswd" ]]; then
  115. break
  116. fi
  117. echo "Passwords do not match, try again."
  118. done
  119. # Save the password to the tmpfs for disko to pick up during partitioning.
  120. echo "$luksPasswd" > /tmp/secret.key
  121. fi
  122. # Get username for the main user.
  123. echo -n "Main user name [$defaultName]: "
  124. read -r name
  125. [[ -z $name ]] && name=$defaultName me
  126. # Get description for the main user.
  127. echo -n "Main user description [$defaultDescription]: "
  128. read -r description
  129. [[ -z $description ]] && description=$defaultDescription
  130. # Determine password for main user, verifying no typos.
  131. while true; do
  132. echo -n "Enter password for main user: "
  133. read -r -s mainPasswd
  134. echo -n "Confirm your password for main user: "
  135. read -r -s confirmMainPasswd
  136. if [[ "$mainPasswd" == "$confirmMainPasswd" ]]; then
  137. break
  138. fi
  139. echo "Passwords do not match, try again."
  140. done
  141. # Use mkpasswd to create a hashed password with the lastest
  142. # linux password hashing algorithm.
  143. password=$(mkpasswd "$mainPasswd")
  144. # Determine SSH keys to allow into the system.
  145. sshKeys=()
  146. while true; do
  147. echo "To exit loop, press enter."
  148. echo -n "Add ssh key (Github Username or ssh key): "
  149. read -r keyToAdd
  150. # If empty, exit loop as all keys were selected.
  151. [[ -z $keyToAdd ]] && break
  152. # If matches an ssh public key, add to list.
  153. if [[ "$keyToAdd" =~ ^ssh-.* ]]; then
  154. echo "Added key: $keyToAdd"
  155. sshKeys+=("$keyToAdd")
  156. continue
  157. fi
  158. # If is an username, check github for all keys and add them.
  159. if [[ "$keyToAdd" =~ ([a-zA-Z0-9]+) ]]; then
  160. githubUsername=${BASH_REMATCH[1]}
  161. while read -r key; do
  162. if [[ $key == "Not Found" ]]; then
  163. echo "Github user provided not found"
  164. continue
  165. fi
  166. echo "Adding key: $key"
  167. sshKeys+=("$key")
  168. done < <(curl -s -q "https://github.com/$githubUsername.keys")
  169. fi
  170. done
  171. # Determine if we want to autologin to the main user,
  172. # this may be desirable on full disk encrypted machines.
  173. autoLogin="false"
  174. chooseYN "Autologin to main user? [N/y]"
  175. if [[ "$CHOICE" == "y" ]]; then
  176. autoLogin="true"
  177. fi
  178. # Get git name.
  179. echo -n "Git name [$defaultGitName]: "
  180. read -r gitName
  181. [[ -z $gitName ]] && gitName=$defaultGitName me
  182. # Get git email.
  183. echo -n "Git email [$defaultGitEmail]: "
  184. read -r gitEmail
  185. [[ -z $gitEmail ]] && gitEmail=$defaultGitEmail
  186. # Generate settings.nix file with above choosen options.
  187. echo "Generating settings.nix:"
  188. cat <<EOF | tee "$nixosDir/settings.nix"
  189. rec {
  190. system = "x86_64-linux";
  191. timezone = "America/Chicago";
  192. locale = "en_US.UTF-8";
  193. packages = "${PACKAGES}";
  194. profile = "${PROFILE}";
  195. hostId = (builtins.substring 0 8 (builtins.readFile "/etc/machine-id"));
  196. hostName = "${hostName}";
  197. videoDrivers = "${videoDrivers}";
  198. disk = {
  199. device = "${disk}";
  200. swapSize = "${swapSize}";
  201. luks = ${luks};
  202. };
  203. user = {
  204. name = "${name}";
  205. description = "${description}";
  206. hashedPassword = "${password}";
  207. openssh.authorizedKeys.keys = [$(printf ' "%s"' "${sshKeys[@]}") ];
  208. autoLogin = ${autoLogin};
  209. };
  210. root = {
  211. hashedPassword = user.hashedPassword;
  212. openssh.authorizedKeys.keys = user.openssh.authorizedKeys.keys;
  213. };
  214. git = {
  215. name = "${gitName}";
  216. email = "${gitEmail}";
  217. };
  218. networkmanager.profiles = {};
  219. }
  220. EOF
  221. # Generate hardware-configuration.nix without filesystems as we use the disko partitoning flake.
  222. echo
  223. echo "Generating hardware-configuration.nix"
  224. nixos-generate-config --no-filesystems --show-hardware-config | tee "$nixosDir/hardware-configuration.nix"