~bbaqar/charms/trusty/neutron-api-plumgrid/temp

« back to all changes in this revision

Viewing changes to hooks/charmhelpers/core/hookenv.py

  • Committer: bbaqar at plumgrid
  • Date: 2016-04-25 09:05:55 UTC
  • mfrom: (18.1.7 neutron-api-plumgrid)
  • Revision ID: bbaqar@plumgrid.com-20160425090555-yl82ba6bhwjqkwr9
Merge: Liberty/Mitaka support

Show diffs side-by-side

added added

removed removed

Lines of Context:
74
74
        res = func(*args, **kwargs)
75
75
        cache[key] = res
76
76
        return res
 
77
    wrapper._wrapped = func
77
78
    return wrapper
78
79
 
79
80
 
173
174
    return os.environ.get('JUJU_RELATION', None)
174
175
 
175
176
 
176
 
def relation_id():
177
 
    """The relation ID for the current relation hook"""
178
 
    return os.environ.get('JUJU_RELATION_ID', None)
 
177
@cached
 
178
def relation_id(relation_name=None, service_or_unit=None):
 
179
    """The relation ID for the current or a specified relation"""
 
180
    if not relation_name and not service_or_unit:
 
181
        return os.environ.get('JUJU_RELATION_ID', None)
 
182
    elif relation_name and service_or_unit:
 
183
        service_name = service_or_unit.split('/')[0]
 
184
        for relid in relation_ids(relation_name):
 
185
            remote_service = remote_service_name(relid)
 
186
            if remote_service == service_name:
 
187
                return relid
 
188
    else:
 
189
        raise ValueError('Must specify neither or both of relation_name and service_or_unit')
179
190
 
180
191
 
181
192
def local_unit():
193
204
    return local_unit().split('/')[0]
194
205
 
195
206
 
 
207
@cached
 
208
def remote_service_name(relid=None):
 
209
    """The remote service name for a given relation-id (or the current relation)"""
 
210
    if relid is None:
 
211
        unit = remote_unit()
 
212
    else:
 
213
        units = related_units(relid)
 
214
        unit = units[0] if units else None
 
215
    return unit.split('/')[0] if unit else None
 
216
 
 
217
 
196
218
def hook_name():
197
219
    """The name of the currently executing hook"""
198
 
    return os.path.basename(sys.argv[0])
 
220
    return os.environ.get('JUJU_HOOK_NAME', os.path.basename(sys.argv[0]))
199
221
 
200
222
 
201
223
class Config(dict):
469
491
 
470
492
 
471
493
@cached
 
494
def peer_relation_id():
 
495
    '''Get the peers relation id if a peers relation has been joined, else None.'''
 
496
    md = metadata()
 
497
    section = md.get('peers')
 
498
    if section:
 
499
        for key in section:
 
500
            relids = relation_ids(key)
 
501
            if relids:
 
502
                return relids[0]
 
503
    return None
 
504
 
 
505
 
 
506
@cached
 
507
def relation_to_interface(relation_name):
 
508
    """
 
509
    Given the name of a relation, return the interface that relation uses.
 
510
 
 
511
    :returns: The interface name, or ``None``.
 
512
    """
 
513
    return relation_to_role_and_interface(relation_name)[1]
 
514
 
 
515
 
 
516
@cached
 
517
def relation_to_role_and_interface(relation_name):
 
518
    """
 
519
    Given the name of a relation, return the role and the name of the interface
 
520
    that relation uses (where role is one of ``provides``, ``requires``, or ``peers``).
 
521
 
 
522
    :returns: A tuple containing ``(role, interface)``, or ``(None, None)``.
 
523
    """
 
524
    _metadata = metadata()
 
525
    for role in ('provides', 'requires', 'peers'):
 
526
        interface = _metadata.get(role, {}).get(relation_name, {}).get('interface')
 
527
        if interface:
 
528
            return role, interface
 
529
    return None, None
 
530
 
 
531
 
 
532
@cached
 
533
def role_and_interface_to_relations(role, interface_name):
 
534
    """
 
535
    Given a role and interface name, return a list of relation names for the
 
536
    current charm that use that interface under that role (where role is one
 
537
    of ``provides``, ``requires``, or ``peers``).
 
538
 
 
539
    :returns: A list of relation names.
 
540
    """
 
541
    _metadata = metadata()
 
542
    results = []
 
543
    for relation_name, relation in _metadata.get(role, {}).items():
 
544
        if relation['interface'] == interface_name:
 
545
            results.append(relation_name)
 
546
    return results
 
547
 
 
548
 
 
549
@cached
 
550
def interface_to_relations(interface_name):
 
551
    """
 
552
    Given an interface, return a list of relation names for the current
 
553
    charm that use that interface.
 
554
 
 
555
    :returns: A list of relation names.
 
556
    """
 
557
    results = []
 
558
    for role in ('provides', 'requires', 'peers'):
 
559
        results.extend(role_and_interface_to_relations(role, interface_name))
 
560
    return results
 
561
 
 
562
 
 
563
@cached
472
564
def charm_name():
473
565
    """Get the name of the current charm as is specified on metadata.yaml"""
474
566
    return metadata().get('name')
544
636
    return unit_get('private-address')
545
637
 
546
638
 
 
639
@cached
 
640
def storage_get(attribute=None, storage_id=None):
 
641
    """Get storage attributes"""
 
642
    _args = ['storage-get', '--format=json']
 
643
    if storage_id:
 
644
        _args.extend(('-s', storage_id))
 
645
    if attribute:
 
646
        _args.append(attribute)
 
647
    try:
 
648
        return json.loads(subprocess.check_output(_args).decode('UTF-8'))
 
649
    except ValueError:
 
650
        return None
 
651
 
 
652
 
 
653
@cached
 
654
def storage_list(storage_name=None):
 
655
    """List the storage IDs for the unit"""
 
656
    _args = ['storage-list', '--format=json']
 
657
    if storage_name:
 
658
        _args.append(storage_name)
 
659
    try:
 
660
        return json.loads(subprocess.check_output(_args).decode('UTF-8'))
 
661
    except ValueError:
 
662
        return None
 
663
    except OSError as e:
 
664
        import errno
 
665
        if e.errno == errno.ENOENT:
 
666
            # storage-list does not exist
 
667
            return []
 
668
        raise
 
669
 
 
670
 
547
671
class UnregisteredHookError(Exception):
548
672
    """Raised when an undefined hook is called"""
549
673
    pass
644
768
    subprocess.check_call(['action-fail', message])
645
769
 
646
770
 
 
771
def action_name():
 
772
    """Get the name of the currently executing action."""
 
773
    return os.environ.get('JUJU_ACTION_NAME')
 
774
 
 
775
 
 
776
def action_uuid():
 
777
    """Get the UUID of the currently executing action."""
 
778
    return os.environ.get('JUJU_ACTION_UUID')
 
779
 
 
780
 
 
781
def action_tag():
 
782
    """Get the tag for the currently executing action."""
 
783
    return os.environ.get('JUJU_ACTION_TAG')
 
784
 
 
785
 
647
786
def status_set(workload_state, message):
648
787
    """Set the workload state with a message
649
788
 
673
812
 
674
813
 
675
814
def status_get():
676
 
    """Retrieve the previously set juju workload state
677
 
 
678
 
    If the status-set command is not found then assume this is juju < 1.23 and
679
 
    return 'unknown'
 
815
    """Retrieve the previously set juju workload state and message
 
816
 
 
817
    If the status-get command is not found then assume this is juju < 1.23 and
 
818
    return 'unknown', ""
 
819
 
680
820
    """
681
 
    cmd = ['status-get']
 
821
    cmd = ['status-get', "--format=json", "--include-data"]
682
822
    try:
683
 
        raw_status = subprocess.check_output(cmd, universal_newlines=True)
684
 
        status = raw_status.rstrip()
685
 
        return status
 
823
        raw_status = subprocess.check_output(cmd)
686
824
    except OSError as e:
687
825
        if e.errno == errno.ENOENT:
688
 
            return 'unknown'
 
826
            return ('unknown', "")
689
827
        else:
690
828
            raise
 
829
    else:
 
830
        status = json.loads(raw_status.decode("UTF-8"))
 
831
        return (status["status"], status["message"])
691
832
 
692
833
 
693
834
def translate_exc(from_exc, to_exc):
694
835
    def inner_translate_exc1(f):
 
836
        @wraps(f)
695
837
        def inner_translate_exc2(*args, **kwargs):
696
838
            try:
697
839
                return f(*args, **kwargs)
736
878
    subprocess.check_call(cmd)
737
879
 
738
880
 
 
881
@translate_exc(from_exc=OSError, to_exc=NotImplementedError)
 
882
def payload_register(ptype, klass, pid):
 
883
    """ is used while a hook is running to let Juju know that a
 
884
        payload has been started."""
 
885
    cmd = ['payload-register']
 
886
    for x in [ptype, klass, pid]:
 
887
        cmd.append(x)
 
888
    subprocess.check_call(cmd)
 
889
 
 
890
 
 
891
@translate_exc(from_exc=OSError, to_exc=NotImplementedError)
 
892
def payload_unregister(klass, pid):
 
893
    """ is used while a hook is running to let Juju know
 
894
    that a payload has been manually stopped. The <class> and <id> provided
 
895
    must match a payload that has been previously registered with juju using
 
896
    payload-register."""
 
897
    cmd = ['payload-unregister']
 
898
    for x in [klass, pid]:
 
899
        cmd.append(x)
 
900
    subprocess.check_call(cmd)
 
901
 
 
902
 
 
903
@translate_exc(from_exc=OSError, to_exc=NotImplementedError)
 
904
def payload_status_set(klass, pid, status):
 
905
    """is used to update the current status of a registered payload.
 
906
    The <class> and <id> provided must match a payload that has been previously
 
907
    registered with juju using payload-register. The <status> must be one of the
 
908
    follow: starting, started, stopping, stopped"""
 
909
    cmd = ['payload-status-set']
 
910
    for x in [klass, pid, status]:
 
911
        cmd.append(x)
 
912
    subprocess.check_call(cmd)
 
913
 
 
914
 
 
915
@translate_exc(from_exc=OSError, to_exc=NotImplementedError)
 
916
def resource_get(name):
 
917
    """used to fetch the resource path of the given name.
 
918
 
 
919
    <name> must match a name of defined resource in metadata.yaml
 
920
 
 
921
    returns either a path or False if resource not available
 
922
    """
 
923
    if not name:
 
924
        return False
 
925
 
 
926
    cmd = ['resource-get', name]
 
927
    try:
 
928
        return subprocess.check_output(cmd).decode('UTF-8')
 
929
    except subprocess.CalledProcessError:
 
930
        return False
 
931
 
 
932
 
739
933
@cached
740
934
def juju_version():
741
935
    """Full version string (eg. '1.23.3.1-trusty-amd64')"""
800
994
    for callback, args, kwargs in reversed(_atexit):
801
995
        callback(*args, **kwargs)
802
996
    del _atexit[:]
 
997
 
 
998
 
 
999
@translate_exc(from_exc=OSError, to_exc=NotImplementedError)
 
1000
def network_get_primary_address(binding):
 
1001
    '''
 
1002
    Retrieve the primary network address for a named binding
 
1003
 
 
1004
    :param binding: string. The name of a relation of extra-binding
 
1005
    :return: string. The primary IP address for the named binding
 
1006
    :raise: NotImplementedError if run on Juju < 2.0
 
1007
    '''
 
1008
    cmd = ['network-get', '--primary-address', binding]
 
1009
    return subprocess.check_output(cmd).strip()