VirtualBox

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

Last change on this file since 76240 was 75730, checked in by vboxsync, 6 years ago

Main/CloudProviderManager: Make sure to keep cloud providers implementing the expected interface only, i.e. drop anything which VBoxSVC doesn't know how to use.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.7 KB
Line 
1/* $Id: CloudProviderManagerImpl.cpp 75730 2018-11-26 10:57:56Z vboxsync $ */
2/** @file
3 * ICloudProviderManager COM class implementations.
4 */
5
6/*
7 * Copyright (C) 2008-2018 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#include <VBox/com/array.h>
20
21#include "VirtualBoxImpl.h"
22#include "CloudProviderManagerImpl.h"
23#include "ExtPackManagerImpl.h"
24#include "AutoCaller.h"
25#include "Logging.h"
26
27
28////////////////////////////////////////////////////////////////////////////////
29//
30// CloudProviderManager constructor / destructor
31//
32// ////////////////////////////////////////////////////////////////////////////////
33CloudProviderManager::CloudProviderManager()
34{
35}
36
37CloudProviderManager::~CloudProviderManager()
38{
39}
40
41
42HRESULT CloudProviderManager::FinalConstruct()
43{
44 return BaseFinalConstruct();
45}
46
47void CloudProviderManager::FinalRelease()
48{
49 uninit();
50
51 BaseFinalRelease();
52}
53
54HRESULT CloudProviderManager::init()
55{
56 // Enclose the state transition NotReady->InInit->Ready.
57 AutoInitSpan autoInitSpan(this);
58 AssertReturn(autoInitSpan.isOk(), E_FAIL);
59
60 m_apCloudProviders.clear();
61
62 autoInitSpan.setSucceeded();
63 return S_OK;
64}
65
66void CloudProviderManager::uninit()
67{
68 // Enclose the state transition Ready->InUninit->NotReady.
69 AutoUninitSpan autoUninitSpan(this);
70 if (autoUninitSpan.uninitDone())
71 return;
72}
73
74#ifdef VBOX_WITH_EXTPACK
75bool CloudProviderManager::i_canRemoveExtPack(IExtPack *aExtPack)
76{
77 AssertReturn(aExtPack, false);
78
79 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
80
81 // If any cloud provider in this extension pack fails to prepare the
82 // uninstall it and the cloud provider will be kept, so that the user
83 // can retry safely later. All other cloud providers in this extpack
84 // will be done as usual. No attempt is made to bring back the other
85 // cloud providers into working shape.
86
87 bool fRes = true;
88 Bstr bstrName;
89 aExtPack->COMGETTER(Name)(bstrName.asOutParam());
90 Utf8Str strName(bstrName);
91 ExtPackNameCloudProviderManagerMap::iterator it = m_mapCloudProviderManagers.find(strName);
92 if (it != m_mapCloudProviderManagers.end())
93 {
94 ComPtr<ICloudProviderManager> pTmp(it->second);
95
96 Assert(m_astrExtPackNames.size() == m_apCloudProviders.size());
97 for (size_t i = 0; i < m_astrExtPackNames.size(); )
98 {
99 if (m_astrExtPackNames[i] != strName)
100 {
101 i++;
102 continue;
103 }
104
105 // pTmpProvider will point to an object with refcount > 0 until
106 // the ComPtr is removed from m_apCloudProviders.
107 HRESULT hrc = S_OK;
108 ULONG uRefCnt = 1;
109 ICloudProvider *pTmpProvider(m_apCloudProviders[i]);
110 if (pTmpProvider)
111 {
112 hrc = pTmpProvider->PrepareUninstall();
113 // Sanity check the refcount, it should be 1 at this point.
114 pTmpProvider->AddRef();
115 uRefCnt = pTmpProvider->Release();
116 Assert(uRefCnt == 1);
117 }
118 if (SUCCEEDED(hrc) && uRefCnt == 1)
119 {
120 m_astrExtPackNames.erase(m_astrExtPackNames.begin() + i);
121 m_apCloudProviders.erase(m_apCloudProviders.begin() + i);
122 }
123 else
124 {
125 LogRel(("CloudProviderManager: provider '%s' blocks extpack uninstall, result=%Rhrc, refcount=%u\n", strName.c_str(), hrc, uRefCnt));
126 fRes = false;
127 i++;
128 }
129 }
130
131 if (fRes)
132 m_mapCloudProviderManagers.erase(it);
133 }
134
135 return fRes;
136}
137
138void CloudProviderManager::i_addExtPack(IExtPack *aExtPack)
139{
140 AssertReturnVoid(aExtPack);
141
142 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
143
144 Bstr bstrName;
145 aExtPack->COMGETTER(Name)(bstrName.asOutParam());
146 Utf8Str strName(bstrName);
147 ComPtr<IUnknown> pObj;
148 std::vector<com::Utf8Str> astrExtPackNames;
149 com::Guid idObj(COM_IIDOF(ICloudProviderManager));
150 HRESULT hrc = aExtPack->QueryObject(Bstr(idObj.toString()).raw(), pObj.asOutParam());
151 if (FAILED(hrc))
152 return;
153
154 ComPtr<ICloudProviderManager> pTmp(pObj);
155 if (pTmp.isNull())
156 return;
157
158 SafeIfaceArray<ICloudProvider> apProvidersFromCurrExtPack;
159 hrc = pTmp->COMGETTER(Providers)(ComSafeArrayAsOutParam(apProvidersFromCurrExtPack));
160 if (FAILED(hrc))
161 return;
162
163 m_mapCloudProviderManagers[strName] = pTmp;
164 for (unsigned i = 0; i < apProvidersFromCurrExtPack.size(); i++)
165 {
166 // Sanity check each cloud provider by forcing a QueryInterface call,
167 // making sure that it implements the right interface.
168 ComPtr<ICloudProvider> pTmpCP1(apProvidersFromCurrExtPack[i]);
169 if (!pTmpCP1.isNull())
170 {
171 ComPtr<ICloudProvider> pTmpCP2;
172 pTmpCP1.queryInterfaceTo(pTmpCP2.asOutParam());
173 if (!pTmpCP2.isNull())
174 {
175 Assert(m_astrExtPackNames.size() == m_apCloudProviders.size());
176 m_astrExtPackNames.push_back(strName);
177 m_apCloudProviders.push_back(apProvidersFromCurrExtPack[i]);
178 }
179 }
180 }
181}
182#endif /* VBOX_WITH_EXTPACK */
183
184HRESULT CloudProviderManager::getProviders(std::vector<ComPtr<ICloudProvider> > &aProviders)
185{
186 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
187 aProviders = m_apCloudProviders;
188 return S_OK;
189}
190
191HRESULT CloudProviderManager::getProviderById(const com::Guid &aProviderId,
192 ComPtr<ICloudProvider> &aProvider)
193{
194 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
195 for (size_t i = 0; i < m_apCloudProviders.size(); i++)
196 {
197 Bstr bstrId;
198 HRESULT hrc = m_apCloudProviders[i]->COMGETTER(Id)(bstrId.asOutParam());
199 if (SUCCEEDED(hrc) && aProviderId == bstrId)
200 {
201 aProvider = m_apCloudProviders[i];
202 return S_OK;
203 }
204 }
205 return setError(VBOX_E_OBJECT_NOT_FOUND, tr("Could not find a cloud provider with UUID {%RTuuid}"),
206 aProviderId.raw());
207}
208
209HRESULT CloudProviderManager::getProviderByShortName(const com::Utf8Str &aProviderName,
210 ComPtr<ICloudProvider> &aProvider)
211{
212 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
213 for (size_t i = 0; i < m_apCloudProviders.size(); i++)
214 {
215 Bstr bstrName;
216 HRESULT hrc = m_apCloudProviders[i]->COMGETTER(ShortName)(bstrName.asOutParam());
217 if (SUCCEEDED(hrc) && bstrName.equals(aProviderName))
218 {
219 aProvider = m_apCloudProviders[i];
220 return S_OK;
221 }
222 }
223 return setError(VBOX_E_OBJECT_NOT_FOUND, tr("Could not find a cloud provider with short name '%s'"),
224 aProviderName.c_str());
225}
226
227HRESULT CloudProviderManager::getProviderByName(const com::Utf8Str &aProviderName,
228 ComPtr<ICloudProvider> &aProvider)
229{
230 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
231 for (size_t i = 0; i < m_apCloudProviders.size(); i++)
232 {
233 Bstr bstrName;
234 HRESULT hrc = m_apCloudProviders[i]->COMGETTER(Name)(bstrName.asOutParam());
235 if (SUCCEEDED(hrc) && bstrName.equals(aProviderName))
236 {
237 aProvider = m_apCloudProviders[i];
238 return S_OK;
239 }
240 }
241 return setError(VBOX_E_OBJECT_NOT_FOUND, tr("Could not find a cloud provider with name '%s'"),
242 aProviderName.c_str());
243}
244
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