source: ogAgent-Git/src/opengnsys/oglive/operations.py @ bb1ff4d

oglive
Last change on this file since bb1ff4d was bb1ff4d, checked in by Ramón M. Gómez <ramongomez@…>, 5 years ago

#750: OGAgent for ogLive looks for oglive environ variable; route GET /getconfig returns data in JSON format.

  • Property mode set to 100644
File size: 5.9 KB
RevLine 
[983213c]1# -*- coding: utf-8 -*-
2#
3# Copyright (c) 2014 Virtual Cable S.L.
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without modification,
7# are permitted provided that the following conditions are met:
8#
9#    * Redistributions of source code must retain the above copyright notice,
10#      this list of conditions and the following disclaimer.
11#    * Redistributions in binary form must reproduce the above copyright notice,
12#      this list of conditions and the following disclaimer in the documentation
13#      and/or other materials provided with the distribution.
14#    * Neither the name of Virtual Cable S.L. nor the names of its contributors
15#      may be used to endorse or promote products derived from this software
16#      without specific prior written permission.
17#
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
[be334a5]29"""
[983213c]30@author: Ramón M. Gómez, ramongomez at us dot es
[be334a5]31"""
[983213c]32from __future__ import unicode_literals
33
34import socket
35import platform
36import fcntl
37import subprocess
38import struct
39import array
40import six
41from opengnsys import utils
42
43
44def _getMacAddr(ifname):
[be334a5]45    """
[983213c]46    Returns the mac address of an interface
47    Mac is returned as unicode utf-8 encoded
[be334a5]48    """
[983213c]49    if isinstance(ifname, list):
50        return dict([(name, _getMacAddr(name)) for name in ifname])
51    if isinstance(ifname, six.text_type):
52        ifname = ifname.encode('utf-8')  # If unicode, convert to bytes (or str in python 2.7)
53    try:
54        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
55        info = bytearray(fcntl.ioctl(s.fileno(), 0x8927, struct.pack(str('256s'), ifname[:15])))
56        return six.text_type(''.join(['%02x:' % char for char in info[18:24]])[:-1])
57    except Exception:
58        return None
59
60
61def _getIpAddr(ifname):
[be334a5]62    """
[983213c]63    Returns the ip address of an interface
64    Ip is returned as unicode utf-8 encoded
[be334a5]65    """
[983213c]66    if isinstance(ifname, list):
67        return dict([(name, _getIpAddr(name)) for name in ifname])
68    if isinstance(ifname, six.text_type):
69        ifname = ifname.encode('utf-8')  # If unicode, convert to bytes (or str in python 2.7)
70    try:
71        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
72        return six.text_type(socket.inet_ntoa(fcntl.ioctl(
73            s.fileno(),
74            0x8915,  # SIOCGIFADDR
75            struct.pack(str('256s'), ifname[:15])
76        )[20:24]))
77    except Exception:
78        return None
79
80
81def _getInterfaces():
[be334a5]82    """
[983213c]83    Returns a list of interfaces names coded in utf-8
[be334a5]84    """
[983213c]85    max_possible = 128  # arbitrary. raise if needed.
86    space = max_possible * 16
87    if platform.architecture()[0] == '32bit':
88        offset, length = 32, 32
89    elif platform.architecture()[0] == '64bit':
90        offset, length = 16, 40
91    else:
92        raise OSError('Unknown arquitecture {0}'.format(platform.architecture()[0]))
93
94    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
95    names = array.array(str('B'), b'\0' * space)
96    outbytes = struct.unpack(str('iL'), fcntl.ioctl(
97        s.fileno(),
98        0x8912,  # SIOCGIFCONF
99        struct.pack(str('iL'), space, names.buffer_info()[0])
100    ))[0]
101    namestr = names.tostring()
102    # return namestr, outbytes
103    return [namestr[i:i + offset].split(b'\0', 1)[0].decode('utf-8') for i in range(0, outbytes, length)]
104
105
106def _getIpAndMac(ifname):
107    ip, mac = _getIpAddr(ifname), _getMacAddr(ifname)
[be334a5]108    return ip, mac
[983213c]109
110
[be334a5]111def _exec_ogcommand(ogcmd):
112    """
[983213c]113    Loads OpenGnsys environment variables, executes the command and returns the result
[be334a5]114    """
115    ret = subprocess.check_output(ogcmd, shell=True)
[983213c]116    return ret
117
118
119def getComputerName():
[be334a5]120    """
[983213c]121    Returns computer name, with no domain
[be334a5]122    """
[983213c]123    return socket.gethostname().split('.')[0]
124
125
126def getNetworkInfo():
[be334a5]127    """
[983213c]128    Obtains a list of network interfaces
[be334a5]129    :return: A "generator" of elements, that are dict-as-object, with this elements:
[983213c]130      name: Name of the interface
131      mac: mac of the interface
132      ip: ip of the interface
[be334a5]133    """
[983213c]134    for ifname in _getInterfaces():
135        ip, mac = _getIpAndMac(ifname)
136        if mac != '00:00:00:00:00:00':  # Skips local interfaces
137            yield utils.Bunch(name=ifname, mac=mac, ip=ip)
138
139
140def getDomainName():
141    return ''
142
143
[be334a5]144def get_oglive_version():
145    """
146    Returns ogLive Kernel version and architecture
147    :return: kernel version
148    """
149    kv = platform.os.uname()
150    return kv[2] + ', ' + kv[4]
[983213c]151
152
153def reboot():
[be334a5]154    """
[983213c]155    Simple reboot using OpenGnsys script
[be334a5]156    """
[983213c]157    # Workaround for dummy thread
158    if six.PY3 is False:
159        import threading
160        threading._DummyThread._Thread__stop = lambda x: 42
161
[be334a5]162    _exec_ogcommand('/opt/opengnsys/scripts/reboot')
[983213c]163
164
165def poweroff():
[be334a5]166    """
[983213c]167    Simple poweroff using OpenGnsys script
[be334a5]168    """
[983213c]169    # Workaround for dummy thread
170    if six.PY3 is False:
171        import threading
172        threading._DummyThread._Thread__stop = lambda x: 42
173
[be334a5]174    _exec_ogcommand('/opt/opengnsys/scripts/poweroff')
[983213c]175
176
[be334a5]177def get_disk_config():
178    """
179    Returns disk configuration
180    Warning: this operation may take some time
181    """
[983213c]182    try:
183        _exec_ogcommand('/opt/opengnsys/interfaceAdm/getConfiguration')
[bb1ff4d]184        # Returns content of configuration file
185        cfgdata = open('/tmp/getconfig', 'r').read().strip()
[983213c]186    except IOError:
187        cfgdata = ''
188    return cfgdata
Note: See TracBrowser for help on using the repository browser.