Example #1
0
def install_builtin_server():
    """Install the builtin server code."""
    log("Installing the builtin server dependencies.")
    deps = os.path.join(CURRENT_DIR, "deps")
    requirements = os.path.join(CURRENT_DIR, "server-requirements.pip")
    # Install the builtin server dependencies avoiding to download requirements
    # from the network.
    # XXX frankban: this pip installation here implicitly depends on juju-gui
    # dependencies to be installed. In essence, this function does not fetch
    # dependencies from the network only incidentally, because setup_gui() has
    # been already called in the unit.
    with su("root"):
        cmd_log(
            run(
                "pip2",
                "install",
                "--no-index",
                "--no-dependencies",
                "--find-links",
                "file:///{}".format(deps),
                "-r",
                requirements,
            )
        )
    log("Installing the builtin server.")
    setup_cmd = os.path.join(SERVER_DIR, "setup.py")
    with su("root"):
        cmd_log(run("/usr/bin/python", setup_cmd, "install"))
Example #2
0
def upgrade_charm(service_name, timeout=120):
    next_revision = get_charm_revision(service_name) + 1
    start_time = time.time()
    run('juju', 'upgrade-charm', service_name)
    while get_charm_revision(service_name) != next_revision:
        if time.time() - start_time >= timeout:
            raise RuntimeError('timeout waiting for charm to be upgraded')
        time.sleep(0.1)
    return next_revision
Example #3
0
def upgrade_charm(service_name, timeout=120):
    next_revision = get_charm_revision(service_name) + 1
    start_time = time.time()
    run('juju', 'upgrade-charm', service_name)
    while get_charm_revision(service_name) != next_revision:
        if time.time() - start_time >= timeout:
            raise RuntimeError('timeout waiting for charm to be upgraded')
        time.sleep(0.1)
    return next_revision
Example #4
0
def setup_gui(release_tarball):
    """Set up Juju GUI."""
    # Uncompress the release tarball.
    log('Installing Juju GUI.')
    release_dir = os.path.join(CURRENT_DIR, 'release')
    cmd_log(run('rm', '-rf', release_dir))
    os.mkdir(release_dir)
    uncompress = command('tar', '-x', '-z', '-C', release_dir, '-f')
    cmd_log(uncompress(release_tarball))
    # Link the Juju GUI dir to the contents of the release tarball.
    cmd_log(run('ln', '-sf', first_path_in_dir(release_dir), JUJU_GUI_DIR))
Example #5
0
def setup_gui(release_tarball):
    """Set up Juju GUI."""
    # Uncompress the release tarball.
    log('Installing Juju GUI.')
    release_dir = os.path.join(BASE_DIR, 'release')
    cmd_log(run('rm', '-rf', release_dir))
    os.mkdir(release_dir)
    uncompress = command('tar', '-x', '-a', '-C', release_dir, '-f')
    cmd_log(uncompress(release_tarball))
    # Link the Juju GUI dir to the contents of the release tarball.
    cmd_log(run('ln', '-sf', first_path_in_dir(release_dir), JUJU_GUI_DIR))
Example #6
0
def compute_build_dir(juju_gui_debug, serve_tests):
    """Compute the build directory."""
    with su('root'):
        run('chown', '-R', 'ubuntu:', JUJU_GUI_DIR)
        # XXX 2013-02-05 frankban bug=1116320:
        # External insecure resources are still loaded when testing in the
        # debug environment. For now, switch to the production environment if
        # the charm is configured to serve tests.
    if juju_gui_debug and not serve_tests:
        build_dirname = 'build-debug'
    else:
        build_dirname = 'build-prod'
    return os.path.join(JUJU_GUI_DIR, build_dirname)
Example #7
0
def compute_build_dir(juju_gui_debug, serve_tests):
    """Compute the build directory."""
    with su('root'):
        run('chown', '-R', 'ubuntu:', JUJU_GUI_DIR)
        # XXX 2013-02-05 frankban bug=1116320:
        # External insecure resources are still loaded when testing in the
        # debug environment. For now, switch to the production environment if
        # the charm is configured to serve tests.
    if juju_gui_debug and not serve_tests:
        build_dirname = 'build-debug'
    else:
        build_dirname = 'build-prod'
    return os.path.join(JUJU_GUI_DIR, build_dirname)
Example #8
0
def install_builtin_server():
    """Install the builtin server code."""
    log('Installing the builtin server dependencies.')
    deps = os.path.join(CURRENT_DIR, 'deps')
    requirements = os.path.join(CURRENT_DIR, 'server-requirements.pip')
    # Install the builtin server dependencies avoiding to download requirements
    # from the network.
    with su('root'):
        cmd_log(
            run('pip', 'install', '--no-index', '--no-dependencies',
                '--find-links', 'file:///{}'.format(deps), '-r', requirements))
    log('Installing the builtin server.')
    setup_cmd = os.path.join(SERVER_DIR, 'setup.py')
    with su('root'):
        cmd_log(run('/usr/bin/python', setup_cmd, 'install'))
Example #9
0
 def start(self, backend):
     config = backend.config
     # In Juju < 2.0 the model UUID is present in the JUJU_ENV_UUID env var.
     env_uuid = os.getenv('JUJU_MODEL_UUID') or os.getenv('JUJU_ENV_UUID')
     if env_uuid is None:
         raise ValueError('cannot retrieve model UUID from hook context')
     if config['sandbox']:
         # If sandbox mode, force the use of Juju 2 since that is what it
         # simulates.
         juju_version = '2.0.0'
     else:
         juju_version = run('jujud', '--version').strip()
     utils.start_builtin_server(
         config['ssl-cert-path'],
         config['serve-tests'],
         config['sandbox'],
         config['builtin-server-logging'],
         not config['secure'],
         config['charmworld-url'],
         env_password=config.get('password'),
         env_uuid=env_uuid,
         juju_version=juju_version,
         debug=config['juju-gui-debug'],
         port=config.get('port'),
         bundleservice_url=config['bundleservice-url'],
         interactive_login=config['interactive-login'],
         gzip=config['gzip-compression'],
         gtm_enabled=config['gtm-enabled'],
         gisf_enabled=config['gisf-enabled'],
         charmstore_url=config['charmstore-url'])
Example #10
0
def install_builtin_server():
    """Install the builtin server code."""
    log('Installing the builtin server dependencies.')
    deps = os.path.join(CURRENT_DIR, 'deps')
    requirements = os.path.join(CURRENT_DIR, 'server-requirements.pip')
    # Install the builtin server dependencies avoiding to download requirements
    # from the network.
    with su('root'):
        cmd_log(run(
            'pip', 'install', '--no-index', '--no-dependencies',
            '--find-links', 'file:///{}'.format(deps), '-r', requirements
        ))
    log('Installing the builtin server.')
    setup_cmd = os.path.join(SERVER_DIR, 'setup.py')
    with su('root'):
        cmd_log(run('/usr/bin/python', setup_cmd, 'install'))
Example #11
0
def stop_improv():
    """Stop a simulated Juju environment."""
    log('Stopping the staging backend.')
    with su('root'):
        service_control(IMPROV, STOP)
    log('Removing the staging Upstart script.')
    cmd_log(run('rm', '-f', IMPROV_INIT_PATH))
Example #12
0
def stop_agent():
    """Stop the Juju agent."""
    log('Stopping the API agent.')
    with su('root'):
        service_control(AGENT, STOP)
    log('Removing the API agent Upstart script.')
    cmd_log(run('rm', '-f', AGENT_INIT_PATH))
Example #13
0
def fetch_gui_from_branch(branch_url, revision, logpath):
    """Retrieve the Juju GUI from a branch and build a release archive."""
    # Inject NPM packages into the cache for faster building.
    prime_npm_cache(get_npm_cache_archive_url())

    # Create a release starting from a branch.
    juju_gui_source_dir = os.path.join(CURRENT_DIR, 'juju-gui-source')
    cmd_log(run('rm', '-rf', juju_gui_source_dir))
    git_clone = command('git', 'clone')

    if revision is None:
        log('Retrieving Juju GUI source from {} (default trunk).'.format(
            branch_url))
        cmd_log(git_clone('--depth', '1', branch_url, juju_gui_source_dir))
    elif revision.startswith('@'):
        log('Retrieving Juju GUI source from {} (commit: {}).'.format(
            branch_url, revision[1:]))
        # Retrieve a full clone and then checkout the specific commit.
        git_dir = os.path.join(juju_gui_source_dir, '.git')
        cmd_log(git_clone(branch_url, juju_gui_source_dir))
        cmd_log(
            run('git', '--git-dir', git_dir, '--work-tree',
                juju_gui_source_dir, 'checkout', revision[1:]))
    else:
        log('Retrieving Juju GUI source from {} (branch: {}).'.format(
            branch_url, revision))
        cmd_log(
            git_clone('--depth', '1', '-b', revision, branch_url,
                      juju_gui_source_dir))

    log('Preparing a Juju GUI release.')
    logdir = os.path.dirname(logpath)

    fd, name = tempfile.mkstemp(prefix='make-distfile-', dir=logdir)
    log('Output from "make distfile" sent to %s' % name)

    # Passing HOME is required by node during npm packages installation.
    run('make',
        '-C',
        juju_gui_source_dir,
        'distfile',
        'BRANCH_IS_GOOD=true',
        'HOME={}'.format(os.path.expanduser('~')),
        stdout=fd,
        stderr=fd)

    return first_path_in_dir(os.path.join(juju_gui_source_dir, 'releases'))
def get_image_id():
    """Get the most recent image (ubuntu released, precise, amd64)."""
    image_data = run(*'nova --no-cache image-list'.split())
    if not image_data:
        return None
    image_id, description = parse_image_data(image_data)
    print("Using image {} ({})".format(image_id, description))
    return image_id
Example #15
0
def remove_apache_setup():
    """Remove Apache setup."""
    if os.path.exists(APACHE_SITE):
        log('Removing Apache setup.')
        cmd_log(run('rm', '-f', APACHE_SITE))
        with su('root'):
            run('a2dismod', 'headers')
            run('a2dissite', 'juju-gui')
            run('a2ensite', 'default')
        if os.path.exists(APACHE_PORTS):
            cmd_log(run('rm', '-f', APACHE_PORTS))
Example #16
0
def download_release(url, filename):
    """Download a Juju GUI release from the given URL.

    Save the resulting file as filename in the local releases repository.
    Return the full path of the saved file.
    """
    destination = os.path.join(RELEASES_DIR, filename)
    log('Downloading release file: {} --> {}.'.format(url, destination))
    cmd_log(run('curl', '-L', '-o', destination, url))
    return destination
Example #17
0
def install_builtin_server():
    """Install the builtin server code."""
    log('Installing the builtin server dependencies.')
    deps = os.path.join(CURRENT_DIR, 'deps')
    requirements = os.path.join(CURRENT_DIR, 'server-requirements.pip')
    # Install the builtin server dependencies avoiding to download requirements
    # from the network.
    # XXX frankban: this pip installation here implicitly depends on juju-gui
    # dependencies to be installed. In essence, this function does not fetch
    # dependencies from the network only incidentally, because setup_gui() has
    # been already called in the unit.
    with su('root'):
        cmd_log(
            run('pip2', 'install', '--no-index', '--no-dependencies',
                '--find-links', 'file:///{}'.format(deps), '-r', requirements))
    log('Installing the builtin server.')
    setup_cmd = os.path.join(SERVER_DIR, 'setup.py')
    with su('root'):
        cmd_log(run('/usr/bin/python', setup_cmd, 'install'))
Example #18
0
def install_builtin_server():
    """Install the builtin server code."""
    log('Installing the builtin server dependencies.')
    deps = os.path.join(CURRENT_DIR, 'deps')
    requirements = os.path.join(CURRENT_DIR, 'server-requirements.pip')
    # Install the builtin server dependencies avoiding to download requirements
    # from the network.
    # XXX frankban: this pip installation here implicitly depends on juju-gui
    # dependencies to be installed. In essence, this function does not fetch
    # dependencies from the network only incidentally, because setup_gui() has
    # been already called in the unit.
    with su('root'):
        cmd_log(run(
            'pip2', 'install', '--no-index', '--no-dependencies',
            '--find-links', 'file:///{}'.format(deps), '-r', requirements))
    log('Installing the builtin server.')
    setup_cmd = os.path.join(SERVER_DIR, 'setup.py')
    with su('root'):
        cmd_log(run('/usr/bin/python', setup_cmd, 'install'))
Example #19
0
def download_release(url, filename):
    """Download a Juju GUI release from the given URL.

    Save the resulting file as filename in the local releases repository.
    Return the full path of the saved file.
    """
    destination = os.path.join(RELEASES_DIR, filename)
    log('Downloading release file: {} --> {}.'.format(url, destination))
    cmd_log(run('curl', '-L', '-o', destination, url))
    return destination
Example #20
0
def setup_gui():
    """Set up Juju GUI."""
    # Install ensuring network access is not used.  All dependencies should
    # already be installed from the deps directory.
    jujugui_deps = os.path.join(CURRENT_DIR, "jujugui-deps")
    release_tarball_path = get_release_file_path()
    log("Installing Juju GUI from {}.".format(release_tarball_path))
    cmd = ("pip2", "install", "--no-index", "--find-links", "file:///{}".format(jujugui_deps), release_tarball_path)
    with su("root"):
        cmd_log(run(*cmd))
Example #21
0
def setup_gui():
    """Set up Juju GUI."""
    # Install ensuring network access is not used.  All dependencies should
    # already be installed from the deps directory.
    jujugui_deps = os.path.join(CURRENT_DIR, 'jujugui-deps')
    release_tarball_path = get_release_file_path()
    log('Installing Juju GUI from {}.'.format(release_tarball_path))
    cmd = ('pip2', 'install', '--no-index', '--find-links',
           'file:///{}'.format(jujugui_deps), release_tarball_path)
    with su('root'):
        cmd_log(run(*cmd))
Example #22
0
def main():
    # Run pre-install tasks, if available.
    if os.path.isdir('exec.d'):
        dirnames = os.listdir('exec.d')
        dirnames.sort()
        for module in dirnames:
            filename = os.path.join('exec.d', module, 'charm-pre-install')
            try:
                run(filename)
            except OSError, e:
                # If the exec.d file does not exist or is not runnable or
                # is not a directory, assume we can recover.  Log the problem
                # and proceed.  Note that Juju Core has a special need of
                # errno.ENOTDIR because it apparently adds a ".empty" file in
                # empty charm directories, so trying to run
                # ./exec.d/.empty/charm-pre-install will trigger that error.
                if e.errno in (errno.ENOENT, errno.EACCES, errno.ENOTDIR):
                    log('{}: {}'.format(e.strerror, filename))
                else:
                    raise
Example #23
0
def setup_apache():
    """Set up apache."""
    log('Setting up apache.')
    if not os.path.exists(JUJU_GUI_SITE):
        cmd_log(run('touch', JUJU_GUI_SITE))
        cmd_log(run('chown', 'ubuntu:', JUJU_GUI_SITE))
        cmd_log(
            run('ln', '-s', JUJU_GUI_SITE,
                '/etc/apache2/sites-enabled/juju-gui'))

    if not os.path.exists(JUJU_GUI_PORTS):
        cmd_log(run('touch', JUJU_GUI_PORTS))
        cmd_log(run('chown', 'ubuntu:', JUJU_GUI_PORTS))

    with su('root'):
        run('a2dissite', 'default')
        run('a2ensite', 'juju-gui')
Example #24
0
def setup_apache():
    """Set up apache."""
    log('Setting up apache.')
    if not os.path.exists(JUJU_GUI_SITE):
        cmd_log(run('touch', JUJU_GUI_SITE))
        cmd_log(run('chown', 'ubuntu:', JUJU_GUI_SITE))
        cmd_log(
            run('ln', '-s', JUJU_GUI_SITE,
                '/etc/apache2/sites-enabled/juju-gui'))

    if not os.path.exists(JUJU_GUI_PORTS):
        cmd_log(run('touch', JUJU_GUI_PORTS))
        cmd_log(run('chown', 'ubuntu:', JUJU_GUI_PORTS))

    with su('root'):
        run('a2dissite', 'default')
        run('a2ensite', 'juju-gui')
Example #25
0
def setup_gui():
    """Set up Juju GUI."""
    # Install ensuring network access is not used.  All dependencies should
    # already be installed from the deps directory.
    jujugui_deps = os.path.join(CURRENT_DIR, 'jujugui-deps')
    release_tarball_path = get_release_file_path()
    log('Installing Juju GUI from {}.'.format(release_tarball_path))
    cmd = (
        'pip2',  'install', '--no-index', '--find-links',
        'file:///{}'.format(jujugui_deps), release_tarball_path)
    with su('root'):
        cmd_log(run(*cmd))
Example #26
0
 def start(self, backend):
     config = backend.config
     env_uuid = os.getenv('JUJU_ENV_UUID', None)
     juju_version = run('jujud', '--version').strip()
     utils.start_builtin_server(
         config['ssl-cert-path'], config['serve-tests'],
         config['sandbox'], config['builtin-server-logging'],
         not config['secure'], config['charmworld-url'],
         env_password=config.get('password'), env_uuid=env_uuid,
         juju_version=juju_version, debug=config['juju-gui-debug'],
         port=config.get('port'), jem_location=config['jem-location'],
         interactive_login=config['interactive-login'])
Example #27
0
def fetch_gui(juju_gui_source, logpath):
    """Retrieve the Juju GUI release/branch."""
    # Retrieve a Juju GUI release.
    origin, version_or_branch = parse_source(juju_gui_source)
    if origin == 'branch':
        # Make sure we have the dependencies necessary for us to actually make
        # a build.
        _get_build_dependencies()
        # Create a release starting from a branch.
        juju_gui_source_dir = os.path.join(CURRENT_DIR, 'juju-gui-source')
        log('Retrieving Juju GUI source checkout from %s.' % version_or_branch)
        cmd_log(run('rm', '-rf', juju_gui_source_dir))
        cmd_log(bzr_checkout(version_or_branch, juju_gui_source_dir))
        log('Preparing a Juju GUI release.')
        logdir = os.path.dirname(logpath)
        fd, name = tempfile.mkstemp(prefix='make-distfile-', dir=logdir)
        log('Output from "make distfile" sent to %s' % name)
        with environ(NO_BZR='1'):
            run('make',
                '-C',
                juju_gui_source_dir,
                'distfile',
                stdout=fd,
                stderr=fd)
        release_tarball = first_path_in_dir(
            os.path.join(juju_gui_source_dir, 'releases'))
    else:
        log('Retrieving Juju GUI release.')
        if origin == 'url':
            file_url = version_or_branch
        else:
            # Retrieve a release from Launchpad.
            launchpad = Launchpad.login_anonymously('Juju GUI charm',
                                                    'production')
            project = launchpad.projects['juju-gui']
            file_url = get_release_file_url(project, origin, version_or_branch)
        log('Downloading release file from %s.' % file_url)
        release_tarball = os.path.join(CURRENT_DIR, 'release.tgz')
        cmd_log(run('curl', '-L', '-o', release_tarball, file_url))
    return release_tarball
Example #28
0
def prime_npm_cache(npm_cache_url):
    """Download NPM cache archive and prime the NPM cache with it."""
    # Download the cache archive and then uncompress it into the NPM cache.
    npm_cache_archive = os.path.join(CURRENT_DIR, 'npm-cache.tgz')
    cmd_log(run('curl', '-L', '-o', npm_cache_archive, npm_cache_url))
    npm_cache_dir = os.path.expanduser('~/.npm')
    # The NPM cache directory probably does not exist, so make it if not.
    try:
        os.mkdir(npm_cache_dir)
    except OSError, e:
        # If the directory already exists then ignore the error.
        if e.errno != errno.EEXIST:  # File exists.
            raise
Example #29
0
def prime_npm_cache(npm_cache_url):
    """Download NPM cache archive and prime the NPM cache with it."""
    # Download the cache archive and then uncompress it into the NPM cache.
    npm_cache_archive = os.path.join(CURRENT_DIR, 'npm-cache.tgz')
    cmd_log(run('curl', '-L', '-o', npm_cache_archive, npm_cache_url))
    npm_cache_dir = os.path.expanduser('~/.npm')
    # The NPM cache directory probably does not exist, so make it if not.
    try:
        os.mkdir(npm_cache_dir)
    except OSError, e:
        # If the directory already exists then ignore the error.
        if e.errno != errno.EEXIST:  # File exists.
            raise
Example #30
0
def fetch_gui_from_branch(branch_url, revision, logpath):
    """Retrieve the Juju GUI from a branch and build a release archive."""
    # Inject NPM packages into the cache for faster building.
    prime_npm_cache(get_npm_cache_archive_url())
    # Create a release starting from a branch.
    juju_gui_source_dir = os.path.join(CURRENT_DIR, 'juju-gui-source')
    checkout_args, revno = ([], 'latest revno') if revision is None else (
        ['--revision', revision], 'revno {}'.format(revision))
    log('Retrieving Juju GUI source checkout from {} ({}).'.format(
        branch_url, revno))
    cmd_log(run('rm', '-rf', juju_gui_source_dir))
    checkout_args.extend([branch_url, juju_gui_source_dir])
    cmd_log(bzr_checkout(*checkout_args))
    log('Preparing a Juju GUI release.')
    logdir = os.path.dirname(logpath)
    fd, name = tempfile.mkstemp(prefix='make-distfile-', dir=logdir)
    log('Output from "make distfile" sent to %s' % name)
    with environ(NO_BZR='1'):
        run('make', '-C', juju_gui_source_dir, 'distfile',
            stdout=fd, stderr=fd)
    return first_path_in_dir(
        os.path.join(juju_gui_source_dir, 'releases'))
Example #31
0
def save_or_create_certificates(ssl_cert_path, ssl_cert_contents, ssl_key_contents):
    """Generate the SSL certificates.

    If both *ssl_cert_contents* and *ssl_key_contents* are provided, use them
    as certificates; otherwise, generate them.

    Also create a pem file, suitable for use in the haproxy configuration,
    concatenating the key and the certificate files.
    """
    crt_path = os.path.join(ssl_cert_path, "juju.crt")
    key_path = os.path.join(ssl_cert_path, "juju.key")
    if not os.path.exists(ssl_cert_path):
        os.makedirs(ssl_cert_path)
    if ssl_cert_contents and ssl_key_contents:
        # Save the provided certificates.
        with open(crt_path, "w") as cert_file:
            cert_file.write(ssl_cert_contents)
        with open(key_path, "w") as key_file:
            key_file.write(ssl_key_contents)
    else:
        # Generate certificates.
        # See http://superuser.com/questions/226192/openssl-without-prompt
        cn = "your-jujugui-{0}.local".format(int(time.time()))
        cmd_log(
            run(
                "openssl",
                "req",
                "-new",
                "-newkey",
                "rsa:4096",
                "-days",
                "365",
                "-nodes",
                "-x509",
                "-subj",
                # These are arbitrary test values for the certificate.
                "/C=GB/ST=Juju/L=GUI/O=Ubuntu/CN={0}".format(cn),
                "-keyout",
                key_path,
                "-out",
                crt_path,
            )
        )
    # Generate the pem file.
    pem_path = os.path.join(ssl_cert_path, JUJU_PEM)
    if os.path.exists(pem_path):
        os.remove(pem_path)
    with open(pem_path, "w") as pem_file:
        shutil.copyfileobj(open(key_path), pem_file)
        shutil.copyfileobj(open(crt_path), pem_file)
Example #32
0
def configure_source(update=False):
    source = config_get('source')
    if ((source.startswith('ppa:') or source.startswith('cloud:')
         or source.startswith('http:'))):
        run('add-apt-repository', source)
    if source.startswith("http:"):
        run('apt-key', 'import', config_get('key'))
    if update:
        run('apt-get', 'update')
Example #33
0
def save_or_create_certificates(ssl_cert_path, ssl_cert_contents,
                                ssl_key_contents):
    """Generate the SSL certificates.

    If both *ssl_cert_contents* and *ssl_key_contents* are provided, use them
    as certificates; otherwise, generate them.

    Also create a pem file, suitable for use in the haproxy configuration,
    concatenating the key and the certificate files.
    """
    crt_path = os.path.join(ssl_cert_path, 'juju.crt')
    key_path = os.path.join(ssl_cert_path, 'juju.key')
    if not os.path.exists(ssl_cert_path):
        os.makedirs(ssl_cert_path)
    if ssl_cert_contents and ssl_key_contents:
        # Save the provided certificates.
        with open(crt_path, 'w') as cert_file:
            cert_file.write(ssl_cert_contents)
        with open(key_path, 'w') as key_file:
            key_file.write(ssl_key_contents)
    else:
        # Generate certificates.
        # See http://superuser.com/questions/226192/openssl-without-prompt
        cn = 'your-jujugui-{0}.local'.format(int(time.time()))
        cmd_log(
            run(
                'openssl',
                'req',
                '-new',
                '-newkey',
                'rsa:4096',
                '-days',
                '365',
                '-nodes',
                '-x509',
                '-subj',
                # These are arbitrary test values for the certificate.
                '/C=GB/ST=Juju/L=GUI/O=Ubuntu/CN={0}'.format(cn),
                '-keyout',
                key_path,
                '-out',
                crt_path))
    # Generate the pem file.
    pem_path = os.path.join(ssl_cert_path, JUJU_PEM)
    if os.path.exists(pem_path):
        os.remove(pem_path)
    with open(pem_path, 'w') as pem_file:
        shutil.copyfileobj(open(key_path), pem_file)
        shutil.copyfileobj(open(crt_path), pem_file)
Example #34
0
def fetch_gui(juju_gui_source, logpath):
    """Retrieve the Juju GUI release/branch."""
    # Retrieve a Juju GUI release.
    origin, version_or_branch = parse_source(juju_gui_source)
    if origin == 'branch':
        # Make sure we have the dependencies necessary for us to actually make
        # a build.
        _get_build_dependencies()
        # Create a release starting from a branch.
        juju_gui_source_dir = os.path.join(CURRENT_DIR, 'juju-gui-source')
        log('Retrieving Juju GUI source checkout from %s.' % version_or_branch)
        cmd_log(run('rm', '-rf', juju_gui_source_dir))
        cmd_log(bzr_checkout(version_or_branch, juju_gui_source_dir))
        log('Preparing a Juju GUI release.')
        logdir = os.path.dirname(logpath)
        fd, name = tempfile.mkstemp(prefix='make-distfile-', dir=logdir)
        log('Output from "make distfile" sent to %s' % name)
        with environ(NO_BZR='1'):
            run('make', '-C', juju_gui_source_dir, 'distfile',
                stdout=fd, stderr=fd)
        release_tarball = first_path_in_dir(
            os.path.join(juju_gui_source_dir, 'releases'))
    else:
        log('Retrieving Juju GUI release.')
        if origin == 'url':
            file_url = version_or_branch
        else:
            # Retrieve a release from Launchpad.
            launchpad = Launchpad.login_anonymously(
                'Juju GUI charm', 'production')
            project = launchpad.projects['juju-gui']
            file_url = get_release_file_url(project, origin, version_or_branch)
        log('Downloading release file from %s.' % file_url)
        release_tarball = os.path.join(CURRENT_DIR, 'release.tgz')
        cmd_log(run('curl', '-L', '-o', release_tarball, file_url))
    return release_tarball
Example #35
0
def setup_apache_config(build_dir, serve_tests=False):
    """Set up the Apache configuration."""
    log('Generating the Apache site configuration files.')
    tests_root = os.path.join(JUJU_GUI_DIR, 'test', '') if serve_tests else ''
    context = {
        'port': WEB_PORT,
        'server_root': build_dir,
        'tests_root': tests_root,
    }
    render_to_file('apache-ports.template', context, APACHE_PORTS)
    cmd_log(run('chown', 'ubuntu:', APACHE_PORTS))
    render_to_file('apache-site.template', context, APACHE_SITE)
    cmd_log(run('chown', 'ubuntu:', APACHE_SITE))
    with su('root'):
        run('a2dissite', 'default')
        run('a2ensite', 'juju-gui')
        run('a2enmod', 'headers')
Example #36
0
def configure_source(update=False):
    source = config_get('source')
    if (source.startswith('ppa:') or
        source.startswith('cloud:') or
        source.startswith('http:')):
        run('add-apt-repository', source)
    if source.startswith("http:"):
        run('apt-key', 'import', config_get('key'))
    if update:
        run('apt-get', 'update')
Example #37
0
def save_or_create_certificates(
        ssl_cert_path, ssl_cert_contents, ssl_key_contents):
    """Generate the SSL certificates.

    If both *ssl_cert_contents* and *ssl_key_contents* are provided, use them
    as certificates; otherwise, generate them.

    Also create a pem file, suitable for use in the haproxy configuration,
    concatenating the key and the certificate files.
    """
    crt_path = os.path.join(ssl_cert_path, 'juju.crt')
    key_path = os.path.join(ssl_cert_path, 'juju.key')
    if not os.path.exists(ssl_cert_path):
        os.makedirs(ssl_cert_path)
    if ssl_cert_contents and ssl_key_contents:
        # Save the provided certificates.
        with open(crt_path, 'w') as cert_file:
            cert_file.write(ssl_cert_contents)
        with open(key_path, 'w') as key_file:
            key_file.write(ssl_key_contents)
    else:
        # Generate certificates.
        # See http://superuser.com/questions/226192/openssl-without-prompt
        cmd_log(run(
            'openssl', 'req', '-new', '-newkey', 'rsa:4096',
            '-days', '365', '-nodes', '-x509', '-subj',
            # These are arbitrary test values for the certificate.
            '/C=GB/ST=Juju/L=GUI/O=Ubuntu/CN=juju.ubuntu.com',
            '-keyout', key_path, '-out', crt_path))
    # Generate the pem file.
    pem_path = os.path.join(ssl_cert_path, JUJU_PEM)
    if os.path.exists(pem_path):
        os.remove(pem_path)
    with open(pem_path, 'w') as pem_file:
        shutil.copyfileobj(open(key_path), pem_file)
        shutil.copyfileobj(open(crt_path), pem_file)
Example #38
0
def juju_status(key):
    return yaml.safe_load(run('juju', 'status'))[key]
Example #39
0
def fetch_api(juju_api_branch):
    """Retrieve the Juju branch, removing it first if already there."""
    # Retrieve Juju API source checkout.
    log('Retrieving Juju API source checkout.')
    cmd_log(run('rm', '-rf', JUJU_AGENT_DIR))
    cmd_log(bzr_checkout(juju_api_branch, JUJU_AGENT_DIR))
Example #40
0
def write_gui_config(console_enabled,
                     login_help,
                     readonly,
                     charmworld_url,
                     charmstore_url,
                     build_dir,
                     secure=True,
                     sandbox=False,
                     cached_fonts=False,
                     hide_login_button=False,
                     config_js_path=None,
                     ga_key='',
                     juju_core_version=None,
                     password=None,
                     juju_env_uuid=None):
    """Generate the GUI configuration file."""
    log('Generating the Juju GUI configuration file.')
    user = '******'
    # Normalize empty string passwords to None. If sandbox is enabled then set
    # the password to admin and it will auto login.
    if not password:
        if sandbox:
            password = '******'
        else:
            password = None
    api_backend = 'go'
    if secure:
        protocol = 'wss'
    else:
        log('Running in insecure mode! Port 80 will serve unencrypted.')
        protocol = 'ws'
    # Set up the help message displayed by the GUI login view.
    if login_help is None:
        env_name = os.getenv('JUJU_ENV_NAME')
        if env_name:
            login_help = (
                'The password is the admin-secret from the Juju environment. '
                'This can be found by looking in ~/.juju/environments/{}.jenv '
                'and searching for the password field. Note that using '
                'juju-quickstart (https://launchpad.net/juju-quickstart) can '
                'automate logging in, as well as other parts of installing '
                'and starting Juju.'.format(env_name))
        else:
            # The Juju environment name is included in the hooks context
            # starting from juju-core v1.18.
            login_help = (
                'The password for newer Juju clients can be found by locating '
                'the Juju environment file placed in ~/.juju/environments/ '
                'with the same name as the current environment. For example, '
                'if you have an environment named "production", then the file '
                'is named ~/.juju/environments/production.jenv. Look for the '
                '"password" field in the file, or if that is empty, for the '
                '"admin-secret". Remove the quotes from the value, and use '
                'this to log in. The password for older Juju clients (< 1.16) '
                'is in ~/.juju/environments.yaml, and listed as the '
                'admin-secret for the environment you are using. Note that '
                'using juju-quickstart '
                '(https://launchpad.net/juju-quickstart) can automate logging '
                'in, as well as other parts of installing and starting Juju.')
    if not juju_core_version:
        log('Retrieving Juju version.')
        juju_core_version = run('jujud', '--version').strip()

    context = {
        'cached_fonts': json.dumps(cached_fonts),
        'raw_protocol': protocol,
        'address': unit_get('public-address'),
        'console_enabled': json.dumps(console_enabled),
        'login_help': json.dumps(login_help),
        'password': json.dumps(password),
        'api_backend': json.dumps(api_backend),
        'readonly': json.dumps(readonly),
        'user': json.dumps(user),
        'protocol': json.dumps(protocol),
        'sandbox': json.dumps(sandbox),
        'charmworld_url': json.dumps(charmworld_url),
        'charmstore_url': json.dumps(charmstore_url),
        'ga_key': json.dumps(ga_key),
        'hide_login_button': json.dumps(hide_login_button),
        'juju_core_version': json.dumps(juju_core_version),
        'juju_env_uuid': json.dumps(juju_env_uuid),
    }
    if config_js_path is None:
        config_js_path = os.path.join(build_dir, 'juju-ui', 'assets',
                                      'config.js')
    render_to_file('config.js.template', context, config_js_path)
Example #41
0
def stop_builtin_server():
    """Stop the builtin server."""
    log('Stopping the builtin server.')
    with su('root'):
        service(STOP, GUISERVER)
    cmd_log(run('rm', '-f', GUISERVER_INIT_PATH))
Example #42
0
def stop_builtin_server():
    """Stop the builtin server."""
    log('Stopping the builtin server.')
    with su('root'):
        service_control(BUILTIN_SERVER, STOP)
    cmd_log(run('rm', '-f', GUISERVER_INIT_PATH))
Example #43
0
def start_gui(console_enabled,
              login_help,
              readonly,
              in_staging,
              ssl_cert_path,
              charmworld_url,
              serve_tests,
              haproxy_path='/etc/haproxy/haproxy.cfg',
              config_js_path=None,
              secure=True,
              sandbox=False):
    """Set up and start the Juju GUI server."""
    with su('root'):
        run('chown', '-R', 'ubuntu:', JUJU_GUI_DIR)
    # XXX 2013-02-05 frankban bug=1116320:
    # External insecure resources are still loaded when testing in the
    # debug environment. For now, switch to the production environment if
    # the charm is configured to serve tests.
    if in_staging and not serve_tests:
        build_dirname = 'build-debug'
    else:
        build_dirname = 'build-prod'
    build_dir = os.path.join(JUJU_GUI_DIR, build_dirname)
    log('Generating the Juju GUI configuration file.')
    is_legacy_juju = legacy_juju()
    user, password = None, None
    if (is_legacy_juju and in_staging) or sandbox:
        user, password = '******', 'admin'
    else:
        user, password = None, None

    api_backend = 'python' if is_legacy_juju else 'go'
    if secure:
        protocol = 'wss'
    else:
        log('Running in insecure mode! Port 80 will serve unencrypted.')
        protocol = 'ws'

    context = {
        'raw_protocol': protocol,
        'address': unit_get('public-address'),
        'console_enabled': json.dumps(console_enabled),
        'login_help': json.dumps(login_help),
        'password': json.dumps(password),
        'api_backend': json.dumps(api_backend),
        'readonly': json.dumps(readonly),
        'user': json.dumps(user),
        'protocol': json.dumps(protocol),
        'sandbox': json.dumps(sandbox),
        'charmworld_url': json.dumps(charmworld_url),
    }
    if config_js_path is None:
        config_js_path = os.path.join(build_dir, 'juju-ui', 'assets',
                                      'config.js')
    render_to_file('config/config.js.template', context, config_js_path)

    write_apache_config(build_dir, serve_tests)

    log('Generating haproxy configuration file.')
    if is_legacy_juju:
        # The PyJuju API agent is listening on localhost.
        api_address = '127.0.0.1:{0}'.format(API_PORT)
    else:
        # Retrieve the juju-core API server address.
        api_address = get_api_address(os.path.join(CURRENT_DIR, '..'))
    context = {
        'api_address': api_address,
        'api_pem': JUJU_PEM,
        'legacy_juju': is_legacy_juju,
        'ssl_cert_path': ssl_cert_path,
        # In PyJuju environments, use the same certificate for both HTTPS and
        # WebSocket connections. In juju-core the system already has the proper
        # certificate installed.
        'web_pem': JUJU_PEM,
        'web_port': WEB_PORT,
        'secure': secure
    }
    render_to_file('config/haproxy.cfg.template', context, haproxy_path)
    log('Starting Juju GUI.')
Example #44
0
from shelltoolbox import run
import shutil
import tempfile
import unittest

import mock

import backend
import utils


EXPECTED_DEBS = (
    'curl', 'libcurl3', 'openssl', 'python-bzrlib', 'python-pip',
    'python-pycurl')

JUJU_VERSION = run('jujud', '--version').strip()


def patch_environ(**kwargs):
    """Patch the environment context by adding the given kwargs."""
    environ = os.environ.copy()
    environ.update(kwargs)
    return mock.patch('os.environ', environ)


class TestBackendProperties(unittest.TestCase):
    """Ensure the correct mixins and property values are collected."""

    def test_mixins(self):
        # Ensure the backend includes the expected mixins.
        expected_mixins = ['SetUpMixin', 'GuiMixin', 'GuiServerMixin']
Example #45
0
def remove_haproxy_setup():
    """Remove haproxy setup."""
    log('Removing haproxy setup.')
    cmd_log(run('rm', '-f', HAPROXY_CFG_PATH))
    cmd_log(run('rm', '-f', HAPROXY_INIT_PATH))
Example #46
0
)
import os
from shelltoolbox import run
import shutil
import tempfile
import unittest

import mock

import backend
import utils

EXPECTED_DEBS = ('curl', 'libcurl3', 'openssl', 'python-bzrlib', 'python-pip',
                 'python-pycurl')

JUJU_VERSION = run('jujud', '--version').strip()


def patch_environ(**kwargs):
    """Patch the environment context by adding the given kwargs."""
    environ = os.environ.copy()
    environ.update(kwargs)
    return mock.patch('os.environ', environ)


class TestBackendProperties(unittest.TestCase):
    """Ensure the correct mixins and property values are collected."""
    def test_mixins(self):
        # Ensure the backend includes the expected mixins.
        expected_mixins = ['SetUpMixin', 'GuiMixin', 'GuiServerMixin']
        test_backend = backend.Backend(config={})
Example #47
0
def fetch_api(juju_api_branch):
    """Retrieve the Juju branch."""
    # Retrieve Juju API source checkout.
    log('Retrieving Juju API source checkout.')
    cmd_log(run('rm', '-rf', JUJU_DIR))
    cmd_log(bzr_checkout(juju_api_branch, JUJU_DIR))
Example #48
0
def juju_status(key):
    return yaml.safe_load(run('juju', 'status'))[key]
Example #49
0
def fetch_api(juju_api_branch):
    """Retrieve the Juju branch."""
    # Retrieve Juju API source checkout.
    log('Retrieving Juju API source checkout.')
    cmd_log(run('rm', '-rf', JUJU_DIR))
    cmd_log(bzr_checkout(juju_api_branch, JUJU_DIR))