~landscape/charms/trusty/neutron-api-odl-vpp/trunk

« back to all changes in this revision

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

  • Committer: Liam Young
  • Date: 2015-11-03 13:42:27 UTC
  • mfrom: (4.1.1 neutron-api-odl)
  • Revision ID: liam.young@canonical.com-20151103134227-pnazu50qwdizbudp
Sync from lp:charm-helpers and fix services.py to fit with it

Show diffs side-by-side

added added

removed removed

Lines of Context:
63
63
    return service_result
64
64
 
65
65
 
 
66
def service_pause(service_name, init_dir="/etc/init", initd_dir="/etc/init.d"):
 
67
    """Pause a system service.
 
68
 
 
69
    Stop it, and prevent it from starting again at boot."""
 
70
    stopped = service_stop(service_name)
 
71
    upstart_file = os.path.join(init_dir, "{}.conf".format(service_name))
 
72
    sysv_file = os.path.join(initd_dir, service_name)
 
73
    if os.path.exists(upstart_file):
 
74
        override_path = os.path.join(
 
75
            init_dir, '{}.override'.format(service_name))
 
76
        with open(override_path, 'w') as fh:
 
77
            fh.write("manual\n")
 
78
    elif os.path.exists(sysv_file):
 
79
        subprocess.check_call(["update-rc.d", service_name, "disable"])
 
80
    else:
 
81
        # XXX: Support SystemD too
 
82
        raise ValueError(
 
83
            "Unable to detect {0} as either Upstart {1} or SysV {2}".format(
 
84
                service_name, upstart_file, sysv_file))
 
85
    return stopped
 
86
 
 
87
 
 
88
def service_resume(service_name, init_dir="/etc/init",
 
89
                   initd_dir="/etc/init.d"):
 
90
    """Resume a system service.
 
91
 
 
92
    Reenable starting again at boot. Start the service"""
 
93
    upstart_file = os.path.join(init_dir, "{}.conf".format(service_name))
 
94
    sysv_file = os.path.join(initd_dir, service_name)
 
95
    if os.path.exists(upstart_file):
 
96
        override_path = os.path.join(
 
97
            init_dir, '{}.override'.format(service_name))
 
98
        if os.path.exists(override_path):
 
99
            os.unlink(override_path)
 
100
    elif os.path.exists(sysv_file):
 
101
        subprocess.check_call(["update-rc.d", service_name, "enable"])
 
102
    else:
 
103
        # XXX: Support SystemD too
 
104
        raise ValueError(
 
105
            "Unable to detect {0} as either Upstart {1} or SysV {2}".format(
 
106
                service_name, upstart_file, sysv_file))
 
107
 
 
108
    started = service_start(service_name)
 
109
    return started
 
110
 
 
111
 
66
112
def service(action, service_name):
67
113
    """Control a system service"""
68
114
    cmd = ['service', service_name, action]
119
165
 
120
166
 
121
167
def user_exists(username):
 
168
    """Check if a user exists"""
122
169
    try:
123
 
        user_info = pwd.getpwnam(username)
 
170
        pwd.getpwnam(username)
124
171
        user_exists = True
125
172
    except KeyError:
126
173
        user_exists = False
149
196
 
150
197
def add_user_to_group(username, group):
151
198
    """Add a user to a group"""
152
 
    cmd = [
153
 
        'gpasswd', '-a',
154
 
        username,
155
 
        group
156
 
    ]
 
199
    cmd = ['gpasswd', '-a', username, group]
157
200
    log("Adding user {} to group {}".format(username, group))
158
201
    subprocess.check_call(cmd)
159
202
 
263
306
    return system_mounts
264
307
 
265
308
 
266
 
 
267
309
def fstab_mount(mountpoint):
 
310
    """Mount filesystem using fstab"""
268
311
    cmd_args = ['mount', mountpoint]
269
312
    try:
270
313
        subprocess.check_output(cmd_args)
390
433
    return(''.join(random_chars))
391
434
 
392
435
 
393
 
def list_nics(nic_type):
 
436
def is_phy_iface(interface):
 
437
    """Returns True if interface is not virtual, otherwise False."""
 
438
    if interface:
 
439
        sys_net = '/sys/class/net'
 
440
        if os.path.isdir(sys_net):
 
441
            for iface in glob.glob(os.path.join(sys_net, '*')):
 
442
                if '/virtual/' in os.path.realpath(iface):
 
443
                    continue
 
444
 
 
445
                if interface == os.path.basename(iface):
 
446
                    return True
 
447
 
 
448
    return False
 
449
 
 
450
 
 
451
def get_bond_master(interface):
 
452
    """Returns bond master if interface is bond slave otherwise None.
 
453
 
 
454
    NOTE: the provided interface is expected to be physical
 
455
    """
 
456
    if interface:
 
457
        iface_path = '/sys/class/net/%s' % (interface)
 
458
        if os.path.exists(iface_path):
 
459
            if '/virtual/' in os.path.realpath(iface_path):
 
460
                return None
 
461
 
 
462
            master = os.path.join(iface_path, 'master')
 
463
            if os.path.exists(master):
 
464
                master = os.path.realpath(master)
 
465
                # make sure it is a bond master
 
466
                if os.path.exists(os.path.join(master, 'bonding')):
 
467
                    return os.path.basename(master)
 
468
 
 
469
    return None
 
470
 
 
471
 
 
472
def list_nics(nic_type=None):
394
473
    '''Return a list of nics of given type(s)'''
395
474
    if isinstance(nic_type, six.string_types):
396
475
        int_types = [nic_type]
397
476
    else:
398
477
        int_types = nic_type
 
478
 
399
479
    interfaces = []
400
 
    for int_type in int_types:
401
 
        cmd = ['ip', 'addr', 'show', 'label', int_type + '*']
 
480
    if nic_type:
 
481
        for int_type in int_types:
 
482
            cmd = ['ip', 'addr', 'show', 'label', int_type + '*']
 
483
            ip_output = subprocess.check_output(cmd).decode('UTF-8')
 
484
            ip_output = ip_output.split('\n')
 
485
            ip_output = (line for line in ip_output if line)
 
486
            for line in ip_output:
 
487
                if line.split()[1].startswith(int_type):
 
488
                    matched = re.search('.*: (' + int_type +
 
489
                                        r'[0-9]+\.[0-9]+)@.*', line)
 
490
                    if matched:
 
491
                        iface = matched.groups()[0]
 
492
                    else:
 
493
                        iface = line.split()[1].replace(":", "")
 
494
 
 
495
                    if iface not in interfaces:
 
496
                        interfaces.append(iface)
 
497
    else:
 
498
        cmd = ['ip', 'a']
402
499
        ip_output = subprocess.check_output(cmd).decode('UTF-8').split('\n')
403
 
        ip_output = (line for line in ip_output if line)
 
500
        ip_output = (line.strip() for line in ip_output if line)
 
501
 
 
502
        key = re.compile('^[0-9]+:\s+(.+):')
404
503
        for line in ip_output:
405
 
            if line.split()[1].startswith(int_type):
406
 
                matched = re.search('.*: (' + int_type + r'[0-9]+\.[0-9]+)@.*', line)
407
 
                if matched:
408
 
                    interface = matched.groups()[0]
409
 
                else:
410
 
                    interface = line.split()[1].replace(":", "")
411
 
                interfaces.append(interface)
 
504
            matched = re.search(key, line)
 
505
            if matched:
 
506
                iface = matched.group(1)
 
507
                iface = iface.partition("@")[0]
 
508
                if iface not in interfaces:
 
509
                    interfaces.append(iface)
412
510
 
413
511
    return interfaces
414
512
 
468
566
        os.chdir(cur)
469
567
 
470
568
 
471
 
def chownr(path, owner, group, follow_links=True):
 
569
def chownr(path, owner, group, follow_links=True, chowntopdir=False):
 
570
    """
 
571
    Recursively change user and group ownership of files and directories
 
572
    in given path. Doesn't chown path itself by default, only its children.
 
573
 
 
574
    :param bool follow_links: Also Chown links if True
 
575
    :param bool chowntopdir: Also chown path itself if True
 
576
    """
472
577
    uid = pwd.getpwnam(owner).pw_uid
473
578
    gid = grp.getgrnam(group).gr_gid
474
579
    if follow_links:
476
581
    else:
477
582
        chown = os.lchown
478
583
 
 
584
    if chowntopdir:
 
585
        broken_symlink = os.path.lexists(path) and not os.path.exists(path)
 
586
        if not broken_symlink:
 
587
            chown(path, uid, gid)
479
588
    for root, dirs, files in os.walk(path):
480
589
        for name in dirs + files:
481
590
            full = os.path.join(root, name)
486
595
 
487
596
def lchownr(path, owner, group):
488
597
    chownr(path, owner, group, follow_links=False)
 
598
 
 
599
 
 
600
def get_total_ram():
 
601
    '''The total amount of system RAM in bytes.
 
602
 
 
603
    This is what is reported by the OS, and may be overcommitted when
 
604
    there are multiple containers hosted on the same machine.
 
605
    '''
 
606
    with open('/proc/meminfo', 'r') as f:
 
607
        for line in f.readlines():
 
608
            if line:
 
609
                key, value, unit = line.split()
 
610
                if key == 'MemTotal:':
 
611
                    assert unit == 'kB', 'Unknown unit'
 
612
                    return int(value) * 1024  # Classic, not KiB.
 
613
        raise NotImplementedError()