From 8ed3ec6551d566d99cd05b773d5f4ae097e09c7d Mon Sep 17 00:00:00 2001 From: Brian Zalewski <59970525+ProfessorManhattan@users.noreply.github.com> Date: Wed, 20 Dec 2023 05:18:20 +0000 Subject: [PATCH] Latest --- home/.chezmoidata.yaml | 1 - .../run_onchange_after_05-postfix.sh.tmpl | 154 --- .../run_onchange_after_14-keybase.sh.tmpl | 27 - .../run_onchange_after_14-timeshift.sh.tmpl | 24 - ...nchange_after_26-vscode-extensions.sh.tmpl | 72 - .../run_onchange_after_40-chrome.sh.tmpl | 95 -- .../run_onchange_after_40-firefox.sh.tmpl | 345 ----- .../run_onchange_after_45-vmware.sh.tmpl | 202 --- .../run_onchange_after_46_virtualbox.sh.tmpl | 45 - .../run_onchange_after_57-netdata.sh.tmpl | 169 --- home/dot_config/shell/private_private.sh.tmpl | 16 +- software.yml | 1200 +++++++++++++++++ 12 files changed, 1212 insertions(+), 1138 deletions(-) delete mode 100644 home/.chezmoiscripts/universal/run_onchange_after_05-postfix.sh.tmpl delete mode 100644 home/.chezmoiscripts/universal/run_onchange_after_14-keybase.sh.tmpl delete mode 100644 home/.chezmoiscripts/universal/run_onchange_after_14-timeshift.sh.tmpl delete mode 100644 home/.chezmoiscripts/universal/run_onchange_after_26-vscode-extensions.sh.tmpl delete mode 100644 home/.chezmoiscripts/universal/run_onchange_after_40-chrome.sh.tmpl delete mode 100644 home/.chezmoiscripts/universal/run_onchange_after_40-firefox.sh.tmpl delete mode 100644 home/.chezmoiscripts/universal/run_onchange_after_45-vmware.sh.tmpl delete mode 100644 home/.chezmoiscripts/universal/run_onchange_after_46_virtualbox.sh.tmpl delete mode 100644 home/.chezmoiscripts/universal/run_onchange_after_57-netdata.sh.tmpl diff --git a/home/.chezmoidata.yaml b/home/.chezmoidata.yaml index 24417f05..ae25a892 100644 --- a/home/.chezmoidata.yaml +++ b/home/.chezmoidata.yaml @@ -39,7 +39,6 @@ docker: internalSubnet: 10.93.92.0 kubernetesHost: kochab macosRemoteLogin: 'on' -netdataClaimURL: https://app.netdata.cloud themeparkTheme: aquamarine figmaAddons: - https://www.figma.com/community/plugin/1037309320238203168/DhiWise---Figma-to-Code diff --git a/home/.chezmoiscripts/universal/run_onchange_after_05-postfix.sh.tmpl b/home/.chezmoiscripts/universal/run_onchange_after_05-postfix.sh.tmpl deleted file mode 100644 index b2813f34..00000000 --- a/home/.chezmoiscripts/universal/run_onchange_after_05-postfix.sh.tmpl +++ /dev/null @@ -1,154 +0,0 @@ -{{- if or (and (stat (joinPath .host.home ".config" "age" "chezmoi.txt")) (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "SENDGRID_API_KEY"))) (env "SENDGRID_API_KEY") -}} -#!/usr/bin/env bash -# @file SendGrid Postfix Configuration -# @brief Configures Postfix to use SendGrid as a relay host so you can use the `mail` program to send e-mail from the command-line -# @description -# This script follows the instructions from [SendGrid's documentation on integrating Postfix](https://docs.sendgrid.com/for-developers/sending-email/postfix). -# After this script runs, you should be able to send outgoing e-mails using SendGrid as an SMTP handler. In other words, you will -# be able to use the `mail` CLI command to send e-mails. The following is an example mailing the contents of `~/.bashrc` to `name@email.com`: -# -# ```shell -# cat ~/.bashrc | mail -s "My subject" name@email.com -# ``` - -{{ includeTemplate "universal/profile" }} -{{ includeTemplate "universal/logg" }} - -if command -v postfix > /dev/null; then - ### Ensure dependencies are installed - if command -v apt-get > /dev/null; then - logg info 'Installing libsasl2-modules' - sudo apt-get update - sudo apt-get install -y libsasl2-modules || EXIT_CODE=$? - elif command -v dnf > /dev/null; then - sudo dnf install -y cyrus-sasl-plain || EXIT_CODE=$? - elif command -v yum > /dev/null; then - sudo yum install -y cyrus-sasl-plain || EXIT_CODE=$? - fi - if [ -n "$EXIT_CODE" ]; then - logg warn 'There was an error ensuring the Postfix-SendGrid dependencies were installed' - fi - - if [ -d /etc/postfix ]; then - ### Add the SendGrid Postfix settings to the Postfix configuration - if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}/postfix/main.cf" ]; then - CONFIG_FILE=/etc/postfix/main.cf - if cat "$CONFIG_FILE" | grep '### INSTALL DOCTOR MANAGED' > /dev/null; then - logg info 'Removing Install Doctor-managed block of code in /etc/postfix/main.cf block' - START_LINE="$(echo `grep -n -m 1 "### INSTALL DOCTOR MANAGED ### START" "$CONFIG_FILE" | cut -f1 -d ":"`)" - END_LINE="$(echo `grep -n -m 1 "### INSTALL DOCTOR MANAGED ### END" "$CONFIG_FILE" | cut -f1 -d ":"`)" - if [ -n "$START_LINE" ] && [ -n "$END_LINE" ]; then - if command -v gsed > /dev/null; then - sudo gsed -i "${START_LINE},${END_LINE}d" "$CONFIG_FILE" - else - sudo sed -i "${START_LINE},${END_LINE}d" "$CONFIG_FILE" - fi - else - logg info 'No start-line or end-line detected - configuration appears to already be clean' - fi - fi - - ### Add Postfix main configuration - logg "Adding the following configuration from ${XDG_CONFIG_HOME:-$HOME/.config}/postfix/main.cf to /etc/postfix/main.cf" - cat "${XDG_CONFIG_HOME:-$HOME/.config}/postfix/main.cf" | sudo tee -a "$CONFIG_FILE" > /dev/null - echo "" | sudo tee -a "$CONFIG_FILE" > /dev/null - fi - - ### Ensure proper permissions on `sasl_passwd` and update Postfix hashmaps - if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}/postfix/sasl_passwd" ]; then - logg info "Copying file from ${XDG_CONFIG_HOME:-$HOME/.config}/postfix/sasl_passwd to /etc/postfix/sasl_passwd" - sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/postfix/sasl_passwd" /etc/postfix/sasl_passwd - logg info 'Assigning proper permissions to /etc/postfix/sasl_passwd' - sudo chmod 600 /etc/postfix/sasl_passwd - logg info 'Updating Postfix hashmaps for /etc/postfix/sasl_passwd' - sudo postmap /etc/postfix/sasl_passwd - else - logg warn '~/.config/postfix/sasl_passwd file is missing' - fi - - ### Forward root e-mails - if [ -d /root ]; then - logg info 'Forwarding root e-mails to {{ .user.email }}' - echo '{{ .user.email }}' | sudo tee /root/.forward > /dev/null || logg error 'Failed to set root user .forward file' - elif [ -d /var/root ]; then - logg info 'Forwarding root e-mails to {{ .user.email }}' - echo '{{ .user.email }}' | sudo tee /var/root/.forward > /dev/null || logg error 'Failed to set root user .forward file' - else - logg warn 'Unable to identify root user home directory' - fi - - ### Ensure /etc/postfix/header_checks exists - if [ ! -d /etc/postfix/header_checks ]; then - logg info 'Creating /etc/postfix/header_checks since it does not exist' - sudo touch /etc/postfix/header_checks - fi - - ### Re-write header From for SendGrid - if ! cat /etc/postfix/header_checks | grep 'no-reply@{{ .host.domain }}' > /dev/null; then - logg info 'Added From REPLACE to /etc/postfix/header_checks' - echo '/^From:.*@{{ .host.domain }}/ REPLACE From: no-reply@{{ .host.domain }}' | sudo tee -a /etc/postfix/header_checks > /dev/null - fi - - ### Update aliases - if [ -f /etc/aliases ]; then - logg info 'Forward root e-mails to {{ .user.email }}' - ALIASES_TMP="$(mktemp)" - logg info 'Setting {{ .user.email }} as root e-mail in temporary file' - sudo sed "s/#root.*/root:\ {{ .user.email }}/" /etc/aliases > "$ALIASES_TMP" - logg info 'Moving temporary file to /etc/aliases' - sudo mv -f "$ALIASES_TMP" /etc/aliases - if ! cat /etc/aliases | grep '{{ .user.username }}: root' > /dev/null; then - logg info 'Forward user e-mail to root@localhost' - echo '{{ .user.username }}: root' | sudo tee -a /etc/aliases > /dev/null - fi - - ### Ensure old /etc/aliases.db is removed - if [ -f /etc/aliases.db ]; then - logg info 'Ensuring /etc/aliases.db is removed' && sudo rm -f /etc/aliases.db - else - logg info '/etc/aliases.db was not found' - fi - - ### Re-generate the /etc/aliases.db file - if [ -f /etc/aliases ]; then - logg info 'Ensuring proper permissions on the /etc/aliases file' && sudo chown $(stat -c "%U:%G" /etc/sudoers) /etc/aliases - logg info 'Generating Postfix aliases' && sudo postalias /etc/aliases > /dev/null - else - logg warn '/etc/aliases is missing which is required for Postfix' - fi - # The `sudo newaliases` mode is probably used to regenerate the /etc/aliases.db - # but since we are removing it to ensure proper permissions, this method is commented out. - # logg info 'Running newaliases to regenerate the alias database' && sudo newaliases - else - logg warn '/etc/aliases does not appear to exist' - fi - - if [ -d /Applications ] && [ -d /System ]; then - ### macOS - # Source: https://budiirawan.com/install-mail-server-mac-osx/ - if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}/postfix/com.apple.postfix.master.plist" ] && ! sudo launchctl list | grep 'postfix.master' > /dev/null; then - logg info 'Copying com.apple.postfix.master.plist' - sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/postfix/com.apple.postfix.master.plist" /System/Library/LaunchDaemons/com.apple.postfix.master.plist - sudo launchctl load /System/Library/LaunchDaemons/com.apple.postfix.master.plist && logg success 'launchctl load of com.apple.postfix.master successful' - fi - if ! sudo postfix status > /dev/null; then - logg info 'Starting postfix' - sudo postfix start > /dev/null - else - logg info 'Reloading postfix' - sudo postfix reload > /dev/null - fi - else - ### Enable / restart postfix on Linux - logg info 'Enabling / restarting postfix' - sudo systemctl enable postfix - sudo systemctl restart postfix - fi - else - logg warn '/etc/postfix is not a directory! Skipping SendGrid Postfix setup.' - fi -else - logg info 'Skipping Postfix configuration because Postfix is not installed' -fi - -{{ end -}} \ No newline at end of file diff --git a/home/.chezmoiscripts/universal/run_onchange_after_14-keybase.sh.tmpl b/home/.chezmoiscripts/universal/run_onchange_after_14-keybase.sh.tmpl deleted file mode 100644 index a17771da..00000000 --- a/home/.chezmoiscripts/universal/run_onchange_after_14-keybase.sh.tmpl +++ /dev/null @@ -1,27 +0,0 @@ -{{- if eq .host.distro.family "linux" -}} -#!/usr/bin/env bash -# @file Keybase Configuration -# @brief Updates Keybase's system configuration with the Keybase configuration stored in the `home/dot_config/keybase/config.json` location. -# @description -# This script ensures Keybase utilizes a configuration that, by default, adds a security fix. - -# Keybase config hash: {{ include (joinPath .chezmoi.homeDir ".config" "keybase" "config.json") | sha256sum }} - -{{ includeTemplate "universal/profile" }} -{{ includeTemplate "universal/logg" }} - -if command -v keybase > /dev/null; then - KEYBASE_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/keybase/config.json" - if [ -f "$KEYBASE_CONFIG" ]; then - logg info 'Ensuring /etc/keybase is a directory' - sudo mkdir -p /etc/keybase - logg info "Copying $KEYBASE_CONFIG to /etc/keybase/config.json" - sudo cp -f "$KEYBASE_CONFIG" /etc/keybase/config.json - else - logg warn "No Keybase config located at $KEYBASE_CONFIG" - fi -else - logg info 'The keybase executable is not available' -fi - -{{ end -}} diff --git a/home/.chezmoiscripts/universal/run_onchange_after_14-timeshift.sh.tmpl b/home/.chezmoiscripts/universal/run_onchange_after_14-timeshift.sh.tmpl deleted file mode 100644 index cedb5a25..00000000 --- a/home/.chezmoiscripts/universal/run_onchange_after_14-timeshift.sh.tmpl +++ /dev/null @@ -1,24 +0,0 @@ -{{- if eq .host.distro.family "linux" -}} -#!/usr/bin/env bash -# @file Timeshift Configuration -# @brief Updates the Timeshift system configuration with the Timeshift configuration stored in the `home/dot_config/timeshift/timeshift.json` location. -# @description -# This script applies a Timeshift configuration that defines how Timeshift should maintain system backups. - -# timeshift.json hash: {{ include (joinPath .chezmoi.homeDir ".config" "timeshift" "timeshift.json") | sha256sum }} - -{{ includeTemplate "universal/profile" }} -{{ includeTemplate "universal/logg" }} - -if command -v timeshift > /dev/null; then - logg info 'Ensuring /etc/timeshift is a directory' - sudo mkdir -p /etc/timeshift - - TIMESHIFT_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/timeshift/timeshift.json" - logg info "Copying $TIMESHIFT_CONFIG to /etc/timeshift/timeshift.json" - sudo cp -f "$TIMESHIFT_CONFIG" /etc/timeshift/timeshift.json -else - logg info 'The timeshift executable is not available' -fi - -{{ end -}} diff --git a/home/.chezmoiscripts/universal/run_onchange_after_26-vscode-extensions.sh.tmpl b/home/.chezmoiscripts/universal/run_onchange_after_26-vscode-extensions.sh.tmpl deleted file mode 100644 index 30255d4e..00000000 --- a/home/.chezmoiscripts/universal/run_onchange_after_26-vscode-extensions.sh.tmpl +++ /dev/null @@ -1,72 +0,0 @@ -{{- if (ne .host.distro.family "windows") -}} -#!/usr/bin/env bash -# @file VSCode Extensions -# @brief Installs all of the Visual Studio Code extensions specified in the [`home/dot_config/Code/User/extensions.json`](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/Code/User/extensions.json) file. -# @description -# This script loops through all the extensions listed in the [`home/dot_config/Code/User/extensions.json`](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/Code/User/extensions.json) -# file. It installs the extensions when either Visual Studio Code or VSCodium is installed. If both are installed, then both will -# have the plugins automatically installed. -# -# The `extensions.json` file is used to house the plugin list so that if you decide to remove this auto-installer script then -# VSCode will retain some functionality from the file. It will show a popover card that recommends installing any plugins in the -# list that are not already installed. -# -# ## Plugin Settings -# -# Most of the plugin settings have been configured and optimized to work properly with the other default settings -# included by Install Doctor. These settings can be found in the [`home/dot_config/Code/User/settings.json` file](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/Code/User/settings.json). -# If you manage to come up with an improvement, please open a pull request so other users can benefit from your work. -# -# ## Default Extensions -# -# The default plugins in the `extensions.json` list are catered mostly towards full-stack web development. The technologies -# that are catered to by the default extensions relate to TypeScript, JavaScript, Go, Python, Rust, and many more technologies. -# Most of the plugins are not language-specific. -# -# ## Links -# -# * [Visual Studio Code settings folder](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/Code/User) -# * [Visual Studio Code `extensions.json`](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/Code/User/extensions.json) - -{{ includeTemplate "universal/profile" }} -{{ includeTemplate "universal/logg" }} - -### Hides useless error during extension installations -# Error looks like: -# (node:53151) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead. -# (Use `Electron --trace-deprecation ...` to show where the warning was created) -export NODE_OPTIONS=--throw-deprecation - -# @description Install Visual Studio Code extensions if they are not already installed (by checking the `code --list-extensions` output) -if command -v code > /dev/null; then - EXTENSIONS="$(code --list-extensions)" - jq -r '.recommendations[]' "${XDG_CONFIG_HOME:-$HOME/.config}/Code/User/extensions.json" | while read EXTENSION; do - if ! echo "$EXTENSIONS" | grep -iF "$EXTENSION" > /dev/null; then - logg info 'Installing Visual Studio Code extension '"$EXTENSION"'' - code --install-extension "$EXTENSION" - logg success 'Installed '"$EXTENSION"'' - else - logg info ''"$EXTENSION"' already installed' - fi - done -else - logg info 'code executable not available - skipping plugin install process for it' -fi - -# @description Check for the presence of the `codium` command in the `PATH` and install extensions for VSCodium if it is present -if command -v codium > /dev/null; then - EXTENSIONS="$(codium --list-extensions)" - jq -r '.recommendations[]' "${XDG_CONFIG_HOME:-$HOME/.config}/Code/User/extensions.json" | while read EXTENSION; do - if ! echo "$EXTENSIONS" | grep -iF "$EXTENSION" > /dev/null; then - logg info 'Installing VSCodium extension '"$EXTENSION"'' - codium --install-extension "$EXTENSION" - logg success 'Installed '"$EXTENSION"'' - else - logg info ''"$EXTENSION"' already installed' - fi - done -else - logg info 'codium executable not available - skipping plugin install process for it' -fi - -{{ end -}} diff --git a/home/.chezmoiscripts/universal/run_onchange_after_40-chrome.sh.tmpl b/home/.chezmoiscripts/universal/run_onchange_after_40-chrome.sh.tmpl deleted file mode 100644 index 9b0eba22..00000000 --- a/home/.chezmoiscripts/universal/run_onchange_after_40-chrome.sh.tmpl +++ /dev/null @@ -1,95 +0,0 @@ -{{- if ne .host.distro.family "windows" -}} -#!/usr/bin/env bash -# @file Chrome Settings / Extensions -# @brief This script configures Chrome, Brave, and Chromium system-wide managed / recommended policies settings. It also pre-loads a configurable list of Chrome extensions to Chrome, Brave, Chromium, and Edge (if they are installed). -# @description -# This Chrome setup script applies system-wide settings and pre-loads Chrome extensions into the browser profiles. The -# extensions still must be enabled but they appear in the Chrome extensions menu and can be enabled with the toggle. The -# system settings are applied to Chrome, Chromium, and Brave. Extensions are installed to the same browsers plus Microsoft Edge. -# -# ## Features -# -# * Adds `~/.config/chrome/managed.json` to the `managed/policies.json` system locations -# * Adds `~/.config/chrome/recommended.json` to the `recommended/policies.json` system locations -# * Pre-loads extension metadata for all the extensions defined under `chromeExtensions` in the [`home/.chezmoidata.yaml`](https://github.com/megabyte-labs/install.doctor/blob/master/home/.chezmoidata.yaml) file -# -# ## TODO -# -# * Automatically enable the extensions that are pre-loaded -# * Create several profiles with different characteristics (similar to the Firefox setup script) -# * Ensure the directories that the script cycles through to install managed settings and extensions are complete for all installation types (i.e. there might need to be some additions for Flatpak installations since their folder structure is different) -# * Document how [`chromium-flags.conf`](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/chromium-flags.conf) can be or is integrated -# -# ## Links -# -# * [`managed.json`](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/chrome/managed.json) -# * [`recommended.json`](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/chrome/recommended.json) - -{{ includeTemplate "universal/profile" }} -{{ includeTemplate "universal/logg" }} - -function chromeSetUp() { - ### Ensure Chrome policies directory is present - logg info 'Processing policy directories for Chromium based browsers' - for POLICY_DIR in "/opt/google/chrome/policies" "/etc/chromium/policies" "/etc/brave/policies"; do - if [ -d "$(dirname "$POLICY_DIR")" ]; then - ### Managed policies - if [ ! -f "$POLICY_DIR/managed/policies.json" ]; then - logg info "Ensuring directory $POLICY_DIR/managed exists" - sudo mkdir -p "$POLICY_DIR/managed" - logg info "Copying ${XDG_CONFIG_HOME:-$HOME/.config}/chrome/managed.json to $POLICY_DIR/managed/policies.json" - sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/managed.json" "$POLICY_DIR/managed/policies.json" - fi - - ### Recommended policies - if [ ! -f "$POLICY_DIR/recommended/policies.json" ]; then - logg info "Ensuring directory $POLICY_DIR/recommended exists" - sudo mkdir -p "$POLICY_DIR/recommended" - logg info "Copying ${XDG_CONFIG_HOME:-$HOME/.config}/chrome/recommended.json to $POLICY_DIR/recommended/policies.json" - sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/recommended.json" "$POLICY_DIR/recommended/policies.json" - fi - else - logg info "Skipping extension injection into $POLICY_DIR - create these folders prior to running to create managed configs" - fi - done - - ### Add Chrome extension JSON - logg info 'Populating Chrome extension JSON' - for EXTENSION_DIR in "/opt/google/chrome/extensions" "/etc/chromium/extensions" "/etc/brave/extensions" "$HOME/Library/Application Support/Google/Chrome/External Extensions" "$HOME/Library/Application Support/Microsoft/Edge/External Extensions" "$HOME/Library/Application Support/BraveSoftware/Brave-Browser/External Extensions"; do - ### Ensure program-type is installed - if [ -d "$(dirname "$EXTENSION_DIR")" ]; then - ### Ensure extension directory exists - if [[ "$EXTENSION_DIR" == '/opt/'* ]] || [[ "$EXTENSION_DIR" == '/etc/'* ]]; then - if [ ! -d "$EXTENSION_DIR" ]; then - logg info "Creating directory $EXTENSION_DIR" - sudo mkdir -p "$EXTENSION_DIR" - fi - else - if [ ! -d "$EXTENSION_DIR" ]; then - logg info "Creating directory $EXTENSION_DIR" - mkdir -p "$EXTENSION_DIR" - fi - fi - - ### Add extension JSON - logg info "Adding Chrome extensions to $EXTENSION_DIR" - for EXTENSION in {{ list (.chromeExtensions | toString | replace "[" "" | replace "]" "") | uniq | join " " }}; do - logg info "Adding Chrome extension manifest ($EXTENSION)" - if ! echo "$EXTENSION" | grep 'https://chrome.google.com/webstore/detail/' > /dev/null; then - EXTENSION="https://chrome.google.com/webstore/detail/$EXTENSION" - fi - EXTENSION_ID="$(echo "$EXTENSION" | sed 's/^.*\/\([^\/]*\)$/\1/')" - if [[ "$EXTENSION_DIR" == '/opt/'* ]] || [[ "$EXTENSION_DIR" == '/etc/'* ]]; then - sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/extension.json" "$EXTENSION_DIR/${EXTENSION_ID}.json" - else - cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/extension.json" "$EXTENSION_DIR/${EXTENSION_ID}.json" - fi - done - else - logg info "$EXTENSION_DIR does not exist" - fi - done -} -chromeSetUp - -{{ end -}} diff --git a/home/.chezmoiscripts/universal/run_onchange_after_40-firefox.sh.tmpl b/home/.chezmoiscripts/universal/run_onchange_after_40-firefox.sh.tmpl deleted file mode 100644 index c149939e..00000000 --- a/home/.chezmoiscripts/universal/run_onchange_after_40-firefox.sh.tmpl +++ /dev/null @@ -1,345 +0,0 @@ -{{- if ne .host.distro.family "windows" -}} -#!/usr/bin/env bash -# @file Firefox Settings / Add-Ons / Profiles -# @brief This script configures system-wide settings, sets up Firefox Profile Switcher, creates various profiles from different sources, and installs a configurable list of Firefox Add-Ons. -# @description -# The Firefox setup script performs a handful of tasks that automate the setup of Firefox as well as -# useful utilities that will benefit Firefox power-users. The script also performs the same logic on -# [LibreWolf](https://librewolf.net/) installations. -# -# ## Features -# -# * Installs and sets up [Firefox Profile Switcher](https://github.com/null-dev/firefox-profile-switcher) -# * Sets up system-wide enterprise settings (with configurations found in `~/.local/share/firefox`) -# * Sets up a handful of default profiles to use with the Firefox Profile Switcher -# * Automatically installs the plugins defined in the firefoxAddOns key of [`home/.chezmoidata.yaml`](https://github.com/megabyte-labs/install.doctor/blob/master/home/.chezmoidata.yaml) to the Standard and Private profiles -# * Configures the default profile to clone its settings from the profile stored in firefoxPublicProfile of `home/.chezmoidata.yaml` -# * Optionally, if the Chezmoi encryption key is present, then the default profile will be set to the contents of an encrypted `.tar.gz` that must be stored in the cloud somewhere (with the firefoxPrivateProfile key in `home/.chezmoidata.yaml` defining the URL of the encrypted `.tar.gz`) -# -# ## Profiles -# -# The script sets up numerous profiles for user flexibility. They can be switched by using the Firefox Profile Switcher -# that this script sets up. The map of the profiles is generated by using the template file stored in `~/.local/share/firefox/profiles.ini`. -# The following details the features of each profile: -# -# | Name | Description | -# |------------------|---------------------------------------------------------------------------------------------| -# | Factory | Default browser settings (system-wide configurations still apply) | -# | default-release | Same as Factory (unmodified and generated by headlessly opening Firefox / LibreWolf) | -# | Git (Public) | Pre-configured profile with address stored in `firefoxPublicProfile` | -# | Standard | Cloned from the profile above with `firefoxAddOns` also installed | -# | Miscellaneous | Cloned from the Factory profile (with the user.js found in `~/.config/firefox` applied) | -# | Development | Same as Miscellaneous | -# | Automation | Same as Miscellaneous | -# | Private | Populated from an encrypted profile stored in the cloud (also installs `firefoxAddOns`) | -# -# ## Notes -# -# * The Firefox Profile Switcher is only compatible with Firefox and not LibreWolf -# * This script is only designed to properly provision profiles on a fresh installation (so it does not mess around with pre-existing / already configured profiles) -# * Additional profiles for LibreWolf are not added because the Firefox Profile Switcher is not compatible with LibreWolf -# -# ## Links -# -# * [System-wide configurations](https://github.com/megabyte-labs/install.doctor/tree/master/home/dot_local/share/firefox) as well as the location of the `profile.ini` and some other configurations -# * [User-specific configurations](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/firefox/user.js) added to all profiles except Factory - -{{ includeTemplate "universal/profile" }} -{{ includeTemplate "universal/logg" }} - -# Firefox plugins: {{ list (.firefoxAddOns | toString | replace "[" "" | replace "]" "") | uniq | join " " }} - -logg info 'Processing post-logic for Firefox-based browsers' -function firefoxSetup() { - ### Installs the Firefox Profile Connector on Linux systems (Snap / Flatpak installs are not included in this function, but instead inline below) - function installFirefoxProfileConnector() { - logg info 'Installing the Firefox Profile Connector' - if command -v apt-get > /dev/null; then - sudo apt-get install -y https://github.com/null-dev/firefox-profile-switcher-connector/releases/latest/download/linux-x64.deb - elif command -v dnf > /dev/null; then - sudo dnf install -y https://github.com/null-dev/firefox-profile-switcher-connector/releases/latest/download/linux-x64.rpm - elif command -v yay > /dev/null; then - yay -Ss firefox-profile-switcher-connector - else - logg warn 'apt-get, dnf, and yay were all unavailable so the Firefox Profile Connector helper executable could not be installed' - fi - - } - - ### Add Firefox enterprise profile - # TODO - figure out how to do this for other installations like Flatpak and macOS and Librewolf - for FIREFOX_DIR in '/usr/lib/firefox' '/usr/lib/firefox-esr' '/etc/firefox' '/etc/firefox-esr' '/Applications/Firefox.app/Contents/Resources' '/Applications/LibreWolf.app/Contents/Resources/'; do - if [ -d "$FIREFOX_DIR" ] && [ -d "${XDG_DATA_HOME:-$HOME/.local/share}/firefox" ] && command -v rsync > /dev/null; then - logg info "Syncing enterprise profiles from ${XDG_DATA_HOME:-$HOME/.local/share}/firefox to $FIREFOX_DIR" - sudo rsync -artvu "${XDG_DATA_HOME:-$HOME/.local/share}/firefox/" "$FIREFOX_DIR" > /dev/null - fi - done - - ### Loop through various Firefox profile locations - for SETTINGS_DIR in "$HOME/snap/firefox/common/.mozilla/firefox" "$HOME/.var/app/org.mozilla.firefox/.mozilla/firefox" "$HOME/.var/app/io.gitlab.librewolf-community/.librewolf" "$HOME/Library/Application Support/Firefox/Profiles" "$HOME/Library/Application Support/LibreWolf/Profiles" "$HOME/.mozilla/firefox"; do - ### Determine executable to use - logg info "Processing Firefox profile location $SETTINGS_DIR" - unset FIREFOX_EXE - if [ "$SETTINGS_DIR" == "$HOME/.var/app/org.mozilla.firefox/.mozilla/firefox" ]; then - if ! command -v org.mozilla.firefox > /dev/null || [ ! -d "$HOME/.var/app/org.mozilla.firefox" ]; then - continue - else - FIREFOX_EXE="$(which org.mozilla.firefox)" - - ### Firefox Profile Switcher - BASE_DIR="$HOME/.var/app/org.mozilla.firefox" - BIN_INSTALL_DIR="$BASE_DIR/data/firefoxprofileswitcher-install" - MANIFEST_INSTALL_DIR="$BASE_DIR/.mozilla/native-messaging-hosts" - DOWNLOAD_URL="https://github.com/null-dev/firefox-profile-switcher-connector/releases/latest/download/linux-x64.deb" - - ### Ensure Firefox Profile Switcher is not already installed - if [ ! -f "$BIN_INSTALL_DIR/usr/bin/ff-pswitch-connector" ] || [ ! -f "$MANIFEST_INSTALL_DIR/ax.nd.profile_switcher_ff.json" ]; then - ### Download profile switcher - mkdir -p "$BIN_INSTALL_DIR" - TMP_FILE="$(mktemp)" - logg info 'Downloading Firefox Profile Switch connector' - curl -sSL "$DOWNLOAD_URL" -o "$TMP_FILE" - ar p "$TMP_FILE" data.tar.xz | tar xfJ - --strip-components=2 -C "$BIN_INSTALL_DIR" usr/bin/ff-pswitch-connector - rm -f "$TMP_FILE" - - ### Create manifest - logg info 'Copying profile switcher configuration to manifest directory' - mkdir -p "$MANIFEST_INSTALL_DIR" - cat "${XDG_DATA_HOME:-$HOME/.local/share}/firefox/profile-switcher.json" | sed 's=PATH_PLACEHOLDER='"$BIN_INSTALL_DIR"'=' > "$MANIFEST_INSTALL_DIR/ax.nd.profile_switcher_ff.json" - fi - fi - elif [ "$SETTINGS_DIR" == "$HOME/.var/app/io.gitlab.librewolf-community/.librewolf" ]; then - if ! command -v io.gitlab.librewolf-community > /dev/null || [ ! -d "$HOME/.var/app/io.gitlab.librewolf-community" ]; then - continue - else - FIREFOX_EXE="$(which io.gitlab.librewolf-community)" - fi - elif [ "$SETTINGS_DIR" == "$HOME/Library/Application Support/Firefox/Profiles" ]; then - FIREFOX_EXE="/Applications/Firefox.app/Contents/MacOS/firefox" - if [ ! -f "$FIREFOX_EXE" ] || [ ! -d /Applications ]; then - continue - else - ### Download Firefox Profile Switcher - if [ ! -d /usr/local/Cellar/firefox-profile-switcher-connector ]; then - logg info 'Ensuring Firefox Profile Switcher is installed' - brew install --quiet null-dev/firefox-profile-switcher/firefox-profile-switcher-connector - fi - - ### Ensure Firefox Profile Switcher configuration is symlinked - if [ ! -d "/Library/Application Support/Mozilla/NativeMessagingHosts/ax.nd.profile_switcher_ff.json" ]; then - logg info 'Ensuring Firefox Profile Switcher is configured' - sudo mkdir -p "/Library/Applcation Support/Mozilla/NativeMessagingHosts" - sudo ln -sf "$(brew ls -l firefox-profile-switcher-connector | grep -i ax.nd.profile_switcher_ff.json | head -n1)" "/Library/Application Support/Mozilla/NativeMessagingHosts/ax.nd.profile_switcher_ff.json" - fi - fi - elif [ "$SETTINGS_DIR" == "$HOME/Library/Application Support/LibreWolf/Profiles" ]; then - FIREFOX_EXE="/Applications/LibreWolf.app/Contents/MacOS/librewolf" - if [ ! -f "$FIREFOX_EXE" ] || [ ! -d /Applications ]; then - logg info "$FIREFOX_EXE is not a file" - continue - fi - elif [ "$SETTINGS_DIR" == "$HOME/snap/firefox/common/.mozilla/firefox" ]; then - FIREFOX_EXE="/snap/bin/firefox" - if [ ! -f "$FIREFOX_EXE" ] || [ ! -d "$HOME/snap/firefox" ]; then - continue - else - ### Firefox Profile Switcher - BASE_DIR="$HOME/snap/firefox/common" - BIN_INSTALL_DIR="$BASE_DIR/firefoxprofileswitcher-install" - MANIFEST_INSTALL_DIR="$BASE_DIR/.mozilla/native-messaging-hosts" - DOWNLOAD_URL="https://github.com/null-dev/firefox-profile-switcher-connector/releases/latest/download/linux-x64.deb" - - ### Ensure Firefox Profile Switcher is not already installed - if [ ! -f "$BIN_INSTALL_DIR/usr/bin/ff-pswitch-connector" ] || [ ! -f "$MANIFEST_INSTALL_DIR/ax.nd.profile_switcher_ff.json" ]; then - ### Download profile switcher - mkdir -p "$BIN_INSTALL_DIR" - TMP_FILE="$(mktemp)" - logg info 'Downloading Firefox Profile Switch connector' - curl -sSL "$DOWNLOAD_URL" -o "$TMP_FILE" - ar p "$TMP_FILE" data.tar.xz | tar xfJ - --strip-components=2 -C "$BIN_INSTALL_DIR" usr/bin/ff-pswitch-connector - rm -f "$TMP_FILE" - - ### Create manifest - logg info 'Copying profile switcher configuration to manifest directory' - mkdir -p "$MANIFEST_INSTALL_DIR" - cat "${XDG_DATA_HOME:-$HOME/.local/share}/firefox/profile-switcher.json" | sed 's/PATH_PLACEHOLDER/'"$BIN_INSTALL_DIR"'/' > "$MANIFEST_INSTALL_DIR/ax.nd.profile_switcher_ff.json" - fi - fi - elif [ "$SETTINGS_DIR" == "$HOME/.mozilla/firefox" ]; then - if command -v firefox-esr > /dev/null; then - FIREFOX_EXE="$(which firefox-esr)" - installFirefoxProfileConnector - elif command -v firefox > /dev/null && [ "$(which firefox)" != *'snap'* ] && [ "$(which firefox)" != *'flatpak'* ] && [ ! -d /Applications ] && [ ! -d /System ]; then - # Conditional check ensures Snap / Flatpak / macOS Firefox versions do not try to install to the wrong folder - FIREFOX_EXE="$(which firefox)" - installFirefoxProfileConnector - else - if [ -d /Applications ] && [ -d /System ]; then - # Continue on macOS without logging because profiles are not stored here on macOS - continue - else - logg warn 'Unable to register Firefox executable' - logg info "Settings directory: $SETTINGS_DIR" - continue - fi - fi - fi - ### Initiatize Firefox default profiles - logg info "Processing executable located at $FIREFOX_EXE" - if command -v "$FIREFOX_EXE" > /dev/null; then - ### Create default profile by launching Firefox headlessly - logg info "Firefox executable set to $FIREFOX_EXE" - if [ ! -d "$SETTINGS_DIR" ]; then - logg info 'Running Firefox (or its derivative) headlessly to generate default profiles' - timeout 14 "$FIREFOX_EXE" --headless - logg info 'Finished running Firefox headlessly' - elif [ -d /Applications ] && [ -d /System ] && [ ! -f "$SETTINGS_DIR/../installs.ini" ]; then - logg info 'Running Firefox (or its derivative) headlessly to generate default profiles because install.ini is not at the macOS default location.' - timeout 14 "$FIREFOX_EXE" --headless - logg info 'Finished running Firefox headlessly (while fixing the missing macOS installs.ini issue)' - fi - - ### Ensure settings directory exists (since the application was brought up temporarily headlessly) - if [ ! -d "$SETTINGS_DIR" ]; then - logg warn "The settings directory located at $SETTINGS_DIR failed to be populated by running the browser headlessly" - continue - fi - - ### Add the populated profiles.ini - logg info "Copying "${XDG_DATA_HOME:-$HOME/.local/share}/firefox/profiles.ini" to profile directory" - logg info "The settings directory is $SETTINGS_DIR" - if [ -d /Applications ] && [ -d /System ]; then - # macOS - logg info "Copying ~/.local/share/firefox/profiles.ini to $SETTINGS_DIR/../profiles.ini" - cp -f "${XDG_DATA_HOME:-$HOME/.local/share}/firefox/profiles.ini" "$SETTINGS_DIR/../profiles.ini" - SETTINGS_INI="$SETTINGS_DIR/../installs.ini" - else - # Linux - logg info "Copying ~/.local/share/firefox/profiles.ini to $SETTINGS_DIR/profiles.ini" - cp -f "${XDG_DATA_HOME:-$HOME/.local/share}/firefox/profiles.ini" "$SETTINGS_DIR/profiles.ini" - SETTINGS_INI="$SETTINGS_DIR/installs.ini" - fi - - ### Default profile (created by launching Firefox headlessly) - DEFAULT_RELEASE_PROFILE="$(find "$SETTINGS_DIR" -mindepth 1 -maxdepth 1 -name "*.default" -not -name "profile.default")" - if [ -n "$DEFAULT_RELEASE_PROFILE" ]; then - logg info "Syncing $DEFAULT_RELEASE_PROFILE to $SETTINGS_DIR/profile.default" - rsync -a "$DEFAULT_RELEASE_PROFILE/" "$SETTINGS_DIR/profile.default" - else - logg warn 'Unable to sync default Mozilla Firefox profile' - fi - - ### Ensure original installs.ini is removed - if [ -f "$SETTINGS_INI" ]; then - # DEFAULT_PROFILE_PROFILE="$SETTINGS_DIR/$(cat "$SETTINGS_INI" | grep 'Default=' | sed 's/.*Profiles\///')" - logg info 'Removing previous installs.ini file' - rm -f "$SETTINGS_INI" - else - logg info 'installs.ini was not present in the Mozilla Firefox settings folder' - fi - - ### Miscellaneous default profiles - for NEW_PROFILE in "automation" "development" "miscellaneous"; do - if [ ! -d "$SETTINGS_DIR/profile.${NEW_PROFILE}" ] && [ -d "$SETTINGS_DIR/profile.default" ]; then - logg info "Cloning $NEW_PROFILE from profile.default" - rsync -a "$SETTINGS_DIR/profile.default/" "$SETTINGS_DIR/profile.${NEW_PROFILE}" - rsync -a "${XDG_DATA_HOME:-$HOME/.local/share}/firefox/" "$SETTINGS_DIR/profile.${NEW_PROFILE}" - cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/firefox/user.js" "$SETTINGS_DIR/profile.${NEW_PROFILE}" - fi - done - - ### Public git profile - if [ -d "$SETTINGS_DIR/profile.git" ]; then - logg info 'Resetting the Firefox git profile' - cd "$SETTINGS_DIR/profile.git" - git reset --hard HEAD - git clean -fxd - logg info 'Pulling latest updates to the Firefox git profile' - git pull origin master - else - logg info 'Cloning the public Firefox git profile' - cd "$SETTINGS_DIR" && git clone {{ .firefoxPublicProfile }} profile.git - fi - - ### Copy user.js to profile.git profile - cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/firefox/user.js" "$SETTINGS_DIR/profile.git" - - ### Git profile w/ plugins installed (installation happens below) - if [ ! -d "$SETTINGS_DIR/profile.plugins" ]; then - logg info "Syncing $SETTINGS_DIR/profile.git to $SETTINGS_DIR/profile.plugins" - rsync -a "$SETTINGS_DIR/profile.git/" "$SETTINGS_DIR/profile.plugins" - rsync -a "${XDG_DATA_HOME:-$HOME/.local/share}/firefox/" "$SETTINGS_DIR/profile.plugins" - cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/firefox/user.js" "$SETTINGS_DIR/profile.plugins" - fi - - {{- if stat (joinPath .host.home ".config" "age" "chezmoi.txt") }} - ### Private hosted profile - # Deprecated in favor of using the Restic profile tasks saved in `~/.config/task/Taskfile.yml` - # if [ ! -d "$SETTINGS_DIR/profile.private" ]; then - # logg info 'Downloading the encrypted Firefox private profile' - # cd "$SETTINGS_DIR" - # curl -sSL '{ { .firefoxPrivateProfile } }' -o profile.private.tar.gz.age - # logg info 'Decrypting the Firefox private profile' - # chezmoi decrypt profile.private.tar.gz.age > profile.private.tar.gz || EXIT_DECRYPT_CODE=$? - # if [ -z "$EXIT_DECRYPT_CODE" ]; then - # rm -f profile.private.tar.gz.age - # logg info 'Decompressing the Firefox private profile' - # tar -xzf profile.private.tar.gz - # logg success 'The Firefox private profile was successfully installed' - # cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/firefox/user.js" "$SETTINGS_DIR/profile.private" - # logg info 'Copied ~/.config/firefox/user.js to profile.private profile' - # else - # logg error 'Failed to decrypt the private Firefox profile' - # fi - # fi - {{- end }} - - ### Install Firefox addons (using list declared in .chezmoidata.yaml) - for SETTINGS_PROFILE in "profile.plugins" "profile.private"; do - if [ -d "$SETTINGS_DIR/$SETTINGS_PROFILE" ]; then - for FIREFOX_PLUGIN in {{ list (.firefoxAddOns | toString | replace "[" "" | replace "]" "") | uniq | join " " }}; do - logg info "Processing the $FIREFOX_PLUGIN Firefox add-on" - PLUGIN_HTML="$(mktemp)" - curl --silent "https://addons.mozilla.org/en-US/firefox/addon/$FIREFOX_PLUGIN/" > "$PLUGIN_HTML" - PLUGIN_TMP="$(mktemp)" - if ! command -v htmlq > /dev/null && command -v brew > /dev/null; then - logg info 'Installing htmlq using Homebrew since it is a dependency for populating Firefox add-ons' && brew install htmlq - fi - cat "$PLUGIN_HTML" | htmlq '#redux-store-state' | sed 's/^//' | sed 's/<\/script>$//' > "$PLUGIN_TMP" - PLUGIN_ID="$(jq '.addons.bySlug["'"$FIREFOX_PLUGIN"'"]' "$PLUGIN_TMP")" - if [ "$PLUGIN_ID" != 'null' ]; then - PLUGIN_FILE_ID="$(jq -r '.addons.byID["'"$PLUGIN_ID"'"].guid' "$PLUGIN_TMP")" - if [ "$PLUGIN_FILE_ID" != 'null' ]; then - PLUGIN_URL="$(cat "$PLUGIN_HTML" | htmlq '.InstallButtonWrapper-download-link' --attribute href)" - PLUGIN_FILENAME="${PLUGIN_FILE_ID}.xpi" - PLUGIN_FOLDER="$(echo "$PLUGIN_FILENAME" | sed 's/.xpi$//')" - if [ ! -d "$SETTINGS_DIR/$SETTINGS_PROFILE/extensions/$PLUGIN_FOLDER" ]; then - logg info 'Downloading add-on XPI file for '"$PLUGIN_FILENAME"' ('"$FIREFOX_PLUGIN"')' - if [ ! -d "$SETTINGS_DIR/$SETTINGS_PROFILE/extensions" ]; then - mkdir -p "$SETTINGS_DIR/$SETTINGS_PROFILE/extensions" - fi - curl -sSL "$PLUGIN_URL" -o "$SETTINGS_DIR/$SETTINGS_PROFILE/extensions/$PLUGIN_FILENAME" - # Unzipping like this causes Firefox to complain about unsigned plugins - # TODO - figure out how to headlessly enable the extensions in such a way that is compatible with Flatpak / Snap - # using the /usr/lib/firefox/distribution/policies.json works but this is not compatible with Flatpak / Snap out of the box - # it seems since they do not have access to the file system by default. Also, using the policies.json approach forces - # all Firefox profiles to use the same extensions. Ideally, we should find a way to enable the extensions scoped - # to the user profile. - # logg info 'Unzipping '"$PLUGIN_FILENAME"' ('"$FIREFOX_PLUGIN"')' - # unzip "$SETTINGS_DIR/$SETTINGS_PROFILE/extensions/$PLUGIN_FILENAME" -d "$SETTINGS_DIR/$SETTINGS_PROFILE/extensions/$PLUGIN_FOLDER" - logg success 'Installed '"$FIREFOX_PLUGIN"'' - fi - else - logg warn 'A null Firefox add-on filename was detected for '"$FIREFOX_PLUGIN"'' - fi - else - logg warn 'A null Firefox add-on ID was detected for '"$FIREFOX_PLUGIN"'' - fi - done - fi - done - fi - done -} -firefoxSetup -{{ end -}} diff --git a/home/.chezmoiscripts/universal/run_onchange_after_45-vmware.sh.tmpl b/home/.chezmoiscripts/universal/run_onchange_after_45-vmware.sh.tmpl deleted file mode 100644 index 5aa62310..00000000 --- a/home/.chezmoiscripts/universal/run_onchange_after_45-vmware.sh.tmpl +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env bash -# @file Linux VMWare Workstation Install -# @brief Installs VMWare Workstation Pro on Linux devices, applies a "publicly-retrieved" license key (see disclaimer), and automatically accepts the terms and conditions -# @description -# This script ensures the user included `vmware` in their software installation list. It then checks for presence of the `vmware` utility. If it is not present, then the script: -# -# 1. Downloads the [VMWare Workstation Pro](https://www.vmware.com/content/vmware/vmware-published-sites/us/products/workstation-pro.html.html) Linux installer -# 2. Installs VMWare Workstation Pro -# 3. Passes options to the installation script that automatically apply a publicly retrived license key and accept the Terms & Conditions -# -# **DISCLAIMER:** If you plan on using VMWare Workstation for anything but evaluation purposes, then we highly suggest purchasing a copy -# of VMWare Workstation. The "publicly-retrived" license keys are scattered throughout GitHub and we are not exactly -# sure why they work. You can pass in your own key by utilizing the `VMWARE_WORKSTATION_LICENSE_KEY` environment variable. More details on -# using environment variables or repository-housed encrypted secrets can be found in our [Secrets documentation](https://install.doctor/docs/customization/secrets). -# -# ## VMWare on macOS -# -# This script only installs VMWare Workstation on Linux. The macOS-variant titled VMWare Fusion can be installed using a Homebrew -# cask so a "work-around" script does not have to be used. -# -# ## VMWare vs. Parallels vs. VirtualBox vs. KVM vs. Hyper-V -# -# There are a handful of VM virtualization providers you can choose from. VMWare is a nice compromise between OS compatibility and performance. -# Parallels, on the hand, might be better for macOS since it is designed specifically for macOS. Finally, VirtualBox is a truly free, -# open-source option that does not come with the same optimizations that VMWare and Parallels provide. -# -# Other virtualization options include KVM (Linux / macOS) and Hyper-V (Windows). These options are better used for headless -# systems. -# -# ## Links -# -# * [VMWare Workstation homepage](https://www.vmware.com/content/vmware/vmware-published-sites/us/products/workstation-pro.html.html) -# @file Vagrant VMWare Utility -# @brief Installs the `vagrant-vmware-utility` if both Vagrant and VMWare are installed -# @description -# This script first checks if `vagrant`, `vmware`, and `vagrant-vmware-utility` are available in the `PATH`. If they are present, then the script -# configures the [`vagrant-vmware-utility`](https://developer.hashicorp.com/vagrant/docs/providers/vmware/vagrant-vmware-utility) by generating the required security certificates and enabling the service. -# This system package enables the capability of controlling both VMWare Workstation and VMWare Fusion with Vagrant. -# -# Since this script runs only when `vagrant`, `vmware`, and `vagrant-vmware-utility` are in the `PATH`, this means that it will run -# when you use an installation template that includes all three pieces of software in the software list defined in -# `home/.chezmoidata.yaml`. -# -# ## Links -# -# * [Vagrant VMWare Utility on GitHub](https://github.com/hashicorp/vagrant-vmware-desktop) -# * [`home/.chezmoidata.yaml`](https://github.com/megabyte-labs/install.doctor/blob/master/home/.chezmoidata.yaml) -# @file VMWare Configuration -# @brief Patches VMWare to leverage kernel optimizations, support macOS, and work harmoniously with Secure Boot. It also enables optional services such as the USB service. -# @description -# This script performs various VMWare optimizations that allow VMWare to work optimally with all features enabled. - -{{- $softwareGroup := nospace (cat "_" .host.softwareGroup) -}} -{{- $softwareList := list (index .softwareGroups $softwareGroup | toString | replace "[" "" | replace "]" "") | uniq | join " " -}} - -{{- $secretKey := "" -}} -{{- if (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "VMWARE_WORKSTATION_LICENSE_KEY")) -}} -{{- $secretKey = (default "4C21U-2KK9Q-M8130-4V2QH-CF810" (includeTemplate "secrets/VMWARE_WORKSTATION_LICENSE_KEY" | decrypt | trim)) -}} -{{- else -}} -{{- $secretKey = (default "4C21U-2KK9Q-M8130-4V2QH-CF810" (env "VMWARE_WORKSTATION_LICENSE_KEY")) -}} -{{- end }} - -# Source: https://gist.github.com/PurpleVibe32/30a802c3c8ec902e1487024cdea26251 -# key: {{ $secretKey }} - -{{ includeTemplate "universal/profile" }} -{{ includeTemplate "universal/logg" }} - -function vmwareSetup() { - ### Run on Linux only - if [ -f /etc/os-release ]; then - ### Run if vmware is to be installed - {{- if (contains " vmware" $softwareList) -}} - ### Install VMware Workstation - if ! command -v vmware > /dev/null; then - ### Download VMWare Workstation - logg info 'VMware Workstation is not installed' - VMWARE_WORKSTATION_URL=https://www.vmware.com/go/getworkstation-linux - VMWARE_WORKSTATION_DIR=/tmp/workstation-downloads - mkdir -p $VMWARE_WORKSTATION_DIR - logg info 'Downloading VMware Workstation Installer' - curl -sSLA "Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20220101 Firefox/102.0" "$VMWARE_WORKSTATION_URL" -o "$VMWARE_WORKSTATION_DIR/tryworkstation-linux-64.sh" - - ### Register product key / license - VMWARE_WORKSTATION_LICENSE_KEY='{{- $secretKey -}}' - if [ -n "$VMWARE_WORKSTATION_LICENSE_KEY" ]; then - logg info 'Registering VMware Workstation Pro license with serial number' - sudo "$VMWARE_WORKSTATION_DIR/tryworkstation-linux-64.sh" --eulas-agreed --console --required --set-setting vmware-workstation serialNumber "$VMWARE_WORKSTATION_LICENSE_KEY" - else - logg info 'Agreeing to VMWare Workstation Pro license (without serial number)' - sudo "$VMWARE_WORKSTATION_DIR/tryworkstation-linux-64.sh" --eulas-agreed --console --required - fi - logg success 'VMware Workstation installed successfully' - else - logg info 'VMware Workstation is already installed' - fi - {{ end -}} - - ### Run logic if VMware is installed - if command -v vmware > /dev/null; then - ### Build kernel modules if they are not present - if [ ! -f "/lib/modules/$(uname -r)/misc/vmmon.ko" ] || [ ! -f "/lib/modules/$(uname -r)/misc/vmnet.ko" ]; then - ### Build VMWare host modules - logg info 'Building VMware host modules' - if sudo vmware-modconfig --console --install-all; then - logg success 'Built VMWare host modules successfully with sudo vmware-modconfig --console --install-all' - else - logg info 'Acquiring VMware version from CLI' - VMW_VERSION="$(vmware --version | cut -f 3 -d' ')" - mkdir -p /tmp/vmw_patch - cd /tmp/vmw_patch - logg info 'Downloading VMware host module patches' - curl -sSL "https://github.com/mkubecek/vmware-host-modules/archive/workstation-$VMW_VERSION.tar.gz" -o /tmp/vmw_patch/workstation.tar.gz - tar -xzf /tmp/vmw_patch/workstation.tar.gz - cd vmware* - logg info 'Running sudo make and sudo make install' - sudo make - sudo make install - logg success 'Successfully configured VMware host module patches' - fi - - ### Sign VMware host modules if Secure Boot is enabled - if [ -f /sys/firmware/efi ]; then - logg info 'Signing host modules' - mkdir -p /tmp/vmware - cd /tmp/vmware - openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -nodes -days 36500 -subj "/CN=VMware/" - "/usr/src/linux-headers-$(uname -r)/scripts/sign-file" sha256 ./MOK.priv ./MOK.der "$(modinfo -n vmmon)" - "/usr/src/linux-headers-$(uname -r)/scripts/sign-file" sha256 ./MOK.priv ./MOK.der "$(modinfo -n vmnet)" - echo '' | mokutil --import MOK.der - logg success 'Successfully signed VMware host modules. Reboot the host before powering on VMs' - fi - - ### Patch VMware with Unlocker - if [ ! -f /usr/lib/vmware/isoimages/darwin.iso ]; then - logg info 'Acquiring VMware Unlocker latest release version' - UNLOCKER_URL="$(curl -sSL 'https://api.github.com/repos/DrDonk/unlocker/releases/latest' | jq -r '.assets[0].browser_download_url')" - mkdir -p /tmp/vmware-unlocker - cd /tmp/vmware-unlocker - logg info 'Downloading unlocker.zip' - curl -sSL "$UNLOCKER_URL" -o unlocker.zip - unzip unlocker.zip - cd linux - logg info 'Running the unlocker' - echo "y" | sudo ./unlock - logg success 'Successfully unlocked VMware for macOS compatibility' - else - logg info '/usr/lib/vmware/isoimages/darwin.iso is already present on the system so VMware macOS unlocking will not be performed' - fi - - if [[ ! "$(test -d /proc && grep Microsoft /proc/version > /dev/null)" ]]; then - ### Start / enable VMWare service - logg info 'Ensuring vmware.service is enabled and running' - sudo systemctl enable vmware.service - sudo systemctl restart vmware.service - - ### Start / enable VMWare Workstation Server service - logg info 'Ensuring vmware-workstation-server.service is enabled and running' - sudo systemctl enable vmware-workstation-server.service - sudo systemctl restart vmware-workstation-server.service - - ### Start / enable VMWare USB Arbitrator service - if command -v vmware-usbarbitrator.service > /dev/null; then - logg info 'Ensuring vmware-usbarbitrator.service is enabled and running' - sudo systemctl enable vmware-usbarbitrator.service - sudo systemctl restart vmware-usbarbitrator.service - else - logg warn 'vmware-usbarbitrator does not exist in the PATH' - fi - fi - else - logg info 'VMware host modules are present' - fi - else - logg warn 'VMware Workstation is not installed so the VMware Unlocker will not be installed' - fi - fi - - # @description Only run logic if both Vagrant and VMWare are installed - if command -v vagrant > /dev/null && command -v vmware-id > /dev/null; then - # @description Vagrant VMWare Utility configuration - if command -v vagrant-vmware-utility > /dev/null; then - if [ -f /usr/local/bin/certificates/vagrant-utility.key ]; then - logg info 'Assuming Vagrant VMWare Utility certificates have been properly generated since /usr/local/bin/certificates/vagrant-utility.key is present' - else - logg info 'Generating Vagrant VMWare Utility certificates' - sudo vagrant-vmware-utility certificate generate - logg success 'Generated Vagrant VMWare Utility certificates via vagrant-vmware-utility certificate generate' - fi - logg info 'Ensuring the Vagrant VMWare Utility service is enabled' - sudo vagrant-vmware-utility service install || EXIT_CODE=$? - if [ -n "$EXIT_CODE" ]; then - logg info 'The Vagrant VMWare Utility command vagrant-vmware-utility service install failed. It is probably already setup.' - fi - fi - else - logg info 'Vagrant is not installed so the Vagrant plugins will not be installed' - logg info 'Vagrant or VMWare is not installed so the Vagrant VMWare utility will not be configured' - fi -} - -vmwareSetup diff --git a/home/.chezmoiscripts/universal/run_onchange_after_46_virtualbox.sh.tmpl b/home/.chezmoiscripts/universal/run_onchange_after_46_virtualbox.sh.tmpl deleted file mode 100644 index 30aa0b4b..00000000 --- a/home/.chezmoiscripts/universal/run_onchange_after_46_virtualbox.sh.tmpl +++ /dev/null @@ -1,45 +0,0 @@ -{{- if ne .host.distro.family "windows" -}} -#!/usr/bin/env bash -# @file VirtualBox Extension Pack -# @brief Ensures the VirtualBox extension pack is installed. -# @description -# This script ensures the VirtualBox extension pack that corresponds with VirtualBox's version is properly installed. - -{{ includeTemplate "universal/profile" }} -{{ includeTemplate "universal/logg" }} - -### Run logic if VirtualBox is installed -if command -v VirtualBox > /dev/null; then - ### Install VirtualBox extension pack if it is not installed already - if [ ! -d /usr/lib/virtualbox/ExtensionPacks/Oracle_VM_VirtualBox_Extension_Pack ] && [ ! -d /Applications/VirtualBox.app/Contents/MacOS/ExtensionPacks/Oracle_VM_VirtualBox_Extension_Pack ]; then - logg info 'Acquiring VirtualBox version information' - VBOX_VERSION="$(VirtualBox --help | head -n 1 | cut -f 6 -d' ')" - VBOX_VERSION="${VBOX_VERSION//v}" - - ### Set up folders - # Check for macOS installation before creating ExtensionPacks folder on Linux machines - if [ ! -d /Applications/VirtualBox.app ]; then - sudo mkdir -p /usr/lib/virtualbox/ExtensionPacks - fi - mkdir -p /tmp/vbox - cd /tmp/vbox - - ### Download extension pack - logg info 'Downloading VirtualBox extension pack' - curl -sSL https://download.virtualbox.org/virtualbox/$VBOX_VERSION/Oracle_VM_VirtualBox_Extension_Pack-$VBOX_VERSION.vbox-extpack \ - -o /tmp/vbox/Oracle_VM_VirtualBox_Extension_Pack-$VBOX_VERSION.vbox-extpack || logg error 'Failed to download the VirtualBox extension pack so the extension pack installation will be skipped' - - ### Install extension pack - if [ -f /tmp/vbox/Oracle_VM_VirtualBox_Extension_Pack-$VBOX_VERSION.vbox-extpack ]; then - logg info 'Installing VirtualBox extension pack' - echo 'y' | sudo VBoxManage extpack install --replace /tmp/vbox/Oracle_VM_VirtualBox_Extension_Pack-$VBOX_VERSION.vbox-extpack - logg success 'Successfully installed VirtualBox extension pack' - fi - else - logg info 'VirtualBox Extension pack is already installed' - fi -else - logg info 'VirtualBox is not installed so VirtualBox Extension pack will not be installed' -fi - -{{ end -}} diff --git a/home/.chezmoiscripts/universal/run_onchange_after_57-netdata.sh.tmpl b/home/.chezmoiscripts/universal/run_onchange_after_57-netdata.sh.tmpl deleted file mode 100644 index a9cbcb04..00000000 --- a/home/.chezmoiscripts/universal/run_onchange_after_57-netdata.sh.tmpl +++ /dev/null @@ -1,169 +0,0 @@ -{{- if and (ne .host.distro.family "windows") (stat (joinPath .host.home ".config" "age" "chezmoi.txt")) (or (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "NETDATA_TOKEN")) (env "NETDATA_TOKEN")) (or (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "NETDATA_ROOM")) (env "NETDATA_ROOM")) -}} -#!/usr/bin/env bash -# @file Netdata -# @brief Connects Netdata with Netdata's free cloud dashboard and applies some system optimizations, if necessary -# @description -# This script connects Netdata with Netdata Cloud if Netdata is installed, the `NETDATA_TOKEN` is provided, and the -# `NETDATA_ROOM` is defined. This allows you to graphically browse through system metrics on all your connected devices -# from a single free web application. -# -# This script installs additional alerts and enables notifications if Netdata is installed. Email notifications are configured -# using the provided primary email address. If the OS is Debian based, Netdata shows the number of CVEs in currently installed packages. - -{{ includeTemplate "universal/profile" }} -{{ includeTemplate "universal/logg" }} - -ensureNetdataOwnership() { - ### Ensure /usr/local/var/lib/netdata/cloud.d is owned by user - if [ -d /usr/local/var/lib/netdata ]; then - logg info 'Ensuring permissions are correct on /usr/local/var/lib/netdata' - sudo chown -Rf netdata:netdata /usr/local/var/lib/netdata 2> /dev/null || sudo chown -Rf netdata:$(id -g -n) /usr/local/var/lib/netdata - elif [ -d /var/lib/netdata ]; then - logg info 'Ensuring permissions are correct on /var/lib/netdata' - sudo chown -Rf netdata:netdata /var/lib/netdata 2> /dev/null || sudo chown -Rf netdata:$(id -g -n) /var/lib/netdata - elif [ -d "${HOMEBREW_PREFIX:-/opt/homebrew}/var/lib/netdata" ]; then - logg info "Ensuring permissions are correct on ${HOMEBREW_PREFIX:-/opt/homebrew}/var/lib/netdata" - sudo chown -Rf netdata:netdata "${HOMEBREW_PREFIX:-/opt/homebrew}/var/lib/netdata" 2> /dev/null || sudo chown -Rf netdata:$(id -g -n) "${HOMEBREW_PREFIX:-/opt/homebrew}/var/lib/netdata" - else - logg warn 'No /var/lib/netdata folder found' - fi -} - -### Claim the instance with Netdata Cloud -if command -v netdata-claim.sh > /dev/null; then - # Add user / group with script in ~/.local/bin/add-usergroup, if it is available - if command -v add-usergroup > /dev/null; then - sudo add-usergroup "$USER" netdata - fi - - ensureNetdataOwnership - - # netdata-claim.sh must be run as netdata user - sudo -H -u netdata bash -c 'export NETDATA_ROOM="{{- if (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "NETDATA_ROOM")) -}}{{- includeTemplate "secrets/NETDATA_ROOM" | decrypt | trim -}}{{- else -}}{{- env "NETDATA_ROOM" -}}{{- end -}}" && export NETDATA_TOKEN="{{- if (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "NETDATA_TOKEN")) -}}{{- includeTemplate "secrets/NETDATA_TOKEN" | decrypt | trim -}}{{- else -}}{{- env "NETDATA_TOKEN" -}}{{- end -}}" && yes | netdata-claim.sh -token="$NETDATA_TOKEN" -rooms="$NETDATA_ROOM" -url="{{ .netdataClaimURL }}"' - - # Kernel optimizations - # These are mentioned while installing via the kickstart.sh script method. We are using Homebrew for the installation though. - # Assuming these optimizations do not cause any harm. - if [ -d /Applications ] && [ -d /System ]; then - # macOS - logg info 'System is macOS so Netdata kernel optimizations are not required' - else - # Linux - if [ -d /sys/kernel/mm/ksm ]; then - logg info 'Adding Netdata kernel optimization for /sys/kernel/mm/ksm/run' - echo 1 | sudo tee /sys/kernel/mm/ksm/run - logg info 'Adding Netdata kernel optimization for /sys/kernel/mm/ksm/sleep_millisecs' - echo 1000 | sudo tee /sys/kernel/mm/ksm/sleep_millisecs - else - logg info 'The /sys/kernel/mm/ksm directory does not exist so Netdata kernel optimizations are not being applied' - fi - fi - - ### Install additional alerts and enable notifications - if command -v netdata > /dev/null; then - # Copy the additional alert definitions - if [ -d /usr/local/etc/netdata ]; then - NETDATA_ETC='/usr/local/etc/netdata/' - elif [ -d /etc/netdata ]; then - NETDATA_ETC='/etc/netdata' - elif [ -d "${HOMEBREW_PREFIX:-/opt/homebrew}/etc/netdata" ]; then - NETDATA_ETC="${HOMEBREW_PREFIX:-/opt/homebrew}/etc/netdata" - else - logg error 'No etc location found for netdata' && exit 1 - fi - logg info "Copying ${XDG_CONFIG_HOME:-$HOME/.config}/netdata/health.d/ to $NETDATA_ETC" - sudo cp -rf "${XDG_CONFIG_HOME:-$HOME/.config}/netdata/health.d/" "$NETDATA_ETC" - - # Backup current health alarm configuration and apply new one - if [ -d /usr/local/lib/netdata ]; then - NETDATA_LIB='/usr/local/lib/netdata' - elif [ -d /usr/lib/netdata ]; then - NETDATA_LIB='/usr/lib/netdata' - elif [ -d "${HOMEBREW_PREFIX:-/opt/homebrew}/lib/netdata" ]; then - NETDATA_LIB="${HOMEBREW_PREFIX:-/opt/homebrew}/lib/netdata" - else - logg error 'No lib location found for netdata' && exit 1 - fi - logg info "Copying ${XDG_CONFIG_HOME:-$HOME/.config}/netdata/health_alarm_notify.conf to $NETDATA_LIB/conf.d/health_alarm_notify.conf" - sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/netdata/health_alarm_notify.conf" "$NETDATA_LIB/conf.d/health_alarm_notify.conf" - else - logg warn 'netdata is not available in the PATH or is not installed' - fi - - ### Ensure the apt command is available before running `debsecan` logic - if command -v apt-get > /dev/null; then - ### Configure Netdata to gather information about CVEs in the installed packages - if command -v debsecan > /dev/null; then - DEBSECAN_GIT="${XDG_DATA_HOME:-$HOME/.local/share}/netdata-debsecan" - - # Installing the script to generate report on CVEs in installed packages - logg info 'Installing script to generate report on CVEs in installed packages' - sudo cp -f "$DEBSECAN_GIT/usr_local_bin_debsecan-by-type" "/usr/local/bin/debsecan-by-type" - - # Generate initial debsecan reports in /var/log/debsecan/ - logg info 'Generating initial debsecan reports in /var/log/debsecan/' - debsecan-by-type - - # Configure dpkg to refresh the file after each run - logg info 'Configuring dpkg to refresh the file after each run' - sudo cp -f "$DEBSECAN_GIT/etc_apt_apt.conf.d_99debsecan" /etc/apt/apt.conf.d/99-debsecan - - # Add a cron job to refresh the file every hour - logg info 'Adding a cron job to refresh the file every hour' - sudo cp -f "$DEBSECAN_GIT/etc_cron.d_debsecan" /etc/cron.d/debsecan - - # Install the module/configuration file - logg info 'Installing the module and configuration file' - sudo "$DEBSECAN_GIT/debsecan.chart.py" /usr/libexec/netdata/python.d/debsecan.chart.py - sudo "$DEBSECAN_GIT/debsecan.conf" /etc/netdata/python.d/debsecan.conf - else - logg warn 'apt-get is available but debsecan is not available in the PATH or is not installed' - fi - fi - - ### Ensure / report whether speedtest-cli is installed - if ! command -v speedtest-cli > /dev/null; then - if command -v pipx > /dev/null; then - pipx install speedtest-cli - else - logg warn 'speedtest-cli not installed and pipx is not available' - fi - fi - - ### Configure Netdata to gather information about Internet connection speed - if command -v speedtest-cli > /dev/null; then - # Installing the script to generate report on Internet connection speed - logg info 'Installing script to generate report on Internet connection speed' - LIBEXEC_PATH="$(netdata -W buildinfo | grep 'Configure' | sed "s/.*--libexecdir=\([^ \']*\).*/\1/")" - if [ -d /usr/libexec/netdata/charts.d ]; then - sudo cp -f "${XDG_DATA_HOME:-$HOME/.local/share}/netdata-speedtest/speedtest.chart.sh" "/usr/libexec/netdata/charts.d/speedtest.chart.sh" - elif [ -d "$LIBEXEC_PATH/netdata/charts.d" ]; then - logg info "$LIBEXEC_PATH/netdata/charts.d present on system" - cp -f "${XDG_DATA_HOME:-$HOME/.local/share}/netdata-speedtest/speedtest.chart.sh" "$LIBEXEC_PATH/netdata/charts.d/speedtest.chart.sh" - else - logg warn "Failed to find appropriate directory to add Netdata speedtest chart script" - fi - else - logg warn 'speedtest-cli is not available in the PATH or is not installed' - fi - - ensureNetdataOwnership - - ### Restart Netdata service - if command -v systemctl > /dev/null; then - logg info 'Enabling netdata service' - sudo systemctl enable netdata - logg info 'Restarting netdata service' - sudo systemctl restart netdata - elif [ -d /Applications ] && [ -d /System ]; then - logg info 'Starting / enabling netdata service' - brew services restart netdata - else - logg warn 'systemctl is not available' - fi - -else - logg info 'netdata-claim.sh is not available in the PATH' -fi - -{{ end -}} diff --git a/home/dot_config/shell/private_private.sh.tmpl b/home/dot_config/shell/private_private.sh.tmpl index 93944f69..a023d31c 100644 --- a/home/dot_config/shell/private_private.sh.tmpl +++ b/home/dot_config/shell/private_private.sh.tmpl @@ -65,15 +65,17 @@ export HISHTORY_USER_SECRET="{{ if (stat (joinPath .chezmoi.sourceDir ".chezmoit ### Install Doctor # TODO: Replace HEADLESS_INSTALL with {{ .host.headless }} data source once headless install detection is implemented # export HEADLESS_INSTALL={{ .host.headless }} -export HEADLESS_INSTALL=true -export SOFTWARE_GROUP="{{ .host.softwareGroup }}" +export FIREFOX_PUBLIC_PROFILE="{{ .firefoxPublicProfile }}" export FULL_NAME="{{ .user.name }}" +export HEADLESS_INSTALL=true +export HOST="{{ .host.hostname }}" +export KEYID="{{ .user.gpg.id }}" export PRIMARY_EMAIL="{{ .user.email }}" export PUBLIC_SERVICES_DOMAIN="{{ .host.domain }}" export RESTRICTED_ENVIRONMENT={{ .host.restricted }} +export SOFTWARE_GROUP="{{ .host.softwareGroup }}" +export USER_USERNAME="{{ .user.username }}" export WORK_ENVIRONMENT={{ .host.work }} -export HOST="{{ .host.hostname }}" -export KEYID="{{ .user.gpg.id }}" # Set to work environment if Cisco applications are installed (modify this to your liking) if [ -d /Applications/Cisco ]; then @@ -103,6 +105,9 @@ export REPLICATE_API_KEY="{{ if (stat (joinPath .chezmoi.sourceDir ".chezmoitemp export GOOGLE_SEARCH_API_KEY="{{ if (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "GOOGLE_SEARCH_API_KEY")) }}{{ includeTemplate "secrets/GOOGLE_SEARCH_API_KEY" | decrypt | trim }}{{ else }}{{ env "GOOGLE_SEARCH_API_KEY" }}{{ end }}" export GOOGLE_SEARCH_ID="{{ if (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "GOOGLE_SEARCH_ID")) }}{{ includeTemplate "secrets/GOOGLE_SEARCH_ID" | decrypt | trim }}{{ else }}{{ env "GOOGLE_SEARCH_ID" }}{{ end }}" +### SendGrid API Key +export SENDGRID_API_KEY="{{ if (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "SENDGRID_API_KEY")) }}{{ includeTemplate "secrets/SENDGRID_API_KEY" | decrypt | trim }}{{ else }}{{ env "SENDGRID_API_KEY" }}{{ end }}" + ### Serper.dev export SERP_API_KEY="{{ if (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "SERP_API_KEY")) }}{{ includeTemplate "secrets/SERP_API_KEY" | decrypt | trim }}{{ else }}{{ env "SERP_API_KEY" }}{{ end }}" @@ -122,6 +127,9 @@ export SURGE_TOKEN="{{ if (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" ### Vagrant Cloud export VAGRANT_CLOUD_TOKEN="{{ if (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "VAGRANT_CLOUD_TOKEN")) }}{{ includeTemplate "secrets/VAGRANT_CLOUD_TOKEN" | decrypt | trim }}{{ else }}{{ env "VAGRANT_CLOUD_TOKEN" }}{{ end }}" +### VMWare +export VMWARE_WORKSTATION_LICENSE_KEY="{{ if (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "VMWARE_WORKSTATION_LICENSE_KEY")) }}{{ includeTemplate "secrets/VMWARE_WORKSTATION_LICENSE_KEY" | decrypt | trim }}{{ else }}{{ default "4C21U-2KK9Q-M8130-4V2QH-CF810" (env "VMWARE_WORKSTATION_LICENSE_KEY") }}{{ end }}" + ### Xcodes # Apple ID username and password export XCODES_USERNAME="{{ if (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "APPLE_USERNAME")) }}{{ includeTemplate "secrets/APPLE_USERNAME" | decrypt | trim }}{{ else }}{{ env "APPLE_USERNAME" }}{{ end }}" diff --git a/software.yml b/software.yml index d854e82d..c85ee15c 100644 --- a/software.yml +++ b/software.yml @@ -1672,6 +1672,68 @@ softwarePackages: _link:snap: - src: "${XDG_CONFIG_HOME:-$HOME/.config}/BraveSoftware/Brave-Browser/Default" target: "$HOME/snap/brave/current/.config/BraveSoftware/Brave-Browser/Default" + _post: | + # @brief See `google-chrome` `_post` script for more details + function chromeSetUp() { + ### Ensure Chrome policies directory is present + logg info 'Processing policy directories for Chromium based browsers' + for POLICY_DIR in "/etc/brave/policies"; do + if [ -d "$(dirname "$POLICY_DIR")" ]; then + ### Managed policies + if [ ! -f "$POLICY_DIR/managed/policies.json" ]; then + logg info "Ensuring directory $POLICY_DIR/managed exists" + sudo mkdir -p "$POLICY_DIR/managed" + logg info "Copying ${XDG_CONFIG_HOME:-$HOME/.config}/chrome/managed.json to $POLICY_DIR/managed/policies.json" + sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/managed.json" "$POLICY_DIR/managed/policies.json" + fi + + ### Recommended policies + if [ ! -f "$POLICY_DIR/recommended/policies.json" ]; then + logg info "Ensuring directory $POLICY_DIR/recommended exists" && sudo mkdir -p "$POLICY_DIR/recommended" + logg info "Copying ${XDG_CONFIG_HOME:-$HOME/.config}/chrome/recommended.json to $POLICY_DIR/recommended/policies.json" + sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/recommended.json" "$POLICY_DIR/recommended/policies.json" + fi + else + logg info "Skipping extension injection into $POLICY_DIR - create these folders prior to running to create managed configs" + fi + done + + ### Add Chrome extension JSON + logg info 'Populating Chrome extension JSON' + for EXTENSION_DIR in "/etc/brave/extensions" "$HOME/Library/Application Support/BraveSoftware/Brave-Browser/External Extensions"; do + ### Ensure program-type is installed + if [ -d "$(dirname "$EXTENSION_DIR")" ]; then + ### Ensure extension directory exists + if [[ "$EXTENSION_DIR" == '/opt/'* ]] || [[ "$EXTENSION_DIR" == '/etc/'* ]]; then + if [ ! -d "$EXTENSION_DIR" ]; then + logg info "Creating directory $EXTENSION_DIR" && sudo mkdir -p "$EXTENSION_DIR" + fi + else + if [ ! -d "$EXTENSION_DIR" ]; then + logg info "Creating directory $EXTENSION_DIR" && mkdir -p "$EXTENSION_DIR" + fi + fi + + ### Add extension JSON + logg info "Adding Chrome extensions to $EXTENSION_DIR" + for EXTENSION in {{ list (.chromeExtensions | toString | replace "[" "" | replace "]" "") | uniq | join " " }}; do + logg info "Adding Chrome extension manifest ($EXTENSION)" + if ! echo "$EXTENSION" | grep 'https://chrome.google.com/webstore/detail/' > /dev/null; then + EXTENSION="https://chrome.google.com/webstore/detail/$EXTENSION" + fi + EXTENSION_ID="$(echo "$EXTENSION" | sed 's/^.*\/\([^\/]*\)$/\1/')" + if [[ "$EXTENSION_DIR" == '/opt/'* ]] || [[ "$EXTENSION_DIR" == '/etc/'* ]]; then + sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/extension.json" "$EXTENSION_DIR/${EXTENSION_ID}.json" + else + cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/extension.json" "$EXTENSION_DIR/${EXTENSION_ID}.json" + fi + done + else + logg info "$EXTENSION_DIR does not exist" + fi + done + } + chromeSetUp cask: brave-browser choco: brave flatpak: com.brave.Browser @@ -1902,6 +1964,92 @@ softwarePackages: _link:flatpak: - src: "${XDG_CONFIG_HOME:-$HOME/.config}/google-chrome/Default" target: "$HOME/.var/app/com.google.Chrome/config/google-chrome/Default" + _post: | + # @file Chrome Settings / Extensions + # @brief This script configures Chrome, Brave, and Chromium system-wide managed / recommended policies settings. It also pre-loads a configurable list of Chrome extensions to Chrome, Brave, Chromium, and Edge (if they are installed). + # @description + # This Chrome setup script applies system-wide settings and pre-loads Chrome extensions into the browser profiles. The + # extensions still must be enabled but they appear in the Chrome extensions menu and can be enabled with the toggle. The + # system settings are applied to Chrome, Chromium, and Brave. Extensions are installed to the same browsers plus Microsoft Edge. + # + # ## Features + # + # * Adds `~/.config/chrome/managed.json` to the `managed/policies.json` system locations + # * Adds `~/.config/chrome/recommended.json` to the `recommended/policies.json` system locations + # * Pre-loads extension metadata for all the extensions defined under `chromeExtensions` in the [`home/.chezmoidata.yaml`](https://github.com/megabyte-labs/install.doctor/blob/master/home/.chezmoidata.yaml) file + # + # ## TODO + # + # * Automatically enable the extensions that are pre-loaded + # * Create several profiles with different characteristics (similar to the Firefox setup script) + # * Ensure the directories that the script cycles through to install managed settings and extensions are complete for all installation types (i.e. there might need to be some additions for Flatpak installations since their folder structure is different) + # * Document how [`chromium-flags.conf`](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/chromium-flags.conf) can be or is integrated + # + # ## Links + # + # * [`managed.json`](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/chrome/managed.json) + # * [`recommended.json`](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/chrome/recommended.json) + + function chromeSetUp() { + ### Ensure Chrome policies directory is present + logg info 'Processing policy directories for Chromium based browsers' + for POLICY_DIR in "/opt/google/chrome/policies"; do + if [ -d "$(dirname "$POLICY_DIR")" ]; then + ### Managed policies + if [ ! -f "$POLICY_DIR/managed/policies.json" ]; then + logg info "Ensuring directory $POLICY_DIR/managed exists" + sudo mkdir -p "$POLICY_DIR/managed" + logg info "Copying ${XDG_CONFIG_HOME:-$HOME/.config}/chrome/managed.json to $POLICY_DIR/managed/policies.json" + sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/managed.json" "$POLICY_DIR/managed/policies.json" + fi + + ### Recommended policies + if [ ! -f "$POLICY_DIR/recommended/policies.json" ]; then + logg info "Ensuring directory $POLICY_DIR/recommended exists" && sudo mkdir -p "$POLICY_DIR/recommended" + logg info "Copying ${XDG_CONFIG_HOME:-$HOME/.config}/chrome/recommended.json to $POLICY_DIR/recommended/policies.json" + sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/recommended.json" "$POLICY_DIR/recommended/policies.json" + fi + else + logg info "Skipping extension injection into $POLICY_DIR - create these folders prior to running to create managed configs" + fi + done + + ### Add Chrome extension JSON + logg info 'Populating Chrome extension JSON' + for EXTENSION_DIR in "/opt/google/chrome/extensions" "$HOME/Library/Application Support/Google/Chrome/External Extensions"; do + ### Ensure program-type is installed + if [ -d "$(dirname "$EXTENSION_DIR")" ]; then + ### Ensure extension directory exists + if [[ "$EXTENSION_DIR" == '/opt/'* ]] || [[ "$EXTENSION_DIR" == '/etc/'* ]]; then + if [ ! -d "$EXTENSION_DIR" ]; then + logg info "Creating directory $EXTENSION_DIR" && sudo mkdir -p "$EXTENSION_DIR" + fi + else + if [ ! -d "$EXTENSION_DIR" ]; then + logg info "Creating directory $EXTENSION_DIR" && mkdir -p "$EXTENSION_DIR" + fi + fi + + ### Add extension JSON + logg info "Adding Chrome extensions to $EXTENSION_DIR" + for EXTENSION in {{ list (.chromeExtensions | toString | replace "[" "" | replace "]" "") | uniq | join " " }}; do + logg info "Adding Chrome extension manifest ($EXTENSION)" + if ! echo "$EXTENSION" | grep 'https://chrome.google.com/webstore/detail/' > /dev/null; then + EXTENSION="https://chrome.google.com/webstore/detail/$EXTENSION" + fi + EXTENSION_ID="$(echo "$EXTENSION" | sed 's/^.*\/\([^\/]*\)$/\1/')" + if [[ "$EXTENSION_DIR" == '/opt/'* ]] || [[ "$EXTENSION_DIR" == '/etc/'* ]]; then + sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/extension.json" "$EXTENSION_DIR/${EXTENSION_ID}.json" + else + cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/extension.json" "$EXTENSION_DIR/${EXTENSION_ID}.json" + fi + done + else + logg info "$EXTENSION_DIR does not exist" + fi + done + } + chromeSetUp ansible: professormanhattan.chrome cask: google-chrome choco: googlechrome @@ -1941,6 +2089,68 @@ softwarePackages: _deps: - chrome-gnome-shell _bin: chromium + _post: | + function chromeSetUp() { + ### Ensure Chrome policies directory is present + logg info 'Processing policy directories for Chromium based browsers' + for POLICY_DIR in "/etc/chromium/policies"; do + if [ -d "$(dirname "$POLICY_DIR")" ]; then + ### Managed policies + if [ ! -f "$POLICY_DIR/managed/policies.json" ]; then + logg info "Ensuring directory $POLICY_DIR/managed exists" + sudo mkdir -p "$POLICY_DIR/managed" + logg info "Copying ${XDG_CONFIG_HOME:-$HOME/.config}/chrome/managed.json to $POLICY_DIR/managed/policies.json" + sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/managed.json" "$POLICY_DIR/managed/policies.json" + fi + + ### Recommended policies + if [ ! -f "$POLICY_DIR/recommended/policies.json" ]; then + logg info "Ensuring directory $POLICY_DIR/recommended exists" && sudo mkdir -p "$POLICY_DIR/recommended" + logg info "Copying ${XDG_CONFIG_HOME:-$HOME/.config}/chrome/recommended.json to $POLICY_DIR/recommended/policies.json" + sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/recommended.json" "$POLICY_DIR/recommended/policies.json" + fi + else + logg info "Skipping extension injection into $POLICY_DIR - create these folders prior to running to create managed configs" + fi + done + + ### Add Chrome extension JSON + logg info 'Populating Chrome extension JSON' + ### TODO - Find `EXTENSION_DIR` for macOS in Application Support folder like `$HOME/Library/Application Support/Google/Chrome/External Extensions` for Google Chrome + for EXTENSION_DIR in "/etc/chromium/extensions"; do + ### Ensure program-type is installed + if [ -d "$(dirname "$EXTENSION_DIR")" ]; then + ### Ensure extension directory exists + if [[ "$EXTENSION_DIR" == '/opt/'* ]] || [[ "$EXTENSION_DIR" == '/etc/'* ]]; then + if [ ! -d "$EXTENSION_DIR" ]; then + logg info "Creating directory $EXTENSION_DIR" && sudo mkdir -p "$EXTENSION_DIR" + fi + else + if [ ! -d "$EXTENSION_DIR" ]; then + logg info "Creating directory $EXTENSION_DIR" && mkdir -p "$EXTENSION_DIR" + fi + fi + + ### Add extension JSON + logg info "Adding Chrome extensions to $EXTENSION_DIR" + for EXTENSION in {{ list (.chromeExtensions | toString | replace "[" "" | replace "]" "") | uniq | join " " }}; do + logg info "Adding Chrome extension manifest ($EXTENSION)" + if ! echo "$EXTENSION" | grep 'https://chrome.google.com/webstore/detail/' > /dev/null; then + EXTENSION="https://chrome.google.com/webstore/detail/$EXTENSION" + fi + EXTENSION_ID="$(echo "$EXTENSION" | sed 's/^.*\/\([^\/]*\)$/\1/')" + if [[ "$EXTENSION_DIR" == '/opt/'* ]] || [[ "$EXTENSION_DIR" == '/etc/'* ]]; then + sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/extension.json" "$EXTENSION_DIR/${EXTENSION_ID}.json" + else + cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/extension.json" "$EXTENSION_DIR/${EXTENSION_ID}.json" + fi + done + else + logg info "$EXTENSION_DIR does not exist" + fi + done + } + chromeSetUp apt: chromium dnf: chromium flatpak: org.chromium.Chromium @@ -3406,6 +3616,8 @@ softwarePackages: _name: DevPod cask: devpod firefox: + _deps: + - htmlq _bin: firefox _desc: '[Mozilla Firefox](https://www.mozilla.org/en-US/firefox/new/), or simply Firefox, is a free and open-source web browser developed by the Mozilla Foundation and its subsidiary, the Mozilla Corporation. Firefox uses the Gecko layout engine to render web pages, which implements current and anticipated web standards.' _docs: https://developer.mozilla.org/en-US/ @@ -3428,6 +3640,341 @@ softwarePackages: _link:snap: - src: "${XDG_CONFIG_HOME:-$HOME/.config}/firefox/profiles" target: "$HOME/snap/firefox/common/.mozilla/firefox" + _post: | + # @file Firefox Settings / Add-Ons / Profiles + # @brief This script configures system-wide settings, sets up Firefox Profile Switcher, creates various profiles from different sources, and installs a configurable list of Firefox Add-Ons. + # @description + # The Firefox setup script performs a handful of tasks that automate the setup of Firefox as well as + # useful utilities that will benefit Firefox power-users. The script also performs the same logic on + # [LibreWolf](https://librewolf.net/) installations. + # + # ## Features + # + # * Installs and sets up [Firefox Profile Switcher](https://github.com/null-dev/firefox-profile-switcher) + # * Sets up system-wide enterprise settings (with configurations found in `~/.local/share/firefox`) + # * Sets up a handful of default profiles to use with the Firefox Profile Switcher + # * Automatically installs the plugins defined in the firefoxAddOns key of [`home/.chezmoidata.yaml`](https://github.com/megabyte-labs/install.doctor/blob/master/home/.chezmoidata.yaml) to the Standard and Private profiles + # * Configures the default profile to clone its settings from the profile stored in firefoxPublicProfile of `home/.chezmoidata.yaml` + # * Optionally, if the Chezmoi encryption key is present, then the default profile will be set to the contents of an encrypted `.tar.gz` that must be stored in the cloud somewhere (with the firefoxPrivateProfile key in `home/.chezmoidata.yaml` defining the URL of the encrypted `.tar.gz`) + # + # ## Profiles + # + # The script sets up numerous profiles for user flexibility. They can be switched by using the Firefox Profile Switcher + # that this script sets up. The map of the profiles is generated by using the template file stored in `~/.local/share/firefox/profiles.ini`. + # The following details the features of each profile: + # + # | Name | Description | + # |------------------|---------------------------------------------------------------------------------------------| + # | Factory | Default browser settings (system-wide configurations still apply) | + # | default-release | Same as Factory (unmodified and generated by headlessly opening Firefox / LibreWolf) | + # | Git (Public) | Pre-configured profile with address stored in `firefoxPublicProfile` | + # | Standard | Cloned from the profile above with `firefoxAddOns` also installed | + # | Miscellaneous | Cloned from the Factory profile (with the user.js found in `~/.config/firefox` applied) | + # | Development | Same as Miscellaneous | + # | Automation | Same as Miscellaneous | + # | Private | Populated from an encrypted profile stored in the cloud (also installs `firefoxAddOns`) | + # + # ## Notes + # + # * The Firefox Profile Switcher is only compatible with Firefox and not LibreWolf + # * This script is only designed to properly provision profiles on a fresh installation (so it does not mess around with pre-existing / already configured profiles) + # * Additional profiles for LibreWolf are not added because the Firefox Profile Switcher is not compatible with LibreWolf + # + # ## Links + # + # * [System-wide configurations](https://github.com/megabyte-labs/install.doctor/tree/master/home/dot_local/share/firefox) as well as the location of the `profile.ini` and some other configurations + # * [User-specific configurations](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/firefox/user.js) added to all profiles except Factory + + function installFirefoxProfileConnector() { + logg info 'Installing the Firefox Profile Connector' + if command -v apt-get > /dev/null; then + sudo apt-get install -y https://github.com/null-dev/firefox-profile-switcher-connector/releases/latest/download/linux-x64.deb + elif command -v dnf > /dev/null; then + sudo dnf install -y https://github.com/null-dev/firefox-profile-switcher-connector/releases/latest/download/linux-x64.rpm + elif command -v yay > /dev/null; then + yay -Ss firefox-profile-switcher-connector + else + logg warn 'apt-get, dnf, and yay were all unavailable so the Firefox Profile Connector helper executable could not be installed' + fi + } + + function firefoxSetup() { + ### Installs the Firefox Profile Connector on Linux systems (Snap / Flatpak installs are not included in this function, but instead inline below) + ### Add Firefox enterprise profile + # TODO - figure out how to do this for other installations like Flatpak and macOS and Librewolf + for FIREFOX_DIR in '/usr/lib/firefox' '/usr/lib/firefox-esr' '/etc/firefox' '/etc/firefox-esr' '/Applications/Firefox.app/Contents/Resources'; do + if [ -d "$FIREFOX_DIR" ] && [ -d "${XDG_DATA_HOME:-$HOME/.local/share}/firefox" ] && command -v rsync > /dev/null; then + logg info "Syncing enterprise profiles from ${XDG_DATA_HOME:-$HOME/.local/share}/firefox to $FIREFOX_DIR" + sudo rsync -artvu "${XDG_DATA_HOME:-$HOME/.local/share}/firefox/" "$FIREFOX_DIR" > /dev/null + fi + done + + ### Loop through various Firefox profile locations + for SETTINGS_DIR in "$HOME/snap/firefox/common/.mozilla/firefox" "$HOME/.var/app/org.mozilla.firefox/.mozilla/firefox" "$HOME/Library/Application Support/Firefox/Profiles" "$HOME/.mozilla/firefox"; do + ### Determine executable to use + logg info "Processing Firefox profile location $SETTINGS_DIR" + unset FIREFOX_EXE + if [ "$SETTINGS_DIR" == "$HOME/.var/app/org.mozilla.firefox/.mozilla/firefox" ]; then + if ! command -v org.mozilla.firefox > /dev/null || [ ! -d "$HOME/.var/app/org.mozilla.firefox" ]; then + continue + else + FIREFOX_EXE="$(which org.mozilla.firefox)" + ### Firefox Profile Switcher + BASE_DIR="$HOME/.var/app/org.mozilla.firefox" + BIN_INSTALL_DIR="$BASE_DIR/data/firefoxprofileswitcher-install" + MANIFEST_INSTALL_DIR="$BASE_DIR/.mozilla/native-messaging-hosts" + DOWNLOAD_URL="https://github.com/null-dev/firefox-profile-switcher-connector/releases/latest/download/linux-x64.deb" + + ### Ensure Firefox Profile Switcher is not already installed + if [ ! -f "$BIN_INSTALL_DIR/usr/bin/ff-pswitch-connector" ] || [ ! -f "$MANIFEST_INSTALL_DIR/ax.nd.profile_switcher_ff.json" ]; then + ### Download profile switcher + mkdir -p "$BIN_INSTALL_DIR" + TMP_FILE="$(mktemp)" + logg info 'Downloading Firefox Profile Switch connector' + curl -sSL "$DOWNLOAD_URL" -o "$TMP_FILE" + ar p "$TMP_FILE" data.tar.xz | tar xfJ - --strip-components=2 -C "$BIN_INSTALL_DIR" usr/bin/ff-pswitch-connector + rm -f "$TMP_FILE" + + ### Create manifest + logg info 'Copying profile switcher configuration to manifest directory' + mkdir -p "$MANIFEST_INSTALL_DIR" + cat "${XDG_DATA_HOME:-$HOME/.local/share}/firefox/profile-switcher.json" | sed 's=PATH_PLACEHOLDER='"$BIN_INSTALL_DIR"'=' > "$MANIFEST_INSTALL_DIR/ax.nd.profile_switcher_ff.json" + fi + fi + elif [ "$SETTINGS_DIR" == "$HOME/.var/app/io.gitlab.librewolf-community/.librewolf" ]; then + if ! command -v io.gitlab.librewolf-community > /dev/null || [ ! -d "$HOME/.var/app/io.gitlab.librewolf-community" ]; then + continue + else + continue + # FIREFOX_EXE="$(which io.gitlab.librewolf-community)" + fi + elif [ "$SETTINGS_DIR" == "$HOME/Library/Application Support/Firefox/Profiles" ]; then + FIREFOX_EXE="/Applications/Firefox.app/Contents/MacOS/firefox" + if [ ! -f "$FIREFOX_EXE" ] || [ ! -d /Applications ]; then + continue + else + ### Download Firefox Profile Switcher + if [ ! -d /usr/local/Cellar/firefox-profile-switcher-connector ]; then + logg info 'Ensuring Firefox Profile Switcher is installed' + brew install --quiet null-dev/firefox-profile-switcher/firefox-profile-switcher-connector + fi + + ### Ensure Firefox Profile Switcher configuration is symlinked + if [ ! -d "/Library/Application Support/Mozilla/NativeMessagingHosts/ax.nd.profile_switcher_ff.json" ]; then + logg info 'Ensuring Firefox Profile Switcher is configured' + sudo mkdir -p "/Library/Applcation Support/Mozilla/NativeMessagingHosts" + sudo ln -sf "$(brew ls -l firefox-profile-switcher-connector | grep -i ax.nd.profile_switcher_ff.json | head -n1)" "/Library/Application Support/Mozilla/NativeMessagingHosts/ax.nd.profile_switcher_ff.json" + fi + fi + elif [ "$SETTINGS_DIR" == "$HOME/Library/Application Support/LibreWolf/Profiles" ]; then + continue + # FIREFOX_EXE="/Applications/LibreWolf.app/Contents/MacOS/librewolf" + # if [ ! -f "$FIREFOX_EXE" ] || [ ! -d /Applications ]; then + # logg info "$FIREFOX_EXE is not a file" + # continue + # fi + elif [ "$SETTINGS_DIR" == "$HOME/snap/firefox/common/.mozilla/firefox" ]; then + FIREFOX_EXE="/snap/bin/firefox" + if [ ! -f "$FIREFOX_EXE" ] || [ ! -d "$HOME/snap/firefox" ]; then + continue + else + ### Firefox Profile Switcher + BASE_DIR="$HOME/snap/firefox/common" + BIN_INSTALL_DIR="$BASE_DIR/firefoxprofileswitcher-install" + MANIFEST_INSTALL_DIR="$BASE_DIR/.mozilla/native-messaging-hosts" + DOWNLOAD_URL="https://github.com/null-dev/firefox-profile-switcher-connector/releases/latest/download/linux-x64.deb" + + ### Ensure Firefox Profile Switcher is not already installed + if [ ! -f "$BIN_INSTALL_DIR/usr/bin/ff-pswitch-connector" ] || [ ! -f "$MANIFEST_INSTALL_DIR/ax.nd.profile_switcher_ff.json" ]; then + ### Download profile switcher + mkdir -p "$BIN_INSTALL_DIR" + TMP_FILE="$(mktemp)" + logg info 'Downloading Firefox Profile Switch connector' + curl -sSL "$DOWNLOAD_URL" -o "$TMP_FILE" + ar p "$TMP_FILE" data.tar.xz | tar xfJ - --strip-components=2 -C "$BIN_INSTALL_DIR" usr/bin/ff-pswitch-connector + rm -f "$TMP_FILE" + + ### Create manifest + logg info 'Copying profile switcher configuration to manifest directory' + mkdir -p "$MANIFEST_INSTALL_DIR" + cat "${XDG_DATA_HOME:-$HOME/.local/share}/firefox/profile-switcher.json" | sed 's/PATH_PLACEHOLDER/'"$BIN_INSTALL_DIR"'/' > "$MANIFEST_INSTALL_DIR/ax.nd.profile_switcher_ff.json" + fi + fi + elif [ "$SETTINGS_DIR" == "$HOME/.mozilla/firefox" ]; then + if command -v firefox-esr > /dev/null; then + FIREFOX_EXE="$(which firefox-esr)" + installFirefoxProfileConnector + elif command -v firefox > /dev/null && [ "$(which firefox)" != *'snap'* ] && [ "$(which firefox)" != *'flatpak'* ] && [ ! -d /Applications ] && [ ! -d /System ]; then + # Conditional check ensures Snap / Flatpak / macOS Firefox versions do not try to install to the wrong folder + FIREFOX_EXE="$(which firefox)" + installFirefoxProfileConnector + else + if [ -d /Applications ] && [ -d /System ]; then + # Continue on macOS without logging because profiles are not stored here on macOS + continue + else + logg warn 'Unable to register Firefox executable' + logg info "Settings directory: $SETTINGS_DIR" + continue + fi + fi + fi + ### Initiatize Firefox default profiles + logg info "Processing executable located at $FIREFOX_EXE" + if command -v "$FIREFOX_EXE" > /dev/null; then + ### Create default profile by launching Firefox headlessly + logg info "Firefox executable set to $FIREFOX_EXE" + if [ ! -d "$SETTINGS_DIR" ]; then + logg info 'Running Firefox (or its derivative) headlessly to generate default profiles' + timeout 14 "$FIREFOX_EXE" --headless + logg info 'Finished running Firefox headlessly' + elif [ -d /Applications ] && [ -d /System ] && [ ! -f "$SETTINGS_DIR/../installs.ini" ]; then + logg info 'Running Firefox (or its derivative) headlessly to generate default profiles because install.ini is not at the macOS default location.' + timeout 14 "$FIREFOX_EXE" --headless + logg info 'Finished running Firefox headlessly (while fixing the missing macOS installs.ini issue)' + fi + + ### Ensure settings directory exists (since the application was brought up temporarily headlessly) + if [ ! -d "$SETTINGS_DIR" ]; then + logg warn "The settings directory located at $SETTINGS_DIR failed to be populated by running the browser headlessly" + continue + fi + + ### Add the populated profiles.ini + logg info "Copying "${XDG_DATA_HOME:-$HOME/.local/share}/firefox/profiles.ini" to profile directory" + logg info "The settings directory is $SETTINGS_DIR" + if [ -d /Applications ] && [ -d /System ]; then + # macOS + logg info "Copying ~/.local/share/firefox/profiles.ini to $SETTINGS_DIR/../profiles.ini" + cp -f "${XDG_DATA_HOME:-$HOME/.local/share}/firefox/profiles.ini" "$SETTINGS_DIR/../profiles.ini" + SETTINGS_INI="$SETTINGS_DIR/../installs.ini" + else + # Linux + logg info "Copying ~/.local/share/firefox/profiles.ini to $SETTINGS_DIR/profiles.ini" + cp -f "${XDG_DATA_HOME:-$HOME/.local/share}/firefox/profiles.ini" "$SETTINGS_DIR/profiles.ini" + SETTINGS_INI="$SETTINGS_DIR/installs.ini" + fi + + ### Default profile (created by launching Firefox headlessly) + DEFAULT_RELEASE_PROFILE="$(find "$SETTINGS_DIR" -mindepth 1 -maxdepth 1 -name "*.default" -not -name "profile.default")" + if [ -n "$DEFAULT_RELEASE_PROFILE" ]; then + logg info "Syncing $DEFAULT_RELEASE_PROFILE to $SETTINGS_DIR/profile.default" + rsync -a "$DEFAULT_RELEASE_PROFILE/" "$SETTINGS_DIR/profile.default" + else + logg warn 'Unable to sync default Mozilla Firefox profile' + fi + + ### Ensure original installs.ini is removed + if [ -f "$SETTINGS_INI" ]; then + # DEFAULT_PROFILE_PROFILE="$SETTINGS_DIR/$(cat "$SETTINGS_INI" | grep 'Default=' | sed 's/.*Profiles\///')" + logg info 'Removing previous installs.ini file' + rm -f "$SETTINGS_INI" + else + logg info 'installs.ini was not present in the Mozilla Firefox settings folder' + fi + + ### Miscellaneous default profiles + for NEW_PROFILE in "automation" "development" "miscellaneous"; do + if [ ! -d "$SETTINGS_DIR/profile.${NEW_PROFILE}" ] && [ -d "$SETTINGS_DIR/profile.default" ]; then + logg info "Cloning $NEW_PROFILE from profile.default" + rsync -a "$SETTINGS_DIR/profile.default/" "$SETTINGS_DIR/profile.${NEW_PROFILE}" + rsync -a "${XDG_DATA_HOME:-$HOME/.local/share}/firefox/" "$SETTINGS_DIR/profile.${NEW_PROFILE}" + cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/firefox/user.js" "$SETTINGS_DIR/profile.${NEW_PROFILE}" + fi + done + + ### Public git profile + if [ -d "$SETTINGS_DIR/profile.git" ]; then + logg info 'Resetting the Firefox git profile' + cd "$SETTINGS_DIR/profile.git" + git reset --hard HEAD + git clean -fxd + logg info 'Pulling latest updates to the Firefox git profile' + git pull origin master + else + logg info 'Cloning the public Firefox git profile' + cd "$SETTINGS_DIR" && git clone "$FIREFOX_PUBLIC_PROFILE" profile.git + fi + + ### Copy user.js to profile.git profile + cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/firefox/user.js" "$SETTINGS_DIR/profile.git" + + ### Git profile w/ plugins installed (installation happens below) + if [ ! -d "$SETTINGS_DIR/profile.plugins" ]; then + logg info "Syncing $SETTINGS_DIR/profile.git to $SETTINGS_DIR/profile.plugins" + rsync -a "$SETTINGS_DIR/profile.git/" "$SETTINGS_DIR/profile.plugins" + rsync -a "${XDG_DATA_HOME:-$HOME/.local/share}/firefox/" "$SETTINGS_DIR/profile.plugins" + cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/firefox/user.js" "$SETTINGS_DIR/profile.plugins" + fi + + ### Private hosted profile + # Deprecated in favor of using the Restic profile tasks saved in `~/.config/task/Taskfile.yml` + # if [ ! -d "$SETTINGS_DIR/profile.private" ]; then + # logg info 'Downloading the encrypted Firefox private profile' + # cd "$SETTINGS_DIR" + # curl -sSL '{ { .firefoxPrivateProfile } }' -o profile.private.tar.gz.age + # logg info 'Decrypting the Firefox private profile' + # chezmoi decrypt profile.private.tar.gz.age > profile.private.tar.gz || EXIT_DECRYPT_CODE=$? + # if [ -z "$EXIT_DECRYPT_CODE" ]; then + # rm -f profile.private.tar.gz.age + # logg info 'Decompressing the Firefox private profile' + # tar -xzf profile.private.tar.gz + # logg success 'The Firefox private profile was successfully installed' + # cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/firefox/user.js" "$SETTINGS_DIR/profile.private" + # logg info 'Copied ~/.config/firefox/user.js to profile.private profile' + # else + # logg error 'Failed to decrypt the private Firefox profile' + # fi + # fi + + ### Install Firefox addons (using list declared in .chezmoidata.yaml) + for SETTINGS_PROFILE in "profile.plugins" "profile.private"; do + if [ -d "$SETTINGS_DIR/$SETTINGS_PROFILE" ]; then + for FIREFOX_PLUGIN in {{ list (.firefoxAddOns | toString | replace "[" "" | replace "]" "") | uniq | join " " }}; do + logg info "Processing the $FIREFOX_PLUGIN Firefox add-on" + PLUGIN_HTML="$(mktemp)" + curl --silent "https://addons.mozilla.org/en-US/firefox/addon/$FIREFOX_PLUGIN/" > "$PLUGIN_HTML" + PLUGIN_TMP="$(mktemp)" + if ! command -v htmlq > /dev/null && command -v brew > /dev/null; then + logg info 'Installing htmlq using Homebrew since it is a dependency for populating Firefox add-ons' && brew install htmlq + fi + cat "$PLUGIN_HTML" | htmlq '#redux-store-state' | sed 's/^//' | sed 's/<\/script>$//' > "$PLUGIN_TMP" + PLUGIN_ID="$(jq '.addons.bySlug["'"$FIREFOX_PLUGIN"'"]' "$PLUGIN_TMP")" + if [ "$PLUGIN_ID" != 'null' ]; then + PLUGIN_FILE_ID="$(jq -r '.addons.byID["'"$PLUGIN_ID"'"].guid' "$PLUGIN_TMP")" + if [ "$PLUGIN_FILE_ID" != 'null' ]; then + PLUGIN_URL="$(cat "$PLUGIN_HTML" | htmlq '.InstallButtonWrapper-download-link' --attribute href)" + PLUGIN_FILENAME="${PLUGIN_FILE_ID}.xpi" + PLUGIN_FOLDER="$(echo "$PLUGIN_FILENAME" | sed 's/.xpi$//')" + if [ ! -d "$SETTINGS_DIR/$SETTINGS_PROFILE/extensions/$PLUGIN_FOLDER" ]; then + logg info 'Downloading add-on XPI file for '"$PLUGIN_FILENAME"' ('"$FIREFOX_PLUGIN"')' + if [ ! -d "$SETTINGS_DIR/$SETTINGS_PROFILE/extensions" ]; then + mkdir -p "$SETTINGS_DIR/$SETTINGS_PROFILE/extensions" + fi + curl -sSL "$PLUGIN_URL" -o "$SETTINGS_DIR/$SETTINGS_PROFILE/extensions/$PLUGIN_FILENAME" + # Unzipping like this causes Firefox to complain about unsigned plugins + # TODO - figure out how to headlessly enable the extensions in such a way that is compatible with Flatpak / Snap + # using the /usr/lib/firefox/distribution/policies.json works but this is not compatible with Flatpak / Snap out of the box + # it seems since they do not have access to the file system by default. Also, using the policies.json approach forces + # all Firefox profiles to use the same extensions. Ideally, we should find a way to enable the extensions scoped + # to the user profile. + # logg info 'Unzipping '"$PLUGIN_FILENAME"' ('"$FIREFOX_PLUGIN"')' + # unzip "$SETTINGS_DIR/$SETTINGS_PROFILE/extensions/$PLUGIN_FILENAME" -d "$SETTINGS_DIR/$SETTINGS_PROFILE/extensions/$PLUGIN_FOLDER" + logg success 'Installed '"$FIREFOX_PLUGIN"'' + fi + else + logg warn 'A null Firefox add-on filename was detected for '"$FIREFOX_PLUGIN"'' + fi + else + logg warn 'A null Firefox add-on ID was detected for '"$FIREFOX_PLUGIN"'' + fi + done + fi + done + fi + done + } + firefoxSetup apt: firefox apt:debian: firefox-esr cask: firefox @@ -5276,6 +5823,23 @@ softwarePackages: _name: Keybase _post:cask: if [ ! -f /usr/local/bin/keybase ] && [ -f /Applications/Keybase.app/Contents/SharedSupport/bin/keybase ]; then echo "Fixing missing keybase executable symlink permission issue" && sudo ln -s /Applications/Keybase.app/Contents/SharedSupport/bin/keybase /usr/local/bin/keybase; fi _when:ansible: '! test -f /opt/keybase/Keybase' + _post: | + # @file Keybase Configuration + # @brief Updates Keybase's system configuration with the Keybase configuration stored in the `home/dot_config/keybase/config.json` location. + # @description + # This script ensures Keybase utilizes a configuration that, by default, adds a security fix. + + if command -v keybase > /dev/null; then + KEYBASE_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/keybase/config.json" + if [ -f "$KEYBASE_CONFIG" ]; then + logg info 'Ensuring /etc/keybase is a directory' && sudo mkdir -p /etc/keybase + logg info "Copying $KEYBASE_CONFIG to /etc/keybase/config.json" && sudo cp -f "$KEYBASE_CONFIG" /etc/keybase/config.json + else + logg warn "No Keybase config located at $KEYBASE_CONFIG" + fi + else + logg info 'The keybase executable is not available' + fi _app: Keybase.app ansible: professormanhattan.keybase cask: keybase @@ -5995,6 +6559,68 @@ softwarePackages: target: "$HOME/Library/Application Support/Microsoft Edge/Default" _link:choco: 'TODO' _link:flatpak: 'TODO' + _post: | + # @brief See `google-chrome` `_post` script for more details + function chromeSetUp() { + ### Ensure Chrome policies directory is present + # logg info 'Processing policy directories for Chromium based browsers' + ### TODO - Find POLICY_DIR location for Microsoft Edge + # for POLICY_DIR in "/opt/google/chrome/policies" "/etc/chromium/policies" "/etc/brave/policies"; do + # if [ -d "$(dirname "$POLICY_DIR")" ]; then + # ### Managed policies + # if [ ! -f "$POLICY_DIR/managed/policies.json" ]; then + # logg info "Ensuring directory $POLICY_DIR/managed exists" + # sudo mkdir -p "$POLICY_DIR/managed" + # logg info "Copying ${XDG_CONFIG_HOME:-$HOME/.config}/chrome/managed.json to $POLICY_DIR/managed/policies.json" + # sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/managed.json" "$POLICY_DIR/managed/policies.json" + # fi + # ### Recommended policies + # if [ ! -f "$POLICY_DIR/recommended/policies.json" ]; then + # logg info "Ensuring directory $POLICY_DIR/recommended exists" && sudo mkdir -p "$POLICY_DIR/recommended" + # logg info "Copying ${XDG_CONFIG_HOME:-$HOME/.config}/chrome/recommended.json to $POLICY_DIR/recommended/policies.json" + # sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/recommended.json" "$POLICY_DIR/recommended/policies.json" + # fi + # else + # logg info "Skipping extension injection into $POLICY_DIR - create these folders prior to running to create managed configs" + # fi + # done + + ### Add Chrome extension JSON + logg info 'Populating Chrome extension JSON' + for EXTENSION_DIR in "$HOME/Library/Application Support/Microsoft/Edge/External Extensions"; do + ### Ensure program-type is installed + if [ -d "$(dirname "$EXTENSION_DIR")" ]; then + ### Ensure extension directory exists + if [[ "$EXTENSION_DIR" == '/opt/'* ]] || [[ "$EXTENSION_DIR" == '/etc/'* ]]; then + if [ ! -d "$EXTENSION_DIR" ]; then + logg info "Creating directory $EXTENSION_DIR" && sudo mkdir -p "$EXTENSION_DIR" + fi + else + if [ ! -d "$EXTENSION_DIR" ]; then + logg info "Creating directory $EXTENSION_DIR" && mkdir -p "$EXTENSION_DIR" + fi + fi + + ### Add extension JSON + logg info "Adding Chrome extensions to $EXTENSION_DIR" + for EXTENSION in {{ list (.chromeExtensions | toString | replace "[" "" | replace "]" "") | uniq | join " " }}; do + logg info "Adding Chrome extension manifest ($EXTENSION)" + if ! echo "$EXTENSION" | grep 'https://chrome.google.com/webstore/detail/' > /dev/null; then + EXTENSION="https://chrome.google.com/webstore/detail/$EXTENSION" + fi + EXTENSION_ID="$(echo "$EXTENSION" | sed 's/^.*\/\([^\/]*\)$/\1/')" + if [[ "$EXTENSION_DIR" == '/opt/'* ]] || [[ "$EXTENSION_DIR" == '/etc/'* ]]; then + sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/extension.json" "$EXTENSION_DIR/${EXTENSION_ID}.json" + else + cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/chrome/extension.json" "$EXTENSION_DIR/${EXTENSION_ID}.json" + fi + done + else + logg info "$EXTENSION_DIR does not exist" + fi + done + } + chromeSetUp cask: microsoft-edge choco: microsoft-edge flatpak: com.microsoft.Edge @@ -6637,6 +7263,152 @@ softwarePackages: _deps: - debsecan - speedtest-cli + _post: | + # @file Netdata + # @brief Connects Netdata with Netdata's free cloud dashboard and applies some system optimizations, if necessary + # @description + # This script connects Netdata with Netdata Cloud if Netdata is installed, the `NETDATA_TOKEN` is provided, and the + # `NETDATA_ROOM` is defined. This allows you to graphically browse through system metrics on all your connected devices + # from a single free web application. + # + # This script installs additional alerts and enables notifications if Netdata is installed. Email notifications are configured + # using the provided primary email address. If the OS is Debian based, Netdata shows the number of CVEs in currently installed packages. + + ensureNetdataOwnership() { + ### Ensure /usr/local/var/lib/netdata/cloud.d is owned by user + if [ -d /usr/local/var/lib/netdata ]; then + logg info 'Ensuring permissions are correct on /usr/local/var/lib/netdata' && sudo chown -Rf netdata:netdata /usr/local/var/lib/netdata 2> /dev/null || sudo chown -Rf netdata:$(id -g -n) /usr/local/var/lib/netdata + elif [ -d /var/lib/netdata ]; then + logg info 'Ensuring permissions are correct on /var/lib/netdata' && sudo chown -Rf netdata:netdata /var/lib/netdata 2> /dev/null || sudo chown -Rf netdata:$(id -g -n) /var/lib/netdata + elif [ -d "${HOMEBREW_PREFIX:-/opt/homebrew}/var/lib/netdata" ]; then + logg info "Ensuring permissions are correct on ${HOMEBREW_PREFIX:-/opt/homebrew}/var/lib/netdata" && sudo chown -Rf netdata:netdata "${HOMEBREW_PREFIX:-/opt/homebrew}/var/lib/netdata" 2> /dev/null || sudo chown -Rf netdata:$(id -g -n) "${HOMEBREW_PREFIX:-/opt/homebrew}/var/lib/netdata" + else + logg warn 'No /var/lib/netdata folder found' + fi + } + + ### Claim the instance with Netdata Cloud + if command -v netdata-claim.sh > /dev/null; then + ### Add user / group with script in ~/.local/bin/add-usergroup, if it is available + if command -v add-usergroup > /dev/null; then + sudo add-usergroup "$USER" netdata + fi + + ### Ensure ownership + ensureNetdataOwnership + + ### netdata-claim.sh must be run as netdata user + sudo -H -u netdata bash -c 'export NETDATA_ROOM="{{- if (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "NETDATA_ROOM")) -}}{{- includeTemplate "secrets/NETDATA_ROOM" | decrypt | trim -}}{{- else -}}{{- env "NETDATA_ROOM" -}}{{- end -}}" && export NETDATA_TOKEN="{{- if (stat (joinPath .chezmoi.sourceDir ".chezmoitemplates" "secrets" "NETDATA_TOKEN")) -}}{{- includeTemplate "secrets/NETDATA_TOKEN" | decrypt | trim -}}{{- else -}}{{- env "NETDATA_TOKEN" -}}{{- end -}}" && yes | netdata-claim.sh -token="$NETDATA_TOKEN" -rooms="$NETDATA_ROOM" -url="https://app.netdata.cloud"' + + ### Kernel optimizations + # These are mentioned while installing via the kickstart.sh script method. We are using Homebrew for the installation though. + # Assuming these optimizations do not cause any harm. + if [ -d /Applications ] && [ -d /System ]; then + ### macOS + logg info 'System is macOS so Netdata kernel optimizations are not required' + else + ### Linux + if [ -d /sys/kernel/mm/ksm ]; then + logg info 'Adding Netdata kernel optimization for /sys/kernel/mm/ksm/run' + echo 1 | sudo tee /sys/kernel/mm/ksm/run + logg info 'Adding Netdata kernel optimization for /sys/kernel/mm/ksm/sleep_millisecs' + echo 1000 | sudo tee /sys/kernel/mm/ksm/sleep_millisecs + else + logg info 'The /sys/kernel/mm/ksm directory does not exist so Netdata kernel optimizations are not being applied' + fi + fi + + ### Install additional alerts and enable notifications + if command -v netdata > /dev/null; then + ### Copy the additional alert definitions + if [ -d /usr/local/etc/netdata ]; then + NETDATA_ETC='/usr/local/etc/netdata/' + elif [ -d /etc/netdata ]; then + NETDATA_ETC='/etc/netdata' + elif [ -d "${HOMEBREW_PREFIX:-/opt/homebrew}/etc/netdata" ]; then + NETDATA_ETC="${HOMEBREW_PREFIX:-/opt/homebrew}/etc/netdata" + else + logg error 'No etc location found for netdata' && exit 1 + fi + logg info "Copying ${XDG_CONFIG_HOME:-$HOME/.config}/netdata/health.d/ to $NETDATA_ETC" && sudo cp -rf "${XDG_CONFIG_HOME:-$HOME/.config}/netdata/health.d/" "$NETDATA_ETC" + # Backup current health alarm configuration and apply new one + if [ -d /usr/local/lib/netdata ]; then + NETDATA_LIB='/usr/local/lib/netdata' + elif [ -d /usr/lib/netdata ]; then + NETDATA_LIB='/usr/lib/netdata' + elif [ -d "${HOMEBREW_PREFIX:-/opt/homebrew}/lib/netdata" ]; then + NETDATA_LIB="${HOMEBREW_PREFIX:-/opt/homebrew}/lib/netdata" + else + logg error 'No lib location found for netdata' && exit 1 + fi + logg info "Copying ${XDG_CONFIG_HOME:-$HOME/.config}/netdata/health_alarm_notify.conf to $NETDATA_LIB/conf.d/health_alarm_notify.conf" && sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/netdata/health_alarm_notify.conf" "$NETDATA_LIB/conf.d/health_alarm_notify.conf" + else + logg warn 'netdata is not available in the PATH or is not installed' + fi + + ### Ensure the apt command is available before running `debsecan` logic + if command -v apt-get > /dev/null; then + ### Configure Netdata to gather information about CVEs in the installed packages + if command -v debsecan > /dev/null; then + DEBSECAN_GIT="${XDG_DATA_HOME:-$HOME/.local/share}/netdata-debsecan" + ### Installing the script to generate report on CVEs in installed packages + logg info 'Installing script to generate report on CVEs in installed packages' && sudo cp -f "$DEBSECAN_GIT/usr_local_bin_debsecan-by-type" "/usr/local/bin/debsecan-by-type" + ### Generate initial debsecan reports in /var/log/debsecan/ + logg info 'Generating initial debsecan reports in /var/log/debsecan/' && debsecan-by-type + ### Configure dpkg to refresh the file after each run + logg info 'Configuring dpkg to refresh the file after each run' && sudo cp -f "$DEBSECAN_GIT/etc_apt_apt.conf.d_99debsecan" /etc/apt/apt.conf.d/99-debsecan + ### Add a cron job to refresh the file every hour + logg info 'Adding a cron job to refresh the file every hour' && sudo cp -f "$DEBSECAN_GIT/etc_cron.d_debsecan" /etc/cron.d/debsecan + ### Install the module/configuration file + logg info 'Installing the module and configuration file' + sudo "$DEBSECAN_GIT/debsecan.chart.py" /usr/libexec/netdata/python.d/debsecan.chart.py + sudo "$DEBSECAN_GIT/debsecan.conf" /etc/netdata/python.d/debsecan.conf + else + logg warn 'apt-get is available but debsecan is not available in the PATH or is not installed' + fi + fi + + ### Ensure / report whether speedtest-cli is installed + if ! command -v speedtest-cli > /dev/null; then + if command -v pipx > /dev/null; then + pipx install speedtest-cli + else + logg warn 'speedtest-cli not installed and pipx is not available' + fi + fi + + ### Configure Netdata to gather information about Internet connection speed + if command -v speedtest-cli > /dev/null; then + ### Installing the script to generate report on Internet connection speed + logg info 'Installing script to generate report on Internet connection speed' + LIBEXEC_PATH="$(netdata -W buildinfo | grep 'Configure' | sed "s/.*--libexecdir=\([^ \']*\).*/\1/")" + if [ -d /usr/libexec/netdata/charts.d ]; then + sudo cp -f "${XDG_DATA_HOME:-$HOME/.local/share}/netdata-speedtest/speedtest.chart.sh" "/usr/libexec/netdata/charts.d/speedtest.chart.sh" + elif [ -d "$LIBEXEC_PATH/netdata/charts.d" ]; then + logg info "$LIBEXEC_PATH/netdata/charts.d present on system" + cp -f "${XDG_DATA_HOME:-$HOME/.local/share}/netdata-speedtest/speedtest.chart.sh" "$LIBEXEC_PATH/netdata/charts.d/speedtest.chart.sh" + else + logg warn "Failed to find appropriate directory to add Netdata speedtest chart script" + fi + else + logg warn 'speedtest-cli is not available in the PATH or is not installed' + fi + + ### Ensure ownership again + ensureNetdataOwnership + + ### Restart Netdata service + if command -v systemctl > /dev/null; then + logg info 'Enabling netdata service' && sudo systemctl enable netdata + logg info 'Restarting netdata service' && sudo systemctl restart netdata + elif [ -d /Applications ] && [ -d /System ]; then + logg info 'Starting / enabling netdata service' && brew services restart netdata + else + logg warn 'systemctl is not available' + fi + else + logg info 'netdata-claim.sh is not available in the PATH' + fi ansible: professormanhattan.netdata brew: netdata pacman: netdata @@ -10064,6 +10836,156 @@ softwarePackages: _github: https://github.com/vdukhovni/postfix _home: https://www.postfix.org/ _name: Postfix + _post: | + # @file SendGrid Postfix Configuration + # @brief Configures Postfix to use SendGrid as a relay host so you can use the `mail` program to send e-mail from the command-line + # @description + # This script follows the instructions from [SendGrid's documentation on integrating Postfix](https://docs.sendgrid.com/for-developers/sending-email/postfix). + # After this script runs, you should be able to send outgoing e-mails using SendGrid as an SMTP handler. In other words, you will + # be able to use the `mail` CLI command to send e-mails. The following is an example mailing the contents of `~/.bashrc` to `name@email.com`: + # + # ```shell + # cat ~/.bashrc | mail -s "My subject" name@email.com + # ``` + + if [ -n "$SENDGRID_API_KEY" ] && [ "$SENDGRID_API_KEY" != "" ]; then + if command -v postfix > /dev/null; then + ### Ensure dependencies are installed + if command -v apt-get > /dev/null; then + logg info 'Installing libsasl2-modules' + sudo apt-get update + sudo apt-get install -y libsasl2-modules || EXIT_CODE=$? + elif command -v dnf > /dev/null; then + sudo dnf install -y cyrus-sasl-plain || EXIT_CODE=$? + elif command -v yum > /dev/null; then + sudo yum install -y cyrus-sasl-plain || EXIT_CODE=$? + fi + if [ -n "$EXIT_CODE" ]; then + logg warn 'There was an error ensuring the Postfix-SendGrid dependencies were installed' + fi + + if [ -d /etc/postfix ]; then + ### Add the SendGrid Postfix settings to the Postfix configuration + if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}/postfix/main.cf" ]; then + CONFIG_FILE=/etc/postfix/main.cf + if cat "$CONFIG_FILE" | grep '### INSTALL DOCTOR MANAGED' > /dev/null; then + logg info 'Removing Install Doctor-managed block of code in /etc/postfix/main.cf block' + START_LINE="$(echo `grep -n -m 1 "### INSTALL DOCTOR MANAGED ### START" "$CONFIG_FILE" | cut -f1 -d ":"`)" + END_LINE="$(echo `grep -n -m 1 "### INSTALL DOCTOR MANAGED ### END" "$CONFIG_FILE" | cut -f1 -d ":"`)" + if [ -n "$START_LINE" ] && [ -n "$END_LINE" ]; then + if command -v gsed > /dev/null; then + sudo gsed -i "${START_LINE},${END_LINE}d" "$CONFIG_FILE" + else + sudo sed -i "${START_LINE},${END_LINE}d" "$CONFIG_FILE" + fi + else + logg info 'No start-line or end-line detected - configuration appears to already be clean' + fi + fi + + ### Add Postfix main configuration + logg "Adding the following configuration from ${XDG_CONFIG_HOME:-$HOME/.config}/postfix/main.cf to /etc/postfix/main.cf" + cat "${XDG_CONFIG_HOME:-$HOME/.config}/postfix/main.cf" | sudo tee -a "$CONFIG_FILE" > /dev/null + echo "" | sudo tee -a "$CONFIG_FILE" > /dev/null + fi + + ### Ensure proper permissions on `sasl_passwd` and update Postfix hashmaps + if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}/postfix/sasl_passwd" ]; then + logg info "Copying file from ${XDG_CONFIG_HOME:-$HOME/.config}/postfix/sasl_passwd to /etc/postfix/sasl_passwd" + sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/postfix/sasl_passwd" /etc/postfix/sasl_passwd + logg info 'Assigning proper permissions to /etc/postfix/sasl_passwd' + sudo chmod 600 /etc/postfix/sasl_passwd + logg info 'Updating Postfix hashmaps for /etc/postfix/sasl_passwd' + sudo postmap /etc/postfix/sasl_passwd + else + logg warn '~/.config/postfix/sasl_passwd file is missing' + fi + + ### Forward root e-mails + if [ -d /root ]; then + logg info "Forwarding root e-mails to $PRIMARY_EMAIL" + echo "$PRIMARY_EMAIL" | sudo tee /root/.forward > /dev/null || logg error 'Failed to set root user .forward file' + elif [ -d /var/root ]; then + logg info "Forwarding root e-mails to $PRIMARY_EMAIL" + echo "$PRIMARY_EMAIL" | sudo tee /var/root/.forward > /dev/null || logg error 'Failed to set root user .forward file' + else + logg warn 'Unable to identify root user home directory' + fi + + ### Ensure /etc/postfix/header_checks exists + if [ ! -d /etc/postfix/header_checks ]; then + logg info 'Creating /etc/postfix/header_checks since it does not exist' + sudo touch /etc/postfix/header_checks + fi + + ### Re-write header From for SendGrid + if ! cat /etc/postfix/header_checks | grep "no-reply@${PUBLIC_SERVICES_DOMAIN}" > /dev/null; then + logg info 'Added From REPLACE to /etc/postfix/header_checks' + echo "/^From:.*@${PUBLIC_SERVICES_DOMAIN}/ REPLACE From: no-reply@${PUBLIC_SERVICES_DOMAIN}" | sudo tee -a /etc/postfix/header_checks > /dev/null + fi + + ### Update aliases + if [ -f /etc/aliases ]; then + logg info "Forward root e-mails to $PRIMARY_EMAIL" + ALIASES_TMP="$(mktemp)" + logg info "Setting $PRIMARY_EMAIL as root e-mail in temporary file" + sudo sed "s/#root.*/root:\ $PRIMARY_EMAIL/" /etc/aliases > "$ALIASES_TMP" + logg info 'Moving temporary file to /etc/aliases' + sudo mv -f "$ALIASES_TMP" /etc/aliases + if ! cat /etc/aliases | grep "$USER_USERNAME: root" > /dev/null; then + logg info 'Forward user e-mail to root@localhost' + echo "$USER_USERNAME: root" | sudo tee -a /etc/aliases > /dev/null + fi + + ### Ensure old /etc/aliases.db is removed + if [ -f /etc/aliases.db ]; then + logg info 'Ensuring /etc/aliases.db is removed' && sudo rm -f /etc/aliases.db + else + logg info '/etc/aliases.db was not found' + fi + + ### Re-generate the /etc/aliases.db file + if [ -f /etc/aliases ]; then + logg info 'Ensuring proper permissions on the /etc/aliases file' && sudo chown $(stat -c "%U:%G" /etc/sudoers) /etc/aliases + logg info 'Generating Postfix aliases' && sudo postalias /etc/aliases > /dev/null + else + logg warn '/etc/aliases is missing which is required for Postfix' + fi + # The `sudo newaliases` mode is probably used to regenerate the /etc/aliases.db + # but since we are removing it to ensure proper permissions, this method is commented out. + # logg info 'Running newaliases to regenerate the alias database' && sudo newaliases + else + logg warn '/etc/aliases does not appear to exist' + fi + + if [ -d /Applications ] && [ -d /System ]; then + ### macOS + # Source: https://budiirawan.com/install-mail-server-mac-osx/ + if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}/postfix/com.apple.postfix.master.plist" ] && ! sudo launchctl list | grep 'postfix.master' > /dev/null; then + logg info 'Copying com.apple.postfix.master.plist' + sudo cp -f "${XDG_CONFIG_HOME:-$HOME/.config}/postfix/com.apple.postfix.master.plist" /System/Library/LaunchDaemons/com.apple.postfix.master.plist + sudo launchctl load /System/Library/LaunchDaemons/com.apple.postfix.master.plist && logg success 'launchctl load of com.apple.postfix.master successful' + fi + if ! sudo postfix status > /dev/null; then + logg info 'Starting postfix' + sudo postfix start > /dev/null + else + logg info 'Reloading postfix' + sudo postfix reload > /dev/null + fi + else + ### Enable / restart postfix on Linux + logg info 'Enabling / restarting postfix' + sudo systemctl enable postfix + sudo systemctl restart postfix + fi + else + logg warn '/etc/postfix is not a directory! Skipping SendGrid Postfix setup.' + fi + else + logg info 'Skipping Postfix configuration because Postfix is not installed' + fi + fi apt: postfix dnf: postfix pacman: postfix @@ -10164,6 +11086,21 @@ softwarePackages: _github: https://github.com/teejee2008/timeshift _home: https://teejeetech.com/timeshift/ _name: Timeshift + _post: | + #!/usr/bin/env bash + # @file Timeshift Configuration + # @brief Updates the Timeshift system configuration with the Timeshift configuration stored in the `home/dot_config/timeshift/timeshift.json` location. + # @description + # This script applies a Timeshift configuration that defines how Timeshift should maintain system backups. + if command -v timeshift > /dev/null; then + logg info 'Ensuring /etc/timeshift is a directory' + sudo mkdir -p /etc/timeshift + TIMESHIFT_CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/timeshift/timeshift.json" + logg info "Copying $TIMESHIFT_CONFIG to /etc/timeshift/timeshift.json" + sudo cp -f "$TIMESHIFT_CONFIG" /etc/timeshift/timeshift.json + else + logg info 'The timeshift executable is not available' + fi # Unavailable on CentOS Stream 9 # ansible:linux: professormanhattan.timeshift apt: timeshift @@ -10695,6 +11632,44 @@ softwarePackages: # TODOFigure out how to get version without Ansible here and download / install the extpack wget https://download.virtualbox.org/virtualbox/' + vbox_version + '/Oracle_VM_VirtualBox_Extension_Pack-' + vbox_version + '.vbox-extpack' echo y | VBoxManage extpack install --replace ./Oracle_VM_VirtualBox_Extension_Pack.vbox-extpack + _post: | + # @file VirtualBox Extension Pack + # @brief Ensures the VirtualBox extension pack is installed. + # @description + # This script ensures the VirtualBox extension pack that corresponds with VirtualBox's version is properly installed. + + ### Run logic if VirtualBox is installed + if command -v VirtualBox > /dev/null; then + ### Install VirtualBox extension pack if it is not installed already + if [ ! -d /usr/lib/virtualbox/ExtensionPacks/Oracle_VM_VirtualBox_Extension_Pack ] && [ ! -d /Applications/VirtualBox.app/Contents/MacOS/ExtensionPacks/Oracle_VM_VirtualBox_Extension_Pack ]; then + logg info 'Acquiring VirtualBox version information' + VBOX_VERSION="$(VirtualBox --help | head -n 1 | cut -f 6 -d' ')" + VBOX_VERSION="${VBOX_VERSION//v}" + + ### Set up folders + # Check for macOS installation before creating ExtensionPacks folder on Linux machines + if [ ! -d /Applications/VirtualBox.app ]; then + sudo mkdir -p /usr/lib/virtualbox/ExtensionPacks + fi + mkdir -p /tmp/vbox + cd /tmp/vbox + + ### Download extension pack + logg info 'Downloading VirtualBox extension pack' + curl -sSL https://download.virtualbox.org/virtualbox/$VBOX_VERSION/Oracle_VM_VirtualBox_Extension_Pack-$VBOX_VERSION.vbox-extpack -o /tmp/vbox/Oracle_VM_VirtualBox_Extension_Pack-$VBOX_VERSION.vbox-extpack || logg error 'Failed to download the VirtualBox extension pack so the extension pack installation will be skipped' + + ### Install extension pack + if [ -f /tmp/vbox/Oracle_VM_VirtualBox_Extension_Pack-$VBOX_VERSION.vbox-extpack ]; then + logg info 'Installing VirtualBox extension pack' + echo 'y' | sudo VBoxManage extpack install --replace /tmp/vbox/Oracle_VM_VirtualBox_Extension_Pack-$VBOX_VERSION.vbox-extpack + logg success 'Successfully installed VirtualBox extension pack' + fi + else + logg info 'VirtualBox Extension pack is already installed' + fi + else + logg info 'VirtualBox is not installed so VirtualBox Extension pack will not be installed' + fi _pre:dnf: | . /etc/os-release cat < /dev/null; then + EXTENSIONS="$(codium --list-extensions)" + jq -r '.recommendations[]' "${XDG_CONFIG_HOME:-$HOME/.config}/Code/User/extensions.json" | while read EXTENSION; do + if ! echo "$EXTENSIONS" | grep -iF "$EXTENSION" > /dev/null; then + logg info 'Installing VSCodium extension '"$EXTENSION"'' && codium --install-extension "$EXTENSION" && logg success 'Installed '"$EXTENSION"'' + else + logg info ''"$EXTENSION"' already installed' + fi + done + else + logg info 'codium executable not available - skipping plugin install process for it' + fi appimage: vscodium/vscodium cask: vscodium choco: vscodium @@ -10790,8 +11781,168 @@ softwarePackages: _home: https://www.vmware.com/ _name: VMWare _app: VMware Fusion.app + _post: | + # @file VMWare Configuration + # @brief Installs VMWare Workstation Pro on Linux devices, applies a "publicly-retrieved" license key (see disclaimer), and automatically accepts the terms and conditions + # @description + # This script ensures the user included `vmware` in their software installation list. It then checks for presence of the `vmware` utility. If it is not present, then the script: + # + # 1. Downloads the [VMWare Workstation Pro](https://www.vmware.com/content/vmware/vmware-published-sites/us/products/workstation-pro.html.html) Linux installer + # 2. Installs VMWare Workstation Pro + # 3. Passes options to the installation script that automatically apply a publicly retrived license key and accept the Terms & Conditions + # + # This script first checks if `vagrant`, `vmware`, and `vagrant-vmware-utility` are available in the `PATH`. If they are present, then the script + # configures the [`vagrant-vmware-utility`](https://developer.hashicorp.com/vagrant/docs/providers/vmware/vagrant-vmware-utility) by generating the required security certificates and enabling the service. + # This system package enables the capability of controlling both VMWare Workstation and VMWare Fusion with Vagrant. + # + # Since this script runs only when `vagrant`, `vmware`, and `vagrant-vmware-utility` are in the `PATH`, this means that it will run + # when you use an installation template that includes all three pieces of software in the software list defined in + # `home/.chezmoidata.yaml`. + # + # **DISCLAIMER:** If you plan on using VMWare Workstation for anything but evaluation purposes, then we highly suggest purchasing a copy + # of VMWare Workstation. The "publicly-retrived" license keys are scattered throughout GitHub and we are not exactly + # sure why they work. You can pass in your own key by utilizing the `VMWARE_WORKSTATION_LICENSE_KEY` environment variable. More details on + # using environment variables or repository-housed encrypted secrets can be found in our [Secrets documentation](https://install.doctor/docs/customization/secrets). + # + # ## VMWare on macOS + # + # This script only installs VMWare Workstation on Linux. The macOS-variant titled VMWare Fusion can be installed using a Homebrew + # cask so a "work-around" script does not have to be used. + # + # ## VMWare vs. Parallels vs. VirtualBox vs. KVM vs. Hyper-V + # + # There are a handful of VM virtualization providers you can choose from. VMWare is a nice compromise between OS compatibility and performance. + # Parallels, on the hand, might be better for macOS since it is designed specifically for macOS. Finally, VirtualBox is a truly free, + # open-source option that does not come with the same optimizations that VMWare and Parallels provide. + # + # Other virtualization options include KVM (Linux / macOS) and Hyper-V (Windows). These options are better used for headless + # systems. + # + # ## Links + # + # * [VMWare Workstation homepage](https://www.vmware.com/content/vmware/vmware-published-sites/us/products/workstation-pro.html.html) + # * [Vagrant VMWare Utility on GitHub](https://github.com/hashicorp/vagrant-vmware-desktop) + # * [`home/.chezmoidata.yaml`](https://github.com/megabyte-labs/install.doctor/blob/master/home/.chezmoidata.yaml) + # * [Default license key gist](https://gist.github.com/PurpleVibe32/30a802c3c8ec902e1487024cdea26251) + + ### Run logic if VMware is installed + if command -v vmware > /dev/null; then + ### Build kernel modules if they are not present + if [ ! -f "/lib/modules/$(uname -r)/misc/vmmon.ko" ] || [ ! -f "/lib/modules/$(uname -r)/misc/vmnet.ko" ]; then + ### Build VMWare host modules + logg info 'Building VMware host modules' + if sudo vmware-modconfig --console --install-all; then + logg success 'Built VMWare host modules successfully with sudo vmware-modconfig --console --install-all' + else + logg info 'Acquiring VMware version from CLI' + VMW_VERSION="$(vmware --version | cut -f 3 -d' ')" + mkdir -p /tmp/vmw_patch + cd /tmp/vmw_patch + logg info 'Downloading VMware host module patches' && curl -sSL "https://github.com/mkubecek/vmware-host-modules/archive/workstation-$VMW_VERSION.tar.gz" -o /tmp/vmw_patch/workstation.tar.gz + tar -xzf /tmp/vmw_patch/workstation.tar.gz + cd vmware* + logg info 'Running sudo make and sudo make install' + sudo make + sudo make install + logg success 'Successfully configured VMware host module patches' + fi + + ### Sign VMware host modules if Secure Boot is enabled + if [ -f /sys/firmware/efi ]; then + logg info 'Signing host modules' + mkdir -p /tmp/vmware + cd /tmp/vmware + openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -nodes -days 36500 -subj "/CN=VMware/" + "/usr/src/linux-headers-$(uname -r)/scripts/sign-file" sha256 ./MOK.priv ./MOK.der "$(modinfo -n vmmon)" + "/usr/src/linux-headers-$(uname -r)/scripts/sign-file" sha256 ./MOK.priv ./MOK.der "$(modinfo -n vmnet)" + echo '' | mokutil --import MOK.der + logg success 'Successfully signed VMware host modules. Reboot the host before powering on VMs' + fi + + ### Patch VMware with Unlocker + if [ ! -f /usr/lib/vmware/isoimages/darwin.iso ]; then + logg info 'Acquiring VMware Unlocker latest release version' + UNLOCKER_URL="$(curl -sSL 'https://api.github.com/repos/DrDonk/unlocker/releases/latest' | jq -r '.assets[0].browser_download_url')" + mkdir -p /tmp/vmware-unlocker + cd /tmp/vmware-unlocker + logg info 'Downloading unlocker.zip' + curl -sSL "$UNLOCKER_URL" -o unlocker.zip + unzip unlocker.zip + cd linux + logg info 'Running the unlocker' + echo "y" | sudo ./unlock + logg success 'Successfully unlocked VMware for macOS compatibility' + else + logg info '/usr/lib/vmware/isoimages/darwin.iso is already present on the system so VMware macOS unlocking will not be performed' + fi + + if [[ ! "$(test -d /proc && grep Microsoft /proc/version > /dev/null)" ]]; then + ### Start / enable VMWare service + logg info 'Ensuring vmware.service is enabled and running' + sudo systemctl enable vmware.service + sudo systemctl restart vmware.service + + ### Start / enable VMWare Workstation Server service + logg info 'Ensuring vmware-workstation-server.service is enabled and running' + sudo systemctl enable vmware-workstation-server.service + sudo systemctl restart vmware-workstation-server.service + + ### Start / enable VMWare USB Arbitrator service + if command -v vmware-usbarbitrator.service > /dev/null; then + logg info 'Ensuring vmware-usbarbitrator.service is enabled and running' + sudo systemctl enable vmware-usbarbitrator.service + sudo systemctl restart vmware-usbarbitrator.service + else + logg warn 'vmware-usbarbitrator does not exist in the PATH' + fi + fi + else + logg info 'VMware host modules are present' + fi + else + logg warn 'VMware Workstation is not installed so the VMware Unlocker will not be installed' + fi + + # @description Only run logic if both Vagrant and VMWare are installed + if command -v vagrant > /dev/null && command -v vmware-id > /dev/null; then + # @description Vagrant VMWare Utility configuration + if command -v vagrant-vmware-utility > /dev/null; then + if [ -f /usr/local/bin/certificates/vagrant-utility.key ]; then + logg info 'Assuming Vagrant VMWare Utility certificates have been properly generated since /usr/local/bin/certificates/vagrant-utility.key is present' + else + logg info 'Generating Vagrant VMWare Utility certificates' + sudo vagrant-vmware-utility certificate generate + logg success 'Generated Vagrant VMWare Utility certificates via vagrant-vmware-utility certificate generate' + fi + logg info 'Ensuring the Vagrant VMWare Utility service is enabled' + sudo vagrant-vmware-utility service install || EXIT_CODE=$? + if [ -n "$EXIT_CODE" ]; then + logg info 'The Vagrant VMWare Utility command vagrant-vmware-utility service install failed. It is probably already setup.' + fi + fi + else + logg info 'Vagrant is not installed so the Vagrant plugins will not be installed' + logg info 'Vagrant or VMWare is not installed so the Vagrant VMWare utility will not be configured' + fi ansible: professormanhattan.vmware cask: vmware-fusion + script:linux: | + if ! command -v vmware > /dev/null; then + ### Download VMWare Workstation + VMWARE_WORKSTATION_URL=https://www.vmware.com/go/getworkstation-linux + VMWARE_WORKSTATION_DIR=/tmp/workstation-downloads + mkdir -p "$VMWARE_WORKSTATION_DIR" + logg info 'Downloading VMware Workstation Installer' && curl -sSLA "Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20220101 Firefox/102.0" "$VMWARE_WORKSTATION_URL" -o "$VMWARE_WORKSTATION_DIR/tryworkstation-linux-64.sh" + ### Register product key / license + if [ -n "$VMWARE_WORKSTATION_LICENSE_KEY" ]; then + logg info 'Registering VMware Workstation Pro license with serial number' && sudo "$VMWARE_WORKSTATION_DIR/tryworkstation-linux-64.sh" --eulas-agreed --console --required --set-setting vmware-workstation serialNumber "$VMWARE_WORKSTATION_LICENSE_KEY" + else + logg info 'Agreeing to VMWare Workstation Pro license (without serial number)' && sudo "$VMWARE_WORKSTATION_DIR/tryworkstation-linux-64.sh" --eulas-agreed --console --required + fi + logg success 'VMware Workstation installed successfully' + else + logg info 'VMware Workstation is already installed' + fi what-ip: _bin: whatip flatpak: org.gabmus.whatip @@ -10836,6 +11987,55 @@ softwarePackages: _name: Visual Studio Code _snapClassic: true _app: Visual Studio Code.app + _post: | + # @file VSCode Extensions + # @brief Installs all of the Visual Studio Code extensions specified in the [`home/dot_config/Code/User/extensions.json`](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/Code/User/extensions.json) file. + # @description + # This script loops through all the extensions listed in the [`home/dot_config/Code/User/extensions.json`](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/Code/User/extensions.json) + # file. It installs the extensions when either Visual Studio Code or VSCodium is installed. If both are installed, then both will + # have the plugins automatically installed. + # + # The `extensions.json` file is used to house the plugin list so that if you decide to remove this auto-installer script then + # VSCode will retain some functionality from the file. It will show a popover card that recommends installing any plugins in the + # list that are not already installed. + # + # ## Plugin Settings + # + # Most of the plugin settings have been configured and optimized to work properly with the other default settings + # included by Install Doctor. These settings can be found in the [`home/dot_config/Code/User/settings.json` file](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/Code/User/settings.json). + # If you manage to come up with an improvement, please open a pull request so other users can benefit from your work. + # + # ## Default Extensions + # + # The default plugins in the `extensions.json` list are catered mostly towards full-stack web development. The technologies + # that are catered to by the default extensions relate to TypeScript, JavaScript, Go, Python, Rust, and many more technologies. + # Most of the plugins are not language-specific. + # + # ## Links + # + # * [Visual Studio Code settings folder](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/Code/User) + # * [Visual Studio Code `extensions.json`](https://github.com/megabyte-labs/install.doctor/blob/master/home/dot_config/Code/User/extensions.json) + + ### Hides useless error during extension installations + # Error looks like: + # (node:53151) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead. + # (Use `Electron --trace-deprecation ...` to show where the warning was created) + export NODE_OPTIONS=--throw-deprecation + + # @description Install Visual Studio Code extensions if they are not already installed (by checking the `code --list-extensions` output) + if command -v code > /dev/null; then + EXTENSIONS="$(code --list-extensions)" + jq -r '.recommendations[]' "${XDG_CONFIG_HOME:-$HOME/.config}/Code/User/extensions.json" | while read EXTENSION; do + if ! echo "$EXTENSIONS" | grep -iF "$EXTENSION" > /dev/null; then + logg info 'Installing Visual Studio Code extension '"$EXTENSION"'' && code --install-extension "$EXTENSION" + logg success 'Installed '"$EXTENSION"'' + else + logg info ''"$EXTENSION"' already installed' + fi + done + else + logg info 'code executable not available - skipping plugin install process for it' + fi ansible: professormanhattan.vscode cask: visual-studio-code choco: vscode