VirtualBox

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

Last change on this file since 88956 was 86069, checked in by vboxsync, 4 years ago

OCI: Make ICloudProviderRegisteredEvent a non-waitable notification
sent after the fact. Introduce separate ICloudProviderUninstallEvent
sent before unistallation attempt, waitable. Introduce separate
ICloudProviderListChangedEvent that is sent when we are done with all
the extpack providers and the list of providers can be re-read.

  • 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 86069 2020-09-09 03:03:23Z 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.virtualbox.org. 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#ifdef VBOX_WITH_EXTPACK
78 m_mapCloudProviderManagers.clear();
79#endif
80 m_apCloudProviders.clear();
81
82 unconst(m_pVirtualBox) = NULL; // not a ComPtr, but be pedantic
83}
84
85
86#ifdef VBOX_WITH_EXTPACK
87
88bool CloudProviderManager::i_canRemoveExtPack(IExtPack *aExtPack)
89{
90 AssertReturn(aExtPack, false);
91
92 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
93
94 // If any cloud provider in this extension pack fails to prepare the
95 // uninstall it and the cloud provider will be kept, so that the user
96 // can retry safely later. All other cloud providers in this extpack
97 // will be done as usual. No attempt is made to bring back the other
98 // cloud providers into working shape.
99
100 bool fRes = true;
101
102 Bstr bstrExtPackName;
103 aExtPack->COMGETTER(Name)(bstrExtPackName.asOutParam());
104 Utf8Str strExtPackName(bstrExtPackName);
105
106 /* is there a cloud provider in this extpack? */
107 ExtPackNameCloudProviderManagerMap::iterator it
108 = m_mapCloudProviderManagers.find(strExtPackName);
109 if (it != m_mapCloudProviderManagers.end())
110 {
111 // const ComPtr<ICloudProviderManager> pManager(it->second); /* unused */
112
113 /* loop over all providers checking for those from the aExtPack */
114 Assert(m_astrExtPackNames.size() == m_apCloudProviders.size());
115 for (size_t i = 0; i < m_astrExtPackNames.size(); )
116 {
117 /* the horse it rode in on? */
118 if (m_astrExtPackNames[i] != strExtPackName)
119 {
120 i++;
121 continue; /* not the extpack we are looking for */
122 }
123
124 /* note the id of this provider to send an event later */
125 Bstr bstrProviderId;
126
127 /*
128 * pTmpProvider will point to an object with refcount > 0
129 * until the ComPtr is removed from m_apCloudProviders.
130 * PrepareUninstall checks that that is the only reference
131 */
132 HRESULT hrc = S_OK;
133 ULONG uRefCnt = 1;
134 ICloudProvider *pTmpProvider(m_apCloudProviders[i]);
135 if (pTmpProvider)
136 {
137 /* do this before the provider goes over the rainbow bridge */
138 hrc = pTmpProvider->COMGETTER(Id)(bstrProviderId.asOutParam());
139
140 /*
141 * We send this event @em before we try to uninstall
142 * the provider. The GUI can get the event and get
143 * rid of any references to the objects related to
144 * this provider that it still has.
145 */
146 if (bstrProviderId.isNotEmpty())
147 m_pVirtualBox->i_onCloudProviderUninstall(bstrProviderId);
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
160 if (bstrProviderId.isNotEmpty())
161 m_pVirtualBox->i_onCloudProviderRegistered(bstrProviderId, FALSE);
162
163 /* NB: not advancing loop index */
164 }
165 else
166 {
167 LogRel(("CloudProviderManager: provider '%s' blocks extpack uninstall, result=%Rhrc, refcount=%u\n",
168 strExtPackName.c_str(), hrc, uRefCnt));
169 fRes = false;
170 i++;
171 }
172 }
173
174 if (fRes)
175 m_mapCloudProviderManagers.erase(it);
176
177 /**
178 * Tell listeners we are done and they can re-read the new
179 * list of providers.
180 */
181 m_pVirtualBox->i_onCloudProviderListChanged(FALSE);
182 }
183
184 return fRes;
185}
186
187void CloudProviderManager::i_addExtPack(IExtPack *aExtPack)
188{
189 HRESULT hrc;
190
191 AssertReturnVoid(aExtPack);
192 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
193
194 Bstr bstrExtPackName;
195 aExtPack->COMGETTER(Name)(bstrExtPackName.asOutParam());
196 Utf8Str strExtPackName(bstrExtPackName);
197
198 /* get the extpack's cloud provider manager object if present */
199 ComPtr<IUnknown> pObj;
200 com::Guid idObj(COM_IIDOF(ICloudProviderManager));
201 hrc = aExtPack->QueryObject(Bstr(idObj.toString()).raw(), pObj.asOutParam());
202 if (FAILED(hrc))
203 return;
204 const ComPtr<ICloudProviderManager> pManager(pObj);
205 if (pManager.isNull())
206 return;
207
208 /* get the list of cloud providers */
209 SafeIfaceArray<ICloudProvider> apProvidersFromCurrExtPack;
210 hrc = pManager->COMGETTER(Providers)(ComSafeArrayAsOutParam(apProvidersFromCurrExtPack));
211 if (FAILED(hrc))
212 return;
213 if (apProvidersFromCurrExtPack.size() == 0)
214 return;
215
216 m_mapCloudProviderManagers[strExtPackName] = pManager;
217
218 for (unsigned i = 0; i < apProvidersFromCurrExtPack.size(); i++)
219 {
220 const ComPtr<ICloudProvider> pProvider(apProvidersFromCurrExtPack[i]);
221 if (!pProvider.isNull())
222 {
223 // Sanity check each cloud provider by forcing a QueryInterface call,
224 // making sure that it implements the right interface.
225 ComPtr<ICloudProvider> pProviderCheck;
226 pProvider.queryInterfaceTo(pProviderCheck.asOutParam());
227 if (!pProviderCheck.isNull()) /* ok, seems legit */
228 {
229 /* save the provider and the name of the extpack it came from */
230 Assert(m_astrExtPackNames.size() == m_apCloudProviders.size());
231 m_astrExtPackNames.push_back(strExtPackName);
232 m_apCloudProviders.push_back(pProvider);
233
234 Bstr bstrProviderId;
235 pProvider->COMGETTER(Id)(bstrProviderId.asOutParam());
236 if (bstrProviderId.isNotEmpty())
237 m_pVirtualBox->i_onCloudProviderRegistered(bstrProviderId, TRUE);
238 }
239 }
240 }
241
242 /**
243 * Tell listeners we are done and they can re-read the new list of
244 * providers.
245 */
246 m_pVirtualBox->i_onCloudProviderListChanged(TRUE);
247}
248
249#endif /* VBOX_WITH_EXTPACK */
250
251HRESULT CloudProviderManager::getProviders(std::vector<ComPtr<ICloudProvider> > &aProviders)
252{
253 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
254 aProviders = m_apCloudProviders;
255 return S_OK;
256}
257
258HRESULT CloudProviderManager::getProviderById(const com::Guid &aProviderId,
259 ComPtr<ICloudProvider> &aProvider)
260{
261 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
262 for (size_t i = 0; i < m_apCloudProviders.size(); i++)
263 {
264 Bstr bstrId;
265 HRESULT hrc = m_apCloudProviders[i]->COMGETTER(Id)(bstrId.asOutParam());
266 if (SUCCEEDED(hrc) && aProviderId == bstrId)
267 {
268 aProvider = m_apCloudProviders[i];
269 return S_OK;
270 }
271 }
272 return setError(VBOX_E_OBJECT_NOT_FOUND, tr("Could not find a cloud provider with UUID {%RTuuid}"),
273 aProviderId.raw());
274}
275
276HRESULT CloudProviderManager::getProviderByShortName(const com::Utf8Str &aProviderName,
277 ComPtr<ICloudProvider> &aProvider)
278{
279 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
280 for (size_t i = 0; i < m_apCloudProviders.size(); i++)
281 {
282 Bstr bstrName;
283 HRESULT hrc = m_apCloudProviders[i]->COMGETTER(ShortName)(bstrName.asOutParam());
284 if (SUCCEEDED(hrc) && bstrName.equals(aProviderName))
285 {
286 aProvider = m_apCloudProviders[i];
287 return S_OK;
288 }
289 }
290 return setError(VBOX_E_OBJECT_NOT_FOUND, tr("Could not find a cloud provider with short name '%s'"),
291 aProviderName.c_str());
292}
293
294HRESULT CloudProviderManager::getProviderByName(const com::Utf8Str &aProviderName,
295 ComPtr<ICloudProvider> &aProvider)
296{
297 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
298 for (size_t i = 0; i < m_apCloudProviders.size(); i++)
299 {
300 Bstr bstrName;
301 HRESULT hrc = m_apCloudProviders[i]->COMGETTER(Name)(bstrName.asOutParam());
302 if (SUCCEEDED(hrc) && bstrName.equals(aProviderName))
303 {
304 aProvider = m_apCloudProviders[i];
305 return S_OK;
306 }
307 }
308 return setError(VBOX_E_OBJECT_NOT_FOUND, tr("Could not find a cloud provider with name '%s'"),
309 aProviderName.c_str());
310}
311
Note: See TracBrowser for help on using the repository browser.

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