summaryrefslogtreecommitdiffstats
path: root/src/software/openlmi/software/util/__init__.py
blob: f42f25a87db59d8f01391f224ebc85cc41aa03d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# -*- encoding: utf-8 -*-
# Software Management Providers
#
# Copyright (C) 2012-2013 Red Hat, Inc.  All rights reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
#
# Authors: Michal Minar <miminar@redhat.com>
#

"""Common utilities for LMI_Software* providers
"""

import platform
import re
import signal

RE_EVRA  = re.compile(
    r'^(?P<epoch>\d+):(?P<ver>[^-]+)-(?P<rel>.+)\.(?P<arch>[^.]+)$')
RE_NEVRA = re.compile(
    r'^(?P<name>.+)-(?P<evra>(?P<epoch>\d+):(?P<ver>[^-]+)'
    r'-(?P<rel>.+)\.(?P<arch>[^.]+))$')
RE_NEVRA_OPT_EPOCH = re.compile(
    r'^(?P<name>.+)-(?P<evra>((?P<epoch>\d+):)?(?P<ver>[^-]+)'
    r'-(?P<rel>.+)\.(?P<arch>[^.]+))$')
RE_ENVRA = re.compile(
    r'^(?P<epoch>\d+):(?P<name>.+)-(?P<evra>(?P<ver>[^-]+)'
    r'-(?P<rel>.+)\.(?P<arch>[^.]+))$')

def _get_distname():
    """
    @return name of linux distribution
    """
    if hasattr(platform, 'linux_distribution'):
        return platform.linux_distribution(
                full_distribution_name=False)[0].lower()
    else:
        return platform.dist()[0].lower()


def get_target_operating_system():
    """
    @return (val, text).
    Where val is a number from ValueMap of TargetOperatingSystem property
    of CIM_SoftwareElement class and text is its testual representation.
    """

    system = platform.system()
    if system.lower() == 'linux':
        try:
            val, dist = \
            { 'redhat'   : (79, 'RedHat Enterprise Linux')
            , 'suse'     : (81, 'SUSE')
            , 'mandriva' : (88, 'Mandriva')
            , 'ubuntu'   : (93, 'Ubuntu')
            , 'debian'   : (95, 'Debian')
            }[_get_distname()]
        except KeyError:
            linrel = platform.uname()[2]
            if linrel.startswith('2.4'):
                val, dist = (97, 'Linux 2.4.x')
            elif linrel.startswith('2.6'):
                val, dist = (99, 'Linux 2.6.x')
            else:
                return (36, 'LINUX') # no check for x86_64
        if platform.machine() == 'x86_64':
            val  += 1
            dist += ' 64-Bit'
        return (val, dist)
    elif system.lower() in ('macosx', 'darwin'):
        return (2, 'MACOS')
    # elif system.lower() == 'windows': # no general value
    else:
        return (0, 'Unknown')

def check_target_operating_system(system):
    """
    @return if param system matches current target operating system
    """
    if isinstance(system, basestring):
        system = int(system)
    if not isinstance(system, (int, long)):
        raise TypeError("system must be either string or integer, not %s" %
                system.__class__.__name__)
    tos = get_target_operating_system()
    if system == tos:
        return True
    if system == 36: # linux
        if platform.system().lower() == "linux":
            return True
    if (   system >= 97 and system <= 100 # linux 2.x.x
       and platform.uname()[2].startswith('2.4' if system < 99 else '2.6')
       # check machine
       and (  bool(platform.machine().endswith('64'))
           == bool(not (system % 2)))):
        return True
    return False

def nevra2filter(nevra):
    """
    Takes either regexp match object resulting from RE_NEVRA match or
    a nevra string.
    @return dictionary with package filter key-value pairs made from nevra
    """
    if isinstance(nevra, basestring):
        match = RE_NEVRA_OPT_EPOCH.match(nevra)
    elif nevra.__class__.__name__.lower() == "sre_match":
        match = nevra
    else:
        raise TypeError("nevra must be either string or regexp match object")
    epoch = match.group("epoch")
    if not epoch or match.group("epoch") == "(none)":
        epoch = "0"
    return { "name" : match.group("name")
           , "epoch" : epoch
           , "version" : match.group("ver")
           , "release" : match.group("rel")
           , "arch" : match.group("arch")
           }

def make_nevra(name, epoch, ver, rel, arch, with_epoch='NOT_ZERO'):
    """
    @param with_epoch may be one of:
        "NOT_ZERO" - include epoch only if it's not zero
        "ALWAYS"   - include epoch always
        "NEVER"    - do not include epoch at all
    """
    estr = ''
    if with_epoch.lower() == "always":
        estr = epoch
    elif with_epoch.lower() == "not_zero":
        if epoch != "0":
            estr = epoch
    if len(estr):
        estr += ":"
    return "%s-%s%s-%s.%s" % (name, estr, ver, rel, arch)

def pkg2nevra(pkg, with_epoch='NOT_ZERO'):
    """
    @return nevra string made of pkg
    """
    return make_nevra(pkg.name, pkg.epoch, pkg.version,
            pkg.release, pkg.arch, with_epoch)

def get_signal_name(signal_num):
    """
    @return name of signal for signal_num argument
    """
    if not isinstance(signal_num, (int, long)):
        raise TypeError("signal_num must be an integer")
    try:
        return dict((v, k) for k, v in signal.__dict__.items())[signal_num]
    except KeyError:
        return "UNKNOWN_SIGNAL(%d)" % signal_num