summaryrefslogtreecommitdiffstats
path: root/src/software/openlmi/software/core/AffectedSoftwareJobElement.py
blob: 25301047f3c5d74988b8577b551c35eaee0728d7 (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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# -*- encoding: utf-8 -*-
# Software Management Providers
#
# Copyright (C) 2012-2013 Red Hat, Inc.  All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""
Just a common functionality related to AffectedSoftwareJobElement provider.
"""

import pywbem

from openlmi.common import cmpi_logging
from openlmi.software import util
from openlmi.software.core import ComputerSystem
from openlmi.software.core import Identity
from openlmi.software.core import InstallationJob
from openlmi.software.core import SystemCollection
from openlmi.software.yumdb import jobs
from openlmi.software.yumdb import PackageInfo

class Values(object):
    class ElementEffects(object):
        Unknown = pywbem.Uint16(0)
        Other = pywbem.Uint16(1)
        Exclusive_Use = pywbem.Uint16(2)
        Performance_Impact = pywbem.Uint16(3)
        Element_Integrity = pywbem.Uint16(4)
        Create = pywbem.Uint16(5)
        _reverse_map = {
                0: 'Unknown',
                1: 'Other',
                2: 'Exclusive Use',
                3: 'Performance Impact',
                4: 'Element Integrity',
                5: 'Create'
        }

@cmpi_logging.trace_function
def check_path(env, op):
    """
    Checks, whether object path is valid.
    @return affected object path
    """
    if not isinstance(op, pywbem.CIMInstanceName):
        raise TypeError("op must be a CIMInstanceName")
    ch = env.get_cimom_handle()

    job = op['AffectingElement'] = InstallationJob.object_path2job(
        op['AffectingElement'])
    affected = op['AffectedElement']
    if ch.is_subclass(affected.namespace, sub=affected.classname,
            super='LMI_SoftwareIdentity'):
        pkg_info = Identity.object_path2pkg(affected, kind='all')
        if isinstance(job, jobs.YumSpecificPackageJob):
            if isinstance(job.pkg, PackageInfo):
                if pkg_info != job.pkg:
                    raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
                            "AffectedElement does not match job's package:"
                            " \"%s\" != \"%s\"." % (pkg_info, job.pkg))
            else:
                flt = pkg_info.key_props
                flt.pop('repoid', None)
                if util.nevra2filter(job.pkg) != flt:
                    raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
                            "AffectedElement does not match job's package:"
                            " \"%s\" != \"%s\"." % (pkg_info, job.pkg))
            affected = Identity.pkg2model(pkg_info)
        elif isinstance(job, jobs.YumInstallPackageFromURI):
            if job.state == job.COMPLETED:
                affected = Identity.pkg2model(job.result_data)
            else:
                # TODO: this should be somehow obtained from from downloaded
                # package before installation
                raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
                        "No SoftwareIdentity is associated to given job.")
        else:
            cmpi_logging.logger.error("Unsupported async job: %s", job)
            raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
                    "No associated SoftwareIdentity.")
    elif ch.is_subclass(affected.namespace, sub=affected.classname,
            super='LMI_SystemSoftwareCollection'):
        SystemCollection.check_path(env, affected, "AffectedElement")
        affected = SystemCollection.get_path()
    elif ch.is_subclass(affected.namespace, sub=affected.classname,
            super='Linux_ComputerSystem'):
        ComputerSystem.check_path(env, affected, "AffectedElement")
        affected = ComputerSystem.get_path()
    else:
        raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER,
                "Expected an instance of LMI_SoftwareIdentity,"
                " LMI_SystemSoftwareCollection or Linux_ComputerSystem.")
    return (job, affected)

@cmpi_logging.trace_function
def job2affected_software_identity(job):
    """
    @return (path of SoftwareIdentity, ElementEffects array,
        OtherElementEffectsDescriptions array)
    """
    effects = [Values.ElementEffects.Other]
    descriptions = []
    if isinstance(job, jobs.YumSpecificPackageJob):
        if job.state == job.COMPLETED and job.result_data:
            affected = Identity.pkg2model(job.result_data)
        else:
            affected = Identity.pkg2model(job.pkg)
        if isinstance(job, jobs.YumInstallPackage):
            descriptions.append("Installing")
        elif isinstance(job, jobs.YumRemovePackage):
            descriptions.append("Removing")
        elif isinstance(job,
                (jobs.YumUpdatePackage, jobs.YumUpdateToPackage)):
            descriptions.append("Updating")
        elif isinstance(job, jobs.YumCheckPackage):
            descriptions.append("Checking")
        else:
            descriptions.append("Modifying")
            cmpi_logging.logger.error("Unhandled job: %s", job)
    elif isinstance(job, jobs.YumInstallPackageFromURI):
        if job.state == job.COMPLETED:
            affected = Identity.pkg2model(job.result_data)
            descriptions.append("Installing")
        else:
            # TODO: this should be somehow obtained from from downloaded
            # package before installation
            raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
                    "No SoftwareIdentity is associated to given job.")
    else:
        cmpi_logging.logger.error("Unsupported async job: %s", job)
        raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
                "No associated SoftwareIdentity.")
    return (affected, effects, descriptions)

@cmpi_logging.trace_function
def fill_model_computer_system(model, job, keys_only=True):
    """
    Fills model's AffectedElement and all non-key properties.
    """
    model["AffectedElement"] = ComputerSystem.get_path()
    if not keys_only:
        model["ElementEffects"] = [Values.ElementEffects.Other]
        description = "Modifying software collection."
        if isinstance(job, (jobs.YumInstallPackage,
                jobs.YumInstallPackageFromURI)):
            description = "Installing software package to collection."
        elif isinstance(job, jobs.YumRemovePackage):
            description = "Removing package from software collection."
        elif isinstance(job, (jobs.YumUpdatePackage, jobs.YumUpdateToPackage)):
            description = "Updating software package."
        model["OtherElementEffectsDescriptions"] = [description]
    return model

@cmpi_logging.trace_function
def fill_model_system_collection(model, keys_only=True):
    """
    Fills model's AffectedElement and all non-key properties.
    """
    model["AffectedElement"] = SystemCollection.get_path()
    if not keys_only:
        model["ElementEffects"] = [Values.ElementEffects.Exclusive_Use]
        model["OtherElementEffectsDescriptions"] = [
                "Package database is locked."
        ]
    return model

@cmpi_logging.trace_function
def generate_models_from_job(job, keys_only=True, model=None):
    """
    Generates all associations between job and affected elements.
    """
    if not isinstance(job, jobs.YumJob):
        raise TypeError("pkg must be an instance of PackageInfo or nevra")
    if model is None:
        model = pywbem.CIMInstanceName("LMI_AffectedSoftwareJobElement",
                namespace="root/cimv2")
        if not keys_only:
            model = pywbem.CIMInstance("LMI_AffectedSoftwareJobElement",
                    path=model)
    model["AffectingElement"] = InstallationJob.job2model(job)
    (si, element_effects, element_effects_descriptions) = \
            job2affected_software_identity(job)
    model["AffectedElement"] = si
    if not keys_only:
        model["ElementEffects"] = element_effects
        model["OtherElementEffectsDescriptions"] = \
                element_effects_descriptions
    yield model
    fill_model_system_collection(model, keys_only=keys_only)
    yield model
    fill_model_computer_system(model, job, keys_only=keys_only)
    yield model