mirror of
https://github.com/mail-in-a-box/mailinabox.git
synced 2026-09-12 00:18:59 +02:00
First big pass on PEP8'ing all the things.
All PEP8 errors (except line length) have been fixed except one. That one will require a little bit of refactoring.
This commit is contained in:
210
setup/migrate.py
210
setup/migrate.py
@@ -5,134 +5,150 @@
|
||||
# We have to be careful here that any dependencies are already installed in the previous
|
||||
# version since this script runs before all other aspects of the setup script.
|
||||
|
||||
import sys, os, os.path, glob, re, shutil
|
||||
import sys
|
||||
import os
|
||||
import os.path
|
||||
import glob
|
||||
import re
|
||||
import shutil
|
||||
|
||||
sys.path.insert(0, 'management')
|
||||
from utils import load_environment, save_environment, shell
|
||||
|
||||
|
||||
def migration_1(env):
|
||||
# Re-arrange where we store SSL certificates. There was a typo also.
|
||||
# Re-arrange where we store SSL certificates. There was a typo also.
|
||||
|
||||
def move_file(fn, domain_name_escaped, filename):
|
||||
# Moves an SSL-related file into the right place.
|
||||
fn1 = os.path.join( env["STORAGE_ROOT"], 'ssl', domain_name_escaped, file_type)
|
||||
os.makedirs(os.path.dirname(fn1), exist_ok=True)
|
||||
shutil.move(fn, fn1)
|
||||
def move_file(fn, domain_name_escaped, filename):
|
||||
# Moves an SSL-related file into the right place.
|
||||
fn1 = os.path.join(env["STORAGE_ROOT"], 'ssl', domain_name_escaped, file_type)
|
||||
os.makedirs(os.path.dirname(fn1), exist_ok=True)
|
||||
shutil.move(fn, fn1)
|
||||
|
||||
# Migrate the 'domains' directory.
|
||||
for sslfn in glob.glob(os.path.join( env["STORAGE_ROOT"], 'ssl/domains/*' )):
|
||||
fn = os.path.basename(sslfn)
|
||||
m = re.match("(.*)_(certifiate.pem|cert_sign_req.csr|private_key.pem)$", fn)
|
||||
if m:
|
||||
# get the new name for the file
|
||||
domain_name, file_type = m.groups()
|
||||
if file_type == "certifiate.pem": file_type = "ssl_certificate.pem" # typo
|
||||
if file_type == "cert_sign_req.csr": file_type = "certificate_signing_request.csr" # nicer
|
||||
move_file(sslfn, domain_name, file_type)
|
||||
# Migrate the 'domains' directory.
|
||||
for sslfn in glob.glob(os.path.join(env["STORAGE_ROOT"], 'ssl/domains/*')):
|
||||
fn = os.path.basename(sslfn)
|
||||
m = re.match("(.*)_(certifiate.pem|cert_sign_req.csr|private_key.pem)$", fn)
|
||||
if m:
|
||||
# get the new name for the file
|
||||
domain_name, file_type = m.groups()
|
||||
# typo
|
||||
if file_type == "certifiate.pem":
|
||||
file_type = "ssl_certificate.pem"
|
||||
# nicer
|
||||
if file_type == "cert_sign_req.csr":
|
||||
file_type = "certificate_signing_request.csr"
|
||||
move_file(sslfn, domain_name, file_type)
|
||||
|
||||
# Move the old domains directory if it is now empty.
|
||||
try:
|
||||
os.rmdir(os.path.join(env["STORAGE_ROOT"], 'ssl/domains'))
|
||||
except:
|
||||
pass
|
||||
|
||||
# Move the old domains directory if it is now empty.
|
||||
try:
|
||||
os.rmdir(os.path.join( env["STORAGE_ROOT"], 'ssl/domains'))
|
||||
except:
|
||||
pass
|
||||
|
||||
def migration_2(env):
|
||||
# Delete the .dovecot_sieve script everywhere. This was formerly a copy of our spam -> Spam
|
||||
# script. We now install it as a global script, and we use managesieve, so the old file is
|
||||
# irrelevant. Also delete the compiled binary form.
|
||||
for fn in glob.glob(os.path.join(env["STORAGE_ROOT"], 'mail/mailboxes/*/*/.dovecot.sieve')):
|
||||
os.unlink(fn)
|
||||
for fn in glob.glob(os.path.join(env["STORAGE_ROOT"], 'mail/mailboxes/*/*/.dovecot.svbin')):
|
||||
os.unlink(fn)
|
||||
# Delete the .dovecot_sieve script everywhere. This was formerly a copy of our spam -> Spam
|
||||
# script. We now install it as a global script, and we use managesieve, so the old file is
|
||||
# irrelevant. Also delete the compiled binary form.
|
||||
for fn in glob.glob(os.path.join(env["STORAGE_ROOT"], 'mail/mailboxes/*/*/.dovecot.sieve')):
|
||||
os.unlink(fn)
|
||||
for fn in glob.glob(os.path.join(env["STORAGE_ROOT"], 'mail/mailboxes/*/*/.dovecot.svbin')):
|
||||
os.unlink(fn)
|
||||
|
||||
|
||||
def migration_3(env):
|
||||
# Move the migration ID from /etc/mailinabox.conf to $STORAGE_ROOT/mailinabox.version
|
||||
# so that the ID stays with the data files that it describes the format of. The writing
|
||||
# of the file will be handled by the main function.
|
||||
pass
|
||||
# Move the migration ID from /etc/mailinabox.conf to $STORAGE_ROOT/mailinabox.version
|
||||
# so that the ID stays with the data files that it describes the format of. The writing
|
||||
# of the file will be handled by the main function.
|
||||
pass
|
||||
|
||||
|
||||
def migration_4(env):
|
||||
# Add a new column to the mail users table where we can store administrative privileges.
|
||||
db = os.path.join(env["STORAGE_ROOT"], 'mail/users.sqlite')
|
||||
shell("check_call", ["sqlite3", db, "ALTER TABLE users ADD privileges TEXT NOT NULL DEFAULT ''"])
|
||||
# Add a new column to the mail users table where we can store administrative privileges.
|
||||
db = os.path.join(env["STORAGE_ROOT"], 'mail/users.sqlite')
|
||||
shell("check_call", ["sqlite3", db, "ALTER TABLE users ADD privileges TEXT NOT NULL DEFAULT ''"])
|
||||
|
||||
|
||||
def migration_5(env):
|
||||
# The secret key for encrypting backups was world readable. Fix here.
|
||||
os.chmod(os.path.join(env["STORAGE_ROOT"], 'backup/secret_key.txt'), 0o600)
|
||||
# The secret key for encrypting backups was world readable. Fix here.
|
||||
os.chmod(os.path.join(env["STORAGE_ROOT"], 'backup/secret_key.txt'), 0o600)
|
||||
|
||||
|
||||
def migration_6(env):
|
||||
# We now will generate multiple DNSSEC keys for different algorithms, since TLDs may
|
||||
# not support them all. .email only supports RSA/SHA-256. Rename the keys.conf file
|
||||
# to be algorithm-specific.
|
||||
basepath = os.path.join(env["STORAGE_ROOT"], 'dns/dnssec')
|
||||
shutil.move(os.path.join(basepath, 'keys.conf'), os.path.join(basepath, 'RSASHA1-NSEC3-SHA1.conf'))
|
||||
# We now will generate multiple DNSSEC keys for different algorithms, since TLDs may
|
||||
# not support them all. .email only supports RSA/SHA-256. Rename the keys.conf file
|
||||
# to be algorithm-specific.
|
||||
basepath = os.path.join(env["STORAGE_ROOT"], 'dns/dnssec')
|
||||
shutil.move(os.path.join(basepath, 'keys.conf'), os.path.join(basepath, 'RSASHA1-NSEC3-SHA1.conf'))
|
||||
|
||||
|
||||
def get_current_migration():
|
||||
ver = 0
|
||||
while True:
|
||||
next_ver = (ver + 1)
|
||||
migration_func = globals().get("migration_%d" % next_ver)
|
||||
if not migration_func:
|
||||
return ver
|
||||
ver = next_ver
|
||||
ver = 0
|
||||
while True:
|
||||
next_ver = (ver + 1)
|
||||
migration_func = globals().get("migration_%d" % next_ver)
|
||||
if not migration_func:
|
||||
return ver
|
||||
ver = next_ver
|
||||
|
||||
|
||||
def run_migrations():
|
||||
if not os.access("/etc/mailinabox.conf", os.W_OK, effective_ids=True):
|
||||
print("This script must be run as root.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
if not os.access("/etc/mailinabox.conf", os.W_OK, effective_ids=True):
|
||||
print("This script must be run as root.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
env = load_environment()
|
||||
env = load_environment()
|
||||
|
||||
migration_id_file = os.path.join(env['STORAGE_ROOT'], 'mailinabox.version')
|
||||
if os.path.exists(migration_id_file):
|
||||
with open(migration_id_file) as f:
|
||||
ourver = int(f.read().strip())
|
||||
else:
|
||||
# Load the legacy location of the migration ID. We'll drop support
|
||||
# for this eventually.
|
||||
ourver = int(env.get("MIGRATIONID", "0"))
|
||||
migration_id_file = os.path.join(env['STORAGE_ROOT'], 'mailinabox.version')
|
||||
if os.path.exists(migration_id_file):
|
||||
with open(migration_id_file) as f:
|
||||
ourver = int(f.read().strip())
|
||||
else:
|
||||
# Load the legacy location of the migration ID. We'll drop support
|
||||
# for this eventually.
|
||||
ourver = int(env.get("MIGRATIONID", "0"))
|
||||
|
||||
while True:
|
||||
next_ver = (ourver + 1)
|
||||
migration_func = globals().get("migration_%d" % next_ver)
|
||||
while True:
|
||||
next_ver = (ourver + 1)
|
||||
migration_func = globals().get("migration_%d" % next_ver)
|
||||
|
||||
if not migration_func:
|
||||
# No more migrations to run.
|
||||
break
|
||||
if not migration_func:
|
||||
# No more migrations to run.
|
||||
break
|
||||
|
||||
print()
|
||||
print("Running migration to Mail-in-a-Box #%d..." % next_ver)
|
||||
print()
|
||||
print("Running migration to Mail-in-a-Box #%d..." % next_ver)
|
||||
|
||||
try:
|
||||
migration_func(env)
|
||||
except Exception as e:
|
||||
print()
|
||||
print("Error running the migration script:")
|
||||
print()
|
||||
print(e)
|
||||
print()
|
||||
print("Your system may be in an inconsistent state now. We're terribly sorry. A re-install from a backup might be the best way to continue.")
|
||||
sys.exit(1)
|
||||
try:
|
||||
migration_func(env)
|
||||
except Exception as e:
|
||||
print()
|
||||
print("Error running the migration script:")
|
||||
print()
|
||||
print(e)
|
||||
print()
|
||||
print("Your system may be in an inconsistent state now. We're terribly sorry. A re-install from a backup might be the best way to continue.")
|
||||
sys.exit(1)
|
||||
|
||||
ourver = next_ver
|
||||
ourver = next_ver
|
||||
|
||||
# Write out our current version now. Do this sooner rather than later
|
||||
# in case of any problems.
|
||||
with open(migration_id_file, "w") as f:
|
||||
f.write(str(ourver) + "\n")
|
||||
# Write out our current version now. Do this sooner rather than later
|
||||
# in case of any problems.
|
||||
with open(migration_id_file, "w") as f:
|
||||
f.write(str(ourver) + "\n")
|
||||
|
||||
# Delete the legacy location of this field.
|
||||
if "MIGRATIONID" in env:
|
||||
del env["MIGRATIONID"]
|
||||
save_environment(env)
|
||||
# Delete the legacy location of this field.
|
||||
if "MIGRATIONID" in env:
|
||||
del env["MIGRATIONID"]
|
||||
save_environment(env)
|
||||
|
||||
# iterate and try next version...
|
||||
# iterate and try next version...
|
||||
|
||||
if __name__ == "__main__":
|
||||
if sys.argv[-1] == "--current":
|
||||
# Return the number of the highest migration.
|
||||
print(str(get_current_migration()))
|
||||
elif sys.argv[-1] == "--migrate":
|
||||
# Perform migrations.
|
||||
run_migrations()
|
||||
|
||||
if sys.argv[-1] == "--current":
|
||||
# Return the number of the highest migration.
|
||||
print(str(get_current_migration()))
|
||||
elif sys.argv[-1] == "--migrate":
|
||||
# Perform migrations.
|
||||
run_migrations()
|
||||
|
||||
Reference in New Issue
Block a user