Create Apache2 virtualhost, Mysql db & user. CLI tool and GUI on top of itBash Shell Script uses Sed to create and insert multiple lines after a particular line in an existing fileChecking percentage of free memory using top and awkLoop through all virtualhost log files and run goaccess on each fileBash script to create directories and files with a numbered prefixCreate and open a file to take lecture notes depending on day and timeMySQL CLI: Create a MySQL user & DBbash wrapper around 'git commit' to automatically bump (Python) package CalVer and create matching CalVer tag on new commitCreate Apache virtualhost, MySQL db and user, install option - desktop shortcut for GUI version
Is it possible to make sharp wind that can cut stuff from afar?
I see my dog run
Are objects structures and/or vice versa?
How to move the player while also allowing forces to affect it
Is repealing the EU Withdrawal Act a precondition of revoking Article 50?
How to handle columns with categorical data and many unique values
Are white and non-white police officers equally likely to kill black suspects?
Mapping arrows in commutative diagrams
I am not able to install anything in ubuntu
Was there ever an axiom rendered a theorem?
Why do we use polarized capacitors?
Can a planet have a different gravitational pull depending on its location in orbit around its sun?
Is this homebrew feat, Beast of Burden, balanced?
Why was the "bread communication" in the arena of Catching Fire left out in the movie?
How can I fix this gap between bookcases I made?
Where to refill my bottle in India?
How do I create uniquely male characters?
What do you call something that goes against the spirit of the law, but is legal when interpreting the law to the letter?
aging parents with no investments
Is Fable (1996) connected in any way to the Fable franchise from Lionhead Studios?
"listening to me about as much as you're listening to this pole here"
Send two commands to a new terminal?
Why did the Germans forbid the possession of pet pigeons in Rostov-on-Don in 1941?
Visa needed to visit friends in London
Create Apache2 virtualhost, Mysql db & user. CLI tool and GUI on top of it
Bash Shell Script uses Sed to create and insert multiple lines after a particular line in an existing fileChecking percentage of free memory using top and awkLoop through all virtualhost log files and run goaccess on each fileBash script to create directories and files with a numbered prefixCreate and open a file to take lecture notes depending on day and timeMySQL CLI: Create a MySQL user & DBbash wrapper around 'git commit' to automatically bump (Python) package CalVer and create matching CalVer tag on new commitCreate Apache virtualhost, MySQL db and user, install option - desktop shortcut for GUI version
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
$begingroup$
Review for optimization, code standards, missed validation.
What's in this version:
- Rewritten, instead of large complex script - few tools with each own
task. - Solid CLI tool and GUI script on top of it.
- Apply all previous code reviews on new code.
- Some improvements from myself
- Input arguments as usual and pass users/passwords to mysql script as
environment vars for improved security. - Man page written(not for review)
Github
virtualhost-cli.sh - main cli tool, the only one script what need root
#!/usr/bin/env bash
set -e
cd "$0%/*"
source virtualhost.inc.sh
parseargs "$@"
validate
parse
#connect
hostfile="$config[a2ensite]$config[subdomain].conf"
siteconf="$config[apachesites]$hostfile"
(cat >"$siteconf" <<EOF
<VirtualHost $config[virtualhost]:$config[virtualport]>
ServerAdmin $config[serveradmin]
DocumentRoot $config[webroot]
ServerName $config[domain]
ServerAlias $config[domain]
<Directory "$config[webroot]">
AllowOverride All
Require local
</Directory>
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
LogLevel error
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
EOF
) || die "May run as root or give $siteconf writable permissions to current user"
(
mkdir -p "$config[webroot]"
chown $config[webmaster]:$config[webgroup] "$config[webroot]"
chmod u=rwX,g=rXs,o= "$config[webroot]"
chown root:root "$siteconf"
chmod u=rw,g=r,o=r "$siteconf"
a2ensite "$hostfile"
systemctl reload apache2
) || die "Run as root"
die "Config file saved and enabled at $siteconf" "Notice" 0
virtualhost.inc.sh - lib used by all other scripts
#check if function exists
if ! type die &>/dev/null;then
die()
echo "$2:-Error: $1" >&2
exit $3:-1
fi
[[ "$BASH_VERSINFO:-0" -ge 4 ]] || die "Bash version 4 or above required"
# defaults
declare -A config=()
config[webmaster]="$(id -un)" # user who access web files. group is www-data
config[webgroup]="www-data" # apache2 web group, does't need to be webmaster group. SGID set for folder.
config[webroot]='$homedir/Web/$subdomain'
config[domain]="localhost" # domain for creating subdomains
config[virtualhost]="*" # ip of virtualhost in case server listen on many interfaces or "*" for all
config[virtualport]="80" # port of virtualhost. apache2 must listen on that ip:port
config[serveradmin]="webmaster@localhost" # admin email
config[a2ensite]="050-" # short prefix for virtualhost config file
config[apachesites]="/etc/apache2/sites-available/" # virtualhosts config folder
declare -A mysql=() # mysql script read values from env
have_command()
type -p "$1" >/dev/null
try()
have_command "$1" && "$@"
if_match()
[[ "$1" =~ $2 ]]
validate()
(if_match "$config[virtualhost]" "^[a-zA-Z]([a-zA-Z0-9-]0,61[a-zA-Z0-9.])*$")
tolowercase() tr '[:upper:]' '[:lower:]'
parse() cut -d: -f6 )
webmaster="$config[webmaster]"
subdomain="$config[subdomain]"
domain="$config[subdomain].$config[domain]"
envsubst '$homedir,$webmaster,$subdomain,$domain')
config[domain]="$config[subdomain].$config[domain]"
config[domain]=$(tolowercase "$config[domain]")
config[subdomain]=$(tolowercase "$config[subdomain]")
config[virtualhost]=$(tolowercase "$config[virtualhost]")
# check if apache listening on defined host:port
connect()
# load all allowed arguments into $config array
parseargs()
(getopt --test > /dev/null)
validate_mysql()
for key in adminuser database user;do
(LANG=C; if_match "$mysql[$key]" "^[a-zA-Z][a-zA-Z0-9_-]*$")
escape_mysql()
for key in adminpasswd passwd;do
printf -v var "%q" "$mysql[$key]"
mysql[$key]=$var
done
virtualhost-yad.sh - GUI tool for CLI scripts
#!/usr/bin/env bash
set -e
cd "$0%/*"
die()
echo "$2:-Error: $1" >&2
xmessage -buttons Ok:0 -nearmouse "$2:-Error: $1" -timeout 10
exit $3:-1
source virtualhost.inc.sh
in_terminal()
[ -t 0 ]
die()
local msg="$2:-Error: $1"
echo "$msg" >&2
in_terminal && exit $3:-1
try notify-send "$msg" && exit $3:-1
try yad --info --text="$msg" && exit $3:-1
try xmessage -buttons Ok:0 -nearmouse "$msg" -timeout 10 && exit $3:-1
exit $3:-1
have_command yad || die "yad package required. 'sudo apt install yad'"
user_info()
yad --title="Virtualhost" --window-icon="$2:-error" --info --text="$1" --timeout="$3:-15" --button="Ok:0" --center
parseargs "$@"
while true; do
formbutton=0
formoutput=$(yad --form --field="Subdomain" --field="Domain" --field="Web master username"
--field="Apache group" --field='Webroot'
--field='Webroot variables - $homedir(of webmaster) $subdomain $webmaster $domain:LBL'
--field="Virtualhost ip or domain"
--field="Virtualhost port" --field="Server admin email"
--field="Create mysql user&db:CHK"
--field="Mysql admin user" --field="Mysql admin password"
--field="Create database"
--field="Create mysql user" --field="Create mysql password"
--button="Cancel:5" --button="Save defaults:2" --button="Create:0"
--title="Create apache virtualhost"
--text='Subdomain are case sensetive for Webroot folder $subdomain variable'
--focus-field=1 --center --window-icon="preferences-system" --width=600
"$config[subdomain]" "$config[domain]" "$config[webmaster]" "$config[webgroup]"
"$config[webroot]" "test" "$config[virtualhost]" "$config[virtualport]"
"$config[serveradmin]" true
"$mysql[adminuser]" "$mysql[adminpasswd]"
"$mysql[database]" "$mysql[user]" "$mysql[passwd]"
) || formbutton="$?" && true
# Cancel(5) or close window(other code)
[[ "$formbutton" -ne 0 && "$formbutton" -ne 2 && "$formbutton" -ne 1 ]] && die "Cancel"
IFS='|' read -r -a form <<< "$formoutput"
pos=0
for key in subdomain domain webmaster webgroup webroot nothing virtualhost virtualport serveradmin;do
config[$key]="$form[$pos]"
let pos=pos+1
done
usemysql=
[[ "$form[9]" -eq "TRUE" ]] && usemysql=1
pos=10
for key in adminuser adminpasswd database user passwd;do
mysql[$key]="$form[$pos]"
let pos=pos+1
done
vres=0
# subdomain can't be default option, skip it
[[ "$formbutton" -eq 2 ]] && skipsubdomain=1 || skipsubdomain=
# validate input, continue or show error and return to form
valoutput=$(validate $skipsubdomain 2>&1) || vres=$? && true
[[ "$vres" -ne 0 ]] && user_info "$valoutput" && continue
clires=0
if [[ "$formbutton" -ne 2 ]]; then
cmd="pkexec `pwd`/virtualhost-cli.sh"
[[ "$formbutton" -eq 2 ]] && cmd="./virtualhost-install.sh"
clioutput=$($cmd --subdomain "$config[subdomain]"
--domain "$config[domain]" --webmaster "$config[webmaster]"
--webgroup "$config[webgroup]" --webroot "$config[webroot]"
--virtualhost "$config[virtualhost]" --virtualport "$config[virtualport]"
--serveradmin "$config[serveradmin]" 2>&1) || clires=$? && true
[[ "$clioutput" ]] && user_info "$clioutput" || true
[[ "$clires" -ne 0 ]] && continue
# mysql
if [[ "$usemysql" ]]; then
mysqlres=0
mysqloutput=$(adminuser="$mysql[adminuser]" adminpwd="$mysql[adminpasswd]"
database="$mysql[database]" mysqluser="$mysql[user]"
mysqlpasswd="$mysql[passwd]" ./virtualhost-mysql.sh
--subdomain "$config[subdomain]" 2>&1) || mysqlres=$? && true
[[ "$mysqloutput" ]] && user_info "$mysqloutput" || true
[[ "$mysqlres" -ne 0 ]] && continue
break
fi
break
fi
done
virtualhost-mysql.sh - create db and user, values passed by environment variables to not appear in ps output - for security.
#!/usr/bin/env bash
set -e
cd "$0%/*"
source virtualhost.inc.sh
parseargs "$@" # only --subdomain used
# read values from env
subdomain=$(tolowercase "$config[subdomain]")
mysql[adminuser]="$adminuser:-root"
mysql[adminpasswd]="$adminpwd"
mysql[database]="$mysqldatabase:-$subdomain"
mysql[user]="$mysqluser:-$subdomain:-$(id -un)"
mysql[passwd]="$mysqlpasswd"
validate_mysql
escape_mysql
mysqlcreate=$(cat <<EOF
CREATE USER '$mysql[user]'@'localhost' IDENTIFIED BY '$mysql[passwd]';
GRANT USAGE ON *.* TO '$mysql[user]'@'localhost';
CREATE DATABASE IF NOT EXISTS `$mysql[database]` CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL PRIVILEGES ON `$mysql[database]`.* TO '$mysql[user]'@'localhost';
FLUSH PRIVILEGES;
EOF
)
mysql --user="$mysql[adminuser]" --password="$mysql[adminpasswd]" <<<$mysqlcreate
virtualhost-install.sh - install desktop shortcut with arguments defined as defaults for GUI tool. Can be executed from "virtualhost-yad.sh" with values from form. Not for review as simple and similar.
bash
$endgroup$
add a comment |
$begingroup$
Review for optimization, code standards, missed validation.
What's in this version:
- Rewritten, instead of large complex script - few tools with each own
task. - Solid CLI tool and GUI script on top of it.
- Apply all previous code reviews on new code.
- Some improvements from myself
- Input arguments as usual and pass users/passwords to mysql script as
environment vars for improved security. - Man page written(not for review)
Github
virtualhost-cli.sh - main cli tool, the only one script what need root
#!/usr/bin/env bash
set -e
cd "$0%/*"
source virtualhost.inc.sh
parseargs "$@"
validate
parse
#connect
hostfile="$config[a2ensite]$config[subdomain].conf"
siteconf="$config[apachesites]$hostfile"
(cat >"$siteconf" <<EOF
<VirtualHost $config[virtualhost]:$config[virtualport]>
ServerAdmin $config[serveradmin]
DocumentRoot $config[webroot]
ServerName $config[domain]
ServerAlias $config[domain]
<Directory "$config[webroot]">
AllowOverride All
Require local
</Directory>
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
LogLevel error
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
EOF
) || die "May run as root or give $siteconf writable permissions to current user"
(
mkdir -p "$config[webroot]"
chown $config[webmaster]:$config[webgroup] "$config[webroot]"
chmod u=rwX,g=rXs,o= "$config[webroot]"
chown root:root "$siteconf"
chmod u=rw,g=r,o=r "$siteconf"
a2ensite "$hostfile"
systemctl reload apache2
) || die "Run as root"
die "Config file saved and enabled at $siteconf" "Notice" 0
virtualhost.inc.sh - lib used by all other scripts
#check if function exists
if ! type die &>/dev/null;then
die()
echo "$2:-Error: $1" >&2
exit $3:-1
fi
[[ "$BASH_VERSINFO:-0" -ge 4 ]] || die "Bash version 4 or above required"
# defaults
declare -A config=()
config[webmaster]="$(id -un)" # user who access web files. group is www-data
config[webgroup]="www-data" # apache2 web group, does't need to be webmaster group. SGID set for folder.
config[webroot]='$homedir/Web/$subdomain'
config[domain]="localhost" # domain for creating subdomains
config[virtualhost]="*" # ip of virtualhost in case server listen on many interfaces or "*" for all
config[virtualport]="80" # port of virtualhost. apache2 must listen on that ip:port
config[serveradmin]="webmaster@localhost" # admin email
config[a2ensite]="050-" # short prefix for virtualhost config file
config[apachesites]="/etc/apache2/sites-available/" # virtualhosts config folder
declare -A mysql=() # mysql script read values from env
have_command()
type -p "$1" >/dev/null
try()
have_command "$1" && "$@"
if_match()
[[ "$1" =~ $2 ]]
validate()
(if_match "$config[virtualhost]" "^[a-zA-Z]([a-zA-Z0-9-]0,61[a-zA-Z0-9.])*$")
tolowercase() tr '[:upper:]' '[:lower:]'
parse() cut -d: -f6 )
webmaster="$config[webmaster]"
subdomain="$config[subdomain]"
domain="$config[subdomain].$config[domain]"
envsubst '$homedir,$webmaster,$subdomain,$domain')
config[domain]="$config[subdomain].$config[domain]"
config[domain]=$(tolowercase "$config[domain]")
config[subdomain]=$(tolowercase "$config[subdomain]")
config[virtualhost]=$(tolowercase "$config[virtualhost]")
# check if apache listening on defined host:port
connect()
# load all allowed arguments into $config array
parseargs()
(getopt --test > /dev/null)
validate_mysql()
for key in adminuser database user;do
(LANG=C; if_match "$mysql[$key]" "^[a-zA-Z][a-zA-Z0-9_-]*$")
escape_mysql()
for key in adminpasswd passwd;do
printf -v var "%q" "$mysql[$key]"
mysql[$key]=$var
done
virtualhost-yad.sh - GUI tool for CLI scripts
#!/usr/bin/env bash
set -e
cd "$0%/*"
die()
echo "$2:-Error: $1" >&2
xmessage -buttons Ok:0 -nearmouse "$2:-Error: $1" -timeout 10
exit $3:-1
source virtualhost.inc.sh
in_terminal()
[ -t 0 ]
die()
local msg="$2:-Error: $1"
echo "$msg" >&2
in_terminal && exit $3:-1
try notify-send "$msg" && exit $3:-1
try yad --info --text="$msg" && exit $3:-1
try xmessage -buttons Ok:0 -nearmouse "$msg" -timeout 10 && exit $3:-1
exit $3:-1
have_command yad || die "yad package required. 'sudo apt install yad'"
user_info()
yad --title="Virtualhost" --window-icon="$2:-error" --info --text="$1" --timeout="$3:-15" --button="Ok:0" --center
parseargs "$@"
while true; do
formbutton=0
formoutput=$(yad --form --field="Subdomain" --field="Domain" --field="Web master username"
--field="Apache group" --field='Webroot'
--field='Webroot variables - $homedir(of webmaster) $subdomain $webmaster $domain:LBL'
--field="Virtualhost ip or domain"
--field="Virtualhost port" --field="Server admin email"
--field="Create mysql user&db:CHK"
--field="Mysql admin user" --field="Mysql admin password"
--field="Create database"
--field="Create mysql user" --field="Create mysql password"
--button="Cancel:5" --button="Save defaults:2" --button="Create:0"
--title="Create apache virtualhost"
--text='Subdomain are case sensetive for Webroot folder $subdomain variable'
--focus-field=1 --center --window-icon="preferences-system" --width=600
"$config[subdomain]" "$config[domain]" "$config[webmaster]" "$config[webgroup]"
"$config[webroot]" "test" "$config[virtualhost]" "$config[virtualport]"
"$config[serveradmin]" true
"$mysql[adminuser]" "$mysql[adminpasswd]"
"$mysql[database]" "$mysql[user]" "$mysql[passwd]"
) || formbutton="$?" && true
# Cancel(5) or close window(other code)
[[ "$formbutton" -ne 0 && "$formbutton" -ne 2 && "$formbutton" -ne 1 ]] && die "Cancel"
IFS='|' read -r -a form <<< "$formoutput"
pos=0
for key in subdomain domain webmaster webgroup webroot nothing virtualhost virtualport serveradmin;do
config[$key]="$form[$pos]"
let pos=pos+1
done
usemysql=
[[ "$form[9]" -eq "TRUE" ]] && usemysql=1
pos=10
for key in adminuser adminpasswd database user passwd;do
mysql[$key]="$form[$pos]"
let pos=pos+1
done
vres=0
# subdomain can't be default option, skip it
[[ "$formbutton" -eq 2 ]] && skipsubdomain=1 || skipsubdomain=
# validate input, continue or show error and return to form
valoutput=$(validate $skipsubdomain 2>&1) || vres=$? && true
[[ "$vres" -ne 0 ]] && user_info "$valoutput" && continue
clires=0
if [[ "$formbutton" -ne 2 ]]; then
cmd="pkexec `pwd`/virtualhost-cli.sh"
[[ "$formbutton" -eq 2 ]] && cmd="./virtualhost-install.sh"
clioutput=$($cmd --subdomain "$config[subdomain]"
--domain "$config[domain]" --webmaster "$config[webmaster]"
--webgroup "$config[webgroup]" --webroot "$config[webroot]"
--virtualhost "$config[virtualhost]" --virtualport "$config[virtualport]"
--serveradmin "$config[serveradmin]" 2>&1) || clires=$? && true
[[ "$clioutput" ]] && user_info "$clioutput" || true
[[ "$clires" -ne 0 ]] && continue
# mysql
if [[ "$usemysql" ]]; then
mysqlres=0
mysqloutput=$(adminuser="$mysql[adminuser]" adminpwd="$mysql[adminpasswd]"
database="$mysql[database]" mysqluser="$mysql[user]"
mysqlpasswd="$mysql[passwd]" ./virtualhost-mysql.sh
--subdomain "$config[subdomain]" 2>&1) || mysqlres=$? && true
[[ "$mysqloutput" ]] && user_info "$mysqloutput" || true
[[ "$mysqlres" -ne 0 ]] && continue
break
fi
break
fi
done
virtualhost-mysql.sh - create db and user, values passed by environment variables to not appear in ps output - for security.
#!/usr/bin/env bash
set -e
cd "$0%/*"
source virtualhost.inc.sh
parseargs "$@" # only --subdomain used
# read values from env
subdomain=$(tolowercase "$config[subdomain]")
mysql[adminuser]="$adminuser:-root"
mysql[adminpasswd]="$adminpwd"
mysql[database]="$mysqldatabase:-$subdomain"
mysql[user]="$mysqluser:-$subdomain:-$(id -un)"
mysql[passwd]="$mysqlpasswd"
validate_mysql
escape_mysql
mysqlcreate=$(cat <<EOF
CREATE USER '$mysql[user]'@'localhost' IDENTIFIED BY '$mysql[passwd]';
GRANT USAGE ON *.* TO '$mysql[user]'@'localhost';
CREATE DATABASE IF NOT EXISTS `$mysql[database]` CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL PRIVILEGES ON `$mysql[database]`.* TO '$mysql[user]'@'localhost';
FLUSH PRIVILEGES;
EOF
)
mysql --user="$mysql[adminuser]" --password="$mysql[adminpasswd]" <<<$mysqlcreate
virtualhost-install.sh - install desktop shortcut with arguments defined as defaults for GUI tool. Can be executed from "virtualhost-yad.sh" with values from form. Not for review as simple and similar.
bash
$endgroup$
add a comment |
$begingroup$
Review for optimization, code standards, missed validation.
What's in this version:
- Rewritten, instead of large complex script - few tools with each own
task. - Solid CLI tool and GUI script on top of it.
- Apply all previous code reviews on new code.
- Some improvements from myself
- Input arguments as usual and pass users/passwords to mysql script as
environment vars for improved security. - Man page written(not for review)
Github
virtualhost-cli.sh - main cli tool, the only one script what need root
#!/usr/bin/env bash
set -e
cd "$0%/*"
source virtualhost.inc.sh
parseargs "$@"
validate
parse
#connect
hostfile="$config[a2ensite]$config[subdomain].conf"
siteconf="$config[apachesites]$hostfile"
(cat >"$siteconf" <<EOF
<VirtualHost $config[virtualhost]:$config[virtualport]>
ServerAdmin $config[serveradmin]
DocumentRoot $config[webroot]
ServerName $config[domain]
ServerAlias $config[domain]
<Directory "$config[webroot]">
AllowOverride All
Require local
</Directory>
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
LogLevel error
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
EOF
) || die "May run as root or give $siteconf writable permissions to current user"
(
mkdir -p "$config[webroot]"
chown $config[webmaster]:$config[webgroup] "$config[webroot]"
chmod u=rwX,g=rXs,o= "$config[webroot]"
chown root:root "$siteconf"
chmod u=rw,g=r,o=r "$siteconf"
a2ensite "$hostfile"
systemctl reload apache2
) || die "Run as root"
die "Config file saved and enabled at $siteconf" "Notice" 0
virtualhost.inc.sh - lib used by all other scripts
#check if function exists
if ! type die &>/dev/null;then
die()
echo "$2:-Error: $1" >&2
exit $3:-1
fi
[[ "$BASH_VERSINFO:-0" -ge 4 ]] || die "Bash version 4 or above required"
# defaults
declare -A config=()
config[webmaster]="$(id -un)" # user who access web files. group is www-data
config[webgroup]="www-data" # apache2 web group, does't need to be webmaster group. SGID set for folder.
config[webroot]='$homedir/Web/$subdomain'
config[domain]="localhost" # domain for creating subdomains
config[virtualhost]="*" # ip of virtualhost in case server listen on many interfaces or "*" for all
config[virtualport]="80" # port of virtualhost. apache2 must listen on that ip:port
config[serveradmin]="webmaster@localhost" # admin email
config[a2ensite]="050-" # short prefix for virtualhost config file
config[apachesites]="/etc/apache2/sites-available/" # virtualhosts config folder
declare -A mysql=() # mysql script read values from env
have_command()
type -p "$1" >/dev/null
try()
have_command "$1" && "$@"
if_match()
[[ "$1" =~ $2 ]]
validate()
(if_match "$config[virtualhost]" "^[a-zA-Z]([a-zA-Z0-9-]0,61[a-zA-Z0-9.])*$")
tolowercase() tr '[:upper:]' '[:lower:]'
parse() cut -d: -f6 )
webmaster="$config[webmaster]"
subdomain="$config[subdomain]"
domain="$config[subdomain].$config[domain]"
envsubst '$homedir,$webmaster,$subdomain,$domain')
config[domain]="$config[subdomain].$config[domain]"
config[domain]=$(tolowercase "$config[domain]")
config[subdomain]=$(tolowercase "$config[subdomain]")
config[virtualhost]=$(tolowercase "$config[virtualhost]")
# check if apache listening on defined host:port
connect()
# load all allowed arguments into $config array
parseargs()
(getopt --test > /dev/null)
validate_mysql()
for key in adminuser database user;do
(LANG=C; if_match "$mysql[$key]" "^[a-zA-Z][a-zA-Z0-9_-]*$")
escape_mysql()
for key in adminpasswd passwd;do
printf -v var "%q" "$mysql[$key]"
mysql[$key]=$var
done
virtualhost-yad.sh - GUI tool for CLI scripts
#!/usr/bin/env bash
set -e
cd "$0%/*"
die()
echo "$2:-Error: $1" >&2
xmessage -buttons Ok:0 -nearmouse "$2:-Error: $1" -timeout 10
exit $3:-1
source virtualhost.inc.sh
in_terminal()
[ -t 0 ]
die()
local msg="$2:-Error: $1"
echo "$msg" >&2
in_terminal && exit $3:-1
try notify-send "$msg" && exit $3:-1
try yad --info --text="$msg" && exit $3:-1
try xmessage -buttons Ok:0 -nearmouse "$msg" -timeout 10 && exit $3:-1
exit $3:-1
have_command yad || die "yad package required. 'sudo apt install yad'"
user_info()
yad --title="Virtualhost" --window-icon="$2:-error" --info --text="$1" --timeout="$3:-15" --button="Ok:0" --center
parseargs "$@"
while true; do
formbutton=0
formoutput=$(yad --form --field="Subdomain" --field="Domain" --field="Web master username"
--field="Apache group" --field='Webroot'
--field='Webroot variables - $homedir(of webmaster) $subdomain $webmaster $domain:LBL'
--field="Virtualhost ip or domain"
--field="Virtualhost port" --field="Server admin email"
--field="Create mysql user&db:CHK"
--field="Mysql admin user" --field="Mysql admin password"
--field="Create database"
--field="Create mysql user" --field="Create mysql password"
--button="Cancel:5" --button="Save defaults:2" --button="Create:0"
--title="Create apache virtualhost"
--text='Subdomain are case sensetive for Webroot folder $subdomain variable'
--focus-field=1 --center --window-icon="preferences-system" --width=600
"$config[subdomain]" "$config[domain]" "$config[webmaster]" "$config[webgroup]"
"$config[webroot]" "test" "$config[virtualhost]" "$config[virtualport]"
"$config[serveradmin]" true
"$mysql[adminuser]" "$mysql[adminpasswd]"
"$mysql[database]" "$mysql[user]" "$mysql[passwd]"
) || formbutton="$?" && true
# Cancel(5) or close window(other code)
[[ "$formbutton" -ne 0 && "$formbutton" -ne 2 && "$formbutton" -ne 1 ]] && die "Cancel"
IFS='|' read -r -a form <<< "$formoutput"
pos=0
for key in subdomain domain webmaster webgroup webroot nothing virtualhost virtualport serveradmin;do
config[$key]="$form[$pos]"
let pos=pos+1
done
usemysql=
[[ "$form[9]" -eq "TRUE" ]] && usemysql=1
pos=10
for key in adminuser adminpasswd database user passwd;do
mysql[$key]="$form[$pos]"
let pos=pos+1
done
vres=0
# subdomain can't be default option, skip it
[[ "$formbutton" -eq 2 ]] && skipsubdomain=1 || skipsubdomain=
# validate input, continue or show error and return to form
valoutput=$(validate $skipsubdomain 2>&1) || vres=$? && true
[[ "$vres" -ne 0 ]] && user_info "$valoutput" && continue
clires=0
if [[ "$formbutton" -ne 2 ]]; then
cmd="pkexec `pwd`/virtualhost-cli.sh"
[[ "$formbutton" -eq 2 ]] && cmd="./virtualhost-install.sh"
clioutput=$($cmd --subdomain "$config[subdomain]"
--domain "$config[domain]" --webmaster "$config[webmaster]"
--webgroup "$config[webgroup]" --webroot "$config[webroot]"
--virtualhost "$config[virtualhost]" --virtualport "$config[virtualport]"
--serveradmin "$config[serveradmin]" 2>&1) || clires=$? && true
[[ "$clioutput" ]] && user_info "$clioutput" || true
[[ "$clires" -ne 0 ]] && continue
# mysql
if [[ "$usemysql" ]]; then
mysqlres=0
mysqloutput=$(adminuser="$mysql[adminuser]" adminpwd="$mysql[adminpasswd]"
database="$mysql[database]" mysqluser="$mysql[user]"
mysqlpasswd="$mysql[passwd]" ./virtualhost-mysql.sh
--subdomain "$config[subdomain]" 2>&1) || mysqlres=$? && true
[[ "$mysqloutput" ]] && user_info "$mysqloutput" || true
[[ "$mysqlres" -ne 0 ]] && continue
break
fi
break
fi
done
virtualhost-mysql.sh - create db and user, values passed by environment variables to not appear in ps output - for security.
#!/usr/bin/env bash
set -e
cd "$0%/*"
source virtualhost.inc.sh
parseargs "$@" # only --subdomain used
# read values from env
subdomain=$(tolowercase "$config[subdomain]")
mysql[adminuser]="$adminuser:-root"
mysql[adminpasswd]="$adminpwd"
mysql[database]="$mysqldatabase:-$subdomain"
mysql[user]="$mysqluser:-$subdomain:-$(id -un)"
mysql[passwd]="$mysqlpasswd"
validate_mysql
escape_mysql
mysqlcreate=$(cat <<EOF
CREATE USER '$mysql[user]'@'localhost' IDENTIFIED BY '$mysql[passwd]';
GRANT USAGE ON *.* TO '$mysql[user]'@'localhost';
CREATE DATABASE IF NOT EXISTS `$mysql[database]` CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL PRIVILEGES ON `$mysql[database]`.* TO '$mysql[user]'@'localhost';
FLUSH PRIVILEGES;
EOF
)
mysql --user="$mysql[adminuser]" --password="$mysql[adminpasswd]" <<<$mysqlcreate
virtualhost-install.sh - install desktop shortcut with arguments defined as defaults for GUI tool. Can be executed from "virtualhost-yad.sh" with values from form. Not for review as simple and similar.
bash
$endgroup$
Review for optimization, code standards, missed validation.
What's in this version:
- Rewritten, instead of large complex script - few tools with each own
task. - Solid CLI tool and GUI script on top of it.
- Apply all previous code reviews on new code.
- Some improvements from myself
- Input arguments as usual and pass users/passwords to mysql script as
environment vars for improved security. - Man page written(not for review)
Github
virtualhost-cli.sh - main cli tool, the only one script what need root
#!/usr/bin/env bash
set -e
cd "$0%/*"
source virtualhost.inc.sh
parseargs "$@"
validate
parse
#connect
hostfile="$config[a2ensite]$config[subdomain].conf"
siteconf="$config[apachesites]$hostfile"
(cat >"$siteconf" <<EOF
<VirtualHost $config[virtualhost]:$config[virtualport]>
ServerAdmin $config[serveradmin]
DocumentRoot $config[webroot]
ServerName $config[domain]
ServerAlias $config[domain]
<Directory "$config[webroot]">
AllowOverride All
Require local
</Directory>
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
LogLevel error
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
EOF
) || die "May run as root or give $siteconf writable permissions to current user"
(
mkdir -p "$config[webroot]"
chown $config[webmaster]:$config[webgroup] "$config[webroot]"
chmod u=rwX,g=rXs,o= "$config[webroot]"
chown root:root "$siteconf"
chmod u=rw,g=r,o=r "$siteconf"
a2ensite "$hostfile"
systemctl reload apache2
) || die "Run as root"
die "Config file saved and enabled at $siteconf" "Notice" 0
virtualhost.inc.sh - lib used by all other scripts
#check if function exists
if ! type die &>/dev/null;then
die()
echo "$2:-Error: $1" >&2
exit $3:-1
fi
[[ "$BASH_VERSINFO:-0" -ge 4 ]] || die "Bash version 4 or above required"
# defaults
declare -A config=()
config[webmaster]="$(id -un)" # user who access web files. group is www-data
config[webgroup]="www-data" # apache2 web group, does't need to be webmaster group. SGID set for folder.
config[webroot]='$homedir/Web/$subdomain'
config[domain]="localhost" # domain for creating subdomains
config[virtualhost]="*" # ip of virtualhost in case server listen on many interfaces or "*" for all
config[virtualport]="80" # port of virtualhost. apache2 must listen on that ip:port
config[serveradmin]="webmaster@localhost" # admin email
config[a2ensite]="050-" # short prefix for virtualhost config file
config[apachesites]="/etc/apache2/sites-available/" # virtualhosts config folder
declare -A mysql=() # mysql script read values from env
have_command()
type -p "$1" >/dev/null
try()
have_command "$1" && "$@"
if_match()
[[ "$1" =~ $2 ]]
validate()
(if_match "$config[virtualhost]" "^[a-zA-Z]([a-zA-Z0-9-]0,61[a-zA-Z0-9.])*$")
tolowercase() tr '[:upper:]' '[:lower:]'
parse() cut -d: -f6 )
webmaster="$config[webmaster]"
subdomain="$config[subdomain]"
domain="$config[subdomain].$config[domain]"
envsubst '$homedir,$webmaster,$subdomain,$domain')
config[domain]="$config[subdomain].$config[domain]"
config[domain]=$(tolowercase "$config[domain]")
config[subdomain]=$(tolowercase "$config[subdomain]")
config[virtualhost]=$(tolowercase "$config[virtualhost]")
# check if apache listening on defined host:port
connect()
# load all allowed arguments into $config array
parseargs()
(getopt --test > /dev/null)
validate_mysql()
for key in adminuser database user;do
(LANG=C; if_match "$mysql[$key]" "^[a-zA-Z][a-zA-Z0-9_-]*$")
escape_mysql()
for key in adminpasswd passwd;do
printf -v var "%q" "$mysql[$key]"
mysql[$key]=$var
done
virtualhost-yad.sh - GUI tool for CLI scripts
#!/usr/bin/env bash
set -e
cd "$0%/*"
die()
echo "$2:-Error: $1" >&2
xmessage -buttons Ok:0 -nearmouse "$2:-Error: $1" -timeout 10
exit $3:-1
source virtualhost.inc.sh
in_terminal()
[ -t 0 ]
die()
local msg="$2:-Error: $1"
echo "$msg" >&2
in_terminal && exit $3:-1
try notify-send "$msg" && exit $3:-1
try yad --info --text="$msg" && exit $3:-1
try xmessage -buttons Ok:0 -nearmouse "$msg" -timeout 10 && exit $3:-1
exit $3:-1
have_command yad || die "yad package required. 'sudo apt install yad'"
user_info()
yad --title="Virtualhost" --window-icon="$2:-error" --info --text="$1" --timeout="$3:-15" --button="Ok:0" --center
parseargs "$@"
while true; do
formbutton=0
formoutput=$(yad --form --field="Subdomain" --field="Domain" --field="Web master username"
--field="Apache group" --field='Webroot'
--field='Webroot variables - $homedir(of webmaster) $subdomain $webmaster $domain:LBL'
--field="Virtualhost ip or domain"
--field="Virtualhost port" --field="Server admin email"
--field="Create mysql user&db:CHK"
--field="Mysql admin user" --field="Mysql admin password"
--field="Create database"
--field="Create mysql user" --field="Create mysql password"
--button="Cancel:5" --button="Save defaults:2" --button="Create:0"
--title="Create apache virtualhost"
--text='Subdomain are case sensetive for Webroot folder $subdomain variable'
--focus-field=1 --center --window-icon="preferences-system" --width=600
"$config[subdomain]" "$config[domain]" "$config[webmaster]" "$config[webgroup]"
"$config[webroot]" "test" "$config[virtualhost]" "$config[virtualport]"
"$config[serveradmin]" true
"$mysql[adminuser]" "$mysql[adminpasswd]"
"$mysql[database]" "$mysql[user]" "$mysql[passwd]"
) || formbutton="$?" && true
# Cancel(5) or close window(other code)
[[ "$formbutton" -ne 0 && "$formbutton" -ne 2 && "$formbutton" -ne 1 ]] && die "Cancel"
IFS='|' read -r -a form <<< "$formoutput"
pos=0
for key in subdomain domain webmaster webgroup webroot nothing virtualhost virtualport serveradmin;do
config[$key]="$form[$pos]"
let pos=pos+1
done
usemysql=
[[ "$form[9]" -eq "TRUE" ]] && usemysql=1
pos=10
for key in adminuser adminpasswd database user passwd;do
mysql[$key]="$form[$pos]"
let pos=pos+1
done
vres=0
# subdomain can't be default option, skip it
[[ "$formbutton" -eq 2 ]] && skipsubdomain=1 || skipsubdomain=
# validate input, continue or show error and return to form
valoutput=$(validate $skipsubdomain 2>&1) || vres=$? && true
[[ "$vres" -ne 0 ]] && user_info "$valoutput" && continue
clires=0
if [[ "$formbutton" -ne 2 ]]; then
cmd="pkexec `pwd`/virtualhost-cli.sh"
[[ "$formbutton" -eq 2 ]] && cmd="./virtualhost-install.sh"
clioutput=$($cmd --subdomain "$config[subdomain]"
--domain "$config[domain]" --webmaster "$config[webmaster]"
--webgroup "$config[webgroup]" --webroot "$config[webroot]"
--virtualhost "$config[virtualhost]" --virtualport "$config[virtualport]"
--serveradmin "$config[serveradmin]" 2>&1) || clires=$? && true
[[ "$clioutput" ]] && user_info "$clioutput" || true
[[ "$clires" -ne 0 ]] && continue
# mysql
if [[ "$usemysql" ]]; then
mysqlres=0
mysqloutput=$(adminuser="$mysql[adminuser]" adminpwd="$mysql[adminpasswd]"
database="$mysql[database]" mysqluser="$mysql[user]"
mysqlpasswd="$mysql[passwd]" ./virtualhost-mysql.sh
--subdomain "$config[subdomain]" 2>&1) || mysqlres=$? && true
[[ "$mysqloutput" ]] && user_info "$mysqloutput" || true
[[ "$mysqlres" -ne 0 ]] && continue
break
fi
break
fi
done
virtualhost-mysql.sh - create db and user, values passed by environment variables to not appear in ps output - for security.
#!/usr/bin/env bash
set -e
cd "$0%/*"
source virtualhost.inc.sh
parseargs "$@" # only --subdomain used
# read values from env
subdomain=$(tolowercase "$config[subdomain]")
mysql[adminuser]="$adminuser:-root"
mysql[adminpasswd]="$adminpwd"
mysql[database]="$mysqldatabase:-$subdomain"
mysql[user]="$mysqluser:-$subdomain:-$(id -un)"
mysql[passwd]="$mysqlpasswd"
validate_mysql
escape_mysql
mysqlcreate=$(cat <<EOF
CREATE USER '$mysql[user]'@'localhost' IDENTIFIED BY '$mysql[passwd]';
GRANT USAGE ON *.* TO '$mysql[user]'@'localhost';
CREATE DATABASE IF NOT EXISTS `$mysql[database]` CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL PRIVILEGES ON `$mysql[database]`.* TO '$mysql[user]'@'localhost';
FLUSH PRIVILEGES;
EOF
)
mysql --user="$mysql[adminuser]" --password="$mysql[adminpasswd]" <<<$mysqlcreate
virtualhost-install.sh - install desktop shortcut with arguments defined as defaults for GUI tool. Can be executed from "virtualhost-yad.sh" with values from form. Not for review as simple and similar.
bash
bash
asked 1 hour ago
LeonidMewLeonidMew
1477
1477
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f217089%2fcreate-apache2-virtualhost-mysql-db-user-cli-tool-and-gui-on-top-of-it%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f217089%2fcreate-apache2-virtualhost-mysql-db-user-cli-tool-and-gui-on-top-of-it%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown