~openstack-charmers/charms/trusty/nova-compute/0mq

« back to all changes in this revision

Viewing changes to hooks/charmhelpers/contrib/openstack/utils.py

  • Committer: james.page at ubuntu
  • Date: 2015-03-31 15:01:48 UTC
  • mfrom: (79.2.37 nova-compute)
  • Revision ID: james.page@ubuntu.com-20150331150148-fn3iawy9bqboe0d3
Rebase, resync

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
 
31
31
from charmhelpers.contrib.network import ip
32
32
 
 
33
from charmhelpers.core import (
 
34
    unitdata,
 
35
)
 
36
 
33
37
from charmhelpers.core.hookenv import (
34
38
    config,
35
39
    log as juju_log,
330
334
        error_out("Invalid openstack-release specified: %s" % rel)
331
335
 
332
336
 
 
337
def config_value_changed(option):
 
338
    """
 
339
    Determine if config value changed since last call to this function.
 
340
    """
 
341
    hook_data = unitdata.HookData()
 
342
    with hook_data():
 
343
        db = unitdata.kv()
 
344
        current = config(option)
 
345
        saved = db.get(option)
 
346
        db.set(option, current)
 
347
        if saved is None:
 
348
            return False
 
349
        return current != saved
 
350
 
 
351
 
333
352
def save_script_rc(script_path="scripts/scriptrc", **env_vars):
334
353
    """
335
354
    Write an rc file in the charm-delivered directory containing
469
488
 
470
489
 
471
490
def git_install_requested():
472
 
    """Returns true if openstack-origin-git is specified."""
473
 
    return config('openstack-origin-git') != "None"
 
491
    """
 
492
    Returns true if openstack-origin-git is specified.
 
493
    """
 
494
    return config('openstack-origin-git') is not None
474
495
 
475
496
 
476
497
requirements_dir = None
477
498
 
478
499
 
479
 
def git_clone_and_install(file_name, core_project):
480
 
    """Clone/install all OpenStack repos specified in yaml config file."""
 
500
def git_clone_and_install(projects_yaml, core_project):
 
501
    """
 
502
    Clone/install all specified OpenStack repositories.
 
503
 
 
504
    The expected format of projects_yaml is:
 
505
        repositories:
 
506
          - {name: keystone,
 
507
             repository: 'git://git.openstack.org/openstack/keystone.git',
 
508
             branch: 'stable/icehouse'}
 
509
          - {name: requirements,
 
510
             repository: 'git://git.openstack.org/openstack/requirements.git',
 
511
             branch: 'stable/icehouse'}
 
512
        directory: /mnt/openstack-git
 
513
 
 
514
        The directory key is optional.
 
515
    """
481
516
    global requirements_dir
 
517
    parent_dir = '/mnt/openstack-git'
482
518
 
483
 
    if file_name == "None":
 
519
    if not projects_yaml:
484
520
        return
485
521
 
486
 
    yaml_file = os.path.join(charm_dir(), file_name)
487
 
 
488
 
    # clone/install the requirements project first
489
 
    installed = _git_clone_and_install_subset(yaml_file,
490
 
                                              whitelist=['requirements'])
491
 
    if 'requirements' not in installed:
492
 
        error_out('requirements git repository must be specified')
493
 
 
494
 
    # clone/install all other projects except requirements and the core project
495
 
    blacklist = ['requirements', core_project]
496
 
    _git_clone_and_install_subset(yaml_file, blacklist=blacklist,
497
 
                                  update_requirements=True)
498
 
 
499
 
    # clone/install the core project
500
 
    whitelist = [core_project]
501
 
    installed = _git_clone_and_install_subset(yaml_file, whitelist=whitelist,
502
 
                                              update_requirements=True)
503
 
    if core_project not in installed:
504
 
        error_out('{} git repository must be specified'.format(core_project))
505
 
 
506
 
 
507
 
def _git_clone_and_install_subset(yaml_file, whitelist=[], blacklist=[],
508
 
                                  update_requirements=False):
509
 
    """Clone/install subset of OpenStack repos specified in yaml config file."""
510
 
    global requirements_dir
511
 
    installed = []
512
 
 
513
 
    with open(yaml_file, 'r') as fd:
514
 
        projects = yaml.load(fd)
515
 
        for proj, val in projects.items():
516
 
            # The project subset is chosen based on the following 3 rules:
517
 
            # 1) If project is in blacklist, we don't clone/install it, period.
518
 
            # 2) If whitelist is empty, we clone/install everything else.
519
 
            # 3) If whitelist is not empty, we clone/install everything in the
520
 
            #    whitelist.
521
 
            if proj in blacklist:
522
 
                continue
523
 
            if whitelist and proj not in whitelist:
524
 
                continue
525
 
            repo = val['repository']
526
 
            branch = val['branch']
527
 
            repo_dir = _git_clone_and_install_single(repo, branch,
528
 
                                                     update_requirements)
529
 
            if proj == 'requirements':
530
 
                requirements_dir = repo_dir
531
 
            installed.append(proj)
532
 
    return installed
533
 
 
534
 
 
535
 
def _git_clone_and_install_single(repo, branch, update_requirements=False):
536
 
    """Clone and install a single git repository."""
537
 
    dest_parent_dir = "/mnt/openstack-git/"
538
 
    dest_dir = os.path.join(dest_parent_dir, os.path.basename(repo))
539
 
 
540
 
    if not os.path.exists(dest_parent_dir):
541
 
        juju_log('Host dir not mounted at {}. '
542
 
                 'Creating directory there instead.'.format(dest_parent_dir))
543
 
        os.mkdir(dest_parent_dir)
 
522
    projects = yaml.load(projects_yaml)
 
523
    _git_validate_projects_yaml(projects, core_project)
 
524
 
 
525
    if 'directory' in projects.keys():
 
526
        parent_dir = projects['directory']
 
527
 
 
528
    for p in projects['repositories']:
 
529
        repo = p['repository']
 
530
        branch = p['branch']
 
531
        if p['name'] == 'requirements':
 
532
            repo_dir = _git_clone_and_install_single(repo, branch, parent_dir,
 
533
                                                     update_requirements=False)
 
534
            requirements_dir = repo_dir
 
535
        else:
 
536
            repo_dir = _git_clone_and_install_single(repo, branch, parent_dir,
 
537
                                                     update_requirements=True)
 
538
 
 
539
 
 
540
def _git_validate_projects_yaml(projects, core_project):
 
541
    """
 
542
    Validate the projects yaml.
 
543
    """
 
544
    _git_ensure_key_exists('repositories', projects)
 
545
 
 
546
    for project in projects['repositories']:
 
547
        _git_ensure_key_exists('name', project.keys())
 
548
        _git_ensure_key_exists('repository', project.keys())
 
549
        _git_ensure_key_exists('branch', project.keys())
 
550
 
 
551
    if projects['repositories'][0]['name'] != 'requirements':
 
552
        error_out('{} git repo must be specified first'.format('requirements'))
 
553
 
 
554
    if projects['repositories'][-1]['name'] != core_project:
 
555
        error_out('{} git repo must be specified last'.format(core_project))
 
556
 
 
557
 
 
558
def _git_ensure_key_exists(key, keys):
 
559
    """
 
560
    Ensure that key exists in keys.
 
561
    """
 
562
    if key not in keys:
 
563
        error_out('openstack-origin-git key \'{}\' is missing'.format(key))
 
564
 
 
565
 
 
566
def _git_clone_and_install_single(repo, branch, parent_dir, update_requirements):
 
567
    """
 
568
    Clone and install a single git repository.
 
569
    """
 
570
    dest_dir = os.path.join(parent_dir, os.path.basename(repo))
 
571
 
 
572
    if not os.path.exists(parent_dir):
 
573
        juju_log('Directory already exists at {}. '
 
574
                 'No need to create directory.'.format(parent_dir))
 
575
        os.mkdir(parent_dir)
544
576
 
545
577
    if not os.path.exists(dest_dir):
546
578
        juju_log('Cloning git repo: {}, branch: {}'.format(repo, branch))
547
 
        repo_dir = install_remote(repo, dest=dest_parent_dir, branch=branch)
 
579
        repo_dir = install_remote(repo, dest=parent_dir, branch=branch)
548
580
    else:
549
581
        repo_dir = dest_dir
550
582
 
561
593
 
562
594
 
563
595
def _git_update_requirements(package_dir, reqs_dir):
564
 
    """Update from global requirements.
 
596
    """
 
597
    Update from global requirements.
565
598
 
566
 
       Update an OpenStack git directory's requirements.txt and
567
 
       test-requirements.txt from global-requirements.txt."""
 
599
    Update an OpenStack git directory's requirements.txt and
 
600
    test-requirements.txt from global-requirements.txt.
 
601
    """
568
602
    orig_dir = os.getcwd()
569
603
    os.chdir(reqs_dir)
570
 
    cmd = "python update.py {}".format(package_dir)
 
604
    cmd = ['python', 'update.py', package_dir]
571
605
    try:
572
 
        subprocess.check_call(cmd.split(' '))
 
606
        subprocess.check_call(cmd)
573
607
    except subprocess.CalledProcessError:
574
608
        package = os.path.basename(package_dir)
575
609
        error_out("Error updating {} from global-requirements.txt".format(package))
576
610
    os.chdir(orig_dir)
 
611
 
 
612
 
 
613
def git_src_dir(projects_yaml, project):
 
614
    """
 
615
    Return the directory where the specified project's source is located.
 
616
    """
 
617
    parent_dir = '/mnt/openstack-git'
 
618
 
 
619
    if not projects_yaml:
 
620
        return
 
621
 
 
622
    projects = yaml.load(projects_yaml)
 
623
 
 
624
    if 'directory' in projects.keys():
 
625
        parent_dir = projects['directory']
 
626
 
 
627
    for p in projects['repositories']:
 
628
        if p['name'] == project:
 
629
            return os.path.join(parent_dir, os.path.basename(p['repository']))
 
630
 
 
631
    return None