More robust bash backends using heredoc
This commit is contained in:
parent
f60376ab1d
commit
43eb744f81
2
TODO.md
2
TODO.md
|
@ -382,3 +382,5 @@ http://wiki2.dovecot.org/Pigeonhole/Sieve/Examples
|
||||||
|
|
||||||
|
|
||||||
# mail system users group? which one is more convinient? if main group does not exists, backend will fail!
|
# mail system users group? which one is more convinient? if main group does not exists, backend will fail!
|
||||||
|
|
||||||
|
Bash/Python/PHPBackend
|
||||||
|
|
|
@ -23,13 +23,14 @@ class MySQLBackend(ServiceController):
|
||||||
if database.type != database.MYSQL:
|
if database.type != database.MYSQL:
|
||||||
return
|
return
|
||||||
context = self.get_context(database)
|
context = self.get_context(database)
|
||||||
self.append(
|
|
||||||
"mysql -e 'CREATE DATABASE `%(database)s`;' || true" % context
|
|
||||||
)
|
|
||||||
# Not available on delete()
|
# Not available on delete()
|
||||||
context['owner'] = database.owner
|
context['owner'] = database.owner
|
||||||
# clean previous privileges
|
self.append(textwrap.dedent("""
|
||||||
self.append("""mysql mysql -e 'DELETE FROM db WHERE db = "%(database)s";'""" % context)
|
# Create database and re-set permissions
|
||||||
|
mysql -e 'CREATE DATABASE `%(database)s`;' || true
|
||||||
|
mysql mysql -e 'DELETE FROM db WHERE db = "%(database)s";'\
|
||||||
|
""") % context
|
||||||
|
)
|
||||||
for user in database.users.all():
|
for user in database.users.all():
|
||||||
context.update({
|
context.update({
|
||||||
'username': user.username,
|
'username': user.username,
|
||||||
|
@ -44,11 +45,19 @@ class MySQLBackend(ServiceController):
|
||||||
if database.type != database.MYSQL:
|
if database.type != database.MYSQL:
|
||||||
return
|
return
|
||||||
context = self.get_context(database)
|
context = self.get_context(database)
|
||||||
self.append("mysql -e 'DROP DATABASE `%(database)s`;' || exit_code=$?" % context)
|
self.append(textwrap.dedent("""
|
||||||
self.append("mysql mysql -e 'DELETE FROM db WHERE db = \"%(database)s\";'" % context)
|
# Remove database %(database)s
|
||||||
|
mysql -e 'DROP DATABASE `%(database)s`;' || exit_code=$?
|
||||||
|
mysql mysql -e 'DELETE FROM db WHERE db = "%(database)s";'\
|
||||||
|
""") % context
|
||||||
|
)
|
||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
self.append("mysql -e 'FLUSH PRIVILEGES;'")
|
self.append(textwrap.dedent("""
|
||||||
|
# Apply permissions
|
||||||
|
mysql -e 'FLUSH PRIVILEGES;'\
|
||||||
|
""")
|
||||||
|
)
|
||||||
super(MySQLBackend, self).commit()
|
super(MySQLBackend, self).commit()
|
||||||
|
|
||||||
def get_context(self, database):
|
def get_context(self, database):
|
||||||
|
@ -75,10 +84,8 @@ class MySQLUserBackend(ServiceController):
|
||||||
return
|
return
|
||||||
context = self.get_context(user)
|
context = self.get_context(user)
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""\
|
||||||
mysql -e 'CREATE USER "%(username)s"@"%(host)s";' || true \
|
# Create user %(username)s
|
||||||
""") % context
|
mysql -e 'CREATE USER "%(username)s"@"%(host)s";' || true
|
||||||
)
|
|
||||||
self.append(textwrap.dedent("""\
|
|
||||||
mysql -e 'UPDATE mysql.user SET Password="%(password)s" WHERE User="%(username)s";'\
|
mysql -e 'UPDATE mysql.user SET Password="%(password)s" WHERE User="%(username)s";'\
|
||||||
""") % context
|
""") % context
|
||||||
)
|
)
|
||||||
|
@ -87,12 +94,14 @@ class MySQLUserBackend(ServiceController):
|
||||||
if user.type != user.MYSQL:
|
if user.type != user.MYSQL:
|
||||||
return
|
return
|
||||||
context = self.get_context(user)
|
context = self.get_context(user)
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""
|
||||||
|
# Delete user %(username)s
|
||||||
mysql -e 'DROP USER "%(username)s"@"%(host)s";' || exit_code=$? \
|
mysql -e 'DROP USER "%(username)s"@"%(host)s";' || exit_code=$? \
|
||||||
""") % context
|
""") % context
|
||||||
)
|
)
|
||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
|
self.append("# Apply permissions")
|
||||||
self.append("mysql -e 'FLUSH PRIVILEGES;'")
|
self.append("mysql -e 'FLUSH PRIVILEGES;'")
|
||||||
|
|
||||||
def get_context(self, user):
|
def get_context(self, user):
|
||||||
|
|
|
@ -45,19 +45,21 @@ class Bind9MasterDomainBackend(ServiceController):
|
||||||
def update_zone(self, domain, context):
|
def update_zone(self, domain, context):
|
||||||
context['zone'] = ';; %(banner)s\n' % context
|
context['zone'] = ';; %(banner)s\n' % context
|
||||||
context['zone'] += domain.render_zone()
|
context['zone'] += domain.render_zone()
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""\
|
||||||
|
# Generate %(name)s zone file
|
||||||
cat << 'EOF' > %(zone_path)s.tmp
|
cat << 'EOF' > %(zone_path)s.tmp
|
||||||
%(zone)s
|
%(zone)s
|
||||||
EOF
|
EOF
|
||||||
diff -N -I'^\s*;;' %(zone_path)s %(zone_path)s.tmp || UPDATED=1
|
diff -N -I'^\s*;;' %(zone_path)s %(zone_path)s.tmp || UPDATED=1
|
||||||
# Because bind reload will not display any fucking error
|
# Because bind reload will not display any fucking error
|
||||||
named-checkzone -k fail -n fail %(name)s %(zone_path)s.tmp
|
named-checkzone -k fail -n fail %(name)s %(zone_path)s.tmp
|
||||||
mv %(zone_path)s.tmp %(zone_path)s
|
mv %(zone_path)s.tmp %(zone_path)s\
|
||||||
""") % context
|
""") % context
|
||||||
)
|
)
|
||||||
|
|
||||||
def update_conf(self, context):
|
def update_conf(self, context):
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""
|
||||||
|
# Update bind config file for %(name)s
|
||||||
read -r -d '' conf << 'EOF' || true
|
read -r -d '' conf << 'EOF' || true
|
||||||
%(conf)s
|
%(conf)s
|
||||||
EOF
|
EOF
|
||||||
|
@ -68,8 +70,8 @@ class Bind9MasterDomainBackend(ServiceController):
|
||||||
UPDATED=1
|
UPDATED=1
|
||||||
}""") % context
|
}""") % context
|
||||||
)
|
)
|
||||||
# Delete ex-top-domains that are now subdomains
|
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""\
|
||||||
|
# Delete ex-top-domains that are now subdomains
|
||||||
sed -i -e '/zone\s\s*".*\.%(name)s".*/,/^\s*};\s*$/d' \\
|
sed -i -e '/zone\s\s*".*\.%(name)s".*/,/^\s*};\s*$/d' \\
|
||||||
-e 'N; /^\s*\\n\s*$/d; P; D' %(conf_path)s""") % context
|
-e 'N; /^\s*\\n\s*$/d; P; D' %(conf_path)s""") % context
|
||||||
)
|
)
|
||||||
|
@ -79,6 +81,7 @@ class Bind9MasterDomainBackend(ServiceController):
|
||||||
|
|
||||||
def delete(self, domain):
|
def delete(self, domain):
|
||||||
context = self.get_context(domain)
|
context = self.get_context(domain)
|
||||||
|
self.append('# Delete zone file for %(name)s' % context)
|
||||||
self.append('rm -f %(zone_path)s;' % context)
|
self.append('rm -f %(zone_path)s;' % context)
|
||||||
self.delete_conf(context)
|
self.delete_conf(context)
|
||||||
|
|
||||||
|
@ -87,6 +90,7 @@ class Bind9MasterDomainBackend(ServiceController):
|
||||||
# These can never be top level domains
|
# These can never be top level domains
|
||||||
return
|
return
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""
|
||||||
|
# Delete config for %(name)s
|
||||||
sed -e '/zone\s\s*"%(name)s".*/,/^\s*};\s*$/d' \\
|
sed -e '/zone\s\s*"%(name)s".*/,/^\s*};\s*$/d' \\
|
||||||
-e 'N; /^\s*\\n\s*$/d; P; D' %(conf_path)s > %(conf_path)s.tmp""") % context
|
-e 'N; /^\s*\\n\s*$/d; P; D' %(conf_path)s > %(conf_path)s.tmp""") % context
|
||||||
)
|
)
|
||||||
|
@ -95,7 +99,12 @@ class Bind9MasterDomainBackend(ServiceController):
|
||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
""" reload bind if needed """
|
""" reload bind if needed """
|
||||||
self.append('if [[ $UPDATED == 1 ]]; then service bind9 reload; fi')
|
self.append(textwrap.dedent("""
|
||||||
|
# Apply changes
|
||||||
|
if [[ $UPDATED == 1 ]]; then
|
||||||
|
service bind9 reload
|
||||||
|
fi""")
|
||||||
|
)
|
||||||
|
|
||||||
def get_servers(self, domain, backend):
|
def get_servers(self, domain, backend):
|
||||||
""" Get related server IPs from registered backend routes """
|
""" Get related server IPs from registered backend routes """
|
||||||
|
@ -180,12 +189,12 @@ class Bind9SlaveDomainBackend(Bind9MasterDomainBackend):
|
||||||
self.delete_conf(context)
|
self.delete_conf(context)
|
||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
""" ideally slave should be restarted after master """
|
self.append(textwrap.dedent("""
|
||||||
self.append(textwrap.dedent("""\
|
# Apply changes
|
||||||
if [[ $UPDATED == 1 ]]; then
|
if [[ $UPDATED == 1 ]]; then
|
||||||
|
# Async restart, ideally after master
|
||||||
nohup bash -c 'sleep 1 && service bind9 reload' &> /dev/null &
|
nohup bash -c 'sleep 1 && service bind9 reload' &> /dev/null &
|
||||||
fi
|
fi""")
|
||||||
""")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_context(self, domain):
|
def get_context(self, domain):
|
||||||
|
@ -196,7 +205,7 @@ class Bind9SlaveDomainBackend(Bind9MasterDomainBackend):
|
||||||
'masters': '; '.join(self.get_masters_ips(domain)) or 'none',
|
'masters': '; '.join(self.get_masters_ips(domain)) or 'none',
|
||||||
'conf_path': self.CONF_PATH,
|
'conf_path': self.CONF_PATH,
|
||||||
}
|
}
|
||||||
context['conf'] = textwrap.dedent("""
|
context['conf'] = textwrap.dedent("""\
|
||||||
zone "%(name)s" {
|
zone "%(name)s" {
|
||||||
// %(banner)s
|
// %(banner)s
|
||||||
type slave;
|
type slave;
|
||||||
|
|
|
@ -27,6 +27,7 @@ class MailmanVirtualDomainBackend(ServiceController):
|
||||||
domain = context['address_domain']
|
domain = context['address_domain']
|
||||||
if domain and self.is_local_domain(domain):
|
if domain and self.is_local_domain(domain):
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""
|
||||||
|
# Add virtual domain %(address_domain)s
|
||||||
[[ $(grep '^\s*%(address_domain)s\s*$' %(virtual_alias_domains)s) ]] || {
|
[[ $(grep '^\s*%(address_domain)s\s*$' %(virtual_alias_domains)s) ]] || {
|
||||||
echo '%(address_domain)s' >> %(virtual_alias_domains)s
|
echo '%(address_domain)s' >> %(virtual_alias_domains)s
|
||||||
UPDATED_VIRTUAL_ALIAS_DOMAINS=1
|
UPDATED_VIRTUAL_ALIAS_DOMAINS=1
|
||||||
|
@ -39,7 +40,11 @@ class MailmanVirtualDomainBackend(ServiceController):
|
||||||
def exclude_virtual_alias_domain(self, context):
|
def exclude_virtual_alias_domain(self, context):
|
||||||
domain = context['address_domain']
|
domain = context['address_domain']
|
||||||
if domain and self.is_last_domain(domain):
|
if domain and self.is_last_domain(domain):
|
||||||
self.append("sed -i '/^%(address_domain)s\s*$/d' %(virtual_alias_domains)s" % context)
|
self.append(textwrap.dedent("""
|
||||||
|
# Remove %(address_domain)s from virtual domains
|
||||||
|
sed -i '/^%(address_domain)s\s*$/d' %(virtual_alias_domains)s\
|
||||||
|
""") % context
|
||||||
|
)
|
||||||
|
|
||||||
def save(self, mail_list):
|
def save(self, mail_list):
|
||||||
context = self.get_context(mail_list)
|
context = self.get_context(mail_list)
|
||||||
|
@ -52,10 +57,12 @@ class MailmanVirtualDomainBackend(ServiceController):
|
||||||
def commit(self):
|
def commit(self):
|
||||||
context = self.get_context_files()
|
context = self.get_context_files()
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""
|
||||||
|
# Apply changes if needed
|
||||||
if [[ $UPDATED_VIRTUAL_ALIAS_DOMAINS == 1 ]]; then
|
if [[ $UPDATED_VIRTUAL_ALIAS_DOMAINS == 1 ]]; then
|
||||||
service postfix reload
|
service postfix reload
|
||||||
fi""") % context
|
fi""") % context
|
||||||
)
|
)
|
||||||
|
super(MailmanVirtualDomainBackend, self).commit()
|
||||||
|
|
||||||
def get_context_files(self):
|
def get_context_files(self):
|
||||||
return {
|
return {
|
||||||
|
@ -108,15 +115,16 @@ class MailmanBackend(MailmanVirtualDomainBackend):
|
||||||
def save(self, mail_list):
|
def save(self, mail_list):
|
||||||
context = self.get_context(mail_list)
|
context = self.get_context(mail_list)
|
||||||
# Create list
|
# Create list
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""
|
||||||
|
# Create list %(name)s
|
||||||
[[ ! -e '%(mailman_root)s/lists/%(name)s' ]] && {
|
[[ ! -e '%(mailman_root)s/lists/%(name)s' ]] && {
|
||||||
newlist --quiet --emailhost='%(domain)s' '%(name)s' '%(admin)s' '%(password)s'
|
newlist --quiet --emailhost='%(domain)s' '%(name)s' '%(admin)s' '%(password)s'
|
||||||
}""") % context)
|
}""") % context)
|
||||||
# Custom domain
|
# Custom domain
|
||||||
if mail_list.address:
|
if mail_list.address:
|
||||||
context['aliases'] = self.get_virtual_aliases(context)
|
context['aliases'] = self.get_virtual_aliases(context)
|
||||||
# Preserve indentation
|
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""\
|
||||||
|
# Create list alias for custom domain
|
||||||
aliases='%(aliases)s'
|
aliases='%(aliases)s'
|
||||||
if [[ ! $(grep '\s\s*%(name)s\s*$' %(virtual_alias)s) ]]; then
|
if [[ ! $(grep '\s\s*%(name)s\s*$' %(virtual_alias)s) ]]; then
|
||||||
echo "${aliases}" >> %(virtual_alias)s
|
echo "${aliases}" >> %(virtual_alias)s
|
||||||
|
@ -128,27 +136,25 @@ class MailmanBackend(MailmanVirtualDomainBackend):
|
||||||
echo "${aliases}" >> %(virtual_alias)s
|
echo "${aliases}" >> %(virtual_alias)s
|
||||||
UPDATED_VIRTUAL_ALIAS=1
|
UPDATED_VIRTUAL_ALIAS=1
|
||||||
fi
|
fi
|
||||||
fi""") % context
|
fi
|
||||||
)
|
echo "require_explicit_destination = 0" | \\
|
||||||
self.append(
|
%(mailman_root)s/bin/config_list -i /dev/stdin %(name)s
|
||||||
'echo "require_explicit_destination = 0" | '
|
echo "host_name = '%(address_domain)s'" | \\
|
||||||
'%(mailman_root)s/bin/config_list -i /dev/stdin %(name)s' % context
|
|
||||||
)
|
|
||||||
self.append(textwrap.dedent("""\
|
|
||||||
echo "host_name = '%(address_domain)s'" | \
|
|
||||||
%(mailman_root)s/bin/config_list -i /dev/stdin %(name)s""") % context
|
%(mailman_root)s/bin/config_list -i /dev/stdin %(name)s""") % context
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# Cleanup shit
|
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""\
|
||||||
|
# Cleanup possible ex-custom domain
|
||||||
if [[ ! $(grep '\s\s*%(name)s\s*$' %(virtual_alias)s) ]]; then
|
if [[ ! $(grep '\s\s*%(name)s\s*$' %(virtual_alias)s) ]]; then
|
||||||
sed -i "/^.*\s%(name)s\s*$/d" %(virtual_alias)s
|
sed -i "/^.*\s%(name)s\s*$/d" %(virtual_alias)s
|
||||||
fi""") % context
|
fi""") % context
|
||||||
)
|
)
|
||||||
# Update
|
# Update
|
||||||
if context['password'] is not None:
|
if context['password'] is not None:
|
||||||
self.append(
|
self.append(textwrap.dedent("""\
|
||||||
'%(mailman_root)s/bin/change_pw --listname="%(name)s" --password="%(password)s"' % context
|
# Re-set password
|
||||||
|
%(mailman_root)s/bin/change_pw --listname="%(name)s" --password="%(password)s"\
|
||||||
|
""") % context
|
||||||
)
|
)
|
||||||
self.include_virtual_alias_domain(context)
|
self.include_virtual_alias_domain(context)
|
||||||
if mail_list.active:
|
if mail_list.active:
|
||||||
|
@ -160,10 +166,9 @@ class MailmanBackend(MailmanVirtualDomainBackend):
|
||||||
context = self.get_context(mail_list)
|
context = self.get_context(mail_list)
|
||||||
self.exclude_virtual_alias_domain(context)
|
self.exclude_virtual_alias_domain(context)
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""
|
||||||
|
# Remove list %(name)s
|
||||||
sed -i -e '/^.*\s%(name)s\(%(suffixes_regex)s\)\s*$/d' \\
|
sed -i -e '/^.*\s%(name)s\(%(suffixes_regex)s\)\s*$/d' \\
|
||||||
-e 'N; /^\s*\\n\s*$/d; P; D' %(virtual_alias)s""") % context
|
-e 'N; /^\s*\\n\s*$/d; P; D' %(virtual_alias)s
|
||||||
)
|
|
||||||
self.append(textwrap.dedent("""
|
|
||||||
# Non-existent list archives produce exit code 1
|
# Non-existent list archives produce exit code 1
|
||||||
exit_code=0
|
exit_code=0
|
||||||
rmlist -a %(name)s || exit_code=$?
|
rmlist -a %(name)s || exit_code=$?
|
||||||
|
@ -175,12 +180,14 @@ class MailmanBackend(MailmanVirtualDomainBackend):
|
||||||
def commit(self):
|
def commit(self):
|
||||||
context = self.get_context_files()
|
context = self.get_context_files()
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""
|
||||||
|
# Apply changes if needed
|
||||||
if [[ $UPDATED_VIRTUAL_ALIAS == 1 ]]; then
|
if [[ $UPDATED_VIRTUAL_ALIAS == 1 ]]; then
|
||||||
postmap %(virtual_alias)s
|
postmap %(virtual_alias)s
|
||||||
fi
|
fi
|
||||||
if [[ $UPDATED_VIRTUAL_ALIAS_DOMAINS == 1 ]]; then
|
if [[ $UPDATED_VIRTUAL_ALIAS_DOMAINS == 1 ]]; then
|
||||||
service postfix reload
|
service postfix reload
|
||||||
fi""") % context
|
fi
|
||||||
|
exit $exit_code""") % context
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_context_files(self):
|
def get_context_files(self):
|
||||||
|
|
|
@ -364,7 +364,7 @@ class PostfixAddressBackend(PostfixAddressVirtualDomainBackend):
|
||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
context = self.get_context_files()
|
context = self.get_context_files()
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""
|
||||||
# Apply changes if needed
|
# Apply changes if needed
|
||||||
[[ $UPDATED_VIRTUAL_ALIAS_DOMAINS == 1 ]] && {
|
[[ $UPDATED_VIRTUAL_ALIAS_DOMAINS == 1 ]] && {
|
||||||
service postfix reload
|
service postfix reload
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import textwrap
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
|
@ -207,10 +208,10 @@ class ServiceBackend(plugins.Plugin, metaclass=ServiceMount):
|
||||||
hook for executing something at the beging
|
hook for executing something at the beging
|
||||||
define functions or initialize state
|
define functions or initialize state
|
||||||
"""
|
"""
|
||||||
self.append(
|
self.append(textwrap.dedent("""\
|
||||||
'set -e\n'
|
set -e
|
||||||
'set -o pipefail\n'
|
set -o pipefail
|
||||||
'exit_code=0;\n'
|
exit_code=0""")
|
||||||
)
|
)
|
||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
|
|
|
@ -31,27 +31,26 @@ class UNIXUserBackend(ServiceController):
|
||||||
context['groups_arg'] = '--groups %s' % groups if groups else ''
|
context['groups_arg'] = '--groups %s' % groups if groups else ''
|
||||||
# TODO userd add will fail if %(user)s group already exists
|
# TODO userd add will fail if %(user)s group already exists
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""
|
||||||
# Update/create %(user)s user state
|
# Update/create user state for %(user)s
|
||||||
if [[ $( id %(user)s ) ]]; then
|
if [[ $( id %(user)s ) ]]; then
|
||||||
usermod %(user)s --home %(home)s \\
|
usermod %(user)s --home %(home)s \\
|
||||||
--password '%(password)s' \\
|
--password '%(password)s' \\
|
||||||
--shell %(shell)s %(groups_arg)s
|
--shell %(shell)s %(groups_arg)s
|
||||||
else
|
else
|
||||||
|
useradd_code=0
|
||||||
useradd %(user)s --home %(home)s \\
|
useradd %(user)s --home %(home)s \\
|
||||||
--password '%(password)s' \\
|
--password '%(password)s' \\
|
||||||
--shell %(shell)s %(groups_arg)s || {
|
--shell %(shell)s %(groups_arg)s || useradd_code=$?
|
||||||
useradd_code=$?
|
|
||||||
# User is logged in, kill and retry
|
|
||||||
if [[ $useradd_code -eq 8 ]]; then
|
if [[ $useradd_code -eq 8 ]]; then
|
||||||
|
# User is logged in, kill and retry
|
||||||
pkill -u %(user)s; sleep 2
|
pkill -u %(user)s; sleep 2
|
||||||
pkill -9 -u %(user)s; sleep 1
|
pkill -9 -u %(user)s; sleep 1
|
||||||
useradd %(user)s --home %(home)s \\
|
useradd %(user)s --home %(home)s \\
|
||||||
--password '%(password)s' \\
|
--password '%(password)s' \\
|
||||||
--shell %(shell)s %(groups_arg)s
|
--shell %(shell)s %(groups_arg)s
|
||||||
else
|
elif [[ $useradd_code -ne 0 ]]; then
|
||||||
exit $useradd_code
|
exit $useradd_code
|
||||||
fi
|
fi
|
||||||
}
|
|
||||||
fi
|
fi
|
||||||
mkdir -p %(base_home)s
|
mkdir -p %(base_home)s
|
||||||
chmod 750 %(base_home)s
|
chmod 750 %(base_home)s
|
||||||
|
@ -59,7 +58,7 @@ class UNIXUserBackend(ServiceController):
|
||||||
)
|
)
|
||||||
if context['home'] != context['base_home']:
|
if context['home'] != context['base_home']:
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""
|
||||||
# Set extra permissions since %(user)s home is inside %(mainuser)s home
|
# Set extra permissions: %(user)s home is inside %(mainuser)s home
|
||||||
if [[ $(mount | grep "^$(df %(home)s|grep '^/')\s" | grep acl) ]]; then
|
if [[ $(mount | grep "^$(df %(home)s|grep '^/')\s" | grep acl) ]]; then
|
||||||
# Accountn group as the owner
|
# Accountn group as the owner
|
||||||
chown %(mainuser)s:%(mainuser)s %(home)s
|
chown %(mainuser)s:%(mainuser)s %(home)s
|
||||||
|
@ -90,7 +89,7 @@ class UNIXUserBackend(ServiceController):
|
||||||
nohup bash -c 'sleep 2 && killall -u %(user)s -s KILL' &> /dev/null &
|
nohup bash -c 'sleep 2 && killall -u %(user)s -s KILL' &> /dev/null &
|
||||||
killall -u %(user)s || true
|
killall -u %(user)s || true
|
||||||
userdel %(user)s || exit_code=$?
|
userdel %(user)s || exit_code=$?
|
||||||
groupdel %(group)s || exit_code=$?
|
groupdel %(group)s || exit_code=$?\
|
||||||
""") % context
|
""") % context
|
||||||
)
|
)
|
||||||
if context['deleted_home']:
|
if context['deleted_home']:
|
||||||
|
@ -132,14 +131,14 @@ class UNIXUserBackend(ServiceController):
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""\
|
||||||
# Grant access to main user
|
# Grant access to main user
|
||||||
find '%(perm_to)s' -type d %(exclude_acl)s \\
|
find '%(perm_to)s' -type d %(exclude_acl)s \\
|
||||||
-exec setfacl -m d:u:%(mainuser)s:rwx {} \\;
|
-exec setfacl -m d:u:%(mainuser)s:rwx {} \\;\
|
||||||
""") % context
|
""") % context
|
||||||
)
|
)
|
||||||
elif user.set_perm_action == 'revoke':
|
elif user.set_perm_action == 'revoke':
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""\
|
||||||
# Revoke permissions
|
# Revoke permissions
|
||||||
find '%(perm_to)s' %(exclude_acl)s \\
|
find '%(perm_to)s' %(exclude_acl)s \\
|
||||||
-exec setfacl -m u:%(user)s:%(perm_perms)s {} \\;
|
-exec setfacl -m u:%(user)s:%(perm_perms)s {} \\;\
|
||||||
""") % context
|
""") % context
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
@ -149,11 +148,10 @@ class UNIXUserBackend(ServiceController):
|
||||||
context = {
|
context = {
|
||||||
'path': user.path_to_validate,
|
'path': user.path_to_validate,
|
||||||
}
|
}
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""
|
||||||
if [[ ! -e '%(path)s' ]]; then
|
if [[ ! -e '%(path)s' ]]; then
|
||||||
echo "%(path)s path does not exists." >&2
|
echo "%(path)s path does not exists." >&2
|
||||||
fi
|
fi""") % context
|
||||||
""") % context
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_groups(self, user):
|
def get_groups(self, user):
|
||||||
|
|
|
@ -15,17 +15,19 @@ class WebAppServiceMixin(object):
|
||||||
)
|
)
|
||||||
|
|
||||||
def create_webapp_dir(self, context):
|
def create_webapp_dir(self, context):
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""
|
||||||
|
# Create webapp dir
|
||||||
CREATED=0
|
CREATED=0
|
||||||
[[ ! -e %(app_path)s ]] && CREATED=1
|
[[ ! -e %(app_path)s ]] && CREATED=1
|
||||||
mkdir -p %(app_path)s
|
mkdir -p %(app_path)s
|
||||||
chown %(user)s:%(group)s %(app_path)s
|
chown %(user)s:%(group)s %(app_path)s\
|
||||||
""") % context
|
""") % context
|
||||||
)
|
)
|
||||||
|
|
||||||
def set_under_construction(self, context):
|
def set_under_construction(self, context):
|
||||||
if context['under_construction_path']:
|
if context['under_construction_path']:
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""
|
||||||
|
# Set under construction if needed
|
||||||
if [[ $CREATED == 1 && ! $(ls -A %(app_path)s) ]]; then
|
if [[ $CREATED == 1 && ! $(ls -A %(app_path)s) ]]; then
|
||||||
# Async wait 2 more seconds for other backends to lock app_path or cp under construction
|
# Async wait 2 more seconds for other backends to lock app_path or cp under construction
|
||||||
nohup bash -c '
|
nohup bash -c '
|
||||||
|
|
|
@ -44,6 +44,7 @@ class PHPBackend(WebAppServiceMixin, ServiceController):
|
||||||
|
|
||||||
def save_fpm(self, webapp, context):
|
def save_fpm(self, webapp, context):
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""
|
||||||
|
# Generate FPM configuration
|
||||||
read -r -d '' fpm_config << 'EOF' || true
|
read -r -d '' fpm_config << 'EOF' || true
|
||||||
%(fpm_config)s
|
%(fpm_config)s
|
||||||
EOF
|
EOF
|
||||||
|
@ -58,7 +59,8 @@ class PHPBackend(WebAppServiceMixin, ServiceController):
|
||||||
|
|
||||||
def save_fcgid(self, webapp, context):
|
def save_fcgid(self, webapp, context):
|
||||||
self.append("mkdir -p %(wrapper_dir)s" % context)
|
self.append("mkdir -p %(wrapper_dir)s" % context)
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""
|
||||||
|
# Generate FCGID configuration
|
||||||
read -r -d '' wrapper << 'EOF' || true
|
read -r -d '' wrapper << 'EOF' || true
|
||||||
%(wrapper)s
|
%(wrapper)s
|
||||||
EOF
|
EOF
|
||||||
|
@ -78,6 +80,7 @@ class PHPBackend(WebAppServiceMixin, ServiceController):
|
||||||
self.append("chown -R %(user)s:%(group)s %(wrapper_dir)s" % context)
|
self.append("chown -R %(user)s:%(group)s %(wrapper_dir)s" % context)
|
||||||
if context['cmd_options']:
|
if context['cmd_options']:
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""\
|
||||||
|
# FCGID options
|
||||||
read -r -d '' cmd_options << 'EOF' || true
|
read -r -d '' cmd_options << 'EOF' || true
|
||||||
%(cmd_options)s
|
%(cmd_options)s
|
||||||
EOF
|
EOF
|
||||||
|
@ -122,6 +125,7 @@ class PHPBackend(WebAppServiceMixin, ServiceController):
|
||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""
|
||||||
|
# Apply changes if needed
|
||||||
if [[ $UPDATED_FPM -eq 1 ]]; then
|
if [[ $UPDATED_FPM -eq 1 ]]; then
|
||||||
service php5-fpm reload
|
service php5-fpm reload
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -42,6 +42,7 @@ class WordPressBackend(WebAppServiceMixin, ServiceController):
|
||||||
if (count(glob("%(app_path)s/*")) > 1) {
|
if (count(glob("%(app_path)s/*")) > 1) {
|
||||||
die("App directory not empty.");
|
die("App directory not empty.");
|
||||||
}
|
}
|
||||||
|
// Download and untar wordpress (with caching system)
|
||||||
shell_exec("mkdir -p %(app_path)s
|
shell_exec("mkdir -p %(app_path)s
|
||||||
# Prevent other backends from writting here
|
# Prevent other backends from writting here
|
||||||
touch %(app_path)s/.lock
|
touch %(app_path)s/.lock
|
||||||
|
@ -67,6 +68,7 @@ class WordPressBackend(WebAppServiceMixin, ServiceController):
|
||||||
}
|
}
|
||||||
array_pop($secret_keys);
|
array_pop($secret_keys);
|
||||||
|
|
||||||
|
// setup wordpress database and keys config
|
||||||
$config_file = str_replace('database_name_here', "%(db_name)s", $config_file);
|
$config_file = str_replace('database_name_here', "%(db_name)s", $config_file);
|
||||||
$config_file = str_replace('username_here', "%(db_user)s", $config_file);
|
$config_file = str_replace('username_here', "%(db_user)s", $config_file);
|
||||||
$config_file = str_replace('password_here', "%(password)s", $config_file);
|
$config_file = str_replace('password_here', "%(password)s", $config_file);
|
||||||
|
@ -90,6 +92,8 @@ class WordPressBackend(WebAppServiceMixin, ServiceController):
|
||||||
}
|
}
|
||||||
exc('chown -R %(user)s:%(group)s %(app_path)s');
|
exc('chown -R %(user)s:%(group)s %(app_path)s');
|
||||||
|
|
||||||
|
// Execute wordpress installation process
|
||||||
|
|
||||||
define('WP_CONTENT_DIR', 'wp-content/');
|
define('WP_CONTENT_DIR', 'wp-content/');
|
||||||
define('WP_LANG_DIR', WP_CONTENT_DIR . '/languages' );
|
define('WP_LANG_DIR', WP_CONTENT_DIR . '/languages' );
|
||||||
define('WP_USE_THEMES', true);
|
define('WP_USE_THEMES', true);
|
||||||
|
|
|
@ -99,7 +99,7 @@ class Apache2Backend(ServiceController):
|
||||||
apache_conf += self.render_redirect_https(context)
|
apache_conf += self.render_redirect_https(context)
|
||||||
context['apache_conf'] = apache_conf.strip()
|
context['apache_conf'] = apache_conf.strip()
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""
|
||||||
# Generate %(site_name)s Apache site config
|
# Generate Apache site config for %(site_name)s
|
||||||
read -r -d '' apache_conf << 'EOF' || true
|
read -r -d '' apache_conf << 'EOF' || true
|
||||||
%(apache_conf)s
|
%(apache_conf)s
|
||||||
EOF
|
EOF
|
||||||
|
@ -112,7 +112,7 @@ class Apache2Backend(ServiceController):
|
||||||
)
|
)
|
||||||
if context['server_name'] and site.active:
|
if context['server_name'] and site.active:
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""\
|
||||||
# Enable %(site_name)s site
|
# Enable site %(site_name)s
|
||||||
if [[ ! -f %(sites_enabled)s ]]; then
|
if [[ ! -f %(sites_enabled)s ]]; then
|
||||||
a2ensite %(site_unique_name)s.conf
|
a2ensite %(site_unique_name)s.conf
|
||||||
UPDATED_APACHE=1
|
UPDATED_APACHE=1
|
||||||
|
@ -120,7 +120,7 @@ class Apache2Backend(ServiceController):
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.append(textwrap.dedent("""\
|
self.append(textwrap.dedent("""\
|
||||||
# Disable %(site_name)s site
|
# Disable site %(site_name)s
|
||||||
if [[ -f %(sites_enabled)s ]]; then
|
if [[ -f %(sites_enabled)s ]]; then
|
||||||
a2dissite %(site_unique_name)s.conf;
|
a2dissite %(site_unique_name)s.conf;
|
||||||
UPDATED_APACHE=1
|
UPDATED_APACHE=1
|
||||||
|
@ -130,7 +130,7 @@ class Apache2Backend(ServiceController):
|
||||||
def delete(self, site):
|
def delete(self, site):
|
||||||
context = self.get_context(site)
|
context = self.get_context(site)
|
||||||
self.append(textwrap.dedent("""
|
self.append(textwrap.dedent("""
|
||||||
# Remove %(site_name)s site configuration
|
# Remove site configuration for %(site_name)s
|
||||||
a2dissite %(site_unique_name)s.conf && UPDATED_APACHE=1
|
a2dissite %(site_unique_name)s.conf && UPDATED_APACHE=1
|
||||||
rm -f %(sites_available)s\
|
rm -f %(sites_available)s\
|
||||||
""") % context
|
""") % context
|
||||||
|
|
Loading…
Reference in a new issue