VirtualBox

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

Last change on this file since 94078 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • 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 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * ICloudProviderManager COM class implementations.
4 */
5
6/*
7 * Copyright (C) 2008-2022 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