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
RevLine 
[73164]1/* $Id: CloudProviderManagerImpl.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
[73571]3 * ICloudProviderManager COM class implementations.
[73164]4 */
5
6/*
[98103]7 * Copyright (C) 2008-2023 Oracle and/or its affiliates.
[73164]8 *
[96407]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
[73164]26 */
27
28
[76592]29#define LOG_GROUP LOG_GROUP_MAIN_CLOUDPROVIDERMANAGER
[86012]30#include <iprt/cpp/utils.h>
[73164]31#include <VBox/com/array.h>
32
33#include "VirtualBoxImpl.h"
[73716]34#include "CloudProviderManagerImpl.h"
[73873]35#include "ExtPackManagerImpl.h"
[73164]36#include "AutoCaller.h"
[76592]37#include "LoggingNew.h"
[73164]38
39
40////////////////////////////////////////////////////////////////////////////////
41//
[73571]42// CloudProviderManager constructor / destructor
[73164]43//
44// ////////////////////////////////////////////////////////////////////////////////
[73571]45CloudProviderManager::CloudProviderManager()
[86012]46 : m_pVirtualBox(NULL)
[73164]47{
48}
49
[73571]50CloudProviderManager::~CloudProviderManager()
[73164]51{
52}
53
54
[73571]55HRESULT CloudProviderManager::FinalConstruct()
[73164]56{
57 return BaseFinalConstruct();
58}
59
[73571]60void CloudProviderManager::FinalRelease()
[73164]61{
62 uninit();
63
64 BaseFinalRelease();
65}
66
[86012]67HRESULT CloudProviderManager::init(VirtualBox *aVirtualBox)
[73164]68{
[73716]69 // Enclose the state transition NotReady->InInit->Ready.
[73170]70 AutoInitSpan autoInitSpan(this);
71 AssertReturn(autoInitSpan.isOk(), E_FAIL);
72
[73716]73 m_apCloudProviders.clear();
[86012]74 unconst(m_pVirtualBox) = aVirtualBox;
[73549]75
[73170]76 autoInitSpan.setSucceeded();
[73164]77 return S_OK;
78}
79
[73571]80void CloudProviderManager::uninit()
[73164]81{
[73716]82 // Enclose the state transition Ready->InUninit->NotReady.
[73164]83 AutoUninitSpan autoUninitSpan(this);
84 if (autoUninitSpan.uninitDone())
85 return;
[86012]86
[86013]87#ifdef VBOX_WITH_EXTPACK
[86012]88 m_mapCloudProviderManagers.clear();
[86013]89#endif
[86012]90 m_apCloudProviders.clear();
91
92 unconst(m_pVirtualBox) = NULL; // not a ComPtr, but be pedantic
[73164]93}
94
[86012]95
[74926]96#ifdef VBOX_WITH_EXTPACK
[85247]97
[75663]98bool CloudProviderManager::i_canRemoveExtPack(IExtPack *aExtPack)
[73164]99{
[75663]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;
[86012]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);
[75663]119 if (it != m_mapCloudProviderManagers.end())
[73549]120 {
[86012]121 // const ComPtr<ICloudProviderManager> pManager(it->second); /* unused */
[75663]122
[86012]123 /* loop over all providers checking for those from the aExtPack */
[75663]124 Assert(m_astrExtPackNames.size() == m_apCloudProviders.size());
125 for (size_t i = 0; i < m_astrExtPackNames.size(); )
126 {
[86012]127 /* the horse it rode in on? */
128 if (m_astrExtPackNames[i] != strExtPackName)
[75663]129 {
130 i++;
[86012]131 continue; /* not the extpack we are looking for */
[75663]132 }
133
[86012]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 */
[75663]142 HRESULT hrc = S_OK;
143 ULONG uRefCnt = 1;
144 ICloudProvider *pTmpProvider(m_apCloudProviders[i]);
145 if (pTmpProvider)
146 {
[86012]147 /* do this before the provider goes over the rainbow bridge */
[86069]148 hrc = pTmpProvider->COMGETTER(Id)(bstrProviderId.asOutParam());
[86012]149
[86069]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.
[86012]155 */
[86069]156 if (bstrProviderId.isNotEmpty())
157 m_pVirtualBox->i_onCloudProviderUninstall(bstrProviderId);
[86012]158
[75663]159 hrc = pTmpProvider->PrepareUninstall();
160 pTmpProvider->AddRef();
161 uRefCnt = pTmpProvider->Release();
162 }
[86012]163
164 /* has PrepareUninstall uninited the provider? */
[75663]165 if (SUCCEEDED(hrc) && uRefCnt == 1)
166 {
[85247]167 m_astrExtPackNames.erase(m_astrExtPackNames.begin() + (ssize_t)i);
168 m_apCloudProviders.erase(m_apCloudProviders.begin() + (ssize_t)i);
[86069]169
170 if (bstrProviderId.isNotEmpty())
171 m_pVirtualBox->i_onCloudProviderRegistered(bstrProviderId, FALSE);
172
[86012]173 /* NB: not advancing loop index */
[75663]174 }
175 else
176 {
[86012]177 LogRel(("CloudProviderManager: provider '%s' blocks extpack uninstall, result=%Rhrc, refcount=%u\n",
178 strExtPackName.c_str(), hrc, uRefCnt));
[75663]179 fRes = false;
180 i++;
181 }
182 }
183
184 if (fRes)
185 m_mapCloudProviderManagers.erase(it);
[86069]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);
[73549]192 }
[73164]193
[75663]194 return fRes;
195}
196
197void CloudProviderManager::i_addExtPack(IExtPack *aExtPack)
198{
[86012]199 HRESULT hrc;
200
[75663]201 AssertReturnVoid(aExtPack);
[73716]202 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
[75663]203
[86012]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 */
[75663]209 ComPtr<IUnknown> pObj;
210 com::Guid idObj(COM_IIDOF(ICloudProviderManager));
[86012]211 hrc = aExtPack->QueryObject(Bstr(idObj.toString()).raw(), pObj.asOutParam());
[75663]212 if (FAILED(hrc))
[73716]213 return;
[86012]214 const ComPtr<ICloudProviderManager> pManager(pObj);
215 if (pManager.isNull())
[73716]216 return;
[73549]217
[86012]218 /* get the list of cloud providers */
[75663]219 SafeIfaceArray<ICloudProvider> apProvidersFromCurrExtPack;
[86012]220 hrc = pManager->COMGETTER(Providers)(ComSafeArrayAsOutParam(apProvidersFromCurrExtPack));
[75663]221 if (FAILED(hrc))
222 return;
[86012]223 if (apProvidersFromCurrExtPack.size() == 0)
224 return;
[75663]225
[86012]226 m_mapCloudProviderManagers[strExtPackName] = pManager;
227
[75663]228 for (unsigned i = 0; i < apProvidersFromCurrExtPack.size(); i++)
[73164]229 {
[86012]230 const ComPtr<ICloudProvider> pProvider(apProvidersFromCurrExtPack[i]);
231 if (!pProvider.isNull())
[75730]232 {
[86012]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 */
[75730]238 {
[86012]239 /* save the provider and the name of the extpack it came from */
[75730]240 Assert(m_astrExtPackNames.size() == m_apCloudProviders.size());
[86012]241 m_astrExtPackNames.push_back(strExtPackName);
242 m_apCloudProviders.push_back(pProvider);
243
244 Bstr bstrProviderId;
245 pProvider->COMGETTER(Id)(bstrProviderId.asOutParam());
[86069]246 if (bstrProviderId.isNotEmpty())
247 m_pVirtualBox->i_onCloudProviderRegistered(bstrProviderId, TRUE);
[75730]248 }
249 }
[73164]250 }
[86012]251
[86069]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);
[73716]257}
[85247]258
[74926]259#endif /* VBOX_WITH_EXTPACK */
[73164]260
[73716]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}
[73164]267
[73716]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());
[73164]284}
285
[73716]286HRESULT CloudProviderManager::getProviderByShortName(const com::Utf8Str &aProviderName,
287 ComPtr<ICloudProvider> &aProvider)
[73164]288{
[73716]289 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
290 for (size_t i = 0; i < m_apCloudProviders.size(); i++)
[73549]291 {
[73716]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 }
[73549]299 }
[73716]300 return setError(VBOX_E_OBJECT_NOT_FOUND, tr("Could not find a cloud provider with short name '%s'"),
301 aProviderName.c_str());
302}
[73549]303
[73716]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++)
[73164]309 {
[73716]310 Bstr bstrName;
311 HRESULT hrc = m_apCloudProviders[i]->COMGETTER(Name)(bstrName.asOutParam());
312 if (SUCCEEDED(hrc) && bstrName.equals(aProviderName))
[73571]313 {
[73716]314 aProvider = m_apCloudProviders[i];
315 return S_OK;
[73571]316 }
[73164]317 }
[73716]318 return setError(VBOX_E_OBJECT_NOT_FOUND, tr("Could not find a cloud provider with name '%s'"),
319 aProviderName.c_str());
[73164]320}
321
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use