VirtualBox

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

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use