diff --git a/pengwin-setup b/pengwin-setup
index 22d7df07..687eb1d1 100755
--- a/pengwin-setup
+++ b/pengwin-setup
@@ -2,40 +2,50 @@
SetupDir="/usr/local/pengwin-setup.d"
-VERSION="1.2a"
+export VERSION="1.2a"
+# shellcheck disable=SC1090
source ${SetupDir}/common.sh "$@"
+declare CANCELLED
+declare SKIP_UPDATES
+
# define functions
-function CheckUpgrades {
-echo "Updating package database"
-sudo apt-get update
-
-# Check for .dist-upgrade file in /etc/apt and inform user dist-upgrade available if so
-if [ -f "/etc/apt/.dist-upgrade" ] ; then
- # whiptail prompt here, delete on dist-upgrade
- echo "Distribution upgrade flag noticed! Alerting user"
- if (whiptail --title "Upgrade Available" --yesno "A distribution upgrade is available. In addition to regular package upgrades, this may also install / remove packages. Would you like to continue?\n\nTo run a non-automated distribution upgrade and see package changes, or to perform this in your own time, run 'sudo apt-get dist-upgrade'" 12 90) then
- sudo rm /etc/apt/.dist-upgrade
- sudo apt-get dist-upgrade -y
- exit 0
- fi
-fi
+function check_upgrades() {
+ echo "Updating package database"
-# Check if there's any upgrades to pengwin-setup / pengwin-base
-echo "Running upgrade check..."
-UPGRD_CHECK="$(sudo apt-get upgrade --show-upgraded --assume-no | grep pengwin)"
-if [[ "${UPGRD_CHECK}" == *"pengwin"* ]] ; then
- echo "Pengwin core package upgrades found"
- if (whiptail --title "Upgrades Available" --yesno "Updates have been detected for Pengwin core packages. Would you like to update them? This is highly recommended. Note: Pengwin-setup will close after installation complete." 10 91) then
-
- # Ensure that packages get updated without affecting other held packages like udev
- sudo apt-mark unhold pengwin-base pengwin-setup > /dev/null 2>&1
- sudo apt-get upgrade pengwin-base pengwin-setup -y
- exit 0
- fi
-fi
+ local debian_security_ok="$(cat /etc/apt/sources.list 2>&1 | grep -c "https://deb.debian.org/debian-security testing/updates")"
+ if [[ ${debian_security_ok} != 0 ]] ; then
+ sudo sed -i 's$debian-security testing/updates$debian-security testing-security$g' /etc/apt/sources.list
+ fi
+
+ sudo apt-get update --allow-releaseinfo-change
+
+ # Check for .dist-upgrade file in /etc/apt and inform user dist-upgrade available if so
+ if [[ -f "/etc/apt/.dist-upgrade" ]] ; then
+ # whiptail prompt here, delete on dist-upgrade
+ echo "Distribution upgrade flag noticed! Alerting user"
+ if (whiptail --title "Upgrade Available" --yesno "A distribution upgrade is available. In addition to regular package upgrades, this may also install / remove packages. Would you like to continue?\n\nTo run a non-automated distribution upgrade and see package changes, or to perform this in your own time, run 'sudo apt-get dist-upgrade'" 12 90) ; then
+ sudo rm /etc/apt/.dist-upgrade
+ sudo apt-get dist-upgrade -y
+ exit 0
+ fi
+ fi
+
+ # Check if there's any upgrades to pengwin-setup / pengwin-base
+ echo "Running upgrade check..."
+ local upgrd_check="$(sudo apt-get upgrade --show-upgraded --assume-no | grep pengwin)"
+ if [[ "${upgrd_check}" == *"pengwin"* ]] ; then
+ echo "Pengwin core package upgrades found"
+ if (whiptail --title "Upgrades Available" --yesno "Updates have been detected for Pengwin core packages. Would you like to update them? This is highly recommended. Note: Pengwin-setup will close after installation complete." 10 91) ; then
+
+ # Ensure that packages get updated without affecting other held packages like udev
+ sudo apt-mark unhold pengwin-base pengwin-setup > /dev/null 2>&1
+ sudo apt-get upgrade pengwin-base pengwin-setup -y
+ exit 0
+ fi
+ fi
}
function WelcomePrompt {
@@ -65,7 +75,7 @@ function ByeMessage {
function install_menu() {
local menu_choice=$(
- menu --title "pengwin-setup" --checklist --separate-output "\nHand-curated add-ons [SPACE to select, ENTER to confirm]:" 15 99 7 \
+ menu --title "pengwin-setup" --checklist --separate-output "\nHand-curated add-ons [SPACE to select, ENTER to confirm]:" 16 99 8 \
"EDITORS" "Install text editors neovim, emacs, or Visual Studio Code (requires X) " off \
"GUI" "Install an X server or various other GUI applications" off \
"MAINTENANCE" "Various maintenance tasks like home backup" off \
@@ -73,7 +83,7 @@ function install_menu() {
"SERVICES" "Enable services support (SSH, rc.local)" off \
"SETTINGS" "Change various settings in Pengwin" off \
"TOOLS" "Install applications or servers" off \
-
+ "UNINSTALL" "Uninstall applications and packages installed by pengwin-setup" off \
3>&1 1>&2 2>&3)
@@ -127,6 +137,12 @@ function install_menu() {
exit_status=$?
fi
+ if [[ ${menu_choice} == *"UNINSTALL"* ]] ; then
+ echo "UNINSTALL"
+ bash ${SetupDir}/uninstall.sh "$@"
+ exit_status=$?
+ fi
+
if [[ ${exit_status} != 0 ]] ; then
install_menu "$@"
fi
@@ -137,11 +153,11 @@ WelcomePrompt
continue_prompt
if [[ ! ${SKIP_UPDATES} ]]; then
- CheckUpgrades
+ check_upgrades
fi
# Ensure our packages are held to prevent odd situation of
-# being updated while running other operations from pengwin-setup
+# being updated while running other operations from pengwin-setup
# install menu
echo "Holding pengwin-base & pengwin-setup to ensure no changes while operating"
sudo apt-mark hold pengwin-base pengwin-setup > /dev/null 2>&1
diff --git a/pengwin-setup.d/cloudcli.sh b/pengwin-setup.d/cloudcli.sh
index c9f69140..a0704567 100644
--- a/pengwin-setup.d/cloudcli.sh
+++ b/pengwin-setup.d/cloudcli.sh
@@ -1,6 +1,12 @@
#!/bin/bash
-source $(dirname "$0")/common.sh "$@"
+# shellcheck source=/usr/local/pengwin-setup.d/common.sh
+source "$(dirname "$0")/common.sh" "$@"
+
+# Declare globals
+declare SetupDir
+declare GOVERSION
+declare wHome
function install_terraform() {
if (confirm --title "Terraform" --yesno "Would you like to install Terraform?" 8 40) ; then
@@ -8,7 +14,7 @@ function install_terraform() {
createtmp
- wget -O terraform.zip https://releases.hashicorp.com/terraform/0.11.13/terraform_0.11.13_linux_$(dpkg --print-architecture).zip
+ wget -O terraform.zip "https://releases.hashicorp.com/terraform/0.11.13/terraform_0.11.13_linux_$(dpkg --print-architecture).zip"
unzip terraform.zip
sudo mv terraform /usr/bin
sudo chmod +x /usr/bin/terraform
@@ -38,7 +44,7 @@ function install_awscli() {
fi
createtmp
- sudo apt-get -y install unzip
+ sudo apt-get -y install unzip python3-distutils
wget -O awscli-bundle.zip https://s3.amazonaws.com/aws-cli/awscli-bundle.zip
unzip awscli-bundle.zip
@@ -66,33 +72,41 @@ function install_doctl() {
echo "Installing Digital Ocean CTL"
createtmp
-
+
echo "Checking for go"
- if ! (go version); then
+ if ! go version ; then
+ if ! /usr/local/go/bin/go version ; then
echo "Downloading Go using wget."
wget -c "https://dl.google.com/go/go${GOVERSION}.linux-$(dpkg --print-architecture).tar.gz"
tar -xzf go*.tar.gz
-
export GOROOT=$(pwd)/go
export PATH="${GOROOT}/bin:$PATH"
+ else
+ # Whether it was just installed previously, or right now,
+ # makes sure to set correct env variables
+ export GOROOT=/usr/local/go
+ export PATH="${GOROOT}/bin:$PATH"
+ fi
fi
mkdir gohome
export GOPATH=$(pwd)/gohome
echo "Checking for git"
+ local git_exists
+
if (git version); then
- local git_exists=1
+ git_exists=1
else
- local git_exists=0
+ git_exists=0
sudo apt-get -y -q install git
fi
echo "Building doctl"
go get -u github.com/digitalocean/doctl/cmd/doctl
- sudo cp $GOPATH/bin/doctl /usr/local/bin/doctl
-
+ sudo cp ${GOPATH}/bin/doctl /usr/local/bin/doctl
+
if [[ ${git_exists} -eq 0 ]]; then
sudo apt-get -y -q purge git
sudo apt-get -y -q autoremove
@@ -111,6 +125,22 @@ function install_doctl() {
fi
}
+
+function install_kubectl() {
+
+ echo "Installing Helm"
+ curl https://raw.githubusercontent.com/helm/helm/master/scripts/get | bash
+
+ wget https://raw.githubusercontent.com/helm/helm/master/scripts/completions.bash
+ sudo cp completions.bash /etc/bash_completion.d/helm_completions.bash
+
+ echo "Installing kubectl"
+ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
+ echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
+ sudo apt-get -y -q update
+ sudo apt-get -y -q install kubectl
+
+}
function install_ibmcli() {
if (confirm --title "IBM Cloud CLI" --yesno "Would you like to install the stand-alone IBM Cloud CLI?" 8 70) ; then
@@ -137,23 +167,80 @@ function install_ibmcli() {
ibmcloud --version
- echo "Installing Helm"
- curl https://raw.githubusercontent.com/helm/helm/master/scripts/get | bash
+ install_kubectl
+
+ cleantmp
+ else
+ echo "Skipping IBM Cloud CLI"
+
+ fi
+}
+
+function install_kubernetes() {
+
+ if (confirm --title "Kubernetes tooling" --yesno "Would you like to install the Kubernetes tooling?" 10 90) ; then
+
+ createtmp
+
+ install_kubectl
+
+ # Force the creation of a temporary .kube config directory
+ kubectl config set-cluster fake --server=https://5.6.7.8 --insecure-skip-tls-verify
+ kubectl config set-credentials nobody
+ kubectl config set-context fake --cluster=fake --namespace=default --user=nobody
+
+ # Install helm plugins: helm-github, helm-tiller, helm-restore
+
+ helm init --client-only
+ helm plugin install https://github.com/sagansystems/helm-github.git
+ helm plugin install https://github.com/rimusz/helm-tiller
+ helm plugin install https://github.com/maorfr/helm-restore
+
+ # Get the kubectx script
+ curl -O https://raw.githubusercontent.com/ahmetb/kubectx/master/kubectx
+ chmod +x kubectx
+ sudo mv kubectx /usr/local/bin/
+
+ # Get the kubens script
+ curl -O https://raw.githubusercontent.com/ahmetb/kubectx/master/kubens
+ chmod +x kubens
+ sudo mv kubens /usr/local/bin/
+
+ # Add the completion script to the /etc/bash_completion.d directory.
+ local base_url=https://raw.githubusercontent.com/ahmetb/kubectx/master/completion
+ curl ${base_url}/kubectx.bash | sudo tee /etc/bash_completion.d/kubectx > /dev/null
+ curl ${base_url}/kubens.bash | sudo tee /etc/bash_completion.d/kubens > /dev/null
+
+ if( ! docker version 2> /dev/null); then
+
+ bash "${SetupDir}/docker.sh" "$@"
+ fi
+
+ local kube_ctl="${wHome}/.kube/config"
- wget https://raw.githubusercontent.com/helm/helm/master/scripts/completions.bash
- sudo cp completions.bash /etc/bash_completion.d/helm_completions.bash
+ local kubernetes_enabled
+ while [[ ! -f ${kube_ctl} ]]; do
+ if ! (whiptail --title "KUBERNETES" --yesno "Please enable Kubernetes in Docker Desktop. Would you like to try again?" 9 75); then
+ return
+
+ fi
- echo "Installing kubectl"
- curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
- echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
- sudo apt-get -y -q update
- sudo apt-get -y -q install kubectl
+ done
+
+ mkdir -p ${HOME}/.kube
+ ln -sf ${kube_ctl} ${HOME}/.kube/config
+
+ kubectl cluster-info
+ kubens kube-system
+ kubectl get pods
cleantmp
+
else
- echo "Skipping IBM Cloud CLI"
+ echo "Skipping Kubernetes tooling"
fi
+
}
function install_openstack() {
@@ -182,11 +269,12 @@ function install_openstack() {
function main() {
local choice=$(
- whiptail --title "Cloud Management Menu" --checklist --separate-output "CLI tools for cloud management\n[SPACE to select, ENTER to confirm]:" 14 60 5 \
+ whiptail --title "Cloud Management Menu" --checklist --separate-output "CLI tools for cloud management\n[SPACE to select, ENTER to confirm]:" 16 60 7 \
"AWS" "AWS CLI" off \
"AZURE" "Azure CLI" off \
"DO" "Digital Ocean CLI" off \
"IBM" "IBM Cloud CLI" off \
+ "KUBERNETES" "Kubernetes tooling" off \
"OPENSTACK" "OpenStack command-line clients " off \
"TERRAFORM" "Terraform " off 3>&1 1>&2 2>&3
)
@@ -220,6 +308,12 @@ function main() {
fi
+ if [[ ${choice} == *"KUBERNETES"* ]] ; then
+
+ install_kubernetes "$@"
+
+ fi
+
if [[ ${choice} == *"OPENSTACK"* ]] ; then
install_openstack "$@"
diff --git a/pengwin-setup.d/common.sh b/pengwin-setup.d/common.sh
index 7a3b5a79..e21a6353 100644
--- a/pengwin-setup.d/common.sh
+++ b/pengwin-setup.d/common.sh
@@ -19,6 +19,11 @@ function process_arguments() {
SKIP_UPDATES=1
shift
;;
+ --norebuildicons)
+ echo "Skipping rebuild start menu"
+ SKIP_STARTMENU=1
+ shift
+ ;;
*)
shift
esac
diff --git a/pengwin-setup.d/cpp-vs-clion.sh b/pengwin-setup.d/cpp-vs-clion.sh
index eea20a0f..2feff819 100644
--- a/pengwin-setup.d/cpp-vs-clion.sh
+++ b/pengwin-setup.d/cpp-vs-clion.sh
@@ -24,7 +24,7 @@ function main {
echo "Installing CMake"
local dist="$(uname -m)"
- wget -O cmake.sh "https://github.com/Microsoft/CMake/releases/download/untagged/cmake-3.13.18112701-MSVC_2-Linux-${dist/86_/}.sh"
+ wget -O cmake.sh "https://github.com/microsoft/CMake/releases/download/v3.13.18112701/cmake-3.13.18112701-MSVC_2-Linux-${dist/86_/}.sh"
sudo bash cmake.sh --skip-license --prefix=/usr/local
cleantmp
diff --git a/pengwin-setup.d/docker.sh b/pengwin-setup.d/docker.sh
index 07289fbb..0f4053a0 100644
--- a/pengwin-setup.d/docker.sh
+++ b/pengwin-setup.d/docker.sh
@@ -1,10 +1,18 @@
#!/bin/bash
-source $(dirname "$0")/common.sh "$@"
+# shellcheck source=/usr/local/pengwin-setup.d/common.sh
+source "$(dirname "$0")/common.sh" "$@"
DOCKER_VERSION="18.09.2"
DOCKER_COMPOSE_VERSION="1.23.2"
+# Imported from common.sh
+declare wHome
+declare GOVERSION
+
+#Imported global variables
+declare USER
+
function docker_install_build_relay() {
#Build the relay
if [[ ! -f "${wHome}/.npiperelay/npiperelay.exe" ]]; then
@@ -23,10 +31,11 @@ function docker_install_build_relay() {
export GOPATH=$(pwd)/gohome
echo "Checking for git"
+ local git_exists
if (git version); then
- local git_exists=1
+ git_exists=1
else
- local git_exists=0
+ git_exists=0
sudo apt-get -y -q install git
fi
@@ -110,21 +119,49 @@ EOF
if [[ ${connected} != 0 ]]; then
whiptail --title "DOCKER" \
--msgbox "Please go to Docker Desktop -> Settings -> General and enable 'Expose daemon on tcp://localhost:2375 without TLS' or upgrade your Windows version and run this script again." 9 75
+ else
+ docker version
fi
}
+function docker_install_conf_toolbox() {
+ echo "Connect to Docker Toolbox"
+
+ cat << 'EOF' >> docker_relay.sh
+
+# Check if we have Windows Path
+if ( which cmd.exe >/dev/null ); then
+ VM=${DOCKER_MACHINE_NAME-default}
+ DOCKER_MACHINE="$(which docker-machine.exe)"
+ eval "$("${DOCKER_MACHINE}" env --shell=bash --no-proxy "${VM}" 2>/dev/null )" > /dev/null 2>&1
+
+ if [[ "${DOCKER_CERT_PATH}" != "" ]] ; then
+ export DOCKER_CERT_PATH="$(wslpath -u "${DOCKER_CERT_PATH}")"
+ fi
+fi
+
+EOF
+ sudo cp docker_relay.sh /etc/profile.d/docker_relay.sh
+
+ . /etc/profile.d/docker_relay.sh
+
+ docker version
+}
+
function main() {
- if (whiptail --title "DOCKER" --yesno "Would you like to install the bridge to Docker?" 8 55); then
+ if (confirm --title "DOCKER" --yesno "Would you like to install the bridge to Docker?" 8 55); then
echo "Installing the bridge to Docker."
- local connected=$(docker.exe version 2>&1 | grep -c "docker daemon is not running.\|docker.exe: command not found")
+ local errorCheck="docker daemon is not running.\|docker.exe: command not found\|error during connect:"
+ local connected
+ connected=$(docker.exe version 2>&1 | grep -c "${errorCheck}")
while [[ ${connected} != 0 ]]; do
- if ! (whiptail --title "DOCKER" --yesno "Docker Desktop appears not to be running, please check it and ensure that it is running correctly. Would you like to try again?" 9 75); then
+ if ! (whiptail --title "DOCKER" --yesno "Docker Desktop or Docker Toolbox appears not to be running, please check it and ensure that it is running correctly. Would you like to try again?" 9 75); then
return
fi
- local connected=$(docker.exe version 2>&1 | grep -c "docker daemon is not running.\|docker.exe: command not found")
+ connected=$(docker.exe version 2>&1 | grep -c "${errorCheck}")
done
@@ -132,15 +169,20 @@ function main() {
sudo apt-get -y -q update
- wget -c https://download.docker.com/linux/static/stable/$(uname -m)/docker-${DOCKER_VERSION}.tgz
+ wget -c "https://download.docker.com/linux/static/stable/$(uname -m)/docker-${DOCKER_VERSION}.tgz"
sudo tar -xzvf docker-${DOCKER_VERSION}.tgz --overwrite --directory /usr/bin/ --strip-components 1 docker/docker
sudo chmod 755 /usr/bin/docker
sudo chown root:root /usr/bin/docker
#Checks if the Windows 10 version supports Unix Sockets and that the tcp port without TLS is not already open
- local connected=$(env DOCKER_HOST=tcp://0.0.0.0:2375 docker version 2>&1 | grep -c "Cannot connect to the Docker daemon")
- if [[ $(reg.exe query "HKLM\Software\Microsoft\Windows NT\CurrentVersion" /v "CurrentBuild" 2>&1 | egrep -o '([0-9]{5})' | cut -d ' ' -f 2) -gt 17063 && ${connected} != 0 ]]; then
+ connected=$(env DOCKER_HOST=tcp://0.0.0.0:2375 docker version 2>&1 | grep -c "Cannot connect to the Docker daemon")
+ local currentVersion=$(reg.exe query "HKLM\Software\Microsoft\Windows NT\CurrentVersion" /v "CurrentBuild" 2>&1 | egrep -o '([0-9]{5})' | cut -d ' ' -f 2)
+
+ if [[ $(docker-machine.exe active | grep -c "default") != 0 && ${connected} != 0 ]]; then
+ #Install via Docker Toolbox
+ docker_install_conf_toolbox
+ elif [[ ${currentVersion} -gt 17063 && ${connected} != 0 ]]; then
#Connect via Unix Sockets
docker_install_build_relay
else
@@ -161,7 +203,7 @@ function main() {
docker-compose version
- if [[ $(wslpath 'C:\\') = '/mnt/c/' ]]; then
+ if [[ ${currentVersion} -gt 17063 && $(wslpath 'C:\') = '/mnt/c/' ]]; then
if (whiptail --title "DOCKER" --yesno "To correctly integrate the volume mounting between docker Linux and Windows, your root mount point must be changed from /mnt/c to /c. Continue?" 10 80); then
echo "Changing the root from /mnt to /"
@@ -228,5 +270,5 @@ EOF
fi
}
-main "$@"
+main
diff --git a/pengwin-setup.d/editors.sh b/pengwin-setup.d/editors.sh
index 51899eee..507b0b42 100644
--- a/pengwin-setup.d/editors.sh
+++ b/pengwin-setup.d/editors.sh
@@ -2,10 +2,17 @@
source $(dirname "$0")/common.sh "$@"
+declare INSTALLED=false
+
+#Imported from common.h
+declare SetupDir
+
function neovim_install {
if (confirm --title "NEOVIM" --yesno "Would you like to download and install neovim?" 8 50) ; then
echo "Installing neovim and building tools from Debian: $ sudo apt-get install neovim build-essential"
sudo apt-get -y -q -t testing install neovim build-essential
+
+ INSTALLED=true
else
echo "Skipping NEOVIM"
fi
@@ -15,6 +22,8 @@ function emacs_install {
if (confirm --title "EMACS" --yesno "Would you like to download and install emacs?" 8 50) ; then
echo "Installing emacs: $ sudo apt-get install emacs -y"
sudo apt-get -y -q install emacs
+
+ INSTALLED=true
else
echo "Skipping EMACS"
fi
@@ -51,6 +60,7 @@ function code_install {
#Assuming that the stable repository is there by the udev fix
sudo apt-get install -y -q -t stable libssl1.0.2
+ INSTALLED=true
else
echo "Skipping CODE"
fi
@@ -81,6 +91,10 @@ function editor_menu {
if [[ ${editor_choice} == *"CODE"* ]] ; then
code_install
fi
+
+ if [[ "${INSTALLED}" == true ]] ; then
+ bash ${SetupDir}/shortcut.sh --yes "$@"
+ fi
}
diff --git a/pengwin-setup.d/gui.sh b/pengwin-setup.d/gui.sh
index 248b51ff..632bd554 100644
--- a/pengwin-setup.d/gui.sh
+++ b/pengwin-setup.d/gui.sh
@@ -2,18 +2,22 @@
source $(dirname "$0")/common.sh "$@"
+#Imported from common.h
+declare SetupDir
+
function main() {
local menu_choice=$(
- menu --title "Tools Menu" --checklist --separate-output "Install an X server or various other GUI applications\n[SPACE to select, ENTER to confirm]:" 16 99 7 \
- "X410" "View a link to the X410 X-server on the Microsoft Store" off \
- "VCXSRV" "Install the VcXsrv open source X-server" off \
- "GUILIB" "Install a base set of libraries for GUI applications" off \
+ menu --title "GUI Menu" --checklist --separate-output "Install an X server or various other GUI applications\n[SPACE to select, ENTER to confirm]:" 16 99 8 \
"FCITX" "Install fcitx for improved non-Latin input support" off \
+ "GUILIB" "Install a base set of libraries for GUI applications" off \
"HIDPI" "Configure Qt and GTK for HiDPI displays (experimental)" off \
+ "STARTMENU" "Generates Windows Start Menu shortcuts for GUI applications" off \
"SYNAPTIC" "Install the Synaptic package manager" off \
- "WINTHEME" "Install a Windows 10 theme along with the LXAppearance theme switcher" off \
+ "VCXSRV" "Install the VcXsrv open source X-server" off \
+ "WINTHEME" "Install a Windows 10 theme along with the LXAppearance theme switcher " off \
+ "X410" "View a link to the X410 X-server on the Microsoft Store" off \
3>&1 1>&2 2>&3)
@@ -46,6 +50,11 @@ function main() {
bash ${SetupDir}/hidpi.sh
fi
+ if [[ ${menu_choice} == *"STARTMENU"* ]] ; then
+ echo "STARTMENU"
+ bash ${SetupDir}/shortcut.sh "$@"
+ fi
+
if [[ ${menu_choice} == *"SYNAPTIC"* ]] ; then
echo "SYNAPTIC"
bash ${SetupDir}/synaptic.sh "$@"
diff --git a/pengwin-setup.d/guilib.sh b/pengwin-setup.d/guilib.sh
index 0560896e..7372e519 100644
--- a/pengwin-setup.d/guilib.sh
+++ b/pengwin-setup.d/guilib.sh
@@ -1,9 +1,12 @@
#!/bin/bash
-if (whiptail --title "GUI Libraries" --yesno "Would you like to install a base set of libraries for GUI applications?" 8 75) then
+# shellcheck source=/usr/local/pengwin-setup.d/common.sh
+source "$(dirname "$0")/common.sh" "$@"
+
+if (confirm --title "GUI Libraries" --yesno "Would you like to install a base set of libraries for GUI applications?" 8 75); then
echo "Installing GUILIB"
- echo "$ apt-get install -t testing xclip gnome-themes-standard gtk2-engines-murrine dbus dbus-x11 -y"
- sudo apt-get install -t testing xclip gnome-themes-standard gtk2-engines-murrine dbus dbus-x11 -y
+ echo "$ apt-get install -y -q -t testing xclip gnome-themes-standard gtk2-engines-murrine dbus dbus-x11"
+ sudo apt-get install -y -q -t testing xclip gnome-themes-standard gtk2-engines-murrine dbus dbus-x11
echo "Configuring dbus if you already had it installed. If not, you might see some errors, and that is okay."
#stretch
sudo touch /etc/dbus-1/session.conf
@@ -15,6 +18,20 @@ if (whiptail --title "GUI Libraries" --yesno "Would you like to install a base s
sudo sed -i 's$.*$tcp:host=localhost,port=0$' /usr/share/dbus-1/session.conf
sudo sed -i 's$EXTERNAL$ANONYMOUS$' /usr/share/dbus-1/session.conf
sudo sed -i 's$$$' /usr/share/dbus-1/session.conf
+
+ eval "$(dbus-launch --auto-syntax)"
+
+ sudo tee "/etc/profile.d/dbus.sh" << EOF
+#!/bin/bash
+
+# Check if we have Windows Path
+if ( which cmd.exe >/dev/null ); then
+
+ eval "$(dbus-launch --auto-syntax)"
+fi
+
+EOF
+
else
echo "Skipping GUILIB"
fi
diff --git a/pengwin-setup.d/joomla.sh b/pengwin-setup.d/joomla.sh
new file mode 100644
index 00000000..f5e0dada
--- /dev/null
+++ b/pengwin-setup.d/joomla.sh
@@ -0,0 +1,52 @@
+#!/usr/bin/env bash
+
+# shellcheck disable=SC1090
+source "$(dirname "$0")/common.sh" "$@"
+
+declare SetupDir
+declare wHome
+JOOMLA_VERSION="3-9-8"
+
+function install_joomla() {
+
+ if (confirm --title "Joomla" --yesno "Would you like to install the Joomla development server? It includes LAMP Stack" 10 60) ; then
+
+ bash ${SetupDir}/lamp.sh "$@" --yes
+
+ createtmp
+ sudo service mysql start
+
+ sudo sed -i "s/\(output_buffering = \)\([0-9]*\)/\1Off/" /etc/php/7.*/apache2/php.ini
+ sudo service apache2 restart
+
+ wget -O Joomla.tar.bz2 https://downloads.joomla.org/cms/joomla3/${JOOMLA_VERSION}/Joomla_${JOOMLA_VERSION}-Stable-Full_Package.tar.bz2?format=bz2
+
+ local joomla_root="${wHome}/joomla_root"
+ mkdir -p "${joomla_root}"
+ sudo tar -xjvf Joomla.tar.bz2 --overwrite --directory "${joomla_root}"
+ sudo chown -R www-data:www-data "${joomla_root}/installation"
+
+ sudo ln -s "${joomla_root}" /var/www/html/joomla_root
+ sudo mysql -u root << EOF
+
+CREATE DATABASE joomla;
+GRANT ALL PRIVILEGES ON joomla.* TO 'joomla'@'localhost' IDENTIFIED BY 'joomla';
+
+EOF
+ wslview "http://localhost/joomla_root/index.php"
+
+ cleantmp
+
+ bash ${SetupDir}/services.sh --enable-ssh
+ else
+ echo "Skipping Joomla"
+ fi
+}
+
+function main() {
+
+ install_joomla "$@"
+
+}
+
+main "$@"
diff --git a/pengwin-setup.d/lamp.sh b/pengwin-setup.d/lamp.sh
new file mode 100644
index 00000000..27f5e9aa
--- /dev/null
+++ b/pengwin-setup.d/lamp.sh
@@ -0,0 +1,84 @@
+#!/bin/bash
+
+# shellcheck source=/usr/local/pengwin-setup.d/common.sh
+source "$(dirname "$0")/common.sh" "$@"
+
+function install_lamp() {
+
+ if (confirm --title "LAMP Stack" --yesno "Would you like to install the LAMP Stack?" 10 60) ; then
+
+ echo "Installing MariaDB Database Server"
+ sudo apt-get -y -q install mariadb-server mariadb-client
+ apt policy mariadb-server
+
+ service mariadb status
+
+ echo "Installing Apache Web Server"
+ sudo apt-get -y -q install apache2 apache2-utils
+ sudo service apache2 start
+ sudo apache2 -v
+
+ service apache2 status
+
+ echo "Installing PHP"
+ sudo apt-get -y -q install php libapache2-mod-php php-cli php-fpm php-json php-common php-mysql php-zip php-gd php-mbstring php-curl php-xml php-pear php-bcmath
+ sudo a2enmod php7.3
+
+ php -v
+
+ echo "" | sudo tee /var/www/html/phpinfo.php
+
+ sudo service apache2 restart
+
+ wslview "http://localhost/phpinfo.php"
+
+ echo "Installing LAMP as a service"
+
+ startLamp="/usr/bin/start-lamp"
+ #local startLamp
+ sudo tee "${startLamp}" << EOF
+#!/bin/bash
+
+mysql_status=\$(service mysql status)
+if [[ \${mysql_status} = *"is stopped"* ]]; then
+ service mysql --full-restart > /dev/null 2>&1
+fi
+
+apache2_status=\$(service apache2 status)
+if [[ \${apache2_status} = *"is not running"* ]]; then
+ service apache2 --full-restart > /dev/null 2>&1
+fi
+
+EOF
+
+ sudo chmod 700 "${startLamp}"
+
+ echo "%sudo ALL=NOPASSWD: ${startLamp}" | sudo EDITOR='tee -a' visudo --quiet --file=/etc/sudoers.d/start-lamp
+
+ profile_start_lamp="/etc/profile.d/start-lamp.sh"
+ sudo tee "${profile_start_lamp}" << EOF
+#!/bin/bash
+
+# Check if we have Windows Path
+if ( which cmd.exe >/dev/null ); then
+
+ sudo ${startLamp}
+
+fi
+
+EOF
+
+ else
+ echo "Skipping SSH Server"
+ fi
+
+
+}
+
+function main() {
+
+ install_lamp
+
+}
+
+main
diff --git a/pengwin-setup.d/latex.sh b/pengwin-setup.d/latex.sh
new file mode 100644
index 00000000..16874396
--- /dev/null
+++ b/pengwin-setup.d/latex.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+source $(dirname "$0")/common.sh "$@"
+
+
+latex_choice=$(
+
+menu --title "LaTeX" --radiolist --separate-output "Select the version you would like to install\n[SPACE to select, ENTER to confirm]:" 12 74 4 \
+ "FULL" "Install all TexLive packages" on \
+ "BASE" "Install essential TexLive packages " off \
+ "RECOMMENDED" "Install recommended TexLive packages" off \
+ "EXTRA" "Install a large collections of TexLive packages" off \
+
+
+3>&1 1>&2 2>&3)
+
+if [[ ${latex_choice} == "CANCELLED" ]] ; then
+ echo "Skipping LaTeX"
+fi
+
+if [[ ${latex_choice} == *"FULL"* ]] ; then
+ echo "Installing TexLive Full..."
+ sudo apt-get install -y texlive-full
+fi
+
+if [[ ${latex_choice} == *"BASE"* ]] ; then
+ echo "Installing TexLive Base..."
+ sudo apt-get install -y texlive-latex-base
+fi
+
+if [[ ${latex_choice} == *"RECOMMENDED"* ]] ; then
+ echo "Installing TexLive Recommended..."
+ sudo apt-get install -y texlive-latex-base texlive-latex-recommended
+fi
+
+if [[ ${menu_choice} == *"EXTRA"* ]] ; then
+ echo "Installing TexLive Extra..."
+ sudo apt-get install -y texlive-latex-base texlive-latex-extra
+fi
+
diff --git a/pengwin-setup.d/nodejs.sh b/pengwin-setup.d/nodejs.sh
index 81b19990..846e5e00 100644
--- a/pengwin-setup.d/nodejs.sh
+++ b/pengwin-setup.d/nodejs.sh
@@ -17,6 +17,7 @@ createtmp
echo "Look for Windows version of npm"
+NPM_WIN_PROFILE="/etc/profile.d/rm-win-npm-path.sh"
NPM_PROFILE="/etc/profile.d/n-prefix.sh"
if [[ "$(which npm)" == $(wslpath 'C:\')* ]]; then
@@ -29,7 +30,7 @@ if [[ "$(which npm)" == $(wslpath 'C:\')* ]]; then
fi
- sudo tee "${NPM_PROFILE}" << EOF
+ sudo tee "${NPM_WIN_PROFILE}" << EOF
# Check if we have Windows Path
if ( which cmd.exe >/dev/null ); then
@@ -37,21 +38,18 @@ if ( which cmd.exe >/dev/null ); then
WIN_C_PATH="\$(wslpath 'C:\')"
if [[ "\${WIN_NPM_PATH}" == "\${WIN_C_PATH}"* ]]; then
- PATH=\$(echo "\${PATH}" | sed -e "s#\${WIN_NPM_PATH}:##")
+ PATH=\$(echo "\${PATH}" | sed -e "s#\${WIN_NPM_PATH}##")
fi
WIN_YARN_PATH="\$(dirname "\$(which yarn)")"
if [[ "\${WIN_YARN_PATH}" == "\${WIN_C_PATH}"* ]]; then
- PATH=\$(echo "\${PATH}" | sed -e "s#\${WIN_YARN_PATH}:##")
+ PATH=\$(echo "\${PATH}" | sed -e "s#\${WIN_YARN_PATH}##")
fi
fi
EOF
- eval "$(cat "${NPM_PROFILE}")"
+ eval "$(cat "${NPM_WIN_PROFILE}")"
-else
-
- sudo rm "${NPM_PROFILE}"
fi
echo "Ensuring we have build-essential installed"
@@ -63,10 +61,14 @@ env SHELL="$(which bash)" bash n-install.sh -y #Force the installation to bash
N_PATH="$(cat ${HOME}/.bashrc | grep "^.*N_PREFIX.*$" | cut -d'#' -f 1)"
-echo "${N_PATH}" | sudo tee -a "${NPM_PROFILE}"
+echo "${N_PATH}" | sudo tee "${NPM_PROFILE}"
eval "${N_PATH}"
+# Add the path for sudo
+SUDO_PATH="$(sudo cat /etc/sudoers | grep "secure_path" | sed "s/\(^.*secure_path=\"\)\(.*\)\(\"\)/\2/")"
+echo "Defaults secure_path=\"${SUDO_PATH}:${N_PREFIX}/bin\"" | sudo EDITOR='tee ' visudo --quiet --file=/etc/sudoers.d/npm-path
+
echo "Installing latest node.js release"
n latest
diff --git a/pengwin-setup.d/programming.sh b/pengwin-setup.d/programming.sh
index 442cfddf..67879532 100644
--- a/pengwin-setup.d/programming.sh
+++ b/pengwin-setup.d/programming.sh
@@ -1,16 +1,21 @@
#!/bin/bash
-source $(dirname "$0")/common.sh "$@"
+# shellcheck disable=SC1090
+source "$(dirname "$0")/common.sh" "$@"
+
+declare SetupDir
function main() {
local menu_choice=$(
- menu --title "Programming Menu" --checklist --separate-output "Install various programming languages support\n[SPACE to select, ENTER to confirm]:" 16 95 8 \
+ menu --title "Programming Menu" --checklist --separate-output "Install various programming languages support\n[SPACE to select, ENTER to confirm]:" 16 95 10 \
"C++" "Install support for Linux C/C++ programming in Visual Studio and CLion " off \
"DOTNET" "Install .NET Core SDK from Microsoft and optionally install NuGet " off \
"GO" "Install the latest Go from Google" off \
"JAVA" "Install the SDKMan to manage Java SDKs" off \
+ "JOOMLA" "Install development support for Joomla" off \
+ "LATEX" "Install TexLive for LaTeX Support" off \
"NODEJS" "Install Node.js and npm" off \
"PYTHONPI" "Install Python 3.7 and download and install latest PyPi" off \
"RUBY" "Install Ruby using rbenv and optionally install Rails" off \
@@ -25,7 +30,6 @@ function main() {
if [[ ${menu_choice} == *"C++"* ]] ; then
echo "C++"
bash ${SetupDir}/cpp-vs-clion.sh "$@"
- exit_status=$?
fi
if [[ ${menu_choice} == *"DOTNET"* ]] ; then
@@ -43,12 +47,21 @@ function main() {
bash ${SetupDir}/java.sh "$@"
fi
+ if [[ ${menu_choice} == *"JOOMLA"* ]] ; then
+ echo "JOOMLA"
+ bash ${SetupDir}/joomla.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"LATEX"* ]] ; then
+ echo "LATEX"
+ bash ${SetupDir}/latex.sh "$@"
+ fi
+
if [[ ${menu_choice} == *"NODEJS"* ]] ; then
echo "NODE"
bash ${SetupDir}/nodejs.sh "$@"
fi
-
if [[ ${menu_choice} == *"PYTHONPI"* ]] ; then
echo "PYTHON"
bash ${SetupDir}/pythonpi.sh "$@"
diff --git a/pengwin-setup.d/ruby.sh b/pengwin-setup.d/ruby.sh
index 50f3f30e..acd66055 100644
--- a/pengwin-setup.d/ruby.sh
+++ b/pengwin-setup.d/ruby.sh
@@ -52,11 +52,9 @@ if (whiptail --title "RAILS" --yesno "Would you like to download and install Rai
echo "Installing RAILS"
echo "Checking for node"
- if (node -v); then
- node_exists=1
- else
- node_exists=0
-
+ if ! node -v ; then
+ if ! "$HOME/n/bin/node" -v ; then # double checks if our local nodejs install was just performed but PATH not yet updated
+ echo "node not installed. Offering user nodejs install"
if (whiptail --title "NODE" --yesno "Ruby on Rails framework requires JavaScript Runtime Environment (Node.js) to manage the features of Rails.\n\nWould you like to download and install NodeJS using n and the npm package manager?" 12 65); then
bash ${SetupDir}/nodejs.sh -y "$@"
else
@@ -64,6 +62,8 @@ if (whiptail --title "RAILS" --yesno "Would you like to download and install Rai
exit 1
fi
fi
+ fi
+ echo "node installed"
sudo apt-get -y -t testing install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev software-properties-common libffi-dev
createtmp
diff --git a/pengwin-setup.d/services.sh b/pengwin-setup.d/services.sh
index 19c37c34..7b0ad5a2 100644
--- a/pengwin-setup.d/services.sh
+++ b/pengwin-setup.d/services.sh
@@ -1,7 +1,9 @@
#!/bin/bash
-source $(dirname "$0")/common.sh "$@"
+# shellcheck source=/usr/local/pengwin-setup.d/common.sh
+source "$(dirname "$0")/common.sh" "$@"
+declare SetupDir
function enable_rclocal() {
@@ -52,7 +54,7 @@ function enable_ssh() {
local sshd_file=/etc/ssh/sshd_config
- sudo cp ${sshd_file} ${sshd_file}.`date '+%Y-%m-%d_%H-%M-%S'`.back
+ sudo cp ${sshd_file} "${sshd_file}.$(date '+%Y-%m-%d_%H-%M-%S').back"
sudo sed -i '/^# configured by Pengwin/ d' ${sshd_file}
sudo sed -i '/^ListenAddress/ d' ${sshd_file}
@@ -76,14 +78,9 @@ function enable_ssh() {
sudo tee "${startSsh}" << EOF
#!/bin/bash
-# Check if we have Windows Path
-if ( which cmd.exe >/dev/null ); then
-
- sshd_status=\$(service ssh status)
- if [[ \${sshd_status} = *"is not running"* ]]; then
- service ssh --full-restart > /dev/null 2>&1
- fi
-
+sshd_status=\$(service ssh status)
+if [[ \${sshd_status} = *"is not running"* ]]; then
+ service ssh --full-restart > /dev/null 2>&1
fi
EOF
@@ -93,7 +90,16 @@ EOF
echo "%sudo ALL=NOPASSWD: ${startSsh}" | sudo EDITOR='tee -a' visudo --quiet --file=/etc/sudoers.d/start-ssh
local profile_startssh="/etc/profile.d/start-ssh.sh"
- echo "sudo ${startSsh}" | sudo tee "${profile_startssh}"
+ sudo tee "${profile_startssh}" << EOF
+#!/bin/bash
+
+# Check if we have Windows Path
+if ( which cmd.exe >/dev/null ); then
+
+ sudo ${startSsh}
+fi
+
+EOF
else
echo "Skipping SSH Server"
@@ -104,16 +110,17 @@ EOF
function main() {
if [[ "$1" == "--enable-ssh" ]] ; then
- enable_ssh "$@"
+ enable_ssh
return
fi
local menu_choice=$(
- menu --title "Services Menu" --checklist --separate-output "Enables various services\n[SPACE to select, ENTER to confirm]:" 12 70 4 \
+ menu --title "Services Menu" --checklist --separate-output "Enables various services\n[SPACE to select, ENTER to confirm]:" 12 70 5 \
"CASSANDRA" "Install the NoSQL server Cassandra from Apache " off \
"KEYCHAIN" "Install Keychain, the OpenSSH key manager" off \
+ "LAMP" "Install LAMP Stack" off \
"RCLOCAL" "Enable running scripts at startup from rc.local " off \
"SSH" "Enable SSH server" off \
@@ -133,14 +140,19 @@ function main() {
bash ${SetupDir}/keychain.sh "@"
fi
+ if [[ ${menu_choice} == *"LAMP"* ]] ; then
+ echo "LAMP"
+ bash ${SetupDir}/lamp.sh "@"
+ fi
+
if [[ ${menu_choice} == *"RCLOCAL"* ]] ; then
- enable_rclocal "$@"
+ enable_rclocal
fi
if [[ ${menu_choice} == *"SSH"* ]] ; then
- enable_ssh "$@"
+ enable_ssh
fi
}
diff --git a/pengwin-setup.d/shells.sh b/pengwin-setup.d/shells.sh
index 703861a6..cee3e915 100644
--- a/pengwin-setup.d/shells.sh
+++ b/pengwin-setup.d/shells.sh
@@ -1,6 +1,7 @@
#!/bin/bash
-source $(dirname "$0")/common.sh "$@"
+# shellcheck source=/usr/local/pengwin-setup.d/common.sh
+source "$(dirname "$0")/common.sh" "$@"
function zshinstall {
ZSH_SETUP=".zsh_pengwin"
@@ -56,32 +57,40 @@ if (whiptail --title "zsh" --yesno "Would you like to download and install oh-my
cd "Type exit to return to pengwin-setup"
sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
cd ..
+
+ #Change the default theme for one more friendly with Windows console default font
+ sed -i 's/ZSH_THEME="robbyrussell"/ZSH_THEME="bira"/' "${HOME}/.zshrc"
+
cleantmp
else
echo "Skipping oh-my-zsh"
fi
if (whiptail --title "zsh" --yesno "Would you like to set zsh as the default shell?" 8 55) then
- chsh -s $(which zsh)
+ chsh -s "$(which zsh)"
fi
}
-function fishinstall {
-if (whiptail --title "fish" --yesno "Would you like to download and install oh-my-fish?" 8 55) then
+function fish_install() {
+ if (whiptail --title "fish" --yesno "Would you like to download and install oh-my-fish?" 8 55); then
createtmp
whiptail --title "fish" --msgbox "After oh my fish is installed and launched, type 'exit' and ENTER to return to pengwin-setup" 8 95
mkdir "Type exit to return to pengwin-setup"
cd "Type exit to return to pengwin-setup"
curl -L https://get.oh-my.fish | fish
cd ..
+
+ #Change the default theme for one more friendly with Windows console default font
+ fish -c "omf install bira"
+
cleantmp
-else
+ else
echo "Skipping Oh My Fish"
-fi
+ fi
-if (whiptail --title "fish" --yesno "Would you like to set fish as the default shell?" 8 55) then
- chsh -s $(which fish)
-fi
+ if (confirm --title "fish" --yesno "Would you like to set fish as the default shell?" 8 55); then
+ chsh -s "$(which fish)"
+ fi
}
function cshinstall {
@@ -112,7 +121,7 @@ function installandsetshell {
if [[ $menu_choice == *"FISH"* ]] ; then
echo "Installing fish..."
sudo apt install fish -y
- fishinstall
+ fish_install
fi
if [[ $menu_choice == *"CSH"* ]] ; then
diff --git a/pengwin-setup.d/shortcut.sh b/pengwin-setup.d/shortcut.sh
new file mode 100644
index 00000000..f49b9b03
--- /dev/null
+++ b/pengwin-setup.d/shortcut.sh
@@ -0,0 +1,190 @@
+#!/bin/bash
+
+source $(dirname "$0")/common.sh "$@"
+
+#Globals
+declare DEST_PATH
+declare SKIP_STARTMENU
+readonly NO_ICON="NO_ICON"
+
+function create_shortcut() {
+ local cmdName="$1"
+ local cmdToExec="$2"
+ local cmdIcon="$3"
+ local gui="$4"
+
+ if [[ -z "${cmdIcon}" ]]; then
+ return
+
+ elif [[ "${cmdIcon}" == ${NO_ICON} ]]; then
+
+ cmdIcon=""
+ fi
+
+ echo wslusc --name "${cmdName}" ${cmdIcon} ${gui} "${cmdToExec}"
+ wslusc --name "${cmdName}" ${cmdIcon} ${gui} "${cmdToExec}"
+
+ mkdir -p "${DEST_PATH}"
+ mv "$(wslpath "$(wslvar -l Desktop)")/${cmdName}.lnk" "${DEST_PATH}"
+}
+
+function create_shortcut_from_desktop() {
+
+ local desktopFile=$1
+ declare -i state=0
+ local state
+ local cmdToExec
+ local cmdName
+ local cmdIcon
+ local line
+ local gui="--gui"
+
+ while read line; do
+
+ case ${state} in
+ 0*) #Looking for entry
+
+ if [[ ${line} == "[Desktop Entry]" ]]; then
+ ((state++))
+ fi
+ ;;
+ 1*)
+
+ if [[ ${line} == [* ]]; then
+ break
+ fi
+
+ IFS='=' read -ra keyValue <<< "${line}"
+
+ local key="${keyValue[0]}"
+ local value="${keyValue[1]}"
+
+ case "${key}" in
+ Name)
+
+ if [[ -z "${cmdName}" ]]; then
+ cmdName="${value} (WSL)"
+ fi
+
+ ;;
+ Exec)
+
+ if [[ -z "${cmdToExec}" ]]; then
+
+ declare -a cmdToExecArray
+ local cmdToExecArray
+ read -ra cmdToExecArray <<< "${value}"
+
+ cmdToExec="${cmdToExecArray[0]}"
+
+ case "${cmdToExec}" in
+ *display-im6.q16)
+ return
+ ;;
+ synaptic*)
+ return
+ ;;
+ esac
+
+ fi
+
+ ;;
+
+ Icon)
+
+ if [[ -z "${cmdIcon}" ]]; then
+
+ if [[ ! -f "${value}" ]]; then
+ cmdIcon=$(find /usr/share/pixmaps \
+ \
+ /usr/share/icons/hicolor/256x256/apps \
+ /usr/share/icons/Adwaita/256x256/apps \
+ /usr/share/icons/gnome/256x256/apps \
+ /usr/share/icons/hicolor/128x128/apps \
+ /usr/share/icons/hicolor/scalable/apps \
+ /usr/share/icons/hicolor/48x48/apps \
+ /usr/share/icons/gnome/48x48/apps \
+ /usr/share/icons/Adwaita/512x512/places \
+ /usr/share/icons/Adwaita/256x256/devices \
+ /usr/share/icons \
+ \
+ -maxdepth 1 -name "${value}*" -type f,l | head -n 1)
+ else
+ cmdIcon="${value}"
+ fi
+
+ if [[ -n "${cmdIcon}" ]]; then
+ cmdIcon="--icon ${cmdIcon}"
+ else
+ cmdIcon="${NO_ICON}"
+ fi
+ fi
+
+
+ ;;
+
+ Type)
+
+ if [[ "${value}" != "Application" ]]; then
+ return
+ fi
+
+
+ ;;
+
+ Terminal)
+
+ if [[ "${value}" == "true" ]]; then
+ gui=""
+ fi
+
+
+ ;;
+
+ NoDisplay)
+
+ if [[ "${value}" == "true" ]]; then
+ return
+ fi
+
+
+ ;;
+
+ esac
+
+
+ ;;
+
+ esac
+ done < "${desktopFile}"
+
+ create_shortcut "${cmdName}" "${cmdToExec}" "${cmdIcon}" "${gui}"
+}
+
+function main() {
+
+ if [[ ${SKIP_STARTMENU} ]]; then
+ return
+ fi
+
+ if (confirm --title "Start Menu" --yesno "Would you like to generate / regenerate the Start Menu shortcuts for the GUI applications installed in Pengwin?\n\nThe applications will be placed in the 'Pengwin Applications' folder in Windows Start Menu." 12 70) ; then
+
+ echo "Generating Start Menu"
+
+ DEST_PATH=$(wslpath "$(wslvar -l Programs)")/Pengwin\ Applications
+
+ rm "${DEST_PATH}"/*
+
+ find /usr/share/applications -name '*.desktop' | while read desktopFile; do
+
+ create_shortcut_from_desktop "${desktopFile}"
+
+ done
+
+ else
+ echo "Skipping Start Menu Generation"
+ fi
+
+}
+
+main
\ No newline at end of file
diff --git a/pengwin-setup.d/theme.sh b/pengwin-setup.d/theme.sh
index ea41af38..8fb32b2e 100644
--- a/pengwin-setup.d/theme.sh
+++ b/pengwin-setup.d/theme.sh
@@ -2,17 +2,23 @@
source $(dirname "$0")/common.sh "$@"
-if (whiptail --title "Windows 10 Theme" --yesno "Would you like to install a Windows 10 theme? (including lxappearance, a GUI application to set the theme)" 8 70) then
+#Imported from common.h
+declare SetupDir
+
+if (whiptail --title "Windows 10 Theme" --yesno "Would you like to install a Windows 10 theme? (including lxappearance, a GUI application to set the theme)" 8 70); then
echo "Installing Windows 10 theme"
# Source files locations
W10LIGHT_URL="https://github.com/B00merang-Project/Windows-10/archive/master.zip"
W10DARK_URL="https://github.com/B00merang-Project/Windows-10-Dark/archive/master.zip"
+ W10ICONS_URL="https://github.com/B00merang-Artwork/Windows-10/archive/master.zip"
INSTALLDIR="/usr/share/themes"
+ INSTALLICONSDIR="/usr/share/icons"
LIGHTDIR="windows-10-light"
DARKDIR="windows-10-dark"
+ ICONSDIR="windows-10"
- echo "$ sudo apt-get install unzip -y"
- sudo apt-get install unzip -y
+ echo "$ sudo apt-get -y -q install unzip dmz-cursor-theme"
+ sudo apt-get -y -q install unzip dmz-cursor-theme
# Download themes to temporary folder (sub folders for light & dark) then unzip
echo "Downloading themes to temporary folder"
@@ -26,6 +32,13 @@ if (whiptail --title "Windows 10 Theme" --yesno "Would you like to install a Win
echo "Unzipping master-dark.zip..."
unzip -qq master-dark.zip
+ mkdir icons
+ cd icons
+ wget ${W10ICONS_URL} -O master-icons.zip -q --show-progress
+ echo "Unzipping master-icons.zip..."
+ unzip -qq master-icons.zip
+ cd ..
+
if [[ ! -d "${INSTALLDIR}" ]] ; then
echo "${INSTALLDIR} does not exist, creating"
sudo mkdir -p $INSTALLDIR
@@ -41,24 +54,36 @@ if (whiptail --title "Windows 10 Theme" --yesno "Would you like to install a Win
sudo rm -r $INSTALLDIR/$DARKDIR
fi
+ if [[ -d "${INSTALLICONSDIR}/${ICONSDIR}" ]] ; then
+ echo "${INSTALLICONSDIR}/${ICONSDIR} already exists, removing old"
+ sudo rm -r $INSTALLICONSDIR/$ICONSDIR
+ fi
+
# Move to themes folder
- echo "Moving themes to ${INSTALLDIR}"
+ echo "Moving themes to ${INSTALLDIR}" and "${INSTALLICONSDIR}"
sudo mv Windows-10-master "${INSTALLDIR}/${LIGHTDIR}"
sudo mv Windows-10-Dark-master "${INSTALLDIR}/${DARKDIR}"
+ sudo mv icons/Windows-10-master "${INSTALLICONSDIR}/${ICONSDIR}"
# Set correct permissions
echo "Setting correct theme folder permissions"
sudo chown -R root:root "${INSTALLDIR}/${LIGHTDIR}"
sudo chown -R root:root "${INSTALLDIR}/${DARKDIR}"
+ sudo chown -R root:root "${INSTALLICONSDIR}/${ICONSDIR}"
sudo chmod -R 0755 "${INSTALLDIR}/${LIGHTDIR}"
sudo chmod -R 0755 "${INSTALLDIR}/${DARKDIR}"
+ sudo chmod -R 0755 "${INSTALLICONSDIR}/${ICONSDIR}"
# Install lxappearance to let user set theme
sudo apt-get install -q -y lxappearance
+ lxappearance &
+
+ bash ${SetupDir}/shortcut.sh --yes "$@"
+
# Cleanup
cleantmp
- whiptail --title "Set Windows 10 theme" --msgbox "To set the either of the Windows 10 light/dark themes:\nRun 'lxappearance', choose from the list of installed themes and click apply. You may change the theme in this way at anytime, including fonts and cursors." 9 90
+ whiptail --title "Set Windows 10 theme" --msgbox "To set the either of the Windows 10 light/dark themes:\nRun 'lxappearance', choose from the list of installed themes and click apply. You may change the theme in this way at anytime, including fonts, icons and cursors." 9 90
else
echo "Skipping Windows 10 theme install"
fi
diff --git a/pengwin-setup.d/uninstall.sh b/pengwin-setup.d/uninstall.sh
new file mode 100644
index 00000000..a293a28d
--- /dev/null
+++ b/pengwin-setup.d/uninstall.sh
@@ -0,0 +1,215 @@
+#!/bin/bash
+
+source $(dirname "$0")/common.sh "$@"
+
+#Imported from common.h
+declare SetupDir
+
+function main() {
+
+ local UninstallDir="${SetupDir}/uninstall"
+ local menu_choice=$(
+
+ menu --title "GUI Menu" --checklist --separate-output "Uninstall applications and packages installed by pengwin-setup\n[SPACE to select, ENTER to confirm]:" 20 95 12 \
+ "ANSIBLE" "Remove Ansible Playbook deployment tools" off \
+ "AWS" "Remove AWS CLI tools" off \
+ "AZURE" "Remove Azure CLI tools" off \
+ "BASH-RL" "Remove optimized Bash readline settings" off \
+ "C++" "Remove Linux C/C++ programming support in Visual Studio and CLion" off \
+ "CASSANDRA" "Remove Cassandra NoSQL server" off \
+ "COLORTOOL" "Remove ColorTool console color scheme setter" off \
+ "DO" "Remove Digital Ocean CLI tools" off \
+ "DOCKER" "Remove secure bridge between Pengwin and Docker Desktop" off \
+ "DOTNET" "Remove Microsoft's .NET Core SDK and NuGet (if installed)" off \
+ "FCITX" "Remove all fcitx improved non-Latin input support" off \
+ "GO" "Remove Go language" off \
+ "GUILIB" "Remove base GUI application libraries" off \
+ "HIDPI" "Remove Qt and GTK HiDPI modifications" off \
+ "HOMEBREW" "Remove the Homebrew package manager" off \
+ "IBM" "Remove IBM Cloud CLI tools" off \
+ "JAVA" "Remove SDKMan its installed Java SDKs" off \
+ "KEYCHAIN" "Remove Keychain OpenSSH key manager" off \
+ "KUBERNETES" "Remove Kubernetes tooling" off \
+ "LAMP" "Remove LAMP stack" off \
+ "NODEJS" "Remove Node.js, npm and Yarn (if installed)" off \
+ "OPENSTACK" "Remove OpenStack CLI tools" off \
+ "POWERSHELL" "Remove Powershell for Linux" off \
+ "PYENV" "Remove pyenv, its Python version(s) and modules" off \
+ "RUBY" "Remove rbenv, Ruby version(s) and Rails (if installed)" off \
+ "RUST" "Remove Rust and rustup toolchain installer" off \
+ "STARTMENU" "Remove all Pengwin generated Windows Start Menu shortcuts" off \
+ "SSH" "Remove SSH server" off \
+ "TERRAFORM" "Remove Terraform CLI tools" off \
+ "VCXSRV" "Remove VcXsrv X-server" off \
+ "VSCODE" "Remove Visual Studio Code for Linux" off \
+ "WINTHEME" "Remove Windows 10 theme and LXAppearance" off \
+
+ 3>&1 1>&2 2>&3)
+
+ if [[ ${menu_choice} == "CANCELLED" ]] ; then
+ return 1
+ fi
+
+ if [[ ${menu_choice} == *"ANSIBLE"* ]] ; then
+ echo "ANSIBLE"
+ bash ${UninstallDir}/ansible.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"AWS"* ]] ; then
+ echo "AWS"
+ bash ${UninstallDir}/awscli.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"AZURE"* ]] ; then
+ echo "AZURE"
+ bash ${UninstallDir}/azurecli.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"BASH-RL"* ]] ; then
+ echo "BASH-RL"
+ bash ${UninstallDir}/shell-opts.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"C++"* ]] ; then
+ echo "C++"
+ bash ${UninstallDir}/cpp-vs-clion.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"CASSANDRA"* ]] ; then
+ echo "CASSANDRA"
+ bash ${UninstallDir}/cassandra.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"COLORTOOL"* ]] ; then
+ echo "COLORTOOL"
+ bash ${UninstallDir}/colortool.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"DO"* ]] ; then
+ echo "DO"
+ bash ${UninstallDir}/doctl.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"DOCKER"* ]] ; then
+ echo "DOCKER"
+ bash ${UninstallDir}/docker.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"DOTNET"* ]] ; then
+ echo "DOTNET"
+ bash ${UninstallDir}/dotnet.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"FCITX"* ]] ; then
+ echo "FCITX"
+ bash ${UninstallDir}/fcitx.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"GO"* ]] ; then
+ echo "GO"
+ bash ${UninstallDir}/go.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"GUILIB"* ]] ; then
+ echo "GUILIB"
+ bash ${UninstallDir}/guilib.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"HIDPI"* ]] ; then
+ echo "HIDPI"
+ bash ${UninstallDir}/hidpi.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"HOMEBREW"* ]] ; then
+ echo "HOMEBREW"
+ bash ${UninstallDir}/brew.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"IBM"* ]] ; then
+ echo "IBM"
+ bash ${UninstallDir}/ibmcli.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"JAVA"* ]] ; then
+ echo "JAVA"
+ bash ${UninstallDir}/java.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"KEYCHAIN"* ]] ; then
+ echo "KEYCHAIN"
+ bash ${UninstallDir}/keychain.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"KUBERNETES"* ]] ; then
+ echo "KUBERNETES"
+ bash ${UninstallDir}/kubernetes.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"LAMP"* ]] ; then
+ echo "LAMP"
+ bash ${UninstallDir}/lamp.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"NODEJS"* ]] ; then
+ echo "NODEJS"
+ bash ${UninstallDir}/nodejs.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"OPENSTACK"* ]] ; then
+ echo "OPENSTACK"
+ bash ${UninstallDir}/openstack.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"POWERSHELL"* ]] ; then
+ echo "POWERSHELL"
+ bash ${UninstallDir}/powershell.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"PYENV"* ]] ; then
+ echo "PYENV"
+ bash ${UninstallDir}/pyenv.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"RUBY"* ]] ; then
+ echo "RUBY"
+ bash ${UninstallDir}/rbenv.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"RUST"* ]] ; then
+ echo "RUST"
+ bash ${UninstallDir}/rust.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"STARTMENU"* ]] ; then
+ echo "STARTMENU"
+ bash ${UninstallDir}/shortcut.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"SSH"* ]] ; then
+ echo "SSH"
+ bash ${UninstallDir}/ssh.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"TERRAFORM"* ]] ; then
+ echo "TERRAFORM"
+ bash ${UninstallDir}/terraform.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"VCXSRV"* ]] ; then
+ echo "VCXSRV"
+ bash ${UninstallDir}/vcxsrv.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"VSCODE"* ]] ; then
+ echo "VSCODE"
+ bash ${UninstallDir}/vscode.sh "$@"
+ fi
+
+ if [[ ${menu_choice} == *"WINTHEME"* ]] ; then
+ echo "WINTHEME"
+ bash ${UninstallDir}/theme.sh "$@"
+ fi
+
+}
+
+main "$@"
diff --git a/pengwin-setup.d/uninstall/ansible.sh b/pengwin-setup.d/uninstall/ansible.sh
new file mode 100644
index 00000000..06b09850
--- /dev/null
+++ b/pengwin-setup.d/uninstall/ansible.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+ans_key="93C4A3FD7BB9C367"
+
+function main()
+{
+
+echo "Uninstalling Ansible"
+
+remove_package "ansible"
+
+rem_dir "$HOME/.ansible"
+
+echo "Removing APT source..."
+sudo_rem_file "/etc/apt/sources.list.d/ansible.list"
+
+echo "Removing APT key"
+sudo apt-key del "$ans_key"
+
+}
+
+if show_warning "ansible" "$@" ; then
+ main "$@"
+fi
+
diff --git a/pengwin-setup.d/uninstall/awscli.sh b/pengwin-setup.d/uninstall/awscli.sh
new file mode 100644
index 00000000..5bcc6407
--- /dev/null
+++ b/pengwin-setup.d/uninstall/awscli.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+echo "Uninstalling AWS cli"
+
+sudo_rem_file "/usr/local/bin/aws"
+sudo_rem_dir "/usr/local/aws"
+
+echo "Removing bash completion..."
+sudo_rem_file "/etc/bash_completion.d/aws_bash_completer"
+sudo_rem_file "/usr/local/bin/aws_completer"
+
+}
+
+if show_warning "AWS CLI" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/azurecli.sh b/pengwin-setup.d/uninstall/azurecli.sh
new file mode 100644
index 00000000..0a0ccd33
--- /dev/null
+++ b/pengwin-setup.d/uninstall/azurecli.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+echo "Uninstall Azure command line tools"
+
+# Remove packages
+remove_package "azure-cli" "jq"
+
+echo "Removing bash completion..."
+sudo_rem_file "/etc/bash_completion.d/azure-cli"
+
+echo "Removing APT source..."
+sudo_rem_file "/etc/apt/sources.list.d/azurecli.list"
+
+echo "Removing APT key..."
+safe_rem_microsoftgpg
+
+}
+
+if show_warning "Azure CLI" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/brew.sh b/pengwin-setup.d/uninstall/brew.sh
new file mode 100644
index 00000000..6aaa077b
--- /dev/null
+++ b/pengwin-setup.d/uninstall/brew.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+echo "Uninstalling Homebrew"
+local tmp_ruby=1
+
+if ! ruby --version > /dev/null 2>&1 ; then
+ echo "Installing Ruby for uninstall script"
+ sudo apt-get install ruby -y -q
+ tmp_ruby=0
+fi
+
+echo "Running Homebrew uninstall script"
+whiptail --title "Homebrew" --msgbox "Please type 'y' when requested to by the Homebrew uninstaller" 8 85
+if ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)" ; then
+ echo "Successfully executed script"
+else
+ if ! brew ; then
+ echo "Full uninstall failed. Removing remnants"
+ sudo rm -rf "/home/linuxbrew"
+ sudo rm -rf "$HOME/.linuxbrew"
+ else
+ echo "Uninstall failed"
+ fi
+fi
+
+echo "Removing PATH modification..."
+sudo_rem_file "/etc/profile.d/brew.sh"
+
+if [ $tmp_ruby -eq 0 ] ; then
+ echo "Ruby temporarily installed for uninstall script, removing..."
+ sudo apt-get remove -y -q ruby --autoremove
+fi
+
+}
+
+if show_warning "Homebrew" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/cassandra.sh b/pengwin-setup.d/uninstall/cassandra.sh
new file mode 100644
index 00000000..2f5a5ab0
--- /dev/null
+++ b/pengwin-setup.d/uninstall/cassandra.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+sudoers_rgx='^[^#]*\bALL=.(root.) NOPASSWD: /bin/mount, /bin/umount'
+profile_rgx='^[^#]*\bsudo mount -t proc proc /proc'
+
+function main()
+{
+
+echo "Uninstalling Apache Cassandra"
+
+echo "Removing Cassandra-specific changes to /etc/sudoers"
+sudo_clean_file "/etc/sudoers" "$sudoers_rgx"
+
+echo "Removing Cassandra-specific changes to /etc/profile"
+sudo_clean_file "/etc/profile" "$profile_rgx"
+
+echo "Unlinking Cassandra from user directory"
+if [[ -d "$wHome/cassandra" ]] ; then
+ sudo unlink "/etc/cassandra"
+else
+ echo "... not symlinked!"
+fi
+
+remove_package "cassandra"
+
+sudo_rem_dir "/etc/cassandra"
+sudo_rem_dir "/var/lib/cassandra"
+sudo_rem_dir "/var/log/cassandra"
+
+echo "Removing APT source..."
+sudo_rem_file "/etc/apt/sources.list.d/cassandra.list"
+
+echo "Removing APT key"
+sudo_rem_file "/etc/apt/trusted.gpg.d/cassandra.gpg"
+
+}
+
+if show_warning "Apache Cassandra" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/colortool.sh b/pengwin-setup.d/uninstall/colortool.sh
new file mode 100644
index 00000000..8b264869
--- /dev/null
+++ b/pengwin-setup.d/uninstall/colortool.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+colortool_dir="$wHome/.ColorTool"
+
+function main()
+{
+
+echo "Uninstalling ColorTool"
+
+rem_dir "$wHome/.ColorTool"
+sudo_rem_file "/usr/local/bin/colortool"
+
+echo "Removing PATH modifier..."
+sudo_rem_file "/etc/proflie.d/01-colortool.sh"
+
+}
+
+if show_warning "ColorTool" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/cpp-vs-clion.sh b/pengwin-setup.d/uninstall/cpp-vs-clion.sh
new file mode 100644
index 00000000..d16cbcea
--- /dev/null
+++ b/pengwin-setup.d/uninstall/cpp-vs-clion.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+installdir='/usr/local'
+
+function main()
+{
+
+echo "Uninstalling Cpp VisualStudio CLion integration"
+
+sudo_rem_file "$installdir/bin/cmake"
+sudo_rem_file "$installdir/bin/cpack"
+sudo_rem_file "$installdir/bin/ctest"
+sudo_rem_dir "$installdir/doc"
+sudo_rem_file "$installdir/share/aclocal/cmake.m4"
+sudo_rem_dir $installdir/share/cmake-*
+
+}
+
+if show_warning "Cpp VisualStudio CLion" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/docker.sh b/pengwin-setup.d/uninstall/docker.sh
new file mode 100644
index 00000000..21f240c5
--- /dev/null
+++ b/pengwin-setup.d/uninstall/docker.sh
@@ -0,0 +1,91 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+relayexedir="$wHome/.npiperelay"
+
+wslconf_rgx='^[^#]*\broot=/'
+mntbin_rgx='^[^#]*\bsudo\s*ALL=NOPASSWD: /usr/bin/create-mnt-c-link'
+
+function revert_mnt_point()
+{
+
+echo "Offering to revert docker changed Windows volume mount point"
+if whiptail --title "DOCKER" --yesno "Would you like to revert your root mount point to WSL default?" 7 85 ; then
+ echo "Cleaning changes from /etc/wsl.conf"
+ sudo_clean_file "/etc/wsl.conf" "$wslconf_rgx"
+
+ sudo_rem_file "/usr/bin/create-mnt-c-link"
+
+ echo "Removing create-mnt-c-link profile configuration"
+ sudo_rem_file "/etc/profile.d/create-mnt-c-link.sh"
+
+ echo "Cleaning create-mnt-c-link changes from /etc/sudoers"
+ sudo_clean_file "/etc/sudoers" "$mntbin_rgx"
+
+ whiptail --title "DOCKER" --msgbox "Finished reverting root mount point. Please close and re-open Pengwin to see changes" 8 85
+else
+ echo "... user opted to keep docker changed mount point."
+fi
+
+}
+
+function main()
+{
+
+echo "Uninstalling Docker Bridge"
+
+echo "Removing npiperelay.exe"
+if [[ -d "$relayexedir" ]] ; then
+ if cmd-exe /C tasklist | grep -Fq 'npiperelay.exe' ; then
+ echo "npiperelay.exe running. Killing process..."
+ cmd-exe /C taskkill /IM 'npiperelay.exe' /F
+ fi
+
+ # Now safe to remove directory
+ sudo rm -rf "$relayexedir"
+else
+ echo "... not found!"
+fi
+
+sudo_rem_file "/usr/bin/docker-relay"
+
+echo "Removing docker-relay sudoers modification..."
+sudo_rem_file "/etc/sudoers.d/docker-relay"
+
+echo "Removing docker-relay profile modification..."
+sudo_rem_file "/etc/profile.d/docker_relay.sh"
+
+sudo_rem_file "/usr/bin/docker"
+sudo_rem_file "/usr/bin/docker-compose"
+
+echo "Removing bash completion..."
+sudo_rem_file "/etc/bash_completion.d/docker"
+sudo_rem_file "/etc/bash_completion.d/docker-compose"
+
+echo "Checking root mount path"
+if [[ $(wslpath 'C:\\') == '/c' ]] ; then
+ revert_mnt_point "$@"
+else
+ echo "Root mount path already WSL default."
+fi
+
+echo "Removing docker user"
+if grep -Fq 'docker:' '/etc/passwd' ; then
+ sudo deluser docker
+else
+ echo "... not found!"
+fi
+
+echo "Removing docker user group"
+if grep -Fq 'docker:' '/etc/group' ; then
+ sudo delgroup docker
+else
+ echo "... not found!"
+fi
+
+}
+
+if show_warning "Docker Bridge" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/doctl.sh b/pengwin-setup.d/uninstall/doctl.sh
new file mode 100644
index 00000000..b735f1be
--- /dev/null
+++ b/pengwin-setup.d/uninstall/doctl.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+echo "Uninstalling Digital Ocean CTL"
+
+sudo_rem_file "/usr/local/bin/doctl"
+
+echo "Removing bash completion..."
+sudo_rem_file "/etc/bash_completion.d/doc.bash_completion"
+
+}
+
+if show_warning "Digital Ocean CTL" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/dotnet.sh b/pengwin-setup.d/uninstall/dotnet.sh
new file mode 100644
index 00000000..ba4cee46
--- /dev/null
+++ b/pengwin-setup.d/uninstall/dotnet.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+echo "Uninstalling dotnet"
+
+remove_package "dotnet-sdk-2.2" "nuget"
+
+echo "Removing leftover dotnet cli tools directory..."
+rem_dir "$HOME/.dotnet"
+
+echo "Removing dotnet cli tools PATH modification..."
+sudo_rem_file "/etc/profile.d/dotnet-cli-tools-bin-path.sh"
+
+echo "Removing APT source(s)..."
+safe_rem_microsoftsrc
+safe_rem_debianstablesrc
+
+echo "Removing APT key..."
+safe_rem_microsoftgpg
+
+}
+
+if show_warning "dotnet" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/explorer.sh b/pengwin-setup.d/uninstall/explorer.sh
new file mode 100644
index 00000000..11dae03a
--- /dev/null
+++ b/pengwin-setup.d/uninstall/explorer.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+plain_name='Pengwin'
+
+function main()
+{
+
+echo "Uninstalling Pengwin explorering integration"
+
+createtmp
+
+cat << EOF >> Uninstall.reg
+Windows Registry Editor Version 5.00
+[-HKEY_CURRENT_USER\Software\Classes\Directory\Background\shell\\${plain_name}]
+[-HKEY_CURRENT_USER\Software\Classes\Directory\shell\\${plain_name}]
+EOF
+
+cp Uninstall.reg $(wslpath "$(cmd-exe /c 'echo %TEMP%' | tr -d '\r')")/Uninstall.reg
+cmd-exe /C "Reg import %TEMP%\Uninstall.reg"
+
+cleantmp
+
+}
+
+if show_warning "explorer integration" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/fcitx.sh b/pengwin-setup.d/uninstall/fcitx.sh
new file mode 100644
index 00000000..15cc7550
--- /dev/null
+++ b/pengwin-setup.d/uninstall/fcitx.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+echo "Uninstall fcitx non-latin input modifications"
+
+echo "Removing fcitx environment variable modifications..."
+sudo_rem_file "/etc/profile.d/fcitx"
+sudo_rem_file "/etc/profile.d/fcitx.sh"
+
+echo "Removing fcitx packages..."
+remove_package "fcitx" "fcitx-sunpinyin" "fcitx-libpinyin" "fcitx-rime" "fcitx-googlepinyin" "fcitx-chewing" "fcitx-mozc" "fcitx-kkc" "fcitx-kkc-dev" "fcitx-hangul" "fcitx-unikey" "fcitx-sayura" "fcitx-table" "fcitx-table-all"
+
+echo "Regenerating start-menu entry cache..."
+bash ${SetupDir}/shortcut.sh --yes
+
+}
+
+if show_warning "fcitx improved non-latin input" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/go.sh b/pengwin-setup.d/uninstall/go.sh
new file mode 100644
index 00000000..b459fd50
--- /dev/null
+++ b/pengwin-setup.d/uninstall/go.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+local go_conf="/etc/profile.d/go.sh"
+
+echo "Uninstalling go"
+
+echo "Removing $go_dir"
+sudo_rem_dir "/usr/local/go"
+
+echo "Removing go build cache"
+rem_dir "$HOME/.cache/go-build"
+
+echo "Removing PATH modifier..."
+sudo_rem_file "/etc/profile.d/go.sh"
+
+# whiptail user go directory
+
+}
+
+if show_warning "go" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/guilib.sh b/pengwin-setup.d/uninstall/guilib.sh
new file mode 100644
index 00000000..3e81c810
--- /dev/null
+++ b/pengwin-setup.d/uninstall/guilib.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+echo "Uninstalling base GUI libraries and modifications"
+
+echo "Removing dbus configuration files..."
+sudo_rem_file "/etc/dbus-1/session.conf"
+sudo_rem_file "/usr/share/dbus-1/session.conf"
+
+remove_package "xclip" "gnome-themes-standard" "gtk2-engines-murrine" "dbus-x11"
+
+}
+
+if show_warning "base GUI libraries and modifications" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/hidpi.sh b/pengwin-setup.d/uninstall/hidpi.sh
new file mode 100644
index 00000000..ecd205c7
--- /dev/null
+++ b/pengwin-setup.d/uninstall/hidpi.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+echo "Uninstalling Qt and GTK HiDPI modifications"
+sudo_rem_file "/etc/profile.d/hidpi.sh"
+
+}
+
+if show_warning "HiDPI modifications" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/ibmcli.sh b/pengwin-setup.d/uninstall/ibmcli.sh
new file mode 100644
index 00000000..a638053e
--- /dev/null
+++ b/pengwin-setup.d/uninstall/ibmcli.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+echo "Uninstalling IBM Cloud CLI"
+
+# Uninstall kubectl
+bash $(dirname "$0")/kubectl.sh
+
+echo "Removing bash completions..."
+sudo_rem_file "/etc/bash_completion.d/ibmcli_completion"
+
+sudo_rem_file "/usr/local/bin/bluemix"
+sudo_rem_file "/usr/local/bin/bx"
+sudo_rem_file "/usr/local/bin/ibmcloud"
+sudo_rem_file "/usr/local/bin/ibmcloud-analytics"
+
+sudo_rem_dir "/usr/local/ibmcloud"
+rem_dir "$HOME/.bluemix"
+
+}
+
+if show_warning "IBM Cloud CLI" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/java.sh b/pengwin-setup.d/uninstall/java.sh
new file mode 100644
index 00000000..050883b1
--- /dev/null
+++ b/pengwin-setup.d/uninstall/java.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+sdkman_rgx1='^#THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!!'
+sdkman_rgx2='^[^#]*\bexport SDKMAN_DIR='
+sdkman_rgx3='^[^#]*\bsource ".*\/bin\/sdkman-init\.sh"'
+
+function multiclean_file()
+{
+
+if [[ -f "$1" ]] ; then
+ echo "$1 found! Cleaning..."
+ clean_file "$1" "$sdkman_rgx1"
+ clean_file "$1" "$sdkman_rgx2"
+ clean_file "$1" "$sdkman_rgx3"
+fi
+
+}
+
+function main()
+{
+
+echo "Uninstalling SDKMAN (Java)"
+
+rem_dir "$HOME/.sdkman"
+
+echo "Removing PATH modifier(s)..."
+multiclean_file "$HOME/.bashrc"
+multiclean_file "$HOME/.zshrc"
+multiclean_file "$HOME/.profile"
+multiclean_file "$HOME/.bash_profile"
+
+echo "Removing bash completion..."
+sudo_rem_file "/etc/bash_completion.d/sdkman.bash"
+
+}
+
+if show_warning "SDKMAN (Java)" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/keychain.sh b/pengwin-setup.d/uninstall/keychain.sh
new file mode 100644
index 00000000..c1ca38a3
--- /dev/null
+++ b/pengwin-setup.d/uninstall/keychain.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+echo "Uninstalling Keychain and profile modifications"
+
+echo "Removing profile modification..."
+sudo_rem_file "/etc/profile.d/keychain.sh"
+
+remove_package "keychain"
+
+}
+
+if show_warning "Keychain" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/kubectl.sh b/pengwin-setup.d/uninstall/kubectl.sh
new file mode 100644
index 00000000..4e086fb7
--- /dev/null
+++ b/pengwin-setup.d/uninstall/kubectl.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+kubectl_key1='D0BC 747F D8CA F711 7500 D6FA 3746 C208 A731 7B0F'
+kubectl_key2='54A6 47F9 048D 5688 D7DA 2ABE 6A03 0B21 BA07 F4FB'
+
+function main()
+{
+
+echo "Uninstalling kubectl"
+
+# Check if IBM CLI or Kubernetes still installed
+if ibmcloud --version > /dev/null 2>&1 ; then
+ echo "... IBM CLI tools still installed, skipping kubectl uninstall."
+ exit 1
+fi
+if kubectx > /dev/null 2>&1 ; then
+ echo "... Kubernetes tooling still installed, skipping kubectl uninstall."
+ exit 1
+fi
+
+sudo_rem_file "/usr/local/bin/helm"
+sudo_rem_file "/usr/local/bin/tiller"
+
+echo "Removing bash completion..."
+sudo_rem_file "/etc/bash_completion.d/helm_completions.bash"
+
+remove_package "kubectl"
+
+echo "Removing kubectl APT source..."
+sudo_rem_file "/etc/apt/sources.list.d/kubernetes.list"
+
+echo "Removing kubectl APT keys..."
+sudo apt-key del "$kubectl_key1"
+sudo apt-key del "$kubectl_key2"
+
+}
+
+main "$@"
\ No newline at end of file
diff --git a/pengwin-setup.d/uninstall/kubernetes.sh b/pengwin-setup.d/uninstall/kubernetes.sh
new file mode 100644
index 00000000..2060eb28
--- /dev/null
+++ b/pengwin-setup.d/uninstall/kubernetes.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+echo "Uninstalling Kubernetes"
+
+# Uninstall kubectl
+bash $(dirname "$0")/kubectl.sh
+
+echo "Removing bash completions..."
+sudo_rem_file "/etc/bash_completion.d/kubectx"
+sudo_rem_file "/etc/bash_completion.d/kubens"
+
+sudo_rem_file "/usr/local/bin/kubectx"
+sudo_rem_file "/usr/local/bin/kubens"
+
+rem_dir "$HOME/.kube"
+
+if docker version > /dev/null 2>&1 ; then
+ echo "Offering docker uninstall"
+ if (whiptail --title "docker" --yesno "It seems Docker secure bridge is currently installed, would you like to uninstall this too?" 8 85) ; then
+ bash $(dirname "$0")/docker.sh
+ else
+ echo "... user cancelled"
+ fi
+fi
+
+}
+
+if show_warning "Kubernetes" "$@" ; then
+ main "$@"
+fi
\ No newline at end of file
diff --git a/pengwin-setup.d/uninstall/lamp.sh b/pengwin-setup.d/uninstall/lamp.sh
new file mode 100644
index 00000000..8bd3d278
--- /dev/null
+++ b/pengwin-setup.d/uninstall/lamp.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+echo "Uninstalling LAMP stack"
+
+sudo_rem_file "/etc/profile.d/start-lamp.sh"
+sudo_rem_file "/etc/sudoers.d/start-lamp"
+
+sudo_rem_file "/usr/bin/start-lamp"
+
+remove_package "mariadb-server" "mariadb-client" "apache2" "apache2-utils" "php" "libapache2-mod-php" "php-cli" "php-fpm" "php-json" "php-pdo" "php-mysql" "php-zip" "php-gd" "php-mbstring" "php-curl" "php-xml" "php-pear" "php-bcmath"
+
+sudo_rem_file "/var/www/html/phpinfo.php"
+
+}
+
+if show_warning "LAMP stack" "$@" ; then
+ main "$@"
+fi
\ No newline at end of file
diff --git a/pengwin-setup.d/uninstall/latex.sh b/pengwin-setup.d/uninstall/latex.sh
new file mode 100644
index 00000000..bc2b27c6
--- /dev/null
+++ b/pengwin-setup.d/uninstall/latex.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+echo "Uninstalling LaTeX"
+
+remove_package texlive-full texlive-latex-extra texlive-latex-recommended texlive-latex-base
+
+}
+
+if show_warning "LaTeX" "$@" ; then
+ main "$@"
+fi
\ No newline at end of file
diff --git a/pengwin-setup.d/uninstall/nodejs.sh b/pengwin-setup.d/uninstall/nodejs.sh
new file mode 100644
index 00000000..04aaa855
--- /dev/null
+++ b/pengwin-setup.d/uninstall/nodejs.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+yarn_key='72EC F46A 56B4 AD39 C907 BBB7 1646 B01B 86E5 0310'
+line_rgx='^[^#]*\bN_PREFIX='
+
+function main()
+{
+
+echo "Uninstalling nodejs (including n version manager, npm and yarn package managers)"
+
+# Check for ruby rails install
+echo "Checking if Ruby on Rails installed..."
+if gem list --local | grep '^rails' > /dev/null 2>&1 ; then
+ echo "Rails install detected. Showing user warning"
+ if ! (whiptail --title "nodejs" --yesno "A Ruby on Rails install has been detected, which relies upon nodejs. Are you sure you'd like to continue uninstalling nodejs? As this may break your Ruby on Rails install" 9 85) ; then
+ echo "User cancelled nodejs uninstall"
+ exit 1
+ fi
+fi
+
+rem_dir "$HOME/n"
+rem_dir "$HOME/.npm"
+
+echo "Removing PATH modifier(s)..."
+sudo_rem_file "/etc/profile.d/n-prefix.sh"
+if [[ -f "$HOME/.bashrc" ]] ; then
+ echo "$HOME/.bashrc found, cleaning"
+ clean_file "$HOME/.bashrc" "$line_rgx"
+fi
+if [[ -f "$HOME/.zshrc" ]] ; then
+ echo "$HOME/.zshrc found, cleaning"
+ clean_file "$HOME/.zshrc" "$line_rgx"
+fi
+
+echo "Removing bash completion..."
+sudo_rem_file "/etc/bash_completion.d/npm"
+
+remove_package "yarn"
+
+echo "Removing APT source"
+sudo_rem_file "/etc/apt/sources.list.d/yarn.list"
+
+echo "Removing APT key"
+sudo apt-key del "$yarn_key"
+
+}
+
+if show_warning "nodejs" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/openstack.sh b/pengwin-setup.d/uninstall/openstack.sh
new file mode 100644
index 00000000..d4d0c411
--- /dev/null
+++ b/pengwin-setup.d/uninstall/openstack.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+echo "Uninstalling OpenStack CLI"
+
+sudo_pip_uninstall "2" "python-openstackclient" "openstacksdk"
+
+echo "Removing bash completion..."
+sudo_rem_file "/etc/bash_completion.d/osc.bash_completion"
+
+}
+
+if show_warning "OpenStack CLI" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/powershell.sh b/pengwin-setup.d/uninstall/powershell.sh
new file mode 100644
index 00000000..743351c3
--- /dev/null
+++ b/pengwin-setup.d/uninstall/powershell.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+echo "Uninstalling Powershell"
+
+remove_package "powershell"
+
+echo "Removing APT source(s)..."
+safe_rem_microsoftsrc
+safe_rem_debianstablesrc
+
+echo "Removing APT key..."
+safe_rem_microsoftgpg
+
+}
+
+if show_warning "Powershell" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/pyenv.sh b/pengwin-setup.d/uninstall/pyenv.sh
new file mode 100644
index 00000000..67e2429a
--- /dev/null
+++ b/pengwin-setup.d/uninstall/pyenv.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+line_rgx='^[^#]*\bPATH.*/.pyenv/bin'
+line2_rgx='^[^#]*\bpyenv init -'
+line3_rgx='^[^#]*\bpyenv virtualenv-init -'
+
+function multiclean_file()
+{
+
+if [[ -f "$1" ]] ; then
+ echo "$1 found! Cleaning..."
+ clean_file "$1" "$line_rgx"
+ clean_file "$1" "$line2_rgx"
+ clean_file "$1" "$line3_rgx"
+fi
+
+}
+
+function main()
+{
+
+echo "Uninstalling pyenv"
+local initFile tempPath
+
+rem_dir "$HOME/.pyenv"
+
+echo "Removing PATH modifier(s)"
+multiclean_file "$HOME/.bashrc"
+multiclean_file "$HOME/.zshrc"
+multiclean_file "$HOME/.config/fish"
+
+# Otherwise pyenv leaves a lot of functions / variables set in the environment
+# which only get cleared after a shell restart. Ensures we don't have issues
+# if multiple applications are set to be installed
+echo "Cleaning up shell"
+unset 'PROMPT_COMMAND'
+tempPath=$(echo "$PATH" | sed 's|:|\n|g' | grep -v 'pyenv')
+export PATH="$(echo $tempPath | sed 's| |:|g')"
+unset -f 'pyenv'
+unset -f '_pyenv'
+unset -v '_pyenv_virtualenv_hook'
+
+echo "Showing user shell-restart warning"
+whiptail --title "pyenv" --msgbox "Please restart your shell, or 'pyenv not found' will continue to be shown with every command issued" 8 85
+
+}
+
+if show_warning "pyenv" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/rbenv.sh b/pengwin-setup.d/uninstall/rbenv.sh
new file mode 100644
index 00000000..a3f79bac
--- /dev/null
+++ b/pengwin-setup.d/uninstall/rbenv.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+local ruby_conf="/etc/profile.d/rbenv.sh"
+
+echo "Uninstalling rbenv"
+
+rem_dir "$HOME/.rbenv"
+
+echo "Removing PATH modifier..."
+sudo_rem_file "/etc/profile.d/ruby.sh"
+
+# Check if Ruby on RAILS previously installed
+if [[ -d "$HOME/.gem" ]] ; then
+ echo "Ruby on RAILS previously installed"
+ rm -rf "$HOME/.gem"
+
+ echo "Offering nodejs uninstall"
+ if (whiptail --title "rbenv" --yesno "It seems Ruby on RAILS was previously installed, for which nodejs would have been installed. Would you like to uninstall this too?" 8 85) ; then
+ bash $(dirname "$0")/nodejs.sh
+ else
+ echo "... user cancelled"
+ fi
+fi
+
+}
+
+if show_warning "rbenv" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/rclocal.sh b/pengwin-setup.d/uninstall/rclocal.sh
new file mode 100644
index 00000000..e38cd20f
--- /dev/null
+++ b/pengwin-setup.d/uninstall/rclocal.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+echo "Removing rc.local support"
+
+echo "Removing sudoers modifications..."
+sudo_rem_file "/etc/sudoers.d/rclocal"
+
+echo "Removing profile modifications..."
+sudo_rem_file "/etc/profile.d/rclocal.sh"
+
+}
+
+if show_warning "rc.local" "$@" ; then
+ main "$@"
+fi
\ No newline at end of file
diff --git a/pengwin-setup.d/uninstall/rust.sh b/pengwin-setup.d/uninstall/rust.sh
new file mode 100644
index 00000000..0055e755
--- /dev/null
+++ b/pengwin-setup.d/uninstall/rust.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+rust_rgx='^[^#]*\PATH.*/.cargo/bin'
+
+function main()
+{
+
+echo "Uninstalling rust"
+
+rem_dir "$HOME/.rustup"
+rem_dir "$HOME/.cargo"
+
+echo "Removing PATH modifier(s)..."
+sudo_rem_file "/etc/profile.d/rust.sh"
+sudo_rem_file "/etc/fish/conf.d/rust.sh"
+clean_file "$HOME/.profile" "$rust_rgx"
+
+}
+
+if show_warning "rust" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/shell-opts.sh b/pengwin-setup.d/uninstall/shell-opts.sh
new file mode 100644
index 00000000..cefdd57d
--- /dev/null
+++ b/pengwin-setup.d/uninstall/shell-opts.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+# We need to delete everything between 2 instances of this string
+PENGWIN_STRING='### PENGWIN OPTIMISED DEFAULTS'
+
+function main()
+{
+
+echo "Uninstalling readline optimizations"
+
+echo "Cleaning /etc/inputrc"
+if [[ -f "/etc/inputrc" ]] ; then
+ sudo_inclusive_file_clean "/etc/inputrc" "$PENGWIN_STRING"
+else
+ echo "... not found!"
+fi
+
+}
+
+if show_warning "readline optimizations" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/shortcut.sh b/pengwin-setup.d/uninstall/shortcut.sh
new file mode 100644
index 00000000..60a133c2
--- /dev/null
+++ b/pengwin-setup.d/uninstall/shortcut.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+shortcut_path=$(wslpath "$(wslvar -l Programs)")/Pengwin\ Applications
+
+function main()
+{
+
+echo "Uninstalling Pengwin start-menu shortcuts"
+rem_dir "$shortcut_path"
+
+}
+
+if show_warning "Pengwin start-menu shortcuts" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/ssh.sh b/pengwin-setup.d/uninstall/ssh.sh
new file mode 100644
index 00000000..1575e690
--- /dev/null
+++ b/pengwin-setup.d/uninstall/ssh.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+ssh_rgx='^[^#]*\bALL=NOPASSWD: /usr/bin/start-ssh'
+
+function main()
+{
+
+echo "Uninstalling SSH server"
+
+echo "Cleaning sudoers modification..."
+sudo_clean_file "/etc/sudoers" "$ssh_rgx"
+
+sudo_rem_file "/usr/bin/start-ssh"
+sudo_rem_file "/etc/profile.d/start-ssh.sh"
+
+remove_package "ssh"
+
+}
+
+if show_warning "SSH server" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/terraform.sh b/pengwin-setup.d/uninstall/terraform.sh
new file mode 100644
index 00000000..1dc567b1
--- /dev/null
+++ b/pengwin-setup.d/uninstall/terraform.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+terra_rgx='^[^#]*\bcomplete -C /usr/bin/terraform terraform'
+
+function main()
+{
+
+echo "Uninstalling Terraform"
+
+sudo_rem_file "/usr/bin/terraform"
+clean_file "$HOME/.bashrc" "$terra_rgx"
+
+}
+
+if show_warning "Terraform" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/theme.sh b/pengwin-setup.d/uninstall/theme.sh
new file mode 100644
index 00000000..8bd1aa8a
--- /dev/null
+++ b/pengwin-setup.d/uninstall/theme.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+gtk_rgx='s|"windows-10.*"|""|g'
+
+function main()
+{
+
+echo "Uninstalling Windows 10 themes"
+
+sudo_rem_dir "/usr/share/themes/windows-10-dark"
+sudo_rem_dir "/usr/share/themes/windows-10-light"
+sudo_rem_dir "/usr/share/icons/windows-10"
+
+if (whiptail --title "LXAppearance" --yesno "LXAppearance was installed alongside the Windows 10 themes to allow setting of Linux GUI application themes. Would you like to remove this too?" 8 85) ; then
+ remove_package "lxappearance"
+
+ rem_file "$HOME/.gtkrc-2.0"
+
+ echo "Regenerating start-menu entry cache..."
+ bash ${SetupDir}/shortcut.sh --yes
+else
+ echo "User opted to keep LXAppearance installed. Cleaning Win10 theme configurations"
+ sed -i "$HOME/.gtkrc-2.0" -e "$gtk_rgx"
+fi
+
+}
+
+if show_warning "Windows 10 GTK/Qt themes" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/uninstall-common.sh b/pengwin-setup.d/uninstall/uninstall-common.sh
new file mode 100644
index 00000000..67bfbdc3
--- /dev/null
+++ b/pengwin-setup.d/uninstall/uninstall-common.sh
@@ -0,0 +1,276 @@
+#!/bin/bash
+
+source $(dirname "$0")/../common.sh "$@"
+
+function show_warning()
+{
+
+# Usage: show_warning
+local uninstall_item="$1"
+shift 1
+
+echo "Offering user $uninstall_item uninstall"
+if whiptail --title "!! $uninstall_item !!" --yesno "Are you sure you would like to uninstall $uninstall_item?\n\nWhile you can reinstall $uninstall_item from pengwin-setup, any of your own changes to install file(s)/directory(s) will be lost.\n\nSelect 'yes' if you would like to proceed" 14 85 ; then
+ if whiptail --title "!! $uninstall_item !!" --yesno "Are you absolutely sure you'd like to proceed in uninstalling $uninstall_item?" 8 85 ; then
+ echo "User confirmed $uninstall_item uninstall"
+ return
+ fi
+fi
+
+echo "User cancelled $uninstall_item uninstall"
+bash ${SetupDir}/uninstall.sh "$@"
+
+}
+
+function rem_file()
+{
+
+# Usage: remove_file
+echo "Removing file: '$1'"
+if [[ -f "$1" ]] ; then
+ rm -f "$1"
+else
+ echo "... not found!"
+fi
+
+}
+
+
+function rem_dir()
+{
+
+# Usage: remove_dir
+echo "Removing directory: '$1'"
+if [[ -d "$1" ]] ; then
+ rm -rf "$1"
+else
+ echo "... not found!"
+fi
+
+}
+
+function sudo_rem_file()
+{
+
+# Same as above, just with administrative privileges
+echo "Removing file: '$1'"
+if [[ -f "$1" ]] ; then
+ sudo rm -f "$1"
+else
+ echo "... not found!"
+fi
+
+}
+
+function sudo_rem_dir()
+{
+
+# Same as above, just with administrative privileges
+echo "Removing directory: '$1'"
+if [[ -d "$1" ]] ; then
+ sudo rm -rf "$1"
+else
+ echo "... not found!"
+fi
+
+}
+
+function clean_file()
+{
+
+# Usage: clean_file
+
+# Following n (node version manager) install script,
+# best to clean file by writing to memory then
+# writing back to file
+local fileContents
+fileContents=$(grep -Ev "$2" "$1")
+printf '%s\n' "$fileContents" > "$1"
+
+}
+
+function sudo_clean_file()
+{
+
+# Same as above, just with administrative privileges
+local fileContents
+fileContents=$(sudo grep -Ev "$2" "$1")
+sudo bash -c "printf '%s\\n' '$fileContents' > '$1'"
+
+}
+
+function inclusive_file_clean()
+{
+
+# Usage: inclusive_file_clean
+local fileContents
+fileContents=$(sed -e ':a' -e 'N' -e '$!ba' -e "s|$2\\n.*\\n$2||g" "$1")
+cat > "$1" << EOF
+$fileContents
+EOF
+
+}
+
+function sudo_inclusive_file_clean()
+{
+
+# Same as above
+local fileContents
+fileContents=$(sudo sed -e ':a' -e 'N' -e '$!ba' -e "s|$2\\n.*\\n$2||g" "$1")
+sudo bash -c "cat > '$1'" << EOF
+$fileContents
+EOF
+
+}
+
+function remove_package()
+{
+
+# Usage: remove_package
+echo "Removing APT packages: $@"
+local installed
+
+installed=""
+for i in "$@" ; do
+ if (dpkg-query -s "$i" | grep 'installed') > /dev/null 2>&1 ; then
+ installed="$i $installed"
+ else
+ echo "... $i not installed!"
+ fi
+done
+
+if [[ $installed != "" ]] ; then
+ echo "Uninstalling: $installed"
+ sudo apt-get remove -y -q $installed --autoremove
+fi
+
+}
+
+function pip_uninstall()
+{
+
+# Usage: pip_uninstall <2/3>
+local installed=''
+local pip=''
+
+case "$1" in
+ 2)
+ pip='pip2'
+ ;;
+ 3)
+ pip='pip3'
+ ;;
+esac
+shift 1
+
+echo "Removing pip packages: $installed"
+if $pip --version > /dev/null 2>&1 ; then
+ for i in "$@" ; do
+ if ($pip list | grep "$i ") > /dev/null 2>&1 ; then
+ installed="$i $installed"
+ else
+ echo "... $i not installed!"
+ fi
+ done
+
+ $pip uninstall $installed -y
+ return
+fi
+
+echo "... not installed!"
+
+}
+
+function sudo_pip_uninstall()
+{
+
+# Usage: sudo_pip_uninstall <2/3>
+local installed=''
+local pip=''
+
+case "$1" in
+ 2)
+ pip='pip2'
+ ;;
+ 3)
+ pip='pip3'
+ ;;
+esac
+shift 1
+
+echo "Removing pip packages: $installed"
+if $pip --version > /dev/null 2>&1 ; then
+ for i in "$@" ; do
+ if (sudo $pip list | grep "$i ") > /dev/null 2>&1 ; then
+ installed="$i $installed"
+ else
+ echo "... $i not installed!"
+ fi
+ done
+
+ sudo $pip uninstall $installed -y
+ return
+fi
+
+echo "... not installed!"
+
+}
+
+function safe_rem_microsoftgpg()
+{
+
+# Usage: safe_rem_microsoftgpg
+# (no arguments necessary)
+local pkg_list='azure-cli code dotnet powershell'
+
+for i in $pkg_list ; do
+ if (dpkg-query -s "$i" | grep 'installed') > /dev/null 2>&1 ; then
+ echo "$i installed, not safe to remove Microsoft APT key"
+ return
+ fi
+done
+
+# safe to remove!
+sudo_rem_file "/etc/apt/trusted.gpg.d/microsoft.gpg"
+
+}
+
+function safe_rem_microsoftsrc()
+{
+
+# Usage: safe_rem_microsoftsrc
+# (no arguments necessary)
+local pkg_list='dotnet powershell'
+
+# check packages not installed
+for i in $pkg_list ; do
+ if (dpkg-query -s "$i" | grep 'installed') > /dev/null 2>&1 ; then
+ echo "$i installed, not safe to remove Microsoft APT source"
+ return
+ fi
+done
+
+# safe to remove!
+sudo_rem_file "/etc/apt/sources.list.d/microsoft.list"
+
+}
+
+function safe_rem_debianstablesrc()
+{
+
+# Usage: safe_rem_debianstablesrc
+# (no arguments necessary)
+local pkg_list='code dotnet powershell'
+
+# check packages not installed
+for i in $pkg_list ; do
+ if (dpkg-query -s "$i" | grep 'installed') > /dev/null 2>&1 ; then
+ echo "$i installed, not safe to remove Debian stable APT source"
+ return
+ fi
+done
+
+# safe to remove!
+sudo_rem_file "/etc/apt/sources.list.d/stable.list"
+
+}
diff --git a/pengwin-setup.d/uninstall/vcxsrv.sh b/pengwin-setup.d/uninstall/vcxsrv.sh
new file mode 100644
index 00000000..16d3112b
--- /dev/null
+++ b/pengwin-setup.d/uninstall/vcxsrv.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+vcxsrv_dir="$wHome/.vcxsrv"
+
+function main()
+{
+
+local vcxsrv_conf="/etc/profile.d/vcxsrv.sh"
+
+echo "Uninstalling VcxSrv"
+
+echo "Removing $vcxsrv_dir"
+if [[ -d "$vcxsrv_dir" ]] ; then
+ if cmd-exe /C tasklist | grep -Fq 'vcxsrv.exe' ; then
+ echo "vcxsrv.exe running. Killing process..."
+ cmd-exe /C taskkill /IM 'vcxsrv.exe' /F
+ fi
+
+ # now safe to delete
+ rm -rf "$vcxsrv_dir"
+else
+ echo "... not found!"
+fi
+
+echo "Removing PATH modifier..."
+sudo_rem_file "/etc/profile.d/vcxsrv.sh"
+
+}
+
+if show_warning "vcxsrv" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/uninstall/vscode.sh b/pengwin-setup.d/uninstall/vscode.sh
new file mode 100644
index 00000000..bb2bc32d
--- /dev/null
+++ b/pengwin-setup.d/uninstall/vscode.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+source $(dirname "$0")/uninstall-common.sh
+
+function main()
+{
+
+echo "Uninstalling VisualStudio Code"
+
+remove_package "code"
+rem_dir "$HOME/.vscode"
+
+echo "Removing APT source..."
+sudo_rem_file "/etc/apt/sources.list.d/vscode.list"
+
+echo "Removing Microsoft APT key..."
+safe_rem_microsoftgpg
+
+# Undo temporary udev workarounds
+echo "Reverting udev VSCode workarounds"
+sudo apt-mark unhold udev libudev1
+sudo apt-get update
+sudo apt-get install -y -q udev libudev1
+
+echo "Removing Debian stable APT source..."
+safe_rem_debianstablesrc
+
+echo "Regenerating start-menu entry cache..."
+bash ${SetupDir}/shortcut.sh --yes
+
+}
+
+if show_warning "VisualStudio Code" "$@" ; then
+ main "$@"
+fi
diff --git a/pengwin-setup.d/vcxsrv.sh b/pengwin-setup.d/vcxsrv.sh
index 1993c7ff..3e9e6255 100644
--- a/pengwin-setup.d/vcxsrv.sh
+++ b/pengwin-setup.d/vcxsrv.sh
@@ -33,9 +33,7 @@ if (whiptail --title "VCXSRV" --yesno "Would you like to install the VcXsrv X-se
if (whiptail --title "VCXSRV" --yesno "Would you like VcXsrv to be started at Pengwin launch? A startup script will be added to /etc/profile.d" 8 80) then
echo "Configuring VcxSrv to start on Pengwin launch"
sudo bash -c 'cat > /etc/profile.d/vcxsrv.sh' << EOF
-#!/bin/bash
-cmd.exe /C "${wVcxsrvDir}\vcxsrv.exe" :0 -silent-dup-error -multiwindow &> /dev/null &
-disown
+(cmd.exe /C "${wVcxsrvDir}\vcxsrv.exe" :0 -silent-dup-error -multiwindow &> /dev/null &)
EOF
fi
else