From 5bddf7dbc505280c50d81311c5b40d7c6f651614 Mon Sep 17 00:00:00 2001 From: Oleksandr Kuzminskyi Date: Fri, 26 Aug 2016 10:58:09 -0700 Subject: [PATCH] Dockerize Anemometer --- Dockerfile | 23 +++ docker/docker-entrypoint.py | 149 ++++++++++++++++++ mysql56-install.sql | 6 +- mysql56-save_history.sql | 23 ++- vagrant/Vagrantfile | 9 +- vagrant/bootstrap.sh | 34 ---- .../puppet/modules/profile/manifests/base.pp | 22 ++- 7 files changed, 212 insertions(+), 54 deletions(-) create mode 100644 Dockerfile create mode 100644 docker/docker-entrypoint.py delete mode 100644 vagrant/bootstrap.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..9ca7c918 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +FROM centos:7 +MAINTAINER Box Open Source "ops@box.com" + +COPY . /var/www/html +WORKDIR /var/www/html + +RUN yum -y install http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm + +RUN yum -y install percona-toolkit mysql +RUN yum -y install python git nmap-ncat httpd php php-mysql php-bcmath php-xml + + +RUN cd /var/www/html && \ + curl -sS https://getcomposer.org/installer | php && \ + install -m 755 composer.phar /usr/local/bin/composer && \ + /usr/local/bin/composer update && \ + /usr/local/bin/composer install + +RUN install -m 755 docker/docker-entrypoint.py /docker-entrypoint.py + +EXPOSE 80 + +CMD ["/docker-entrypoint.py"] diff --git a/docker/docker-entrypoint.py b/docker/docker-entrypoint.py new file mode 100644 index 00000000..f594bcdd --- /dev/null +++ b/docker/docker-entrypoint.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python +import os +import tempfile +import time +from subprocess import Popen, PIPE + + +class DatabaseException(Exception): + """Exception class for database errors""" + + +def wait_for_mysql(host='localhost', port=3306, user='root', password='', timeout=300): + """ + Wait until MySQL becomes available or timeout expires + + :param host: MySQL host + :param port: MySQL port + :param user: MySQL user + :param password: MySQL password + :param timeout: wait up to this number of seconds + :return: None + :raise: Exception + """ + time_b = time.time() + timeout + cmd = ['mysql', + '-NB', + '-h', host, + '-P', str(port), + '-u', user] + if password: + cmd.append('-p%s' % password) + cmd.append('-e') + cmd.append('SELECT 1') + + while time.time() < time_b: + + process = Popen(cmd, stdout=PIPE, stderr=PIPE) + cout, cerr = process.communicate() + if process.returncode: + if cerr: + print(cerr) + time.sleep(1) + else: + return + + raise DatabaseException('Could not connect to MySQL after %d seconds' % timeout) + + +def mysql_load_file(file_path, host='root', port=3306, user='root', password='', db=None): + """ + Execute SQL dump + + :param file_path: Path to the SQL dump + :param host: MySQL host + :param port: MySQL port + :param user: MySQL user + :param password: MySQL password + :param db: MySQL database + :return: None + """ + cmd = ['mysql', + '-h', host, + '-P', str(port), + '-u', user + ] + + if password: + cmd.append('-p%s' % password) + + if db: + cmd.append(db) + + try: + process = Popen(cmd, stdout=PIPE, stderr=PIPE, stdin=open(file_path)) + cout, cerr = process.communicate() + if process.returncode: + raise DatabaseException('MySQL Error: %s' % cerr) + except IOError as err: + raise DatabaseException(err) + + +def main(): + + try: + mysql_host = os.environ['ANEMOMETER_MYSQL_HOST'] + except KeyError: + mysql_host = 'localhost' + + try: + mysql_port = os.environ['ANEMOMETER_MYSQL_PORT'] + except KeyError: + mysql_port = 3306 + + try: + mysql_user = os.environ['ANEMOMETER_MYSQL_USER'] + except KeyError: + mysql_user = 'root' + + try: + mysql_password = os.environ['ANEMOMETER_MYSQL_PASSWORD'] + except KeyError: + mysql_password = '' + + try: + mysql_db = os.environ['ANEMOMETER_MYSQL_DB'] + except KeyError: + mysql_db = 'slow_query_log' + + try: + wait_for_mysql(host=mysql_host, + port=mysql_port, + user=mysql_user, + password=mysql_password) + + with tempfile.NamedTemporaryFile() as fp: + fp.write('CREATE DATABASE IF NOT EXISTS `%s`' % mysql_db) + fp.flush() + mysql_load_file(fp.name, + host=mysql_host, + port=mysql_port, + user=mysql_user, + password=mysql_password) + + mysql_load_file('/var/www/html/install.sql', + host=mysql_host, + port=mysql_port, + user=mysql_user, + password=mysql_password, + db=mysql_db) + + mysql_load_file('/var/www/html/mysql56-install.sql', + host=mysql_host, + port=mysql_port, + user=mysql_user, + password=mysql_password, + db=mysql_db) + + except DatabaseException as err: + exit(err) + + p = Popen(['httpd', '-DFOREGROUND']) + p.wait() + + +if __name__ == '__main__': + try: + main() + except KeyboardInterrupt: + exit(0) diff --git a/mysql56-install.sql b/mysql56-install.sql index b2c7e113..edef1533 100644 --- a/mysql56-install.sql +++ b/mysql56-install.sql @@ -1,8 +1,6 @@ CREATE DATABASE IF NOT EXISTS slow_query_log; -USE slow_query_log; - -CREATE TABLE events_statements ( +CREATE TABLE IF NOT EXISTS slow_query_log.events_statements ( `DIGEST` varchar(32) character set binary NOT NULL , `DIGEST_TEXT` longtext NOT NULL, `first_seen` datetime DEFAULT NULL, @@ -14,7 +12,7 @@ CREATE TABLE events_statements ( PRIMARY KEY (`DIGEST`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -CREATE TABLE events_statements_history ( +CREATE TABLE IF NOT EXISTS slow_query_log.events_statements_history ( history_id bigint unsigned not null auto_increment PRIMARY KEY, hostname varchar(48) not null default '', `DIGEST` varchar(32) character set binary DEFAULT NULL , diff --git a/mysql56-save_history.sql b/mysql56-save_history.sql index 70ce7179..ddba3bd0 100644 --- a/mysql56-save_history.sql +++ b/mysql56-save_history.sql @@ -1,11 +1,28 @@ USE slow_query_log; -CREATE TEMPORARY TABLE `statements_temp` SELECT * FROM performance_schema.events_statements_summary_by_digest; +CREATE TEMPORARY TABLE `slow_query_log`.`statements_temp` +SELECT * FROM performance_schema.events_statements_summary_by_digest; -INSERT INTO events_statements (DIGEST, DIGEST_TEXT, first_seen, last_seen) SELECT DIGEST, DIGEST_TEXT, FIRST_SEEN, LAST_SEEN FROM statements_temp ON DUPLICATE KEY UPDATE first_seen=LEAST(VALUES(events_statements.first_seen), events_statements.first_seen), last_seen=GREATEST(VALUES(events_statements.last_seen),events_statements.last_seen); +INSERT INTO `slow_query_log`.`events_statements` (DIGEST, DIGEST_TEXT, first_seen, last_seen) +SELECT DIGEST, DIGEST_TEXT, FIRST_SEEN, LAST_SEEN +FROM `slow_query_log`.`statements_temp` + ON DUPLICATE KEY UPDATE + first_seen = LEAST(VALUES(`slow_query_log`.`events_statements`.first_seen), + `slow_query_log`.`events_statements`.first_seen), + last_seen = GREATEST(VALUES(`slow_query_log`.`events_statements`.last_seen), + `slow_query_log`.`events_statements`.last_seen); + +SELECT CONCAT('INSERT IGNORE INTO events_statements_history (', + GROUP_CONCAT(DISTINCT a.column_name),',hostname) SELECT ', + GROUP_CONCAT(DISTINCT a.column_name),', @@hostname FROM statements_temp') + INTO @stmt +FROM information_schema.columns a + JOIN information_schema.columns b + ON a.column_name=b.column_name AND b.table_name='events_statements_history' +WHERE a.table_schema='performance_schema' AND a.table_name='events_statements_summary_by_digest'; -SELECT CONCAT('INSERT IGNORE INTO events_statements_history (', GROUP_CONCAT(DISTINCT a.column_name),',hostname) SELECT ', GROUP_CONCAT(DISTINCT a.column_name),', @@hostname FROM statements_temp') INTO @stmt from information_schema.columns a JOIN information_schema.columns b ON a.column_name=b.column_name and b.table_name='events_statements_history' where a.table_schema='performance_schema' and a.table_name='events_statements_summary_by_digest'; PREPARE stmt FROM @stmt; + EXECUTE stmt; DROP TABLE IF EXISTS statements_temp; diff --git a/vagrant/Vagrantfile b/vagrant/Vagrantfile index 07d944a4..1bf19828 100644 --- a/vagrant/Vagrantfile +++ b/vagrant/Vagrantfile @@ -4,11 +4,18 @@ # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! VAGRANTFILE_API_VERSION = '2' +$script = <