VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/CloudProviderManagerImpl.cpp@ 86012

Last change on this file since 86012 was 86012, checked in by vboxsync, 5 years ago

OCI: Send events when a cloud provider is registered or is about to be
unregistered.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.2 KB
Line 
1/* $Id: CloudProviderManagerImpl.cpp 86012 2020-09-03 00:08:56Z vboxsync $ */
2/** @file
3 * ICloudProviderManager COM class implementations.
4 */
5
6/*
7 * Copyright (C) 2008-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19#define LOG_GROUP LOG_GROUP_MAIN_CLOUDPROVIDERMANAGER
20#include <iprt/cpp/utils.h>
21#include <VBox/com/array.h>
22
23#include "VirtualBoxImpl.h"
24#include "CloudProviderManagerImpl.h"
25#include "ExtPackManagerImpl.h"
26#include "AutoCaller.h"
27#include "LoggingNew.h"
28
29
30////////////////////////////////////////////////////////////////////////////////
31//
32// CloudProviderManager constructor / destructor
33//
34// ////////////////////////////////////////////////////////////////////////////////
35CloudProviderManager::CloudProviderManager()
36 : m_pVirtualBox(NULL)
37{
38}
39
40CloudProviderManager::~CloudProviderManager()
41{
42}
43
44
45HRESULT CloudProviderManager::FinalConstruct()
46{
47 return BaseFinalConstruct();
48}
49
50void CloudProviderManager::FinalRelease()
51{
52 uninit();
53
54 BaseFinalRelease();
55}
56
57HRESULT CloudProviderManager::init(VirtualBox *aVirtualBox)
58{
59 // Enclose the state transition NotReady->InInit->Ready.
60 AutoInitSpan autoInitSpan(this);
61 AssertReturn(autoInitSpan.isOk(), E_FAIL);
62
63 m_apCloudProviders.clear();
64 unconst(m_pVirtualBox) = aVirtualBox;
65
66 autoInitSpan.setSucceeded();
67 return S_OK;
68}
69
70void CloudProviderManager::uninit()
71{
72 // Enclose the state transition Ready->InUninit->NotReady.
73 AutoUninitSpan autoUninitSpan(this);
74 if (autoUninitSpan.uninitDone())
75 return;
76
77 m_mapCloudProviderManagers.clear();
78 m_apCloudProviders.clear();
79
80 unconst(m_pVirtualBox) = NULL; // not a ComPtr, but be pedantic
81}
82
83
84#ifdef VBOX_WITH_EXTPACK
85
86bool CloudProviderManager::i_canRemoveExtPack(IExtPack *aExtPack)
87{
88 AssertReturn(aExtPack, false);
89
90 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
91
92 // If any cloud provider in this extension pack fails to prepare the
93 // uninstall it and the cloud provider will be kept, so that the user
94 // can retry safely later. All other cloud providers in this extpack
95 // will be done as usual. No attempt is made to bring back the other
96 // cloud providers into working shape.
97
98 bool fRes = true;
99
100 Bstr bstrExtPackName;
101 aExtPack->COMGETTER(Name)(bstrExtPackName.asOutParam());
102 Utf8Str strExtPackName(bstrExtPackName);
103
104 /* is there a cloud provider in this extpack? */
105 ExtPackNameCloudProviderManagerMap::iterator it
106 = m_mapCloudProviderManagers.find(strExtPackName);
107 if (it != m_mapCloudProviderManagers.end())
108 {
109 // const ComPtr<ICloudProviderManager> pManager(it->second); /* unused */
110
111 /* loop over all providers checking for those from the aExtPack */
112 Assert(m_astrExtPackNames.size() == m_apCloudProviders.size());
113 for (size_t i = 0; i < m_astrExtPackNames.size(); )
114 {
115 /* the horse it rode in on? */
116 if (m_astrExtPackNames[i] != strExtPackName)
117 {
118 i++;
119 continue; /* not the extpack we are looking for */
120 }
121
122 /* note the id of this provider to send an event later */
123 Bstr bstrProviderId;
124
125 /*
126 * pTmpProvider will point to an object with refcount > 0
127 * until the ComPtr is removed from m_apCloudProviders.
128 * PrepareUninstall checks that that is the only reference
129 */
130 HRESULT hrc = S_OK;
131 ULONG uRefCnt = 1;
132 ICloudProvider *pTmpProvider(m_apCloudProviders[i]);
133 if (pTmpProvider)
134 {
135 /* do this before the provider goes over the rainbow bridge */
136 pTmpProvider->COMGETTER(Id)(bstrProviderId.asOutParam());
137
138 /**
139 * @todo r=uwe We send the event @em before we even
140 * try to uninstall the provider. The GUI can get the
141 * event and get rid of any references to the objects
142 * related to this provider that it still has. The
143 * current uninstall attempt might fail, but the GUI
144 * can then retry once and likely succeed. Needs more
145 * thought and feeback from dsen.
146 */
147 m_pVirtualBox->i_onCloudProviderRegistered(bstrProviderId, FALSE);
148
149 hrc = pTmpProvider->PrepareUninstall();
150 pTmpProvider->AddRef();
151 uRefCnt = pTmpProvider->Release();
152 }
153
154 /* has PrepareUninstall uninited the provider? */
155 if (SUCCEEDED(hrc) && uRefCnt == 1)
156 {
157 m_astrExtPackNames.erase(m_astrExtPackNames.begin() + (ssize_t)i);
158 m_apCloudProviders.erase(m_apCloudProviders.begin() + (ssize_t)i);
159 /* NB: not advancing loop index */
160 }
161 else
162 {
163 LogRel(("CloudProviderManager: provider '%s' blocks extpack uninstall, result=%Rhrc, refcount=%u\n",
164 strExtPackName.c_str(), hrc, uRefCnt));
165 fRes = false;
166 i++;
167 }
168 }
169
170 if (fRes)
171 m_mapCloudProviderManagers.erase(it);
172 }
173
174 return fRes;
175}
176
177void CloudProviderManager::i_addExtPack(IExtPack *aExtPack)
178{
179 HRESULT hrc;
180
181 AssertReturnVoid(aExtPack);
182 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
183
184 Bstr bstrExtPackName;
185 aExtPack->COMGETTER(Name)(bstrExtPackName.asOutParam());
186 Utf8Str strExtPackName(bstrExtPackName);
187
188 /* get the extpack's cloud provider manager object if present */
189 ComPtr<IUnknown> pObj;
190 com::Guid idObj(COM_IIDOF(ICloudProviderManager));
191 hrc = aExtPack->QueryObject(Bstr(idObj.toString()).raw(), pObj.asOutParam());
192 if (FAILED(hrc))
193 return;
194 const ComPtr<ICloudProviderManager> pManager(pObj);
195 if (pManager.isNull())
196 return;
197
198 /* get the list of cloud providers */
199 SafeIfaceArray<ICloudProvider> apProvidersFromCurrExtPack;
200 hrc = pManager->COMGETTER(Providers)(ComSafeArrayAsOutParam(apProvidersFromCurrExtPack));
201 if (FAILED(hrc))
202 return;
203 if (apProvidersFromCurrExtPack.size() == 0)
204 return;
205
206 m_mapCloudProviderManagers[strExtPackName] = pManager;
207
208 /* collect provider ids for bulk-sending the events */
209 std::vector<Utf8Str> aProviderIds;
210 aProviderIds.reserve(apProvidersFromCurrExtPack.size());
211
212 for (unsigned i = 0; i < apProvidersFromCurrExtPack.size(); i++)
213 {
214 const ComPtr<ICloudProvider> pProvider(apProvidersFromCurrExtPack[i]);
215 if (!pProvider.isNull())
216 {
217 // Sanity check each cloud provider by forcing a QueryInterface call,
218 // making sure that it implements the right interface.
219 ComPtr<ICloudProvider> pProviderCheck;
220 pProvider.queryInterfaceTo(pProviderCheck.asOutParam());
221 if (!pProviderCheck.isNull()) /* ok, seems legit */
222 {
223 /* save the provider and the name of the extpack it came from */
224 Assert(m_astrExtPackNames.size() == m_apCloudProviders.size());
225 m_astrExtPackNames.push_back(strExtPackName);
226 m_apCloudProviders.push_back(pProvider);
227
228 /* note the id of this provider to send an event later */
229 Bstr bstrProviderId;
230 pProvider->COMGETTER(Id)(bstrProviderId.asOutParam());
231 aProviderIds.push_back(bstrProviderId);
232 }
233 }
234 }
235
236 /* bulk-send ICloudProviderRegisteredEvent's */
237 for (size_t i = 0; i < aProviderIds.size(); ++i)
238 {
239 m_pVirtualBox->i_onCloudProviderRegistered(aProviderIds[i], TRUE);
240 }
241}
242
243#endif /* VBOX_WITH_EXTPACK */
244
245HRESULT CloudProviderManager::getProviders(std::vector<ComPtr<ICloudProvider> > &aProviders)
246{
247 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
248 aProviders = m_apCloudProviders;
249 return S_OK;
250}
251
252HRESULT CloudProviderManager::getProviderById(const com::Guid &aProviderId,
253 ComPtr<ICloudProvider> &aProvider)
254{
255 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
256 for (size_t i = 0; i < m_apCloudProviders.size(); i++)
257 {
258 Bstr bstrId;
259 HRESULT hrc = m_apCloudProviders[i]->COMGETTER(Id)(bstrId.asOutParam());
260 if (SUCCEEDED(hrc) && aProviderId == bstrId)
261 {
262 aProvider = m_apCloudProviders[i];
263 return S_OK;
264 }
265 }
266 return setError(VBOX_E_OBJECT_NOT_FOUND, tr("Could not find a cloud provider with UUID {%RTuuid}"),
267 aProviderId.raw());
268}
269
270HRESULT CloudProviderManager::getProviderByShortName(const com::Utf8Str &aProviderName,
271 ComPtr<ICloudProvider> &aProvider)
272{
273 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
274 for (size_t i = 0; i < m_apCloudProviders.size(); i++)
275 {
276 Bstr bstrName;
277 HRESULT hrc = m_apCloudProviders[i]->COMGETTER(ShortName)(bstrName.asOutParam());
278 if (SUCCEEDED(hrc) && bstrName.equals(aProviderName))
279 {
280 aProvider = m_apCloudProviders[i];
281 return S_OK;
282 }
283 }
284 return setError(VBOX_E_OBJECT_NOT_FOUND, tr("Could not find a cloud provider with short name '%s'"),
285 aProviderName.c_str());
286}
287
288HRESULT CloudProviderManager::getProviderByName(const com::Utf8Str &aProviderName,
289 ComPtr<ICloudProvider> &aProvider)
290{
291 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
292 for (size_t i = 0; i < m_apCloudProviders.size(); i++)
293 {
294 Bstr bstrName;
295 HRESULT hrc = m_apCloudProviders[i]->COMGETTER(Name)(bstrName.asOutParam());
296 if (SUCCEEDED(hrc) && bstrName.equals(aProviderName))
297 {
298 aProvider = m_apCloudProviders[i];
299 return S_OK;
300 }
301 }
302 return setError(VBOX_E_OBJECT_NOT_FOUND, tr("Could not find a cloud provider with name '%s'"),
303 aProviderName.c_str());
304}
305
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette