Browse Source

Added stack migrate command to migrate MySQL/Percona to MariaDB

bugfixes
gau1991 10 years ago
parent
commit
54e418184a
  1. 2
      ee/cli/plugins/stack.py
  2. 99
      ee/cli/plugins/stack_migrate.py
  3. 43
      ee/core/mysql.py

2
ee/cli/plugins/stack.py

@ -26,6 +26,7 @@ import pwd
import grp
import codecs
from ee.cli.plugins.stack_services import EEStackStatusController
from ee.cli.plugins.stack_migrate import EEStackMigrateController
from ee.core.logging import Log
@ -1523,6 +1524,7 @@ def load(app):
# register the plugin class.. this only happens if the plugin is enabled
handler.register(EEStackController)
handler.register(EEStackStatusController)
handler.register(EEStackMigrateController)
# register a hook (function) to run after arguments are parsed.
hook.register('post_argument_parsing', ee_stack_hook)

99
ee/cli/plugins/stack_migrate.py

@ -0,0 +1,99 @@
from cement.core.controller import CementBaseController, expose
from cement.core import handler, hook
from ee.core.mysql import EEMysql
from ee.core.logging import Log
from ee.core.variables import EEVariables
from ee.core.aptget import EEAptGet
from ee.core.shellexec import EEShellExec
from ee.core.apt_repo import EERepo
import configparser
import os
class EEStackMigrateController(CementBaseController):
class Meta:
label = 'migrate'
stacked_on = 'stack'
stacked_type = 'nested'
description = ('Migrate stack safely')
arguments = [
(['--mariadb'],
dict(help="Migrate database to MariaDB",
action='store_true')),
# (['--PHP'],
# dict(help="update to html site", action='store_true')),
]
@expose(hide=True)
def migrate_mariadb(self):
# Backup all database
EEMysql.backupAll(self)
# Add MariaDB repo
Log.info(self, "Adding repository for MariaDB, please wait ...")
EERepo.add(self, repo_url=EEVariables.ee_mysql_repo)
Log.debug(self, 'Adding key for {0}'
.format(EEVariables.ee_mysql_repo))
EERepo.add_key(self, '0xcbcb082a1bb943db',
keyserver="keyserver.ubuntu.com")
config = configparser.ConfigParser()
config.read(os.path.expanduser("~")+'/.my.cnf')
try:
chars = config['client']['password']
except Exception as e:
Log.error(self, "Error: process exited with error %s"
% e)
Log.debug(self, "Pre-seeding MariaDB")
Log.debug(self, "echo \"mariadb-server-10.0 "
"mysql-server/root_password "
"password \" | "
"debconf-set-selections")
EEShellExec.cmd_exec(self, "echo \"mariadb-server-10.0 "
"mysql-server/root_password "
"password {chars}\" | "
"debconf-set-selections"
.format(chars=chars),
log=False)
Log.debug(self, "echo \"mariadb-server-10.0 "
"mysql-server/root_password_again "
"password \" | "
"debconf-set-selections")
EEShellExec.cmd_exec(self, "echo \"mariadb-server-10.0 "
"mysql-server/root_password_again "
"password {chars}\" | "
"debconf-set-selections"
.format(chars=chars),
log=False)
# Install MariaDB
apt_packages = EEVariables.ee_mysql
Log.info(self, "Updating apt-cache, please wait ...")
EEAptGet.update(self)
Log.info(self, "Installing MariaDB, please wait ...")
EEAptGet.install(self, apt_packages)
@expose(hide=True)
def default(self):
if ((not self.app.pargs.mariadb)):
self.app.args.print_help()
if self.app.pargs.mariadb:
if EEVariables.ee_mysql_host is not "localhost":
Log.error(self, "Remote MySQL found, EasyEngine will not "
"install MariaDB")
if EEShellExec.cmd_exec(self, "mysqladmin ping") and (not
EEAptGet.is_installed(self, 'mariadb-server')):
Log.info(self, "If your database size is big, "
"migration may take some time.")
Log.info(self, "During migration non nginx-cached parts of "
"your site may remain down")
start_migrate = input("Type \"mariadb\" to continue:")
if start_migrate != "mariadb":
Log.error(self, "Not starting migration")
self.migrate_mariadb()
else:
Log.error(self, "Your current MySQL is not alive or "
"you allready installed MariaDB")

43
ee/core/mysql.py

@ -3,7 +3,9 @@ import pymysql
import configparser
from os.path import expanduser
import sys
import os
from ee.core.logging import Log
from ee.core.variables import EEVariables
class EEMysql():
@ -60,7 +62,42 @@ class EEMysql():
else:
Log.error(self, '{0}'.format(errormsg))
def backupAll(self):
import subprocess
try:
Log.info(self, "Backing up database at location: "
"/var/ee-mysqlbackup")
# Setup Nginx common directory
if not os.path.exists('/var/ee-mysqlbackup'):
Log.debug(self, 'Creating directory'
'/var/ee-mysqlbackup')
os.makedirs('/var/ee-mysqlbackup')
db = subprocess.check_output(["mysql -Bse \'show databases\'"],
universal_newlines=True,
shell=True).split('\n')
for dbs in db:
if dbs == "":
continue
Log.info(self, "Backing up {0} database".format(dbs))
p1 = subprocess.Popen("mysqldump {0}"
" --max_allowed_packet=1024M"
" --single-transaction".format(dbs),
stdout=subprocess.PIPE,
stderr=subprocess.PIPE, shell=True)
p2 = subprocess.Popen("gzip -c > /var/ee-mysqlbackup/{0}{1}.s"
"ql.gz".format(dbs, EEVariables.ee_date),
stdin=p1.stdout,
shell=True)
# Allow p1 to receive a SIGPIPE if p2 exits
p1.stdout.close()
output = p1.stderr.read()
# def __del__(self):
# self.cur.close()
# self.conn.close()
if output == b'':
Log.debug(self, "done")
else:
Log.error(self, output)
except Exception as e:
Log.error(self, "Error: process exited with status %s"
% e)

Loading…
Cancel
Save