Exemple #1
0
def initialize_gpg():
    gpghome = os.path.expanduser('~/.dbsake/gpg')
    pycompat.makedirs(gpghome, mode=0o0700, exist_ok=True)
    gpg = pycompat.which('gpg') or pycompat.which('gpg2')
    if not gpg:
        raise common.SandboxError("Failed to find gpg")
    gpg_cmd = cmd.shell_format('{0} -k 5072E1F5', gpg)
    debug("    # Verifying .dbsake/gpg is initialized")
    ret = cmd.capture_both(gpg_cmd, env={'GNUPGHOME': gpghome})
    if not ret.returncode:
        return  # all is well
    else:
        for line in ret.stderr.splitlines():
            debug("    # gpg: %s", line)

    # else import the mysql key
    info("    - Importing mysql public key to %s", gpghome)
    key_server = 'pgp.mit.edu'
    mysql_key_id = '5072E1F5'
    gpg_cmd = cmd.shell_format('{0} --keyserver={1} --recv-keys {2}',
                               gpg, key_server, mysql_key_id)
    ret = cmd.capture_both(gpg_cmd, env={'GNUPGHOME': gpghome})
    for line in ret.stderr.splitlines():
        debug("    # %s", line)
    if ret.returncode != 0:
        raise common.SandboxError("Failed to import mysql public key")
Exemple #2
0
def initialize_gpg():
    gpghome = os.path.expanduser('~/.dbsake/gpg')
    pycompat.makedirs(gpghome, mode=0o0700, exist_ok=True)
    gpg = pycompat.which('gpg') or pycompat.which('gpg2')
    if not gpg:
        raise common.SandboxError("Failed to find gpg")
    gpg_cmd = cmd.shell_format('{0} -k 5072E1F5', gpg)
    debug("    # Verifying .dbsake/gpg is initialized")
    ret = cmd.capture_both(gpg_cmd, env={'GNUPGHOME': gpghome})
    if not ret.returncode:
        return  # all is well
    else:
        for line in ret.stderr.splitlines():
            debug("    # gpg: %s", line)

    # else import the mysql key
    info("    - Importing mysql public key to %s", gpghome)
    key_server = 'pgp.mit.edu'
    mysql_key_id = '5072E1F5'
    gpg_cmd = cmd.shell_format('{0} --keyserver={1} --recv-keys {2}', gpg,
                               key_server, mysql_key_id)
    ret = cmd.capture_both(gpg_cmd, env={'GNUPGHOME': gpghome})
    for line in ret.stderr.splitlines():
        debug("    # %s", line)
    if ret.returncode != 0:
        raise common.SandboxError("Failed to import mysql public key")
Exemple #3
0
def bootstrap(options, distribution, additional_options=()):
    start = time.time()
    defaults_file = os.path.join(options.basedir, 'my.sandbox.cnf')
    logfile = os.path.join(options.basedir, 'bootstrap.log')
    info("    - Logging bootstrap output to %s", logfile)

    bootstrap_cmd = cmd.shell_format("{0} --defaults-file={1}",
                                     distribution.mysqld, defaults_file)
    additional_options = ('--bootstrap',
                          '--default-storage-engine=myisam') + \
        additional_options
    additional = ' '.join(map(cmd.shell_quote, additional_options))
    if additional:
        bootstrap_cmd += ' ' + additional

    bootstrap_sql = os.path.join(options.basedir, 'bootstrap.sql')
    with codecs.open(bootstrap_sql, 'wb', 'utf8') as fileobj:
        os.fchmod(fileobj.fileno(), 0o0660)
        for line in mysql_install_db(options, distribution):
            print(line, file=fileobj)
    info("    - Generated bootstrap SQL")
    with open(logfile, 'wb') as stderr:
        with open(bootstrap_sql, 'rb') as fileobj:
            info("    - Running %s", bootstrap_cmd)
            returncode = cmd.run(bootstrap_cmd,
                                 stdin=fileobj,
                                 stdout=stderr,
                                 stderr=stderr)
    if returncode != 0:
        raise SandboxError("Bootstrapping failed. Details in %s" % stderr.name)
    info("    * Bootstrapped sandbox in %.2f seconds", time.time() - start)
Exemple #4
0
def bootstrap(options, distribution, additional_options=()):
    start = time.time()
    defaults_file = os.path.join(options.basedir, 'my.sandbox.cnf')
    logfile = os.path.join(options.basedir, 'bootstrap.log')
    info("    - Logging bootstrap output to %s", logfile)

    bootstrap_cmd = cmd.shell_format("{0} --defaults-file={1}",
                                     distribution.mysqld, defaults_file)
    additional_options = ('--bootstrap',
                          '--default-storage-engine=myisam') + \
        additional_options
    additional = ' '.join(map(cmd.shell_quote, additional_options))
    if additional:
        bootstrap_cmd += ' ' + additional

    bootstrap_sql = os.path.join(options.basedir, 'bootstrap.sql')
    with codecs.open(bootstrap_sql, 'wb', 'utf8') as fileobj:
        os.fchmod(fileobj.fileno(), 0o0660)
        for line in mysql_install_db(options, distribution):
            print(line, file=fileobj)
    info("    - Generated bootstrap SQL")
    with open(logfile, 'wb') as stderr:
        with open(bootstrap_sql, 'rb') as fileobj:
            info("    - Running %s", bootstrap_cmd)
            returncode = cmd.run(bootstrap_cmd,
                                 stdin=fileobj,
                                 stdout=stderr,
                                 stderr=stderr)
    if returncode != 0:
        raise SandboxError("Bootstrapping failed. Details in %s" % stderr.name)
    info("    * Bootstrapped sandbox in %.2f seconds", time.time() - start)
Exemple #5
0
def test_unpack_xb_uncompressed_pipe():
    runner = CliRunner()
    src = os.path.join(os.path.dirname(__file__), 'backup.xb.gz')
    with runner.isolated_filesystem():
        cat_cmd = cmd.shell_format("zcat {0}", src)
        with cmd.piped_stdout(cat_cmd) as stdin:
            result = runner.invoke(_unpack, ["-"], obj={}, input=stdin)
    assert result.exit_code == 0
Exemple #6
0
def test_unpack_xb_uncompressed_file():
    runner = CliRunner()
    src = os.path.join(os.path.dirname(__file__), 'backup.xb.gz')
    with runner.isolated_filesystem():
        cat_cmd = cmd.shell_format("zcat {0}", src)
        with cmd.piped_stdout(cat_cmd) as stdin:
            with open("backup.xb", "wb") as stdout:
                shutil.copyfileobj(stdin, stdout)
        result = runner.invoke(_unpack, [src], obj={})
    assert result.exit_code == 0
Exemple #7
0
def mysqld_version(mysqld):
    """Discover the MySQL version from a mysqld binary

    This method runs mysqld --version and extract out the
    version string to create a MySQLVersion tuple.  This is used
    to allow other portions of dbsake to check the mysql version
    in use and take appropriate action.  This is largely used by
    the generate_defaults method in dbsake.core.mysql.sandbox.common
    to conditionally enable my.cnf options based on the target
    MySQL version.

    :param mysqld: path to mysqld binary
    :returns: MySQLVersion instance
    """

    version_cmd = cmd.shell_format('{0} --no-defaults --version', mysqld)
    try:
        result = cmd.capture_stdout(version_cmd)
    except OSError as exc:  # pragma: no cover
        if exc.errno == errno.ENOENT:
            if os.path.exists(mysqld):
                raise common.SandboxError(("%s is not executable. You may "
                                           "have a tarball not compatible "
                                           "with this system") % mysqld)
            else:
                raise common.SandboxError(("%s does not exist. Be sure you "
                                           "use a precompiled binary tarball, "
                                           "not a source tarball.") % mysqld)
        else:
            raise common.SandboxError("%s Failed (errno: %d[%s])" %
                                      (version_cmd,
                                       exc.errno,
                                       errno.errorcode[exc.errno]))

    if result.returncode != 0:
        raise common.SandboxError("%s failed (exit status: %d)" %
                                  (version_cmd, result.returncode))
    m = re.search('(\d+[.]\d+[.]\d+)', result.stdout)
    if not m:
        raise common.SandboxError("Failed to discover version for %s" %
                                  version_cmd)
    return MySQLVersion.from_string(result.stdout)
Exemple #8
0
def mysqld_version(mysqld):
    """Discover the MySQL version from a mysqld binary

    This method runs mysqld --version and extract out the
    version string to create a MySQLVersion tuple.  This is used
    to allow other portions of dbsake to check the mysql version
    in use and take appropriate action.  This is largely used by
    the generate_defaults method in dbsake.core.mysql.sandbox.common
    to conditionally enable my.cnf options based on the target
    MySQL version.

    :param mysqld: path to mysqld binary
    :returns: MySQLVersion instance
    """

    version_cmd = cmd.shell_format('{0} --no-defaults --version', mysqld)
    try:
        result = cmd.capture_stdout(version_cmd)
    except OSError as exc:  # pragma: no cover
        if exc.errno == errno.ENOENT:
            if os.path.exists(mysqld):
                raise common.SandboxError(("%s is not executable. You may "
                                           "have a tarball not compatible "
                                           "with this system") % mysqld)
            else:
                raise common.SandboxError(("%s does not exist. Be sure you "
                                           "use a precompiled binary tarball, "
                                           "not a source tarball.") % mysqld)
        else:
            raise common.SandboxError(
                "%s Failed (errno: %d[%s])" %
                (version_cmd, exc.errno, errno.errorcode[exc.errno]))

    if result.returncode != 0:
        raise common.SandboxError("%s failed (exit status: %d)" %
                                  (version_cmd, result.returncode))
    m = re.search('(\d+[.]\d+[.]\d+)', result.stdout)
    if not m:
        raise common.SandboxError("Failed to discover version for %s" %
                                  version_cmd)
    return MySQLVersion.from_string(result.stdout)
Exemple #9
0
def gpg_verify_stream(signature):
    gpghome = os.path.expanduser('~/.dbsake/gpg')
    gpg = pycompat.which('gpg') or pycompat.which('gpg2')
    verify_cmd = cmd.shell_format('{0} --verify {1} -', gpg, signature)
    info("    - Verifying gpg signature via: %s", verify_cmd)
    try:
        with tempfile.TemporaryFile() as output:
            try:
                with cmd.stream_command(verify_cmd,
                                        stdout=output,
                                        stderr=output,
                                        env={'GNUPGHOME': gpghome}) as stdin:
                    yield stdin
            finally:
                output.flush()
                output.seek(0)
                for line in output:
                    debug("    # %s", line.rstrip())
    except cmd.CommandError:
        raise common.SandboxError("gpg signature not valid")
    else:
        info("    - GPG signature validated")
Exemple #10
0
def prepare_datadir(datadir, options):
    innobackupex = pycompat.which('innobackupex')
    if not innobackupex:
        raise common.SandboxError("innobackupex not found in path. Aborting.")

    xb_log = os.path.join(datadir, 'innobackupex.log')
    xb_cmd = cmd.shell_format('{0} --apply-log {1!s} .',
                              innobackupex, options.innobackupex_options)
    info("    - Running: %s", xb_cmd)
    info("    - (cwd: %s)", datadir)
    with open(xb_log, 'wb') as fileobj:
        returncode = cmd.run(xb_cmd,
                             stdout=fileobj,
                             stderr=fileobj,
                             cwd=datadir)

    if returncode != 0:
        info("    ! innobackupex --apply-log failed. See details in %s",
             xb_log)
        raise common.SandboxError("Data preloading failed")
    else:
        info("    - innobackupex --apply-log succeeded. datadir is ready.")
Exemple #11
0
def gpg_verify_stream(signature):
    gpghome = os.path.expanduser('~/.dbsake/gpg')
    gpg = pycompat.which('gpg') or pycompat.which('gpg2')
    verify_cmd = cmd.shell_format('{0} --verify {1} -', gpg, signature)
    info("    - Verifying gpg signature via: %s", verify_cmd)
    try:
        with tempfile.TemporaryFile() as output:
            try:
                with cmd.stream_command(verify_cmd,
                                        stdout=output,
                                        stderr=output,
                                        env={'GNUPGHOME': gpghome}) as stdin:
                    yield stdin
            finally:
                output.flush()
                output.seek(0)
                for line in output:
                    debug("    # %s", line.rstrip())
    except cmd.CommandError:
        raise common.SandboxError("gpg signature not valid")
    else:
        info("    - GPG signature validated")