summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Minar <miminar@redhat.com>2014-06-24 12:13:58 +0200
committerMichal Minar <miminar@redhat.com>2014-06-25 15:17:17 +0200
commit716e800bd323501096b8fe718dc8e09c627683eb (patch)
tree95add28601db4ad50cad4cfc50c0178be0b04f69
parent1837cd02c4eda76a0fb05f88a2c3e1fb557738c0 (diff)
downloadopenlmi-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.c221
-rw-r--r--src/software-dbus/sw-utils.c40
-rw-r--r--src/software-dbus/sw-utils.h11
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
******************************************************************************/
/*