From d9edd981753387321e9e0d126a9f255483cce562 Mon Sep 17 00:00:00 2001 From: vhaudiquet Date: Wed, 20 Aug 2025 15:41:13 +0200 Subject: [PATCH] Initial commit --- distribution/arch/gnome-extensions.txt | 2 + distribution/arch/initial_config.sh | 39 +++ distribution/arch/install.sh | 263 ++++++++++++++++++ distribution/ubuntu/initial_config.sh | 10 + distribution/ubuntu/install.sh | 129 +++++++++ dotfiles/.bashrc | 50 ++++ .../.config/Code - OSS/User/settings.json | 30 ++ dotfiles/.config/gh/config.yml | 16 ++ dotfiles/.config/ghostty/config | 7 + dotfiles/.config/git/config | 31 +++ dotfiles/.config/prompt.sh | 64 +++++ gnome-extensions.txt | 6 + gnome.sh | 164 +++++++++++ mymachine.sh | 211 ++++++++++++++ vscode-extensions.txt | 55 ++++ 15 files changed, 1077 insertions(+) create mode 100644 distribution/arch/gnome-extensions.txt create mode 100644 distribution/arch/initial_config.sh create mode 100644 distribution/arch/install.sh create mode 100644 distribution/ubuntu/initial_config.sh create mode 100644 distribution/ubuntu/install.sh create mode 100644 dotfiles/.bashrc create mode 100644 dotfiles/.config/Code - OSS/User/settings.json create mode 100644 dotfiles/.config/gh/config.yml create mode 100644 dotfiles/.config/ghostty/config create mode 100644 dotfiles/.config/git/config create mode 100644 dotfiles/.config/prompt.sh create mode 100644 gnome-extensions.txt create mode 100644 gnome.sh create mode 100755 mymachine.sh create mode 100644 vscode-extensions.txt diff --git a/distribution/arch/gnome-extensions.txt b/distribution/arch/gnome-extensions.txt new file mode 100644 index 0000000..70e58ce --- /dev/null +++ b/distribution/arch/gnome-extensions.txt @@ -0,0 +1,2 @@ +https://extensions.gnome.org/extension/307/dash-to-dock/ +https://extensions.gnome.org/extension/615/appindicator-support/ diff --git a/distribution/arch/initial_config.sh b/distribution/arch/initial_config.sh new file mode 100644 index 0000000..3d8e7c1 --- /dev/null +++ b/distribution/arch/initial_config.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +configure_pacman() { + # Configure pacman for color, multiple downloads + sed -i 's/#Color/Color/' /etc/pacman.conf + if [ $? -ne 0 ]; then + echo -e "${BRed}Failed to edit /etc/pacman.conf (to enable color). Skipping.${NC}" + fi + sed -i 's/#ParallelDownloads = 5/ParallelDownloads = 5/' /etc/pacman.conf + if [ $? -ne 0 ]; then + echo -e "${BRed}Failed to edit /etc/pacman.conf (to enable parallel downloads). Skipping.${NC}" + fi +} + +create_user() { + # Create user (if needed) + if ! id "${USERNAME}" >/dev/null 2>&1; then + # Add user and set password + useradd -m -c ${USER_COMMENT} -G root,wheel,i2c,input ${USERNAME} + if [ $? -ne 0 ]; then + echo -e "${BRed}Failed to add user ${USERNAME}${NC}. Skipping." + fi + echo "${USERNAME}:${PASSWORD}" | chpasswd + if [ $? -ne 0 ]; then + echo -e "${BRed}Failed to change user ${USERNAME} password${NC}. Skipping." + fi + else + echo -e "${BNC}User '${USERNAME}' already exists, skipping user creation${NC}" + fi +} + + +# Given that on Arch we don't have a dbus session yet, we need to launch one to apply dbus settings +DBUS_LAUNCH="sudo -u ${USERNAME} dbus-launch" + +WHEEL_GROUP="wheel" + +configure_pacman +create_user diff --git a/distribution/arch/install.sh b/distribution/arch/install.sh new file mode 100644 index 0000000..86e4e3b --- /dev/null +++ b/distribution/arch/install.sh @@ -0,0 +1,263 @@ +#!/usr/bin/env bash + +PACKAGES=( + i2c-tools # Needed for group i2c + sudo + wget + curl + jq + micro + wl-clipboard + networkmanager + # Gnome + baobab + papers + file-roller + gdm + gnome-backgrounds + gnome-calculator + gnome-color-manager + gnome-control-center + gnome-disk-utility + gnome-font-viewer + gnome-keyring + gnome-logs + gnome-menus + gnome-session + gnome-settings-daemon + gnome-shell + gnome-shell-extensions + gnome-system-monitor + gnome-text-editor + gvfs + gvfs-afc + gvfs-goa + gvfs-google + gvfs-gphoto2 + gvfs-mtp + gvfs-smb + nautilus + sushi + xdg-user-dirs-gtk + eog + gnome-tweaks + gnome-themes-extra + webp-pixbuf-loader + gnome-text-editor + power-profiles-daemon + xdg-desktop-portal + xdg-desktop-portal-gtk + xdg-desktop-portal-gnome + # End of gnome + ddcutil # Needed for brightness control + # Ghostty + ghostty + ghostty-terminfo + ghostty-shell-integration + # Git-needed secret stores + libsecret + gnome-keyring + # Secret store GUI + seahorse + # Audio + pipewire + pipewire-alsa + pipewire-audio + pipewire-pulse + pipewire-jack + wireplumber + # Git, and needed software to build software + git + base-devel + # Fonts + ttf-fira-code + ttf-inconsolata + ttf-liberation + ttf-roboto + ttf-dejavu + cantarell-fonts + adobe-source-code-pro-fonts + ttf-droid + noto-fonts + gnu-free-fonts + # Mail client + geary + # Photo/Graphics utils + inkscape + gimp + darktable + # LaTeX + texlive-bin + texlive-binextra + texlive-basic + texlive-mathscience + texlive-latexextra + texlive-publishers + texlive-formatsextra + texlive-bibtexextra + # Shell completion + bash-completion + # Man pages + man-db + man-pages + # NFS + nfs-utils + gvfs-nfs + # Github CLI + github-cli + # Code, and needed packages + code + clang + # Communication tools + discord + fractal + polari + # Video utils + mpv + vlc + # Printing + cups cups-pk-helper cups-filters libcups + # MDNS + avahi + # Firmware + gnome-firmware + fwupd + # Wireguard usermode utils + wireguard-tools + # QEMU + qemu-base + qemu-desktop + qemu-tools + qemu-img + qemu-user + qemu-ui-gtk + qemu-ui-sdl + qemu-ui-dbus + qemu-audio-pa + qemu-common + qemu-ui-opengl + qemu-block-ssh + qemu-audio-sdl + qemu-block-dmg + qemu-block-nfs + qemu-audio-oss + qemu-ui-curses + qemu-audio-jack + qemu-audio-alsa + qemu-block-curl + qemu-audio-dbus + qemu-pr-helper + qemu-hw-usb-host + qemu-system-x86 + qemu-system-arm + qemu-audio-spice + qemu-system-mips + qemu-ui-spice-app + qemu-system-riscv + qemu-ui-spice-core + qemu-chardev-spice + qemu-hw-display-qxl + qemu-hw-usb-redirect + qemu-system-aarch64 + qemu-ui-egl-headless + qemu-vhost-user-gpu + qemu-hw-usb-smartcard + qemu-hw-display-virtio-vga + qemu-hw-display-virtio-gpu + qemu-hw-display-virtio-gpu-gl + qemu-hw-display-virtio-vga-gl + qemu-hw-s390x-virtio-gpu-ccw + qemu-hw-display-virtio-gpu-pci + qemu-system-arm-firmware + qemu-system-x86-firmware + qemu-hw-display-virtio-gpu-pci-gl + qemu-system-riscv-firmware + vde2 + # Bitwarden, password manager + bitwarden + # Docker/Kube + docker + kubectl + kubectx + docker-compose +) + +EXTRA_PACKAGES=( + code-features + code-marketplace + wasistlos + revolt-desktop-bin + jellyfin-media-player + zen-browser-bin + spotify +) + +install_package_command() { + $YCMD | pacman -S --needed "${1}" >/dev/null 2>&1 +} + +install_extra_command() { + $YCMD | sudo -u ${USERNAME} yay -S --needed "${1}" >/dev/null 2>&1 +} + +refresh_package_db() { + # Refresh pacman db + echo -e "Refreshing pacman database..." + $YCMD | pacman -Sy >/dev/null 2>&1 +} + +install_yay() { + # Install yay (if not present) + yay=$(which yay 2>/dev/null) + if [ $? -ne 0 ]; then + echo -e "Installing yay..." + sudo -u ${USERNAME} git clone https://aur.archlinux.org/yay.git + if [ $? -ne 0 ]; then + echo "Failed to git clone yay" + return 1 2>/dev/null || exit 1 + fi + cd yay + $YCMD | sudo -u ${USERNAME} makepkg -si + if [ $? -ne 0 ]; then + echo "Failed to makepkg si" + return 1 2>/dev/null || exit 1 + fi + yay -Y --gendb + if [ $? -ne 0 ]; then + echo "Failed to yay --gendb" + return 1 2>/dev/null || exit 1 + fi + cd .. + rm -rf yay + else + echo -e "${BNC}Skipping yay installation, already present${NC}" + fi +} + +install_microcode() { + # Detect wether CPU is AMD or Intel, for microcode installation + CPU_VENDOR=$(cat /proc/cpuinfo | grep vendor | uniq | awk '{print $3}') + if [ "$CPU_VENDOR" == "AuthenticAMD" ]; then + # Install AMD microcode + $YCMD | pacman -S --needed amd-ucode >/dev/null 2>&1 + elif [ "$CPU_VENDOR" == "GenuineIntel" ]; then + # Install Intel microcode + $YCMD | pacman -S --needed intel-ucode >/dev/null 2>&1 + else + echo "Unknown CPU vendor : ${CPU_VENDOR} ; skipping microcode install" + MICROCODE_INSTALLED=false + fi +} + +export EXTRA_INSTALL_MESSAGE="Installing AUR packages with yay" + +extra_init() { + install_microcode + install_yay +} + +extra_finish() { + # Enable installed services + systemctl enable cups + systemctl enable avahi-daemon +} diff --git a/distribution/ubuntu/initial_config.sh b/distribution/ubuntu/initial_config.sh new file mode 100644 index 0000000..7b5593d --- /dev/null +++ b/distribution/ubuntu/initial_config.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +disable_unwanted_extensions() { + # Disable default Ubuntu gnome extensions + gnome-extensions disable ding@rastersoft.com # Desktop Icons +} + +WHEEL_GROUP="sudo" + +disable_unwanted_extensions diff --git a/distribution/ubuntu/install.sh b/distribution/ubuntu/install.sh new file mode 100644 index 0000000..91afc97 --- /dev/null +++ b/distribution/ubuntu/install.sh @@ -0,0 +1,129 @@ +#!/usr/bin/env bash + +PACKAGES=( + # Basic utils + sudo + wget + curl + jq + apt-transport-https + ca-certificates + gnupg + # Micro (text editor) + micro + xclip + wl-clipboard + # Gnome extra + gnome-shell-extension-manager + gnome-tweaks + file-roller + gnome-sushi + # ddcutil, for monitor brightness + ddcutil + # Git and essential building tools + git + build-essential + # clang (for clang-format at least) + clang + # Communication + polari + # Fonts + fonts-firacode + fonts-inconsolata + fonts-roboto + fonts-dejavu + fonts-cantarell + fonts-noto + # Mail client (geary) + geary + # Photo/graphics utils + inkscape + gimp + darktable + # LaTeX + texlive + # Video utils + mpv + vlc + # NFS + nfs-common + # Wireguard usermode tools + wireguard-tools + # QEMU + qemu-system +) + +EXTRA_PACKAGES=( + discord + fractal + wasistlos + revolt-desktop + bitwarden + spotify +) + +install_package_command() { + apt-get install -y "${1}" >/dev/null 2>&1 +} +install_extra_command() { + snap install "${1}" >/dev/null 2>&1 +} + +refresh_package_db() { + # Refresh apt db + apt-get update +} + +export EXTRA_INSTALL_MESSAGE="Installing snap packages" +extra_init() { + # Install ghostty + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/mkasberg/ghostty-ubuntu/HEAD/install.sh)" >/dev/null 2>&1 + if [ $? -ne 0 ]; then + echo -e "${BRed}Could not install ghostty. Skipping.${NC}" + fi + + # TODO: Install code-oss, and features+marketplace + # TODO: Install jellyfin-media-player + # TODO: Install android-studio + # TODO: Install zen browser + + # GitHub CLI + mkdir -p -m 755 /etc/apt/keyrings \ + && out=$(mktemp) && wget -nv -O$out https://cli.github.com/packages/githubcli-archive-keyring.gpg \ + && cat $out | tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \ + && chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \ + && mkdir -p -m 755 /etc/apt/sources.list.d \ + && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ + && apt update \ + && apt install gh -y + if [ $? -ne 0 ]; then + echo -e "${BRed}Could not install github-cli. Skipping.${NC}" + fi + + # Docker, Kubectl + curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc + chmod a+r /etc/apt/keyrings/docker.asc + echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ + $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \ + tee /etc/apt/sources.list.d/docker.list > /dev/null + apt-get update + apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + if [ $? -ne 0 ]; then + echo -e "${BRed}Could not install docker. Skipping.${NC}" + fi + + curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.33/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg + chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.gpg + echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.33/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list + chmod 644 /etc/apt/sources.list.d/kubernetes.list + apt-get update + apt-get install -y kubectl + if [ $? -ne 0 ]; then + echo -e "${BRed}Could not install kubectl. Skipping.${NC}" + fi +} + +extra_finish() { + echo -ne "" +} diff --git a/dotfiles/.bashrc b/dotfiles/.bashrc new file mode 100644 index 0000000..4784881 --- /dev/null +++ b/dotfiles/.bashrc @@ -0,0 +1,50 @@ +# +# ~/.bashrc +# + +# If not running interactively, don't do anything +[[ $- != *i* ]] && return + +# History file settings +# No duplicate lines / lines starting with space in history +HISTCONTROL=ignoreboth +# Append to history file (no overwrite) +shopt -s histappend +# File and history sizes +HISTSIZE=1000 +HISTFILESIZE=2000 + +# Check window size after each command, and update accordingly +shopt -s checkwinsize + +# Enable color in classic programs +alias ls='ls --color=auto' +alias grep='grep --color=auto' +alias egrep='egrep --color=auto' +alias fgrep='fgrep --color=auto' +alias dir='dir --color=auto' +export MICRO_TRUECOLORS=1 + +# Bash completion +if [[ -r /usr/share/bash-completion/bash_completion ]]; then + . /usr/share/bash-completion/bash_completion +fi + +# Prompt +source /home/${USER}/.config/prompt.sh + +# Bitwarden SSH agent +export SSH_AUTH_SOCK=/home/${USER}/.bitwarden-ssh-agent.sock + +# PATH modifications +# Local binaries +export PATH="${PATH}:/home/${USER}/.local/bin" + +# Editor +export EDITOR=micro + +# Aliases +alias e=${EDITOR} +alias l="ls -lla" +alias c="clear" +alias k="kubectl" diff --git a/dotfiles/.config/Code - OSS/User/settings.json b/dotfiles/.config/Code - OSS/User/settings.json new file mode 100644 index 0000000..4a6ea39 --- /dev/null +++ b/dotfiles/.config/Code - OSS/User/settings.json @@ -0,0 +1,30 @@ +{ + "workbench.colorTheme": "One Dark Pro", + "workbench.iconTheme": "material-icon-theme", + "workbench.productIconTheme": "adwaita", + "window.zoomLevel": 2, + "editor.fontFamily": "'Ligconsolata', 'monospace', monospace", + "editor.fontLigatures": true, + "editor.inlineSuggest.enabled": true, + "git.confirmSync": false, + "diffEditor.ignoreTrimWhitespace": false, + "editor.formatOnSave": false, + "github.copilot.enable": { + "*": false + }, + "explorer.confirmDelete": false, + "workbench.editorAssociations": { + "*.pdf": "latex-workshop-pdf-hook" + }, + "workbench.startupEditor": "none", + "[c]": { + "editor.defaultFormatter": "xaver.clang-format" + }, + "window.titleBarStyle": "custom", + "window.commandCenter": true, + "window.autoDetectColorScheme": true, + "workbench.preferredDarkColorTheme": "Adwaita Dark", + "workbench.preferredLightColorTheme": "Adwaita Light", + "editor.renderLineHighlight": "none", + "workbench.tree.indent": 12 +} diff --git a/dotfiles/.config/gh/config.yml b/dotfiles/.config/gh/config.yml new file mode 100644 index 0000000..97cf17c --- /dev/null +++ b/dotfiles/.config/gh/config.yml @@ -0,0 +1,16 @@ +# What protocol to use when performing git operations. Supported values: ssh, https +git_protocol: https +# What editor gh should run when creating issues, pull requests, etc. If blank, will refer to environment. +editor: +# When to interactively prompt. This is a global config that cannot be overridden by hostname. Supported values: enabled, disabled +prompt: enabled +# A pager program to send command output to, e.g. "less". Set the value to "cat" to disable the pager. +pager: +# Aliases allow you to create nicknames for gh commands +aliases: + co: pr checkout +# The path to a unix socket through which send HTTP connections. If blank, HTTP traffic will be handled by net/http.DefaultTransport. +http_unix_socket: +# What web browser gh should use when opening URLs. If blank, will refer to environment. +browser: +version: "1" diff --git a/dotfiles/.config/ghostty/config b/dotfiles/.config/ghostty/config new file mode 100644 index 0000000..c075cb3 --- /dev/null +++ b/dotfiles/.config/ghostty/config @@ -0,0 +1,7 @@ +font-family = Fira Code +font-size = 15 +cursor-style = underline +shell-integration = bash +window-width = 94 +window-height = 26 +theme = Adwaita Dark diff --git a/dotfiles/.config/git/config b/dotfiles/.config/git/config new file mode 100644 index 0000000..5826815 --- /dev/null +++ b/dotfiles/.config/git/config @@ -0,0 +1,31 @@ +[user] + name = ${GIT_USER} + email = ${EMAIL} + +[core] + compression = 9 + whitespace = error + preloadindex = true + autocrlf = input + +[url "https://github.com/"] + insteadOf = "gh:" +[credential "https://github.com"] + helper = !/usr/bin/gh auth git-credential +[credential "https://gist.github.com"] + helper = !/usr/bin/gh auth git-credential +[credential] + helper = /usr/lib/git-core/git-credential-libsecret + +[init] + defaultBranch = main + +[push] + autoSetupRemote = true + default = current + followTags = true +[pull] + default = current +[rebase] + autoStash = true + missingCommitsCheck = warn diff --git a/dotfiles/.config/prompt.sh b/dotfiles/.config/prompt.sh new file mode 100644 index 0000000..0016414 --- /dev/null +++ b/dotfiles/.config/prompt.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +parse_git_branch() +{ + branch=$(git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ <\1>/') + if [ "$branch" = "" ]; then + echo "" + else + echo -e " \Ue702$branch" + fi +} + +parse_docker_context() +{ + psdock=$(docker context inspect | jq --raw-output .[0].Name) + if [ "$psdock" = "default" ]; then + echo "" + else + echo -e " \Uf21f $psdock" + fi +} + +parse_kubernetes_context() +{ + ctx=$(kubectx -c) + if [ "$ctx" = "default" ]; then + echo "" + else + echo -e " \Ue81d $ctx" + fi +} + +kernel_live_version() { + echo $(uname -r) +} +kernel_installed_version() { + pacout=$(pacman -Q linux-zen) + pacarr=($pacout) + echo "${pacarr[1]}-zen" | sed 's/\(.*\)\./\1-/' +} + +PROMPT_NEED_REBOOT() { + live=$(kernel_live_version) + installed=$(kernel_installed_version) + if [ "$live" = "$installed" ]; then + echo "" + else + echo -e '\[\e[38;2;252;23;3m\] \Uf0709 \[$(tput sgr0)\]' + fi +} + +PROMPT_GIT() { + echo "\[$(tput setaf 142)\]\$(parse_git_branch)\[$(tput sgr0)\]" +} + +PROMPT_DOCKER() { + echo "\[\e[38;2;29;99;237m\]\$(parse_docker_context)\[$(tput sgr0)\]" +} + +PROMPT_KUBE() { + echo "\[\e[38;2;50;108;229m\]\$(parse_kubernetes_context)\[$(tput sgr0)\]" +} + +PS1="[\[$(tput setaf 39)\]\u@\h\[$(tput sgr0)\]\[$(tput setaf 31)\] \W\[$(tput sgr0)\]$(PROMPT_GIT)$(PROMPT_DOCKER)$(PROMPT_KUBE)$(PROMPT_NEED_REBOOT)]\\$ \[$(tput sgr0)\]" diff --git a/gnome-extensions.txt b/gnome-extensions.txt new file mode 100644 index 0000000..ca512fa --- /dev/null +++ b/gnome-extensions.txt @@ -0,0 +1,6 @@ +https://extensions.gnome.org/extension/6281/wallpaper-slideshow/ +https://extensions.gnome.org/extension/3193/blur-my-shell/ +https://extensions.gnome.org/extension/2645/brightness-control-using-ddcutil/ +https://extensions.gnome.org/extension/517/caffeine/ +https://extensions.gnome.org/extension/3843/just-perfection/ +https://extensions.gnome.org/extension/4099/no-overview/ diff --git a/gnome.sh b/gnome.sh new file mode 100644 index 0000000..e0fc74f --- /dev/null +++ b/gnome.sh @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +configure_gnome_settings() { + # Configure mouse settings : flat + ${DBUS_LAUNCH} dconf write /org/gnome/desktop/peripherals/mouse/accel-profile "'flat'" + # Configure touchpad settings : emulate left/right click areas + ${DBUS_LAUNCH} dconf write /org/gnome/desktop/peripherals/touchpad/click-method "'areas'" + # Show battery percentage + ${DBUS_LAUNCH} dconf write /org/gnome/desktop/interface/show-battery-percentage true + # Disable 'hot' corners + ${DBUS_LAUNCH} dconf write /org/gnome/desktop/interface/enable-hot-corners false + # Show all 3 min/max/close buttons on windows + ${DBUS_LAUNCH} dconf write /org/gnome/desktop/wm/preferences/button-layout "'appmenu:minimize,maximize,close'" + # Set alt-tab to current workspace only + ${DBUS_LAUNCH} dconf write /org/gnome/shell/app-switcher/current-workspace-only true + + + # Configure gnome to use dark theme + ${DBUS_LAUNCH} dconf write /org/gnome/desktop/interface/color-scheme "'prefer-dark'" + ${DBUS_LAUNCH} dconf write /org/gnome/desktop/interface/gtk-theme "'adw-gtk3-dark'" + + # Set 'favorite' apps + ${DBUS_LAUNCH} dconf write /org/gnome/shell/favorite-apps \ + "['org.gnome.Nautilus.desktop', \ + 'com.mitchellh.ghostty.desktop', \ + 'zen.desktop', \ + 'code-oss.desktop', \ + 'org.kicad.kicad.desktop', \ + 'android-studio.desktop', \ + 'discord.desktop', 'discord_discord.desktop', \ + 'org.gnome.Calculator.desktop', \ + 'org.gnome.TextEditor.desktop', \ + 'org.gnome.Geary.desktop', \ + 'lunacy.desktop', \ + 'notesnook.desktop', \ + 'org.gnome.Papers.desktop', \ + 'org.gnome.Settings.desktop', \ + 'com.github.xeco23.WasIstLos.desktop', 'wasistlos_wasistlos.desktop', \ + 'spotify.desktop', 'spotify_spotify.desktop', \ + 'bitwarden.desktop', 'bitwarden_bitwarden.desktop',\ + 'OrcaSlicer.desktop']" + + # Configure keymap + echo "KEYMAP=${KEYMAP}" >/etc/vconsole.conf + ${DBUS_LAUNCH} dconf write /org/gnome/desktop/input-sources/sources "[('xkb', '${KEYMAP}')]" + localectl set-x11-keymap ${KEYMAP} +} + +configure_dash2dock_settings() { + # Set dash-to-dock parameters + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/always-center-icons true + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/animate-show-apps false + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/apply-custom-theme false + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/background-color "'rgb(36,31,49)'" + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/background-opacity "'0,8'" + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/custom-background-color false + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/custom-theme-shrink true + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/dash-max-icon-size "30" + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/disable-overview-on-startup true + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/dock-fixed true + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/dock-position "'BOTTOM'" + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/extend-height true + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/height-fraction 1 + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/isolate-workspaces true + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/multi-monitor true + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/running-indicator-style "'DASHES'" + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/show-mounts false + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/show-mounts-network false + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/show-show-apps-button true + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/show-trash false + ${DBUS_LAUNCH} dconf write /org/gnome/shell/extensions/dash-to-dock/transparency-mode "'FIXED'" +} + +enable_extension_uuid() { + sudo -u ${USERNAME} gnome-extensions enable "$1" >/dev/null 2>&1 +} +install_extension_from_file() { + sudo -u ${USERNAME} gnome-extensions install "$1" -f >/dev/null 2>&1 +} +parse_extension_id_from_link() { + url="$(echo "$1" | sed '/^[[:space:]]*$/d')" + ext_id="$(echo "$url" | tr '\n' ' ' | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' | tr -s ' ' | awk '{print $1;}')" + echo "${ext_id}" +} + +# Inspired from: +# github.com:ToasterUwU/install-gnome-extensions +GNOME_SHELL_VERSION="$(gnome-shell --version | cut --delimiter=' ' --fields=3 | cut --delimiter='.' --fields=1,2)" +install_extension() { + link="${1}" + ext_id=$(parse_extension_id_from_link "${link}") + request_url="https://extensions.gnome.org/extension-info/?pk=$ext_id&shell_version=$GNOME_SHELL_VERSION" + + http_response="$(curl -s -o /dev/null -I -w "%{http_code}" "$request_url")" + if [ "$http_response" = 404 ]; then + echo -e "${BRed}Gnome extension ${ext_id} not found for shell version ${GNOME_SHELL_VERSION}. Skipping.${NC}" + return + fi + + ext_info="$(curl -s "$request_url")" + ext_uuid="$(echo "$ext_info" | jq -r '.uuid')" + direct_dload_url="$(echo "$ext_info" | jq -r '.download_url')" + download_url="https://extensions.gnome.org"$direct_dload_url + + filename="$(basename "$download_url")" + wget -q "$download_url" + install_extension_from_file "$filename" + if [ $? -ne 0 ]; then + echo -e "${BRed}Could not install gnome extension ${ext_id}. Skipping.${NC}" + rm -f ${filename} + return + fi + + # Cleanup downloaded extension file + rm -f "$filename" + + enable_extension_uuid "$ext_uuid" + if [ $? -ne 0 ]; then + echo -e "${BRed}Could not enable gnome extension ${ext_id}. Skipping.${NC}" + fi +} + +install_extensions_from_links_file() { + i=0 total=$(wc -l < ${1}) totalstr=$(printf "%02d" $total); while read ext; do + # TODO: Here we assume extensions are at most a 2-digit number ; change that :) + istr=$(printf "%02d" $i) + echo -ne "\b\b\b\b\b${istr}/${totalstr}" + + install_extension "${ext}" + + i=$((i + 1)) + done <"${1}"; + if [[ $i = $total ]]; then + echo -ne "\b\b\b\b\b${totalstr}/${totalstr}" + echo "" + fi +} + +# Install gnome extensions +echo -ne "Installing Gnome extensions... " + +# Enable gnome user extensions +${DBUS_LAUNCH} dconf write /org/gnome/shell/disable-user-extensions false +if [ $? -ne 0 ]; then + echo -e "${BRed}Failed to (${DBUS_LAUNCH}) dconf to enable Gnome user extensions. Terminating.${NC}" + exit 1 +fi + +install_extensions_from_links_file "${script_dir}/gnome-extensions.txt" + +# Install distribution-specific extensions if needed +if [[ -f ${script_dir}/distribution/${ID}/gnome-extensions.txt ]]; then + echo -ne "Installing distribution-specific Gnome extensions... " + install_extensions_from_links_file "${script_dir}/distribution/${ID}/gnome-extensions.txt" +fi + +# Enable needed default extensions +${DBUS_LAUNCH} gnome-extensions enable user-theme@gnome-shell-extensions.gcampax.github.com +${DBUS_LAUNCH} gnome-extensions enable system-monitor@gnome-shell-extensions.gcampax.github.com + +echo "Setting up Gnome settings..." + +configure_gnome_settings +configure_dash2dock_settings diff --git a/mymachine.sh b/mymachine.sh new file mode 100755 index 0000000..3c8ca0e --- /dev/null +++ b/mymachine.sh @@ -0,0 +1,211 @@ +#!/usr/bin/env bash + +if [ -z "${USERNAME}" ]; then + USERNAME=${USER} +fi +EMAIL=${EMAIL} +USER_COMMENT=${USER_COMMENT} +USER_PICTURE_URL=${USER_PICTURE_URL} +PASSWORD=${PASSWORD} + +YCMD="yes O" +KEYMAP=fr + +DBUS_LAUNCH="sudo -u ${USERNAME}" +MICROCODE_INSTALLED=true + +current_dir=$(pwd) +script_dir=$(dirname -- $(readlink -f $0)) +script_name=$(basename $0) + +# Check if stdout is tty before outputting color +if [ -t 1 ]; then + BGreen='\033[1;32m' + BRed='\033[1;31m' + BYellow='\033[1;33m' + BNC='\033[1m' + NC='\033[0m' +else + BGreen='' + BRed='' + BYellow='' + BNC='' + NC='' +fi + +# Trap SIGINT +trap handle_int INT +handle_int() { + echo -e "\n${BYellow}SIGINT captured, terminated.${NC}" + exit 1 +} + +# Make sure we are running as root +if [[ $EUID -ne 0 ]]; then + # If we are not running as root, try to relaunch ourselves as root + echo -e "${BNC}Testing root access...${NC}" + sudo bash -c "USERNAME=${USERNAME} GIT_USER=${GIT_USER} EMAIL=${EMAIL} USER_COMMENT=${USER_COMMENT} USER_PICTURE_URL=${USER_PICTURE_URL} PASSWORD=${PASSWORD} ${script_dir}/${script_name}" + exit $? +else + echo -e "${BNC}Root access obtained.${NC}" +fi + +# Ask the user to input PASSWORD if not set +if [ -z "${USERNAME}" ] || [ ${USERNAME} = "root" ]; then + read -p "Username: " USERNAME +fi +if [[ -z ${GIT_USER} ]]; then + GIT_USER=$(git config --global user.name) + if [ -z ${GIT_USER} ]; then + GIT_USER=${USERNAME} + fi +fi +# Ask for user comment and password if user does not yet exist +if ! id "${USERNAME}" >/dev/null 2>&1; then + if [ -z "${USER_COMMENT}" ]; then + read -p "Full name: " USER_COMMENT + fi + if [ -z "${PASSWORD}" ]; then + read -s -p "Password: " PASSWORD + fi + echo "" +fi +if [ -z ${EMAIL} ]; then + EMAIL=$(git config --global user.email) + if [ -z ${EMAIL} ]; then + read -p "Email: " EMAIL + fi +fi +if [ -z "${USER_PICTURE_URL}" ] && [ ! -f "/var/lib/AccountsService/icons/${USERNAME}" ]; then + read -p "User profile picture URL (leave blank for none): " USER_PICTURE_URL +fi + +# Detect distribution +source /etc/os-release +if ! [[ -d ${current_dir}/distribution/${ID} ]]; then + echo -e "${BRed}Error: distribution ${ID} not supported. Terminating.${NC}" + return 1 2>/dev/null || exit 1 +fi + +echo -e "${BNC}Detected distribution ${NAME} (${ID})${NC}" + +# Initial configuration step +source ${current_dir}/distribution/${ID}/initial_config.sh + +# Change directory to user home +cd /home/${USERNAME}/ + +# Authorize members of group ${WHEEL_GROUP} to sudo, without password +echo "%${WHEEL_GROUP} ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers +if [ $? -ne 0 ]; then + echo "Failed to edit /etc/sudoers" + return 1 2>/dev/null || exit 1 +fi + +# Install packages +source ${current_dir}/distribution/${ID}/install.sh +install_package() { + package="${1}" + command="${2}" + + # Print current package on terminal + echo -ne "${package}" + + ${command} "${package}" + if [ $? -ne 0 ]; then + echo -e "\n${BRed}Failed to install package '${package}'. Skipping." + fi + + # Remove current package name from terminal + count=$(echo "${package}" | wc -m) + for ((i=1; i<$count; i++)); do echo -ne '\b'; done + for ((i=1; i<$count; i++)); do echo -ne ' '; done + for ((i=1; i<$count; i++)); do echo -ne '\b'; done +} + +refresh_package_db +if [ $? -ne 0 ]; then + echo -e "${BRed}Could not refresh package database. Terminating." + return 1 2>/dev/null || exit 1 +fi + +echo -ne "Installing packages... " +for package in "${PACKAGES[@]}"; do + install_package "${package}" install_package_command +done +echo "" + +# Install distribution-specific extra packages +extra_init +echo -ne "${EXTRA_INSTALL_MESSAGE}... " +for package in "${EXTRA_PACKAGES[@]}"; do + install_package "${package}" install_extra_command +done +echo "" +extra_finish + +# GNOME SETTINGS, EXTENSIONS, ... +source "${script_dir}/gnome.sh" + +# Create gnome/gdm user info file +if ! [ -z "${USER_PICTURE_URL}" ]; then + echo "Downloading user profile picture..." + curl -L -o "/var/lib/AccountsService/icons/${USERNAME}" "${USER_PICTURE_URL}" + echo -e "[User]\nSession=\nIcon=/var/lib/AccountsService/icons/${USERNAME}\nSystemAccount=false\n" > /var/lib/AccountsService/users/${USERNAME} +fi + +# Install VSCode extensions +export VSCODE_EXTENSIONS="${script_dir}/vscode-extensions.txt" +echo -ne "Installing VSCode extensions... " +i=0 total=$(wc -l < ${VSCODE_EXTENSIONS}); while read ext; do + # TODO: Here we assume extensions are at most a 2-digit number ; change that :) + istr=$(printf "%02d" $i) + echo -ne "\b\b\b\b\b${istr}/${total}" + sudo -u ${USERNAME} code --install-extension "${ext}" >/dev/null 2>&1 + if [ $? -ne 0 ]; then + echo -e "\n${BRed}Error when installing VSCode extensions. Failing extension: '${ext}'${NC}\nSkipping next extensions, manual intervention required." + break + fi + i=$((i + 1)) +done <"${VSCODE_EXTENSIONS}"; +if [[ $i = $total ]]; then + echo -ne "\b\b\b\b\b${total}/${total}" + echo "" +fi + +# Install dotfiles +echo "Installing dotfiles..." +cp -r ${script_dir}/dotfiles/. /home/${USERNAME}/ +cat ${script_dir}/dotfiles/.config/git/config | envsubst '$GIT_USER $EMAIL' >/home/${USERNAME}/.config/git/config + +# TODO: Setup GRUB theme +echo "Setting up GRUB theme..." +# $YCMD | pacman -S grub-theme-vimix +# sed -i 's/#GRUB_THEME=\"\/path\/to\/gfxtheme\"/GRUB_THEME=\"\/usr\/share\/grub\/themes\/Vimix\/theme.txt\"/' /etc/default/grub +# if [ $? -ne 0 ]; then +# echo "Failed to edit /etc/default/grub (to enable grub theme)" +# return 1 2>/dev/null || exit 1 +# fi +grub-mkconfig -o /boot/grub/grub.cfg >/dev/null 2>/dev/null + +# VPN configuration +echo "Setting up VPN..." +# sudo -u ${USERNAME} mkdir /home/${USERNAME}/.wireguard +# sudo -u ${USERNAME} wg genkey > /home/${USERNAME}/.wireguard/privatekey +# TODO: Add networkmanager wireguard connection + +# Print last setup needed message +echo -e "${BNC}MyMachine is done${NC}" +if [[ "${ID}" = "arch" ]]; then + echo "Now you need to check if GDM works, and enable it if so (or install graphics drivers if not)" + echo "You also need to install video decode hwaccel drivers (libva, ...)" +fi +if [ "$MICROCODE_INSTALLED" == "false" ]; then + echo "We could not detect your processor brand (${CPU_VENDOR}) ; you may need to install microcode manually" + if [[ "${ID}" = "arch" ]]; then + echo "Packages: pacman -S amd-ucode/intel-ucode, then regenerate grub config" + fi +fi +echo "To use WireGuard, don't forget to add this client on VPN server (your private key is under ~/.wireguard/privatekey)" +echo "To use GitHub, you need to use 'gh auth login' to connect to GitHub" +echo -e "${BNC}Goodbye !${NC}" diff --git a/vscode-extensions.txt b/vscode-extensions.txt new file mode 100644 index 0000000..9b0e325 --- /dev/null +++ b/vscode-extensions.txt @@ -0,0 +1,55 @@ +13xforever.language-x86-64-assembly +arcticicestudio.nord-visual-studio-code +bradlc.vscode-tailwindcss +catppuccin.catppuccin-vsc +catppuccin.catppuccin-vsc-icons +dan-c-underwood.arm +dansilver.typewriter +docker.docker +donjayamanne.githistory +drcika.apc-extension +exodiusstudios.comment-anchors +foxundermoon.shell-format +ggml-org.llama-vscode +hashicorp.terraform +james-yu.latex-workshop +johnpapa.vscode-peacock +luniclynx.bison +mathiasfrohlich.kotlin +ms-azuretools.vscode-containers +ms-ceintl.vscode-language-pack-fr +ms-kubernetes-tools.vscode-kubernetes-tools +ms-python.debugpy +ms-python.python +ms-python.vscode-pylance +ms-vscode-remote.remote-containers +ms-vscode-remote.remote-ssh +ms-vscode-remote.remote-ssh-edit +ms-vscode.cmake-tools +ms-vscode.cpptools +ms-vscode.cpptools-extension-pack +ms-vscode.cpptools-themes +ms-vscode.hexeditor +ms-vscode.makefile-tools +ms-vscode.remote-explorer +ms-vscode.vscode-serial-monitor +nvarner.typst-lsp +piousdeer.adwaita-theme +pkief.material-icon-theme +pkief.material-product-icons +plorefice.devicetree +prince781.vala +redhat.vscode-xml +redhat.vscode-yaml +ritwickdey.liveserver +sztheory.vscode-packer-powertools +tboox.xmake-vscode +valentjn.vscode-ltex +vasilescur.better-mips +vscjava.vscode-gradle +vue.volar +wokwi.wokwi-vscode +xaver.clang-format +zhuangtongfa.material-theme +zhwu95.riscv +zixuanwang.linkerscript