diff --git a/alias/apps b/alias/apps
new file mode 100644
index 0000000..1f42f9f
--- /dev/null
+++ b/alias/apps
@@ -0,0 +1,3 @@
+if command -v npm >/dev/null 2>&1; then
+alias gterm="GNOME_TERMINAL_SCREEN='' gnome-terminal"
+fi
\ No newline at end of file
diff --git a/app/awscli b/app/awscli
new file mode 100644
index 0000000..e48e402
--- /dev/null
+++ b/app/awscli
@@ -0,0 +1,39 @@
+#!/bin/bash
+command -v docker >/dev/null 2>&1 || return
+
+aws_docker () {
+local cred
+local profile
+local profile_env
+if [[ $1 == "--cred" ]]; then
+cred=$2
+shift 2
+else
+cred=${HOME}/.aws
+fi
+if [[ $1 == "--profile" ]]; then
+profile=$2
+shift 2
+else
+profile=${AWS_PROFILE}
+fi
+[[ ! $(cat $cred/config 2> /dev/null | grep ${profile}]) ]] && echo no profile ${profile} in $cred/config && return
+[[ $profile ]] && profile_env="--env AWS_PROFILE=${profile}"
+# echo credentials directory $cred
+# echo using profile $profile
+[[ ! -f $cred/credentials ]] && echo no credentails file at $cred/credentails && return
+
+# echo remaining args: $@
+docker run --rm -it -v ${cred}:/root/.aws --env AWS_PAGER="" ${profile_env} -v $(pwd):/aws amazon/aws-cli "$@"
+}
+
+aws_docker-update () {
+docker pull amazon/aws-cli:latest
+}
+
+_alt_=$([[ $(command -v aws >/dev/null 2>&1) ]] || echo d)
+
+alias aws${_alt_}='aws_docker'
+alias aws${_alt_}-update='aws_docker_update'
+
+unset _alt_
diff --git a/app/bashly b/app/bashly
new file mode 100644
index 0000000..417c153
--- /dev/null
+++ b/app/bashly
@@ -0,0 +1,4 @@
+command -v docker >/dev/null 2>&1 || return
+
+alias bashly='docker run --rm -it --volume "$PWD:/app" dannyben/bashly'
+alias bashly-update='docker pull dannyben/bashly:latest'
diff --git a/app/brew b/app/brew
new file mode 100644
index 0000000..08cb2e6
--- /dev/null
+++ b/app/brew
@@ -0,0 +1,2 @@
+[[ -d "/opt/brew" ]] && path_append /opt/brew/bin
+[[ -d /home/linuxbrew/.linuxbrew/bin ]] && path_append /home/linuxbrew/.linuxbrew/bin
diff --git a/lang/go b/lang/go
new file mode 100644
index 0000000..5618995
--- /dev/null
+++ b/lang/go
@@ -0,0 +1,8 @@
+
+
+# --- Go Language Environment BEGIN ---
+export GOROOT=/opt/go
+export PATH=$PATH:/opt/go/bin
+export GOPATH=/opt/go/apps
+export PATH=$PATH:/opt/go/apps/bin
+# --- Go Language Environment END ---
diff --git a/lang/node/node b/lang/node/node
new file mode 100644
index 0000000..021c6f0
--- /dev/null
+++ b/lang/node/node
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+if command -v npm >/dev/null 2>&1; then
+
+path_append ./node_modules/.bin
+# load in any node functions
+module_load node
+
+fi
diff --git a/lang/node/npm b/lang/node/npm
new file mode 100644
index 0000000..b475a2f
--- /dev/null
+++ b/lang/node/npm
@@ -0,0 +1,57 @@
+#!/bin/bash
+
+if command -v npm >/dev/null 2>&1; then
+# echo addding node langauge stuff
+# gives access to packages with bin in a project
+path_append ./node_modules/.bin
+export NPM_REGISTRY=https://npm.kebler.net
+alias nr="npm run"
+alias nrs="npm -s run"
+alias nt="npm -s test"
+alias ntw="npm -s run testw"
+alias npms="npm start"
+alias npmlag="npm la --silent --depth=0 --global"
+alias npmla="npm la --silent --depth=0"
+alias npmlaf="npm la --silent | grep"
+alias npmlsf="npm ls --silent grep"
+alias npmlsa="npm ls --silent"
+alias npmls="npm ls --silent --depth=0"
+# just npm install for install without saving into package.json
+alias npmi="npm install --save"
+alias npmr="npm uninstall --save"
+alias npmio="npm install --save-optional"
+alias npmro="npm uninstall --save-optional"
+alias npmidv="npm install --save-dev"
+alias npmidvnd="npm install --save-dev --package-lock-only --no-package-lock"
+alias npmrdv="npm uninstall --save-dev"
+# global for nodejs apps, will be alt directory if npmrc prefix is set
+alias npmlsg="npm ls --silent --depth=0 --global"
+alias npmig="npm install -g"
+alias npmrg="npm uninstall -g"
+# global forced in sudo system location /usr
+alias snpmig="sudo npm install -g --prefix /usr"
+alias snpmlsg="sudo npm ls --silent --depth=0 --global --prefix /usr"
+alias snpmrg="sudo npm uninstall -g --prefix /usr"
+alias npmunpm="echo npm installed version && npm --version && echo npm latest version available && npm view npm@latest version && echo any key to continue npm upgrade or break && read && sudo npm install -g npm@latest"
+alias npmua="npm --depth=9999 update"
+alias npmug="npm update -g"
+alias npmu="npm-check -u"
+alias npmcc="ncu -p -a -u"
+alias npmcdvc="ncu -d -a -u"
+alias npmc="ncu -p"
+alias npma="npm-add-dependencies"
+# will publish to whichever is the default registry - confusing so commented out
+# alias npmpub="npm publish --access public"
+alias npmlrepub="npm publish --registry http://localhost:4873 --force --access restricted"
+alias npmlpub="npm publish --registry http://localhost:4873 --access restricted"
+alias npmkrepub="npm publish --registry https://npm.kebler.net --force --access restricted"
+alias npmkpub="npm publish --registry https://npm.kebler.net --access restricted"
+alias npmpatch="npm version patch"
+alias npmmajor="npm version major"
+alias npmminor="npm version minor"
+alias npmjspub="npm publish --registry https://registry.npmjs.org --access public"
+alias yalcpush="nodemon -x 'yalc push'"
+
+# else
+ # echo "node not installed, npm aliases not loaded"
+fi
diff --git a/lang/node/pm2 b/lang/node/pm2
new file mode 100644
index 0000000..4f69392
--- /dev/null
+++ b/lang/node/pm2
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+if command -v pm2 >/dev/null 2>&1; then
+
+alias pmi="sudo pm2 install"
+alias pms="sudo pm2 start"
+alias pmstp="sudo pm2 stop"
+alias pmr="sudo pm2 delete"
+alias pmra="sudo pm2 delete all"
+alias pmstpa="sudo pm2 stop all"
+alias pmv="sudo pm2 save"
+alias pml="sudo pm2 list"
+alias pmm="sudo pm2 monit"
+
+fi
\ No newline at end of file
diff --git a/lang/node/yarn b/lang/node/yarn
new file mode 100644
index 0000000..ec3389e
--- /dev/null
+++ b/lang/node/yarn
@@ -0,0 +1,24 @@
+#!/bin/bash
+if command -v yarn >/dev/null 2>&1; then
+
+alias ycc="yarn cache clean"
+alias yr="yarn run"
+alias ys="yarn run start"
+alias ya="yarn add"
+# alias yu="yarn upgrade"
+alias yrm="yarn remove"
+alias yao="yarn add --optional"
+alias yad="yarn add --dev"
+alias yl="yarn list --depth=0"
+alias ylp="yarn list --depth=0 --pattern"
+alias yu="yarn upgrade-interactive"
+
+alias ylg="yarn global list --depth=0"
+alias ylgp="yarn global list --depth=0 --pattern"
+alias yag="yarn global add"
+alias yrg="yarn global remove"
+alias yug="yarn global upgrade-interactive"
+
+alias ypub="yarn publish --access public"
+
+fi
\ No newline at end of file
diff --git a/lang/python b/lang/python
new file mode 100644
index 0000000..83fa512
--- /dev/null
+++ b/lang/python
@@ -0,0 +1,58 @@
+#!/bin/bash
+
+
+use_pyenv() {
+ if command -v pyenv >/dev/null 2>&1; then
+ export PYENV_ROOT="/opt/python/pyenv"
+ export PYENV_VERSION=${PYENV_VERSION:-3.8.7}
+ eval "$(pyenv init -)"
+ eval "$(pyenv virtualenv-init -)"
+ fi
+}
+
+if command -v python3 >/dev/null 2>&1; then
+
+# TODO make alias generating function for versions of python
+alias python3x="sudo -H python3 -m"
+alias spip="sudo -H python3 -m pip"
+alias spipi="sudo -H python3 -m pip install"
+alias spipiu="sudo -H python3 -m pip install -U"
+alias spipl="sudo -H python3 -m pip list"
+alias spiplo="sudo -H python3 -m pip list --outdated"
+alias pip3="sudo -H python3 -m pip"
+
+path_append "/opt/python/bin"
+
+spipua() {
+ module_load confirm
+ echo upgrading all base python packages - requires sudo access
+ # sudo -H python3.8 -m pip list --outdated
+ local List
+ local Ver=${1:-3.8}
+ List="$(sudo -H python$Ver -m pip list -o --format columns)"
+ echo "$List"
+ confirm "ATTENTION: upgrade all these packages at once??" || return 0
+ echo "$List" | cut -d' ' -f1 | xargs -n1 sudo -H python$Ver -m pip install -U
+}
+
+fi
+
+if command -v pipx >/dev/null 2>&1; then
+ path_append "/opt/python/apps/bin"
+ export PIPX_HOME=/opt/python/apps
+ export PIPX_BIN_DIR=$PIPX_HOME/bin
+
+ alias pipu="pipx upgrade"
+ alias pipua="pipx upgrade-all"
+ alias pipupip="pipx upgrade pipx"
+ alias pipi="pipx install"
+ alias pipr="pipx uninstall"
+ alias pipl="pipx list"
+ alias piplv="pipx list --verbose"
+
+fi
+
+[[ $USE_PYENV ]] && use_pyenv
+
+
+
diff --git a/modules/bind-mount/bind-mount.inst b/modules/bind-mount/bind-mount.inst
new file mode 100755
index 0000000..09ea24a
--- /dev/null
+++ b/modules/bind-mount/bind-mount.inst
@@ -0,0 +1,7 @@
+DIR="$(cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
+BIN=${1:-/opt/bin/bmount}
+ln -s $DIR/bind-mount.sh $BIN
+sudo chown root:sudo $DIR/bind-mount.sh
+sudo chmod 771 $DIR/bind-mount.sh
+echo "%users $HOSTNAME=(ALL) NOPASSWD:SETENV: /bin/bash $BIN" | sudo tee /etc/sudoers.d/bmount
+sudo chmod 440 /etc/sudoers.d/bmount
diff --git a/modules/bind-mount/bind-mount.sh b/modules/bind-mount/bind-mount.sh
new file mode 100755
index 0000000..6bd0bdb
--- /dev/null
+++ b/modules/bind-mount/bind-mount.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# must have fuser and bindfs installed
+# for use by sudoers
+# ln -s $BASH_SHELL_HOST/all/modules/bind-mount/bind-mount.sh /opt/bin/bmount
+# function xxbmount () {
+# if [ "$1" == "-mp" ]; then
+# MOUNTED=$(mountpoint "$2" | grep not)
+# if [ -z "$MOUNTED" ]; then
+# echo $2 is a mount point so bind mounting $2/$3 to $4
+# notify-send "bind mounting ${2}/${3} to ${4}" --icon=dialog-information -t 2000
+# bindfs "$2/$3" "$4"
+# else
+# notify-send "${2} not a mount point - Unable to bind mount ${2}/${3} to ${4}" --icon=dialog-error -t 2000
+# fi
+# else
+# echo bind mounting $1 to $2
+# notify-send "bind mounting ${1} to ${2}" --icon=dialog-information -t 2000
+# bindfs "$1" "$2"
+# fi
+# }
+
+function bumount {
+ echo "removing bind mount at $1"
+ notify-send "removing bind mount at ${1}" --icon=dialog-information -t 2000
+ fusermount -u "$1"
+}
+
+function bmount {
+ if [ "$1" == "-d" ]; then
+ bumount $2
+ else
+ # if [[ " ${array[@]} " =~ " ${value} " ]]; then
+ # # whatever you want to do when array contains value
+ # fi
+ # mp="${@: -2}"
+ echo mounting $@
+ bindfs $@
+ fi
+}
+
+# if script was executed then call the function
+(return 0 2>/dev/null) || bmount $@
\ No newline at end of file
diff --git a/modules/chromium/chromium copy.sh b/modules/chromium/chromium copy.sh
new file mode 100755
index 0000000..5565d47
--- /dev/null
+++ b/modules/chromium/chromium copy.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+
+# user to start MUST be first in arguments
+# if not supplied then will use default
+chromium_() {
+ local DEFAULT=/opt/chromium
+ # local DEFAULT="$HOME/.local/share/chromium"
+ local exe="/usr/bin/chromium"
+ if [[ ! -f $exe ]]; then
+ echo deb chromium not installed, checking for flatpak version
+ flatpak=$(flatpak info com.github.Eloston.UngoogledChromium | grep error:)
+ if [[ $flatpak ]]; then
+ echo no flatpak version either - exiting && return 1
+ else
+ flatpak=true
+ exe="/usr/bin/flatpak run --branch=stable --arch=x86_64 --filesystem=
--command=/app/bin/chromium --file-forwarding com.github.Eloston.UngoogledChromium @@u"
+ fi
+ fi
+ # an instance gets it's own directory
+ local instance=${CHROMIUM_INSTANCE}
+ [[ $1 && (! $1 == -*) ]] && instance=$1 && shift
+ [[ $1 && (! $1 == -*) ]] && url=$1 && shift
+ if [[ $instance =~ http[s]?:\/\/ ]]; then
+ url=$instance
+ instance=""
+ if [[ $url =~ ^-+ ]]; then
+ url=""
+ set -- "$@" $url
+ url=""
+ fi
+ fi
+
+ local dir
+ if [[ ! $instance ]]; then
+ unset CHROME_CONFIG_HOME
+ $HOME/.config/chromium
+ dir=$HOME/.config/chromium
+ exe="${exe//$dir}"
+ echo starting chromium for $USER in
+ else
+ [[ $instance == "incognito" ]] && set -- "$@" "-incognito"
+ dir=${CHROMIUM_HOME:-$DEFAULT}/$instance
+ exe="${exe//$dir}"
+ fi
+ echo $exe $@ --user-data-dir=$dir $url $([[ $flatpak ]] && echo "@@")
+
+}
+
+# # if script was executed then call the function
+(return 0 2>/dev/null) || chromium_ $@
diff --git a/modules/chromium/chromium-install.sh b/modules/chromium/chromium-install.sh
new file mode 100755
index 0000000..05555d3
--- /dev/null
+++ b/modules/chromium/chromium-install.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+function chromium_install {
+
+source $BASH_SHELL_BASE/module.lib
+module_load helpers
+NAME="chromium"
+DIR=$(adirname "$0")
+BIN=${1:-/opt/bin/$NAME}
+# [[ $(chown :users $DIR/$NAME.sh) ]] || sudo chown :users $DIR/$NAME.sh
+[[ $(chmod 755 $DIR/$NAME.sh) ]] || sudo chmod 755 $DIR/$NAME.sh
+ln -sf $DIR/$NAME.sh $BIN
+echo link created
+ls -la /opt/bin | grep chromium
+echo with permissions
+ls -la $DIR | grep chromium.sh
+}
+
+# if script was executed then call the function
+(return 0 2>/dev/null) || chromium_install $@
diff --git a/modules/chromium/chromium.sh b/modules/chromium/chromium.sh
new file mode 100755
index 0000000..975ac59
--- /dev/null
+++ b/modules/chromium/chromium.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+# user to start MUST be first in arguments
+# if not supplied then will use default
+chromium_() {
+ local DEFAULT=/opt/chromium
+ local DEFAULT_USER=$HOME/.browsers
+ # local DEFAULT="$HOME/.local/share/chromium"
+ local exe="/usr/bin/chromium"
+
+ if [[ $1 == "-version" ]]; then
+ $exe -version
+ return
+ fi
+
+ [[ $1 == -g ]] && exe=$(command -v google-chrome) && shift
+ echo execuatble to be used: $exe
+ if [[ ! -f $exe ]]; then
+ echo chromium/chrome not installed, checking for flatpak version
+ flatpak=$(flatpak info com.github.Eloston.UngoogledChromium | grep error:)
+ if [[ $flatpak ]]; then
+ echo no flatpak version either - exiting
+ return 1
+ else
+ flatpak=true
+ exe="/usr/bin/flatpak run --branch=stable --arch=x86_64 --filesystem= --command=/app/bin/chromium --file-forwarding com.github.Eloston.UngoogledChromium @@u"
+ fi
+ fi
+
+ local instance=${CHROMIUM_INSTANCE}
+ [[ $1 && (! $1 == -*) ]] && instance=$1 && shift
+ [[ $1 && (! $1 == -*) ]] && url=$1 && shift
+ if [[ $instance =~ http[s]?:\/\/ ]]; then
+ url=$instance
+ instance=""
+ if [[ $url =~ ^-+ ]]; then
+ url=""
+ set -- "$@" $url
+ url=""
+ fi
+ fi
+
+ local dir
+ if [[ ! $instance ]]; then
+ unset CHROME_CONFIG_HOME
+ $HOME/.config/chromium
+ echo starting chromium for $USER in
+ dir=$HOME/.config/chromium
+ exe="${exe//$dir}"
+ else
+ [[ $instance == "incognito" ]] && set -- "$@" "-incognito"
+ dir=${DEFAULT_USER}/$instance
+ dir=$([[ -d "$dir" ]] && echo $dir || echo "${CHROMIUM_HOME:-$DEFAULT}/$instance")
+ exe="${exe//$dir}"
+ fi
+ mkdir -p $dir
+ echo $exe $@ --user-data-dir=$dir $url $([[ $flatpak ]] && echo "@@")
+ $exe $@ --user-data-dir=$dir $url $([[ $flatpak ]] && echo "@@")
+
+}
+
+# # if script was executed then call the function
+(return 0 2>/dev/null) || chromium_ $@
diff --git a/modules/chromium/ungoogled-install.sh b/modules/chromium/ungoogled-install.sh
new file mode 100755
index 0000000..3f7f29e
--- /dev/null
+++ b/modules/chromium/ungoogled-install.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+ungoogled_install() {
+ module_load confirm
+ module_load helpers
+
+ SDIR=$(adirname ${1:-$(dirname ${BASH_SOURCE[0]})})
+
+ if [[ ! $(which lastversion) ]]; then
+ echo lastversion is not installed
+ echo it is a required dependency for this script
+ echo see https://github.com/dvershinin/lastversion
+ return
+ fi
+
+ CUR_VERSION=$( /usr/bin/chromium -version | grep -oP '(?<=Chromium )[^ ]*')
+
+ _repo="Eloston/ungoogled-chromium-binaries"
+
+ NEW_VERSION=$(lastversion ${_repo})
+
+ echo "Ungoogled: Current Version : $CUR_VERSION => New Version: $NEW_VERSION"
+
+ [[ $NEW_VERSION = $CUR_VERSION ]] && [[ ! ${1} == "-f" ]] && echo Latest version is already installed
+
+ _temp=/tmp/ungoogled_chromium
+ echo $_temp to download deb and install
+ mkdir -p $_temp || exit &> /dev/null
+ pushd $_temp &> /dev/null || exit
+
+ echo downloading common deb
+ lastversion ${_repo} --format assets --filter common_ -d common.deb
+ lastversion ${_repo} --format assets --filter mium_.+amd64.deb -d chromium.deb
+ echo installing common libraries
+ sudo dpkg -i common.deb
+ echo installing ungoogled-chromium
+ sudo dpkg -i chromium.deb
+
+ echo done installing, removing $_temp
+ rm -r $_temp &> /dev/null || true
+
+ popd >/dev/null
+
+confirm "do you want to install WidevineCDM for digital streaming rights?"
+if [ $? -eq 0 ]; then
+ module_load widevine-install
+ widevine_install
+fi
+
+confirm "do you want to install the uci chromium start script in /opt/bin ?"
+if [ $? -eq 0 ]; then
+ module_load chromium-install
+ chromium_install
+fi
+
+
+}
+
+# # if script was executed then call the function
+(return 0 2>/dev/null) || ungoogled_install $@
diff --git a/modules/chromium/widevine-install.sh b/modules/chromium/widevine-install.sh
new file mode 100755
index 0000000..4ebbb40
--- /dev/null
+++ b/modules/chromium/widevine-install.sh
@@ -0,0 +1,71 @@
+#!/bin/bash
+# -eux
+function confirm()
+{
+ echo -n "$@ "
+ read -e answer
+ for response in y Y yes YES Yes Sure sure SURE OK ok Ok
+ do
+ if [ "_$answer" == "_$response" ]
+ then
+ return 0
+ fi
+ done
+
+ # Any answer other than the list above is considered a "no" answer
+ return 1
+}
+
+function widevine_install {
+
+_chrome_ver=$( /usr/bin/chromium -version | grep -oP '(?<=Chromium )[^ ]*')
+
+_l_target_dir=~/.local/lib/WidevineCdm
+_target_dir=/usr/lib/chromium/WidevineCdm
+_sudo="sudo"
+
+if [[ "${1}" == "-l" ]]; then
+ _sudo=""
+ _target_dir=$_l_target_dir
+ shift
+fi
+
+echo "install widevineCDM for chromium version $_chrome_ver"
+echo "into $_target_dir"
+
+confirm "confirm (y/n)" || exit
+
+_temp=/tmp/chromium_widevine
+echo using $_temp to download deb and extract widevine
+mkdir -p $_temp || exit &> /dev/null
+pushd $_temp &> /dev/null || exit
+
+# Download deb, which has corresponding Widevine version
+# Support resuming partially downloaded (or skipping re-download) with -c flag
+if [[ "${1}" == "-u" ]]; then
+ _un="un"
+fi
+_url=https://dl.google.com/linux/deb/pool/main/g/google-chrome-${_un}stable/google-chrome-${_un}stable_${_chrome_ver}-1_amd64.deb
+echo downloading $_url
+
+wget -c $_url || exit
+
+# Unpack deb
+rm -r unpack_deb &> /dev/null || true
+mkdir -p unpack_deb
+echo extracting package...
+dpkg-deb -R google-chrome-stable_${_chrome_ver}-1_amd64.deb unpack_deb || exit
+echo removing any old WidevineCDM installs at $_target_dir
+$_sudo rm -r $_target_dir &> /dev/null || true
+echo moving WidevineCDM to target $_target_dir
+$_sudo mv unpack_deb/opt/google/chrome/WidevineCdm $_target_dir &> /dev/null || exit
+[[ $_sudo ]] && $_sudo chown -R root:root $_target_dir
+echo done, removing $_temp
+rm -r $_temp &> /dev/null || true
+popd &> /dev/null
+
+}
+
+# if script was executed then call the function
+(return 0 2>/dev/null) || widevine_install $@
+
diff --git a/modules/chromium/widevine.inst b/modules/chromium/widevine.inst
new file mode 100755
index 0000000..169c45e
--- /dev/null
+++ b/modules/chromium/widevine.inst
@@ -0,0 +1,66 @@
+#!/bin/bash
+# -eux
+function confirm()
+{
+ echo -n "$@ "
+ read -e answer
+ for response in y Y yes YES Yes Sure sure SURE OK ok Ok
+ do
+ if [ "_$answer" == "_$response" ]
+ then
+ return 0
+ fi
+ done
+
+ # Any answer other than the list above is considered a "no" answer
+ return 1
+}
+
+
+_chrome_ver=$( /usr/bin/chromium -version | grep -oP '(?<=Chromium )[^ ]*')
+
+_l_target_dir=~/.local/lib/WidevineCdm
+_target_dir=/usr/lib/chromium/WidevineCdm
+_sudo="sudo"
+
+if [[ "${1}" == "-l" ]]; then
+ _sudo=""
+ _target_dir=$_l_target_dir
+ shift
+fi
+
+echo "install widevineCDM for chromium version $_chrome_ver"
+echo "into $_target_dir"
+
+confirm "confirm (y/n)" || exit
+
+_temp=/tmp/chromium_widevine
+echo using $_temp to download deb and extract widevine
+mkdir -p $_temp || exit &> /dev/null
+pushd $_temp &> /dev/null || exit
+
+# Download deb, which has corresponding Widevine version
+# Support resuming partially downloaded (or skipping re-download) with -c flag
+if [[ "${1}" == "-u" ]]; then
+ _un="un"
+fi
+_url=https://dl.google.com/linux/deb/pool/main/g/google-chrome-${_un}stable/google-chrome-${_un}stable_${_chrome_ver}-1_amd64.deb
+echo downloading $_url
+
+wget -c $_url || exit
+
+# Unpack deb
+rm -r unpack_deb &> /dev/null || true
+mkdir -p unpack_deb
+echo extracting package...
+dpkg-deb -R google-chrome-stable_${_chrome_ver}-1_amd64.deb unpack_deb || exit
+echo removing any old WidevineCDM installs at $_target_dir
+$_sudo rm -r $_target_dir &> /dev/null || true
+echo moving WidevineCDM to target $_target_dir
+$_sudo mv unpack_deb/opt/google/chrome/WidevineCdm $_target_dir &> /dev/null || exit
+[[ $_sudo ]] && $_sudo chown -R root:root $_target_dir
+echo done, removing $_temp
+rm -r $_temp &> /dev/null || true
+popd &> /dev/null
+
+
diff --git a/modules/chromium/widevine.sh b/modules/chromium/widevine.sh
new file mode 100755
index 0000000..a11c4f7
--- /dev/null
+++ b/modules/chromium/widevine.sh
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+# https://raw.githubusercontent.com/flathub/com.github.Eloston.UngoogledChromium/master/widevine-install.sh
+# https://github.com/flathub/com.github.Eloston.UngoogledChromium
+# Exit on error and forbid unset variables
+set -eu
+
+# Get latest WideVine Version by getting last line in https://dl.google.com/widevine-cdm/versions.txt
+_widevine_ver="$(wget -qO- https://dl.google.com/widevine-cdm/versions.txt | tail -n1)"
+
+# Get the architecture of the current machine
+ARCH="$(uname -m)"
+case "$ARCH" in
+x86_64)
+ WIDEVINE_ARCH="x64"
+ CHROMIUM_ARCH="x64"
+ ;;
+
+*)
+ echo "The architecture $ARCH is not supported." >&2
+ exit 1
+ ;;
+esac
+
+# Download WideVine into a temporary file and use trap to delete it on exit
+widevine_zip="$(mktemp)"
+trap 'rm -f "${widevine_zip:?}"' EXIT
+wget -O "$widevine_zip" "https://dl.google.com/widevine-cdm/${_widevine_ver}-linux-${WIDEVINE_ARCH}.zip"
+
+# Install WideVine from zip file into UngoogledChromium flatpak
+_install_prefix="/opt/chromium/$1/WidevineCdm/${_widevine_ver}"
+unzip -p "$widevine_zip" libwidevinecdm.so | install -Dm644 "/dev/stdin" "${_install_prefix}/_platform_specific/linux_$CHROMIUM_ARCH/libwidevinecdm.so"
+unzip -p "$widevine_zip" manifest.json | install -m644 "/dev/stdin" "${_install_prefix}/manifest.json"
+unzip -p "$widevine_zip" LICENSE.txt | install -m644 "/dev/stdin" "${_install_prefix}/LICENSE.txt"
diff --git a/modules/install/tools/golang-install.func b/modules/install/tools/golang-install.func
new file mode 100755
index 0000000..7ddf556
--- /dev/null
+++ b/modules/install/tools/golang-install.func
@@ -0,0 +1,227 @@
+#!/bin/bash
+# shellcheck disable=SC2016
+# set -e
+
+ # golang_install remove
+ # golang_ install -e m
+
+function get_platform () {
+
+ local OS
+ local ARCH
+ local PLATFORM
+
+ OS="$(uname -s)"
+ ARCH="$(uname -m)"
+
+ case $OS in
+ "Linux")
+ case $ARCH in
+ "x86_64")
+ ARCH=amd64
+ ;;
+ "aarch64")
+ ARCH=arm64
+ ;;
+ "armv6")
+ ARCH=armv6l
+ ;;
+ "armv8")
+ ARCH=arm64
+ ;;
+ .*386.*)
+ ARCH=386
+ ;;
+ esac
+ PLATFORM="linux-$ARCH"
+ ;;
+ "Darwin")
+ PLATFORM="darwin-amd64"
+ ;;
+ esac
+
+ echo $PLATFORM
+}
+
+golang_install () {
+
+## START INSTALL
+PLATFORM=$(get_platform)
+if [ -z "$PLATFORM" ]; then
+ echo "Your operating system is not supported by this install script."
+ return 1
+fi
+
+module_load block
+[ ! "$(module_loaded block)" ] && echo unable to load block module, exiting && return 1
+module_load confirm
+
+declare ENV_TYPE="u" # Which shell repo for the block
+declare ENV_FILE # override shell repo location
+# u=user h=host n=network b=base
+# by default it is installed in userspace
+# local versions of these
+declare goroot
+declare gopath
+local force
+
+declare OPTION
+declare OPTARG
+declare OPTIND
+
+while getopts 're:f:r:p:' OPTION; do
+ # echo $OPTION $OPTARG
+ case "$OPTION" in
+ r)
+ force=true
+ ;;
+ f)
+ ENV_FILE=$OPTARG
+ echo explicing setting block to $ENV_FILE
+ ;;
+ e)
+ ENV_TYPE=$OPTARG
+ echo
+ ;;
+ r)
+ goroot=$OPTARG
+ echo setting root $goroot
+ ;;
+ p)
+ gopath=$OPTARG
+ echo setting path $gopath
+ ;;
+ *)
+ echo unknown option $OPTION
+ ;;
+ esac
+done
+
+shift $(( OPTIND - 1 ))
+
+if [[ ! $ENV_FILE ]]; then
+ FILE=lang/go
+ case $ENV_TYPE in
+ # h=host m=machine n=network b=base
+ "h")
+ [[ -d $BASH_SHELL_HOST/$(hostname) ]] && ENV_FILE=$BASH_SHELL_HOST/$(hostname)/$FILE
+ ;&
+ "m")
+ [[ -d $BASH_SHELL_HOST/all ]] && ENV_FILE=$BASH_SHELL_HOST/all/$FILE
+ ;&
+ "n")
+ ([[ -d $BASH_SHELL_NETWORK/$NETWORKNAME ]] && [[ ! $ENV_FILE ]]) && ENV_FILE=$BASH_SHELL_NETWORK/$NETWORKNAME/$FILE
+ ;&
+ "b")
+ ([[ -d $BASH_SHELL_BASE ]] && [[ ! $ENV_FILE ]]) && ENV_FILE=$BASH_SHELL_BASE/$FILE
+ ;;
+ esac
+ [[ ! $ENV_FILE ]] && ENV_FILE=$HOME/.bashrc # default is userspace
+ ENV_TYPE="u"
+fi
+
+if [[ ! $goroot ]]; then
+ goroot=$GOROOT
+ if [[ ! $goroot ]]; then
+ [[ $ENV_TYPE = "u" ]] && goroot="$HOME/go" || goroot="/opt/go"
+ fi
+fi
+
+if [[ ! $gopath ]]; then
+ gopath=$GOPATH
+ if [[ ! $gopath ]]; then
+ [[ $ENV_TYPE = "u" ]] && gopath="$HOME/go/apps" || gopath="/opt/go/apps"
+ fi
+fi
+
+echo --- go environment settings are -----
+echo GOROOT: $goroot
+echo GOPATH: $gopath
+echo ---------------------------------------
+
+goenv=('export GOROOT='"$goroot"'\n'
+'export PATH=$PATH:'"$goroot"'/bin\n'
+'export GOPATH='"$gopath"'\n'
+'export PATH=$PATH:'"$gopath"'/bin')
+
+echo ==== envionrment block is ====
+printf "${goenv[*]}\n"
+echo =========================================
+echo environment block file is $ENV_FILE
+confirm Do you want to continue || return 1
+
+set_block -f $ENV_FILE -n "Go Language Environment"
+
+if [[ $1 = remove ]]; then
+ confirm Do you really want to remove the go installation? || return 1
+ remove_block
+ confirm Delete directory $gopath??? && rm -rf $gopath
+ confirm Delete directory $goroot??? && rm -rf $goroot
+ return 1
+fi
+
+ # the github api doesn't show any release records to had to grab this way
+VERSION=$(echo "$(wget -qO- https://github.com/golang/go/tags)" | sed -e 's/<[^>]*>//g'| sed '/^\s*$/d'| grep release-branch| awk '{ print $2 }'|grep -v runtime|sort -V|tail -1|cut -c 3-)
+if [[ $(which go) ]]; then
+ INSTALLED_VERSION=$(echo $(go version)| awk '{print $3}' | cut -c 3-)
+ # INSTALLED_VERSION=1.15.2 # this is for testing, comment out for production
+ echo installed: $INSTALLED_VERSION available: $VERSION
+ if [ "$INSTALLED_VERSION" == "$VERSION" ]; then
+ if [[ ! $force ]]; then
+ echo Installed Version $INSTALLED_VERSION is current nothing to do, exiting
+ echo use -r flag to force reinstall
+ return 2
+ fi
+ fi
+fi
+
+if [ -d "$goroot" ]; then
+ echo "The Go install directory ($goroot) already exists. "
+ confirm Do you want to upgrade to $VERSION? || return 0
+fi
+
+echo installing version $VERSION ......
+
+PACKAGE_NAME="go$VERSION.$PLATFORM.tar.gz"
+TEMP_DIRECTORY=$(mktemp -d)
+
+echo "Downloading $PACKAGE_NAME ..."
+if hash wget 2>/dev/null; then
+ wget https://storage.googleapis.com/golang/$PACKAGE_NAME -O "$TEMP_DIRECTORY/go.tar.gz"
+else
+ curl -o "$TEMP_DIRECTORY/go.tar.gz" https://storage.googleapis.com/golang/$PACKAGE_NAME
+fi
+
+if [ $? -ne 0 ]; then
+ echo "Download failed! Exiting."
+ return 1
+fi
+
+echo "Extracting File..."
+mkdir -p "$goroot"
+# TODO set correct permissions here if necessary
+
+sudo tar -C "$goroot" --strip-components=1 -xzf "$TEMP_DIRECTORY/go.tar.gz"
+
+
+echo done installing go binary and support files
+rm -rf $TEMP_DIRECTORY
+echo making go workspace directories
+
+mkdir -p "${gopath}/"{src,pkg,bin}
+# TODO set correct permission if all have access
+
+echo "Configuring GO environment in: $ENV_FILE"
+
+mkdir -p "$(dirname $ENV_FILE)"
+touch "$ENV_FILE"
+add_block
+block_add_line "${goenv[*]}"
+# echo ---------contents of $ENV_FILE------------------
+# cat $ENV_FILE
+# echo ------------------------------------------------
+
+echo -e "\nGo $VERSION was installed into $goroot.\n(re)start a new shell environment to take effect"
+echo NOTE: all files have root:root user:group, run a chown/chmod/setfacl commands if need be
+return 0
+}
diff --git a/modules/install/tools/hugo-install.func b/modules/install/tools/hugo-install.func
new file mode 100755
index 0000000..958ef61
--- /dev/null
+++ b/modules/install/tools/hugo-install.func
@@ -0,0 +1,142 @@
+#!/bin/bash
+
+hugo_install() {
+ # inspried from this forum post https://discourse.gohugo.io/t/script-to-install-latest-hugo-release-on-macos-and-ubuntu/14774/10
+ # if you have run into github api anonymous access limits which happens during debugging/dev then add user and token here or sourced from a separate file
+ # . ~/githubapitoken
+ #GITHUB_USER=""
+ #GITHUB_TOKEN=""
+
+ if [ "$GITHUB_TOKEN" != "" ]; then
+ echo using access token with script
+ echo $GITHUB_USER $GITHUB_TOKEN
+ fi
+
+ EXTENDED=false
+ FORCE=false
+ EFILE=""
+
+ # options
+ # e - download and install the extended version
+ # c - use 'hugoe' as the install command for extended version otherwise 'hugo' will launch extended version
+ # f - force download/overwrite of same version
+
+ declare OPTION
+ declare OPTARG
+ declare OPTIND
+
+ while getopts 'ecf' OPTION; do
+ case "$OPTION" in
+ e)
+ echo "installing extended hugo"
+ EXTENDED=true
+ ;;
+ c)
+ if [ $EXTENDED = true ]; then
+ EFILE="e"
+ echo using hugoe for extended command
+ fi
+ ;;
+ f)
+ echo "FORCING download/overwrite"
+ FORCE=true
+ ;;
+ esac
+ done
+
+ shift $((OPTIND - 1))
+
+ DEFAULT_BIN_DIR="/usr/local/bin"
+ # Single optional argument is directory in which to install hugo
+ BIN_DIR=${1:-"$DEFAULT_BIN_DIR"}
+
+ BIN_PATH="$(which hugo$EFILE)"
+ declare -A ARCHES
+ ARCHES=(["arm64"]="ARM64" ["aarch64"]="ARM64" ["x86_64"]="64bit" ["arm32"]="ARM" ["armhf"]="ARM")
+ ARCH=$(arch)
+
+ if [ -z "${ARCHES[$ARCH]}" ]; then
+ echo Your machine kernel architecture $ARCH is not supported by this script, aborting
+ exit 1
+ fi
+
+ INSTALLED="$(hugo$EFILE version 2>/dev/null | cut -d'v' -f2 | cut -c 1-6)"
+ CUR_VERSION=${INSTALLED:-"None"}
+ # echo $(curl -u $GITHUB_USER:$GITHUB_TOKEN -s https://api.github.com/repos/gohugoio/hugo/releases/latest | grep tag_name)
+ # NEW_VERSION="$(curl -u $GITHUB_USER:$GITHUB_TOKEN -s https://api.github.com/repos/gohugoio/hugo/releases/latest \
+ # | grep tag_name \
+ # | cut -d'v' -f2 | cut -c 1-6)"
+
+ NEW_VERSION=$(lastversion hugo)
+
+ echo "Hugo $([ $EXTENDED == true ] && echo "Extended"): Current Version : $CUR_VERSION => New Version: $NEW_VERSION"
+
+ # if [ -z "$NEW_VERSION" ]; then
+ # echo Unable to retrieve new version number - Likely you have reached github anonymous limit
+ # echo set environment variable $($GITHUB_USER) and $($GITHUB_TOKEN) and try again
+ # exit 1
+ # fi
+
+ [[ $NEW_VERSION = $CUR_VERSION ]] && [[ $FORCE = false ]] && echo Latest version already installed at $BIN_PATH && return 0
+
+ pushd /tmp/ >/dev/null
+
+ # curl -u $GITHUB_USER:$GITHUB_TOKEN -s https://api.github.com/repos/gohug#oio/hugo/releases/latest |
+ # grep "browser_download_url.*hugo.*._Linux-${ARCHES[$ARCH]}\.tar\.gz" |
+
+ URL=$(
+ lastversion hugo --format assets --filter Linux-${ARCHES[$ARCH]}\.tar\.gz |
+ if [ $EXTENDED = true ]; then
+ grep "_extended"
+ else
+ grep -v "_extended"
+ fi
+ # |
+ # cut -d ":" -f 2,3 |
+ # tr -d \"
+ )
+
+ echo $URL
+
+ echo "Installing version $NEW_VERSION $([ $EXTENDED == true ] && echo "Extended") "
+ echo "This machine's architecture is $ARCH"
+ echo "Downloading Tarball $URL"
+
+ wget --user=-u $GITHUB_USER --password=$GITHUB_TOKEN -q $URL
+
+ TARBALL=$(basename $URL)
+ # TARBALL="$(find . -name "*Linux-${ARCHES[$ARCH]}.tar.gz" 2>/dev/null)"
+ echo Expanding Tarball, $TARBALL
+ tar -xzf $TARBALL hugo
+
+ chmod +x hugo
+
+ if [ -w $BIN_DIR ]; then
+ echo "Installing hugo to $BIN_DIR"
+ mv hugo -f $BIN_DIR/hugo$EFILE
+ else
+ echo "installing hugo to $BIN_DIR (sudo)"
+ sudo mv -f hugo $BIN_DIR/hugo$EFILE
+ fi
+
+ rm $TARBALL
+
+ popd >/dev/null
+
+ echo Installing hugo $([ $EXTENDED == true ] && echo "extended") as hugo$EFILE
+
+ BIN_PATH="$(which hugo$EFILE)"
+
+ if [ -z "$BIN_PATH" ]; then
+ printf "WARNING: Installed Hugo Binary in $BIN_DIR is not in your environment path\nPATH=$PATH\n"
+ else
+ if [ "$BIN_DIR/hugo$EFILE" != "$BIN_PATH" ]; then
+ echo "WARNING: Just installed Hugo binary hugo$EFILE to, $BIN_DIR , conflicts with existing Hugo in $BIN_PATH"
+ echo "add $BIN_DIR to path and delete $BIN_PATH"
+ else
+ echo "--- Installation Confirmation ---"
+ printf "New Hugo binary version at $BIN_PATH is\n $($BIN_PATH version)\n"
+ fi
+ fi
+
+}
diff --git a/modules/install/tools/rclone-install.func b/modules/install/tools/rclone-install.func
new file mode 100644
index 0000000..1ba88d2
--- /dev/null
+++ b/modules/install/tools/rclone-install.func
@@ -0,0 +1,29 @@
+sudo rclone.bin
+ chmod 775 rclone.bin
+ touch $INSTALL_DIR/rclone
+ touch $INSTALL_DIR/rclone.conf
+ mkdir $INSTALL_DIR/cache 2> /dev/null || true
+ echo '#!/bin/bash' > $INSTALL_DIR/rclone
+ CMD=$(echo $INSTALL_DIR/rclone.bin \
+ --config=$INSTALL_DIR/rclone.conf \
+ --cache-dir=$INSTALL_DIR/cache \
+ '$@' \
+ )
+ echo "$CMD" >> $INSTALL_DIR/rclone
+ chown :sudo rclone
+ chmod 775 rclone
+ rm $BIN_DIR/rclone
+ ln -s $INSTALL_DIR/rclone $BIN_DIR/rclone
+ echo -e "rclone customized command can be launched from $(command -v rclone) \n $CMD"
+ echo -e "uncustomized rclone can be run from $INSTALL_DIR/rclone.bin"
+ cd ..
+
+
+ #update version variable post install
+ version=`rclone --version 2>>errors | head -n 1`
+
+ printf "\n${last_version} has successfully installed."
+ printf '\nNow run "rclone config" to set up remotes. Check https://rclone.org/docs/ for more details.\n\n'
+ return 0
+
+}
diff --git a/modules/lightdm/.session/session_login b/modules/lightdm/.session/session_login
new file mode 100755
index 0000000..57f9f7a
--- /dev/null
+++ b/modules/lightdm/.session/session_login
@@ -0,0 +1,12 @@
+#!/bin/bash
+log=$HOME/.session/session.log
+&>> $log
+echo $USER $HOME
+echo "lightdm login setup $(date)"
+
+# example commands to run when logging in, here binding some other directories for the user
+#echo "binding chromium browsers to .browsers"
+#/usr/bin/bindfs --map=sysadmin/$USER:@users/@$USER /opt/chromium/default $HOME/.browsers/default
+# bind alternate downloads directory
+#/usr/bin/bindfs --map=sysadmin/$USER:@users/@$USER /data/downloads $HOME/Downloads
+
diff --git a/modules/lightdm/.session/session_logout b/modules/lightdm/.session/session_logout
new file mode 100755
index 0000000..d985884
--- /dev/null
+++ b/modules/lightdm/.session/session_logout
@@ -0,0 +1,9 @@
+#!/bin/bash
+log=$HOME/.session/session.log
+&>> $log
+echo $USER $HOME
+echo "lightdm logout cleanup $(date)"
+# example complimentary cleanup here unmounting those mounted in session_login
+#echo "un mounting chromium browsers from .browsers"
+#/bin/fusermount -u $HOME/.browsers/default
+#/bin/fusermount -u $HOME/Downloads
diff --git a/modules/lightdm/.session/slogin b/modules/lightdm/.session/slogin
new file mode 100755
index 0000000..2423345
--- /dev/null
+++ b/modules/lightdm/.session/slogin
@@ -0,0 +1,3 @@
+#!/bin/bash
+# run the session login script manually, used for debugging
+sudo -E HOME=$HOME USER=$USER ./session_login
diff --git a/modules/lightdm/.session/slogout b/modules/lightdm/.session/slogout
new file mode 100755
index 0000000..b90e33a
--- /dev/null
+++ b/modules/lightdm/.session/slogout
@@ -0,0 +1,4 @@
+#!/bin/bash
+# run the session logout script manually, used for debugging
+sudo -E HOME=$HOME USER=$USER /bin/bash session_logout
+
diff --git a/modules/lightdm/50-setup-cleanup.conf b/modules/lightdm/50-setup-cleanup.conf
new file mode 100644
index 0000000..3e6c851
--- /dev/null
+++ b/modules/lightdm/50-setup-cleanup.conf
@@ -0,0 +1,4 @@
+[Seat:*]
+session-setup-script=/opt/session/lightdm-setup.sh
+session-cleanup-script=/opt/session/lightdm-cleanup.sh
+
diff --git a/modules/lightdm/cpy.session.sh b/modules/lightdm/cpy.session.sh
new file mode 100644
index 0000000..24fc0d2
--- /dev/null
+++ b/modules/lightdm/cpy.session.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+function confirm()
+{
+ echo -n "$@ "
+ read -e answer
+ for response in y Y yes YES Yes Sure sure SURE OK ok Ok
+ do
+ if [ "_$answer" == "_$response" ]
+ then
+ return 0
+ fi
+ done
+
+ # Any answer other than the list above is considered a "no" answer
+ return 1
+}
+
+if [[ -d $HOME/.session ]]; then
+echo $HOME/.session folder already exists
+confirm "!overwrite??? (y/n)" || exit
+/bin/cp -r -f $HOME/.session/ $HOME/.session-saved/
+echo saved copy first to $HOME/.session-saved
+fi
+echo copying .session from $(pwd) to $HOME
+/bin/cp -r -f .session/ $HOME
+echo setting execute permissions
+chmod +x $HOME/.session/*
\ No newline at end of file
diff --git a/modules/lightdm/loginout-install.sh b/modules/lightdm/loginout-install.sh
new file mode 100755
index 0000000..81ea48f
--- /dev/null
+++ b/modules/lightdm/loginout-install.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+loginout_install() {
+ module_load confirm
+ module_load helpers
+
+ [[ ! $(systemctl list-units | grep lightdm) ]] && echo lightdm not running on this machine, aborting && return
+
+ SDIR=$(adirname "${BASH_SOURCE[0]}")
+ # echo source directory: $SDIR
+
+
+ pushd $SDIR &> /dev/null || exit
+ [[ ! -d /etc/lightdm/lightdm.conf.d ]] && mkdir -p /etc/lightdm/lightdm.conf.d
+ echo copying 50-setup-cleanup.conf to /etc/lightdm/lightdm.conf.d
+ sudo cp -f 50-setup-cleanup.conf /etc/lightdm/lightdm.conf.d
+
+ if [[ ! -d /opt/session ]]; then
+ if [[ ! $(mkdir -p /opt/session) ]]; then
+ echo unable to make /opt/session with user $USER, elevating to sudo
+ _sudo="sudo"
+ [[ $($_sudo mkdir -p /opt/session) ]] && echo can not make /opt/session, aborting && return
+ fi
+ fi
+
+
+ echo copying lightdm-cleanup.sh and lightdm-setup.sh to /opt/session
+ $_sudo cp -f scripts/* /opt/session
+ echo setting execute permissions
+ $_sudo chmod -R +x /opt/session/*.sh
+
+
+
+ popd >/dev/null
+
+ _user=${1:-${USER}}
+ confirm "add a user .session folder for $_user" && add_user_session $1
+
+
+}
+
+function add_user_session {
+
+ module_load confirm
+ module_load helpers
+
+ SDIR=$(adirname "${BASH_SOURCE[0]}")
+ # echo source directory: $SDIR
+
+ pushd $SDIR &> /dev/null || exit
+
+ _user=${1:-${USER}}
+
+ [[ ! $(user_exists $_user) ]] && echo user $_user does not exist, aborting && return
+ _home=$(bash -c "cd ~$(printf %q $_user) && pwd")
+
+ echo making $_home/.session folder for $_user
+ # mkdir $USER/.session
+
+ sudo -H -E -u "$_user" -s /bin/bash cpy.session.sh
+
+ popd >/dev/null
+
+
+# confirm "do you want to install WidevineCDM for digital streaming rights?"
+# if [ $? -eq 0 ]; then
+# module_load widevine-install
+# widevine_install
+# fi
+
+
+}
+
+# if script was executed then call the function
+(return 0 2>/dev/null) || loginout_install $@
diff --git a/modules/lightdm/readme.md b/modules/lightdm/readme.md
new file mode 100644
index 0000000..b25a7e8
--- /dev/null
+++ b/modules/lightdm/readme.md
@@ -0,0 +1,51 @@
+
+Lightdm (gdm) is the login manager for linux ubuntu and mint (by default)
+
+If you need setup and cleanup that is ONLY done at lightdm login/logout then
+one can run a script to setup and cleanup the session by
+
+running the loginout-install script, requires sudo
+
+`module_load loginout-install; loginout_install ` # default is current user
+
+after loading common scripts this will ask if you want to add the .session folder for the user
+
+or if you just need to add a user .session folder afterward
+
+`module_load loginout-install; add_user_session `
+
+
+the script does this
+
+in `/etc/lightdm/lightdm.conf.d` adds a file `50-setup-cleanup.conf`
+
+```
+[Seat:*]
+session-cleanup-script=/opt/scripts/lightdm-cleanup.sh
+session-setup-script=/opt/scripts/lightdm-setup.sh
+```
+
+in /opt/scripts put two files below and make sure they are +x executable
+
+```
+#!/bin/bash
+#lightdm-setup.sh
+echo "setup for ${USER}:${HOME} $(date)" >> /opt/scripts/lightdm.log
+log=${HOME}/.session.log
+if [[ -e $HOME/.session_login ]]; then su -c "/bin/bash $HOME/.session_login 1>>${log} 2>>${log} || true" $USER; fi
+```
+
+```
+#!/bin/bash
+#lightdm-cleanup.sh
+echo "cleanup for ${USER}:${HOME} $(date)" >> /opt/scripts/lightdm.log
+log=${HOME}/.session.log
+if [[ -e $HOME/.session_logout ]]; then su -c "/bin/bash $HOME/.session_logout 1>>${log} 2>>${log} || true" $USER; fi
+```
+
+then in the user home puts
+`.session_login` and `.session_logout` files both executable
+in those you can do anything like bindfs and fusermount -u
+
+make sure you restart lightdm or reboot
+`sdr lightdm`
\ No newline at end of file
diff --git a/modules/lightdm/scripts/lightdm-cleanup.sh b/modules/lightdm/scripts/lightdm-cleanup.sh
new file mode 100644
index 0000000..382f507
--- /dev/null
+++ b/modules/lightdm/scripts/lightdm-cleanup.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+_udir=${HOME}/.session
+_uscript=${_udir}/session_logout
+_log=${_udir}/session.log
+_sdir=$(dirname "${BASH_SOURCE[0]}")
+echo "${UID:-$(id -u)}:$(whoami) is running CLEANUP script in $_sdir for ${USER} sourcing ${_uscript}::$(date)" >> ${_sdir}/lightdm.log
+if [[ -e ${_uscript} ]]; then
+ /bin/bash ${_uscript} 1>>${_log} 2>>${_log} || true
+fi
\ No newline at end of file
diff --git a/modules/lightdm/scripts/lightdm-setup.sh b/modules/lightdm/scripts/lightdm-setup.sh
new file mode 100644
index 0000000..c878e2f
--- /dev/null
+++ b/modules/lightdm/scripts/lightdm-setup.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+_udir=${HOME}/.session
+_uscript=${_udir}/session_login
+_log=${_udir}/session.log
+_sdir=$(dirname "${BASH_SOURCE[0]}")
+echo "${UID:-$(id -u)}:$(whoami) is running SETUP script in $_sdir for ${USER} sourcing ${_uscript}::$(date)" >> ${_sdir}/lightdm.log
+if [[ -e ${_uscript} ]]; then
+ /bin/bash ${_uscript} 1>>${_log} 2>>${_log} || true
+fi
diff --git a/tools/01-snap/snap.alias b/tools/01-snap/snap.alias
new file mode 100644
index 0000000..df0232e
--- /dev/null
+++ b/tools/01-snap/snap.alias
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+command -v snap >/dev/null 2>&1 || return
+
diff --git a/tools/01-snap/snap.func b/tools/01-snap/snap.func
new file mode 100644
index 0000000..df0232e
--- /dev/null
+++ b/tools/01-snap/snap.func
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+command -v snap >/dev/null 2>&1 || return
+
diff --git a/tools/01-snap/snap.path b/tools/01-snap/snap.path
new file mode 100644
index 0000000..dddcd93
--- /dev/null
+++ b/tools/01-snap/snap.path
@@ -0,0 +1,6 @@
+#!/bin/bash
+command -v snap >/dev/null 2>&1 || return
+
+path_append /snap/bin
+
+
diff --git a/tools/docker/00-docker.env b/tools/docker/00-docker.env
new file mode 100644
index 0000000..6886770
--- /dev/null
+++ b/tools/docker/00-docker.env
@@ -0,0 +1,2 @@
+#!/bin/bash
+export DOCKER_COMPOSE_ROOT=/opt/containers
diff --git a/tools/docker/01-docker b/tools/docker/01-docker
new file mode 100644
index 0000000..e248fe3
--- /dev/null
+++ b/tools/docker/01-docker
@@ -0,0 +1,4 @@
+#!/bin/bash
+docker_terminal () {
+docker exec -it $1 /bin/sh
+}
diff --git a/tools/docker/docker-compose b/tools/docker/docker-compose
new file mode 100644
index 0000000..0eef129
--- /dev/null
+++ b/tools/docker/docker-compose
@@ -0,0 +1,88 @@
+#!/bin/bash
+
+# only source if docker and docker_compose are installed
+command -v docker >/dev/null 2>&1 || return
+command -v docker-compose >/dev/null 2>&1 || return
+
+function dkcmp () {
+ module_load path
+ local path
+ local dir
+ local ext
+ local cmd
+ local OPTIND
+
+file="docker-compose"
+dir=""
+path=""
+
+OPTIND=1
+while getopts 'd:f:p:e:' OPTION; do
+ # echo $OPTION $OPTARG
+ case "$OPTION" in
+ f)
+ file=$OPTARG
+ ;;
+ d)
+ dir=$OPTARG
+ echo setting directory
+ ;;
+ e)
+ ext=$OPTARG
+ ;;
+ p)
+ path=$OPTARG
+ ;;
+ *)
+ echo unknown option $OPTION
+ ;;
+ esac
+done
+
+shift $(( OPTIND - 1 ))
+echo directory $dir
+[[ ! $path ]] && path=$dir/$file
+echo $path
+
+[[ $ext ]] && path=$path.$ext
+if [[ ! -f $path ]];then
+ if [[ -f ${path}.yml ]];then
+ path=$path.yml
+ elif [[ -f ${path}.yaml ]];then
+ path=$path.yaml
+ else
+ echo no compose file at $path
+ return 0
+ fi
+fi
+path=$(abs-path $path)
+echo compose: $path file exits, command to run $1
+cmd="docker-compose -f $path"
+case $1 in
+ s) ;&
+ start)
+ $cmd up -d
+ ;;
+ stp) ;&
+ stop)
+ $cmd down
+ ;;
+ rm) ;&
+ remove )
+ $cmd docker-compose rm -s -v
+ ;;
+ rst) ;&
+ restart)
+ $cmd restart
+ ;;
+ mk) ;&
+ make)
+ $cmd down
+ $cmd up -d --force-recreate
+ ;;
+ *)
+ echo "no command supplied (i.e. start,stop,remove restart,make)"
+ ;;
+esac
+return 0
+}
diff --git a/tools/docker/docker.alias b/tools/docker/docker.alias
new file mode 100644
index 0000000..69f69c9
--- /dev/null
+++ b/tools/docker/docker.alias
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# if docker loaded only
+command -v docker >/dev/null 2>&1 || return
+
+#docker - add users to docker group to avoid needing sudo
+# run a command on a container
+
+alias dkcr="docker run"
+# start a container
+alias dkcs="docker start"
+# restart all running containers
+alias dkcrr="docker restart $(docker ps -q)"
+# start all exited containers
+alias dkcsu="docker start $(docker ps --filter "status=exited")"
+# ls stopped, la all, l running
+alias dkcls="docker ps --filter "status=exited""
+alias dkcla="docker ps -a "
+alias dkcl="docker ps "
+alias dkil="docker images --digests=true"
+alias dkir="docker rmi $(docker images -q)"
+alias dks="sudo service docker"
+alias dkcstpa="docker stop $(docker ps -a -q)"
+# remove unrunning containers
+alias dkcrm="docker rm $(docker ps -a -q)"
+# stop and remove
+alias dkcsrm="docker rm -f $(docker ps -a -q)"
+# cleans out unused/dangling aufs volumes - run this occasionally
+alias dkclean="docker volume ls -qf dangling=true | xargs -r docker volume rm"
+alias dkde="gksudo gedit /etc/default/docker"
+
+alias dkterm="docker_terminal"
diff --git a/tools/multipass/multipass.alias b/tools/multipass/multipass.alias
new file mode 100644
index 0000000..57de869
--- /dev/null
+++ b/tools/multipass/multipass.alias
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+command -v multipass >/dev/null 2>&1 || return
+# [[ ! -f /snap/bin/multipass ]] && return
+
+alias mpls="multipass list"
+alias mp="multipass"
+alias mpl="multipass_launch"
+alias mps="multipass shell"
+alias mpssh="multipass_ssh"
+alias mprm="multipass_remove"
+alias mph="multipass --help"
diff --git a/tools/multipass/multipass.func b/tools/multipass/multipass.func
new file mode 100644
index 0000000..415623e
--- /dev/null
+++ b/tools/multipass/multipass.func
@@ -0,0 +1,68 @@
+#!/bin/bash
+
+command -v multipass >/dev/null 2>&1 || return
+
+multipass_launch () {
+ subdir=${MULTIPASS_HOME:-multipass}
+ [[ $1 ]] && name="-n $1"
+ if [[ $2 ]]; then
+ file="$HOME/$subdir/cloud-init/$2.yaml"
+ if [[ -f $file ]]; then
+ init="--cloud-init $file"
+ else
+ echo no cloud init file $file
+ return 1
+ fi
+ fi
+ echo running: multipass launch $name $init
+ multipass launch $name $init
+ }
+
+ multipass_remove () {
+ [[ ! $1 ]] && echo must supply an instance name && return 1
+ module_load confirm
+ confirm "delete and purge instance $1?" || return 1
+ multipass delete -p $1
+
+ }
+
+ multipass_get_sshid () {
+ dest=${1:-$HOME/.ssh/multipass_id_rsa}
+ [[ -f $dest ]] && echo $dest && return 0
+ src=${SNAP_VAR:-/var/snap}/multipass/common/data/multipassd/ssh-keys/id_rsa
+ [[ ! -f $src ]] && return 1
+ sudo cp $src $dest
+ sudo chown $USER:$USER $dest
+ echo $dest
+ }
+
+multipass_get_ip () {
+ [[ ! $1 ]] && return 1
+ json=$(multipass info --format json $1 2> /dev/null)
+ [[ ! $json ]] && return 2
+ ip=$(echo "$json" | jq -r .info.$1.ipv4[0] 2> /dev/null)
+ [[ $ip ]] && echo $ip || return 3
+ return 0
+}
+
+ multipass_ssh () {
+ [[ ! $1 ]] && echo must supply name of instance name && return 1
+ ip=$(multipass_get_ip $1)
+ [[ ! $ip ]] && echo "no ip for instance $1, aborting" && return
+ id=$(multipass_get_sshid)
+ user=${2:-ubuntu}
+ echo ssh -i $id $user@$ip
+ ssh -i $id $user@$ip
+ }
+
+ multipass_scp () {
+ [[ $1 = "-u" ]] && user=$2 && shift 2 || user=ubuntu
+ [[ ! $1 ]] && echo must supply name of instance name && return 1
+ ip=$(multipass_get_ip $1)
+ [[ ! $ip ]] && echo "no ip for instance $1, aborting" && return
+ id=$(multipass_get_sshid)
+ cat $id
+ return
+ echo sudo scp -i $id -r $2 $user@$ip:$3
+ sudo scp -i $id $2 $user@$ip:$3
+ }