diff options
author | Michal Minar <miminar@redhat.com> | 2014-06-24 12:13:58 +0200 |
---|---|---|
committer | Michal Minar <miminar@redhat.com> | 2014-06-25 15:17:17 +0200 |
commit | 716e800bd323501096b8fe718dc8e09c627683eb (patch) | |
tree | 95add28601db4ad50cad4cfc50c0178be0b04f69 | |
parent | 1837cd02c4eda76a0fb05f88a2c3e1fb557738c0 (diff) | |
download | openlmi-providers-716e800bd323501096b8fe718dc8e09c627683eb.tar.gz openlmi-providers-716e800bd323501096b8fe718dc8e09c627683eb.tar.xz openlmi-providers-716e800bd323501096b8fe718dc8e09c627683eb.zip |
software-dbus: implemented LMI_SoftwareInstallationsService
Currently only InstallFromSoftwareIdentity() method is implemented.
-rw-r--r-- | src/software-dbus/LMI_SoftwareInstallationServiceProvider.c | 221 | ||||
-rw-r--r-- | src/software-dbus/sw-utils.c | 40 | ||||
-rw-r--r-- | src/software-dbus/sw-utils.h | 11 |
3 files changed, 264 insertions, 8 deletions
diff --git a/src/software-dbus/LMI_SoftwareInstallationServiceProvider.c b/src/software-dbus/LMI_SoftwareInstallationServiceProvider.c index a84c5aa..1864863 100644 --- a/src/software-dbus/LMI_SoftwareInstallationServiceProvider.c +++ b/src/software-dbus/LMI_SoftwareInstallationServiceProvider.c @@ -1,10 +1,39 @@ +/* + * Copyright (C) 2013-2014 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> + */ + #include <konkret/konkret.h> +#include "LMI_SoftwareIdentity.h" #include "LMI_SoftwareInstallationService.h" +#include "job_manager.h" +#include "sw-utils.h" +#include "lmi_sw_job.h" static const CMPIBroker* _cb = NULL; -static void LMI_SoftwareInstallationServiceInitialize() +static gboolean is_power_of_two(guint32 x) { + return ((x != 0) && !(x & (x - 1))); +} + +static void LMI_SoftwareInstallationServiceInitialize(const CMPIContext *ctx) { + software_init(provider_name, _cb, ctx, provider_config_defaults); } static CMPIStatus LMI_SoftwareInstallationServiceCleanup( @@ -12,7 +41,7 @@ static CMPIStatus LMI_SoftwareInstallationServiceCleanup( const CMPIContext* cc, CMPIBoolean term) { - CMReturn(CMPI_RC_OK); + return software_cleanup(); } static CMPIStatus LMI_SoftwareInstallationServiceEnumInstanceNames( @@ -22,7 +51,7 @@ static CMPIStatus LMI_SoftwareInstallationServiceEnumInstanceNames( const CMPIObjectPath* cop) { return KDefaultEnumerateInstanceNames( - _cb, mi, cc, cr, cop); + _cb, mi, cc, cr, cop); } static CMPIStatus LMI_SoftwareInstallationServiceEnumInstances( @@ -32,6 +61,39 @@ static CMPIStatus LMI_SoftwareInstallationServiceEnumInstances( const CMPIObjectPath* cop, const char** properties) { + char instance_id[BUFLEN] = ""; + + create_instance_id(LMI_SoftwareInstallationService_ClassName, NULL, instance_id, + BUFLEN); + + LMI_SoftwareInstallationService w; + LMI_SoftwareInstallationService_Init(&w, _cb, KNameSpace(cop)); + LMI_SoftwareInstallationService_Set_CreationClassName(&w, + LMI_SoftwareInstallationService_ClassName); + LMI_SoftwareInstallationService_Set_SystemCreationClassName(&w, + lmi_get_system_creation_class_name()); + LMI_SoftwareInstallationService_Set_SystemName(&w, + lmi_get_system_name_safe(cc)); + LMI_SoftwareInstallationService_Set_Name(&w, instance_id); + LMI_SoftwareInstallationService_Set_Caption(&w, + "Software installation service for this system."); + LMI_SoftwareInstallationService_Set_CommunicationStatus_Not_Available(&w); + LMI_SoftwareInstallationService_Set_Description(&w, + "Software installation service using YUM package manager."); + LMI_SoftwareInstallationService_Set_DetailedStatus_Not_Available(&w); + LMI_SoftwareInstallationService_Set_EnabledDefault_Not_Applicable(&w); + LMI_SoftwareInstallationService_Set_EnabledState_Not_Applicable(&w); + LMI_SoftwareInstallationService_Set_HealthState_OK(&w); + LMI_SoftwareInstallationService_Set_InstanceID(&w, instance_id); + if (LMI_SoftwareInstallationService_Init_OperationalStatus(&w, 1)) + LMI_SoftwareInstallationService_Set_OperationalStatus_OK(&w, 0); + LMI_SoftwareInstallationService_Set_OperatingStatus_Servicing(&w); + LMI_SoftwareInstallationService_Set_PrimaryStatus_OK(&w); + LMI_SoftwareInstallationService_Set_RequestedState_Not_Applicable(&w); + LMI_SoftwareInstallationService_Set_Started(&w, TRUE); + LMI_SoftwareInstallationService_Set_TransitioningToState_Not_Applicable(&w); + KReturnInstance(cr, w); + CMReturn(CMPI_RC_OK); } @@ -91,7 +153,7 @@ CMInstanceMIStub( LMI_SoftwareInstallationService, LMI_SoftwareInstallationService, _cb, - LMI_SoftwareInstallationServiceInitialize()) + LMI_SoftwareInstallationServiceInitialize(ctx)) static CMPIStatus LMI_SoftwareInstallationServiceMethodCleanup( CMPIMethodMI* mi, @@ -118,7 +180,7 @@ CMMethodMIStub( LMI_SoftwareInstallationService, LMI_SoftwareInstallationService, _cb, - LMI_SoftwareInstallationServiceInitialize()) + LMI_SoftwareInstallationServiceInitialize(ctx)) KUint32 LMI_SoftwareInstallationService_RequestStateChange( const CMPIBroker* cb, @@ -191,7 +253,7 @@ KUint32 LMI_SoftwareInstallationService_CheckSoftwareIdentity( { KUint32 result = KUINT32_INIT; - KSetStatus(status, ERR_NOT_SUPPORTED); + KUint32_Set(&result, INSTALL_METHOD_RESULT_NOT_SUPPORTED); return result; } @@ -209,8 +271,151 @@ KUint32 LMI_SoftwareInstallationService_InstallFromSoftwareIdentity( CMPIStatus* status) { KUint32 result = KUINT32_INIT; + KUint16 opt; + guint32 op = 0; + LmiJob *job = NULL; + GVariant *variant; + gchar *jobid; + CMPIObjectPath *cop; + LMI_SoftwareIdentityRef pkgop; + + if (!KHasValue(Source)) { + lmi_error("Missing Source argument!"); + KUint32_Set(&result, INSTALL_METHOD_RESULT_INVALID_PARAMETER); + return result; + } + + if (KHasValue(InstallOptions)) { + for (size_t i=0; i < InstallOptions->count; ++i) { + opt = KUint16A_Get(InstallOptions, i); + switch (opt.value) { + case INSTALL_OPTION_INSTALL: + op |= INSTALLATION_OPERATION_INSTALL; + break; + case INSTALL_OPTION_UPDATE: + op |= INSTALLATION_OPERATION_UPDATE; + break; + case INSTALL_OPTION_UNINSTALL: + op |= INSTALLATION_OPERATION_REMOVE; + break; + case INSTALL_OPTION_FORCE_INSTALLATION: + op |= INSTALLATION_OPERATION_FORCE; + break; + case INSTALL_OPTION_REPAIR: + op |= INSTALLATION_OPERATION_REPAIR; + break; + default: + lmi_error("Given unsupported install option %u!", opt); + KUint32_Set(&result, INSTALL_METHOD_RESULT_INVALID_PARAMETER); + return result; + } + } + if (!is_power_of_two(op & INSTALLATION_OPERATION_EXCLUSIVE_GROUP)) { + lmi_error("Conflicting install options given!" + " Choose one of Install, Remove, Update."); + KUint32_Set(&result, INSTALL_METHOD_RESULT_INVALID_PARAMETER); + return result; + } + } + if (!(op & INSTALLATION_OPERATION_EXCLUSIVE_GROUP)) { + op |= INSTALLATION_OPERATION_INSTALL; + } + + if (KHasValue(InstallOptionsValues) && InstallOptionsValues->count) { + if (InstallOptionsValues->count > InstallOptions->count) { + lmi_error("InstallOptionsValues can not have more" + " values than InstallOptions!"); + KUint32_Set(&result, INSTALL_METHOD_RESULT_INVALID_PARAMETER); + return result; + } + for (size_t i=0; i < InstallOptionsValues->count; ++i) { + if (KHasValue(KStringA_Get(InstallOptionsValues, i))) { + lmi_error("None of supported install option can have associated" + " install option value!"); + KUint32_Set(&result, INSTALL_METHOD_RESULT_INVALID_PARAMETER); + return result; + } + } + } + + if (KHasValue(Target)) { + if (!lmi_check_computer_system(context, Target->value)) { + lmi_error("Target does not match this system!"); + KUint32_Set(&result, INSTALL_METHOD_RESULT_INVALID_PARAMETER); + return result; + } + } + if (KHasValue(Collection)) { + if (!check_system_software_collection(cb, Collection->value)) { + lmi_error("Invalid system software collection!"); + KUint32_Set(&result, INSTALL_METHOD_RESULT_INVALID_PARAMETER); + return result; + } + } + if (KHasValue(Target) && KHasValue(Collection)) { + lmi_error("Only one of Target and Collection parameters cen be given" + " at the same time!"); + KUint32_Set(&result, INSTALL_METHOD_RESULT_INVALID_PARAMETER); + return result; + } + + if (!KHasValue(Target) && !KHasValue(Collection)) { + lmi_error("Either Target or Collection parameter must be specified!"); + KUint32_Set(&result, INSTALL_METHOD_RESULT_INVALID_PARAMETER); + return result; + } + + *status = LMI_SoftwareIdentityRef_InitFromObjectPath( + &pkgop, cb, Source->value); + if (status->rc) { + lmi_error("Invalid Source parameter!"); + KUint32_Set(&result, INSTALL_METHOD_RESULT_INVALID_PARAMETER); + return result; + } + if (g_ascii_strncasecmp(pkgop.InstanceID.chars, + SW_IDENTITY_INSTANCE_ID_PREFIX, + SW_IDENTITY_INSTANCE_ID_PREFIX_LEN) != 0) + { + lmi_error("Invalid InstanceID of Source!"); + KUint32_Set(&result, INSTALL_METHOD_RESULT_INVALID_PARAMETER); + return result; + } + + if ((job = jobmgr_new_job(LMI_TYPE_SW_INSTALLATION_JOB)) == NULL) { + lmi_error("Memory allocation failed!"); + KUint32_Set(&result, INSTALL_METHOD_RESULT_NOT_ENOUGH_MEMORY); + return result; + } + + lmi_job_set_method_name(job, "InstallFromSoftwareIdentity"); + + variant = g_variant_new_boolean(KHasValue(Target)); + lmi_job_set_in_param(job, IN_PARAM_TARGET_NAME, variant); + variant = g_variant_new_boolean(KHasValue(Collection)); + lmi_job_set_in_param(job, IN_PARAM_COLLECTION_NAME, variant); + variant = g_variant_new_string(pkgop.InstanceID.chars + + SW_IDENTITY_INSTANCE_ID_PREFIX_LEN); + lmi_job_set_in_param(job, IN_PARAM_SOURCE_NAME, variant); + variant = g_variant_new_uint32(op); + lmi_job_set_in_param(job, IN_PARAM_INSTALL_OPTIONS_NAME, variant); + + if ((*status = jobmgr_run_job(job)).rc) { + lmi_error("Failed to run job on SoftwareIdentity \"%s\"!", + pkgop.InstanceID.chars); + KUint32_Set(&result, INSTALL_METHOD_RESULT_UNSPECIFIED_ERROR); + return result; + } + + if ((*status = jobmgr_job_to_cim_op(job, &cop)).rc) + return result; + + KRef_SetObjectPath(Job, cop); + jobid = lmi_job_get_jobid(job); + lmi_info("Installation job \"%s\" started on SoftwareIdentity \"%s\".", + jobid, pkgop.InstanceID.chars); + KUint32_Set(&result, INSTALL_METHOD_RESULT_JOB_STARTED); + g_free(jobid); - KSetStatus(status, ERR_NOT_SUPPORTED); return result; } @@ -228,7 +433,7 @@ KUint32 LMI_SoftwareInstallationService_InstallFromByteStream( { KUint32 result = KUINT32_INIT; - KSetStatus(status, ERR_NOT_SUPPORTED); + KUint32_Set(&result, INSTALL_METHOD_RESULT_NOT_SUPPORTED); return result; } diff --git a/src/software-dbus/sw-utils.c b/src/software-dbus/sw-utils.c index 89f843a..6922015 100644 --- a/src/software-dbus/sw-utils.c +++ b/src/software-dbus/sw-utils.c @@ -1116,6 +1116,46 @@ void create_instance_id(const char *class_name, const char *id, } /******************************************************************************* + * Object path checks + ******************************************************************************/ +bool check_system_software_collection(const CMPIBroker *cb, + const CMPIObjectPath *path) +{ + CMPIString *str_namespace; + CMPIData data; + CMPIStatus status; + char *our_namespace; + char instance_id[BUFLEN] = ""; + + if ((our_namespace = lmi_read_config("CIM", "Namespace")) == NULL) + goto err_l; + if ((str_namespace = CMGetNameSpace(path, NULL)) == NULL) + goto namespace_err_l; + if (strcmp(KChars(str_namespace), our_namespace)) + goto namespace_err_l; + g_free(our_namespace); + + if (!CMClassPathIsA(cb, path, LMI_SystemSoftwareCollection_ClassName, NULL)) + goto err_l; + + create_instance_id(LMI_SystemSoftwareCollection_ClassName, NULL, instance_id, + BUFLEN); + data = CMGetKey(path, "InstanceID", &status); + if (status.rc || data.type != CMPI_string || + data.state != (CMPI_goodValue | CMPI_keyValue)) + goto err_l; + if (strcmp(KChars(data.value.string), instance_id)) + goto err_l; + + return true; + +namespace_err_l: + g_free(our_namespace); +err_l: + return false; +} + +/******************************************************************************* * General functions ******************************************************************************/ diff --git a/src/software-dbus/sw-utils.h b/src/software-dbus/sw-utils.h index 6e09b80..94a3ff1 100644 --- a/src/software-dbus/sw-utils.h +++ b/src/software-dbus/sw-utils.h @@ -366,6 +366,17 @@ void create_instance_id(const char *class_name, const char *id, char *instance_id, const unsigned instance_id_len); /******************************************************************************* + * Object path checks + ******************************************************************************/ +/* + * Check object path of LMI_SystemSoftwareCollection. + * @return true if given object path is equal to local + * LMI_SystemSoftwareCollection instance. + */ +bool check_system_software_collection(const CMPIBroker *cb, + const CMPIObjectPath *path); + +/******************************************************************************* * General functions ******************************************************************************/ /* |