mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 20:02:29 +01:00
Merge branch 'master' into ui-plugins
Conflicts: ui/index.jsp
This commit is contained in:
commit
dfaffcebad
185
LICENSE
185
LICENSE
@ -180,7 +180,6 @@ Copyright (c) 2013 The Apache Software Foundation
|
||||
|
||||
|
||||
This distribution contains third party resources.
|
||||
|
||||
Within the . directory
|
||||
licensed under the BSD (3-clause) http://www.opensource.org/licenses/BSD-3-Clause (as follows)
|
||||
|
||||
@ -209,10 +208,9 @@ Within the . directory
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
from Thomas Nagy http://code.google.com/p/waf/
|
||||
waf
|
||||
|
||||
waf
|
||||
|
||||
Within the awsapi directory
|
||||
licensed under the BSD (3-clause) http://www.opensource.org/licenses/BSD-3-Clause (as follows)
|
||||
@ -242,10 +240,9 @@ Within the awsapi directory
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
from Thomas Nagy http://code.google.com/p/waf/
|
||||
waf
|
||||
|
||||
waf
|
||||
|
||||
Within the console-proxy/js directory
|
||||
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
|
||||
@ -270,10 +267,9 @@ Within the console-proxy/js directory
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
from John Resig
|
||||
jquery.js
|
||||
|
||||
jquery.js
|
||||
|
||||
Within the deps directory
|
||||
licensed under the BSD (2-clause) for XenServerJava http://www.opensource.org/licenses/BSD-2-Clause (as follows)
|
||||
@ -304,28 +300,27 @@ Within the deps directory
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
from Citrix Systems, Inc http://www.citrix.com/
|
||||
XenServerJava http://community.citrix.com/cdn/xs/sdks/
|
||||
|
||||
XenServerJava from http://community.citrix.com/cdn/xs/sdks/
|
||||
|
||||
Within the patches/systemvm/debian/config/etc directory
|
||||
placed in the public domain
|
||||
by Adiscon GmbH http://www.adiscon.com/
|
||||
rsyslog.conf
|
||||
by Simon Kelley
|
||||
dnsmasq.conf
|
||||
vpcdnsmasq.conf
|
||||
|
||||
dnsmasq.conf
|
||||
vpcdnsmasq.conf
|
||||
|
||||
Within the patches/systemvm/debian/config/etc/apache2 directory
|
||||
licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above)
|
||||
Copyright (c) 2012 The Apache Software Foundation
|
||||
from The Apache Software Foundation http://www.apache.org/
|
||||
httpd.conf
|
||||
ports.conf
|
||||
sites-available/default
|
||||
sites-available/default-ssl
|
||||
vhostexample.conf
|
||||
|
||||
httpd.conf
|
||||
ports.conf
|
||||
sites-available/default
|
||||
sites-available/default-ssl
|
||||
vhostexample.conf
|
||||
|
||||
Within the patches/systemvm/debian/config/etc/ssh/ directory
|
||||
licensed under the BSD (2-clause) http://www.opensource.org/licenses/BSD-2-Clause (as follows)
|
||||
@ -354,40 +349,95 @@ Within the patches/systemvm/debian/config/etc/ssh/ directory
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
from OpenSSH Project http://www.openssh.org/
|
||||
sshd_config
|
||||
|
||||
sshd_config
|
||||
|
||||
Within the patches/systemvm/debian/config/root/redundant_router directory
|
||||
placed in the public domain
|
||||
by The netfilter.org project http://www.netfilter.org/
|
||||
conntrackd.conf.templ
|
||||
|
||||
conntrackd.conf.templ
|
||||
|
||||
Within the scripts/storage/secondary directory
|
||||
licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above)
|
||||
Copyright (c) 2010-2011 OpenStack, LLC.
|
||||
from OpenStack, LLC http://www.openstack.org
|
||||
swift
|
||||
|
||||
swift
|
||||
|
||||
Within the scripts/vm/hypervisor/xenserver directory
|
||||
licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above)
|
||||
Copyright (c) 2010-2011 OpenStack, LLC.
|
||||
from OpenStack, LLC http://www.openstack.org
|
||||
swift
|
||||
swift
|
||||
|
||||
Within the tools/appliance/definitions/systemvmtemplate directory
|
||||
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
|
||||
|
||||
Copyright (c) 2010-2012 Patrick Debois
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
from Patrick Debois http://www.jedi.be/blog/
|
||||
base.sh from https://github.com/jedi4ever/veewee
|
||||
cleanup.sh from https://github.com/jedi4ever/veewee
|
||||
definition.rb from https://github.com/jedi4ever/veewee
|
||||
preseed.cfg from https://github.com/jedi4ever/veewee
|
||||
zerodisk.sh from https://github.com/jedi4ever/veewee
|
||||
|
||||
Within the tools/devcloud/src/deps/boxes/basebox-build directory
|
||||
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
|
||||
|
||||
Copyright (c) 2010-2012 Patrick Debois
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
from Patrick Debois http://www.jedi.be/blog/
|
||||
definition.rb from https://github.com/jedi4ever/veewee
|
||||
preseed.cfg from https://github.com/jedi4ever/veewee
|
||||
|
||||
Within the ui/lib directory
|
||||
placed in the public domain
|
||||
by Eric Meyer http://meyerweb.com/eric/
|
||||
reset.css
|
||||
reset.css from http://meyerweb.com/eric/tools/css/reset/
|
||||
|
||||
licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above)
|
||||
Copyright (c) 2006 Google Inc.
|
||||
from Google Inc. http://google.com
|
||||
excanvas.js http://code.google.com/p/explorercanvas/
|
||||
excanvas.js from http://code.google.com/p/explorercanvas/
|
||||
|
||||
licensed under the BSD (2-clause) http://www.opensource.org/licenses/BSD-2-Clause (as follows)
|
||||
|
||||
@ -417,9 +467,9 @@ Within the ui/lib directory
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
from George McGinley Smith
|
||||
jquery.easing.js
|
||||
jquery.easing.js
|
||||
|
||||
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
|
||||
|
||||
@ -443,9 +493,9 @@ Within the ui/lib directory
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
from John Resig
|
||||
jquery.js
|
||||
jquery.js
|
||||
|
||||
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
|
||||
|
||||
@ -469,9 +519,9 @@ Within the ui/lib directory
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
from Jorn Zaefferer
|
||||
jquery.validate.js
|
||||
jquery.validate.js
|
||||
|
||||
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
|
||||
|
||||
@ -495,9 +545,9 @@ Within the ui/lib directory
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
from Sebastian Tschan https://blueimp.net
|
||||
jquery.md5.js
|
||||
jquery.md5.js
|
||||
|
||||
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
|
||||
|
||||
@ -521,10 +571,9 @@ Within the ui/lib directory
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
from Klaus Hartl http://stilbuero.de
|
||||
jquery.cookies.js
|
||||
|
||||
jquery.cookies.js
|
||||
|
||||
Within the ui/lib/flot directory
|
||||
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
|
||||
@ -549,18 +598,18 @@ Within the ui/lib/flot directory
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
from IOLA http://www.iola.dk/
|
||||
jquery.flot.crosshair.js
|
||||
jquery.flot.fillbetween.js
|
||||
jquery.flot.image.js
|
||||
jquery.flot.js
|
||||
jquery.flot.navigate.js
|
||||
jquery.flot.resize.js
|
||||
jquery.flot.selection.js
|
||||
jquery.flot.stack.js
|
||||
jquery.flot.symbol.js
|
||||
jquery.flot.threshold.js
|
||||
jquery.flot.crosshair.js
|
||||
jquery.flot.fillbetween.js
|
||||
jquery.flot.image.js
|
||||
jquery.flot.js
|
||||
jquery.flot.navigate.js
|
||||
jquery.flot.resize.js
|
||||
jquery.flot.selection.js
|
||||
jquery.flot.stack.js
|
||||
jquery.flot.symbol.js
|
||||
jquery.flot.threshold.js
|
||||
|
||||
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
|
||||
|
||||
@ -585,9 +634,9 @@ Within the ui/lib/flot directory
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
from Brian Medendorp
|
||||
jquery.pie.js
|
||||
jquery.pie.js
|
||||
|
||||
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
|
||||
|
||||
@ -610,10 +659,9 @@ Within the ui/lib/flot directory
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
from Ole Laursen
|
||||
jquery.colorhelpers.js
|
||||
|
||||
jquery.colorhelpers.js
|
||||
|
||||
Within the ui/lib/jquery-ui directory
|
||||
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
|
||||
@ -637,12 +685,11 @@ Within the ui/lib/jquery-ui directory
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
from jQuery UI Developers http://jqueryui.com/about
|
||||
css/jquery-ui.css
|
||||
index.html
|
||||
js/jquery-ui.js
|
||||
|
||||
css/jquery-ui.css
|
||||
index.html
|
||||
js/jquery-ui.js
|
||||
|
||||
Within the ui/lib/qunit directory
|
||||
licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows)
|
||||
@ -667,14 +714,14 @@ Within the ui/lib/qunit directory
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
from Jorn Zaefferer
|
||||
qunit.css http://docs.jquery.com/QUnit
|
||||
qunit.js http://docs.jquery.com/QUnit
|
||||
|
||||
qunit.css from http://docs.jquery.com/QUnit
|
||||
qunit.js from http://docs.jquery.com/QUnit
|
||||
|
||||
Within the utils/src/com/cloud/utils/db directory
|
||||
licensed under the Apache License, Version 2 http://www.apache.org/licenses/LICENSE-2.0.txt (as above)
|
||||
Copyright (c) 2004 Clinton Begin
|
||||
from Clinton Begin http://code.google.com/p/mybatis/
|
||||
ScriptRunner.java http://code.google.com/p/mybatis/
|
||||
ScriptRunner.java from http://code.google.com/p/mybatis/
|
||||
|
||||
|
||||
49
NOTICE
49
NOTICE
@ -6,30 +6,7 @@
|
||||
|
||||
|
||||
|
||||
Source code distribution if this software contains third party resources requiring
|
||||
the following notices:
|
||||
|
||||
|
||||
For
|
||||
jquery.md5.js
|
||||
|
||||
|
||||
jQuery MD5 Plugin 1.2.1
|
||||
https://github.com/blueimp/jQuery-MD5
|
||||
|
||||
Copyright 2010, Sebastian Tschan
|
||||
https://blueimp.net
|
||||
|
||||
Licensed under the MIT license:
|
||||
http://creativecommons.org/licenses/MIT/
|
||||
|
||||
Based on
|
||||
A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
|
||||
Digest Algorithm, as defined in RFC 1321.
|
||||
Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
|
||||
Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
||||
Distributed under the BSD License
|
||||
See http://pajhome.org.uk/crypt/md5 for more info.
|
||||
This distribution contains third party resources requiring the following notices:
|
||||
|
||||
|
||||
For
|
||||
@ -66,6 +43,28 @@
|
||||
Date: Thu May 12 15:04:36 2011 -0400
|
||||
|
||||
|
||||
For
|
||||
jquery.md5.js
|
||||
|
||||
|
||||
jQuery MD5 Plugin 1.2.1
|
||||
https://github.com/blueimp/jQuery-MD5
|
||||
|
||||
Copyright 2010, Sebastian Tschan
|
||||
https://blueimp.net
|
||||
|
||||
Licensed under the MIT license:
|
||||
http://creativecommons.org/licenses/MIT/
|
||||
|
||||
Based on
|
||||
A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
|
||||
Digest Algorithm, as defined in RFC 1321.
|
||||
Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
|
||||
Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
||||
Distributed under the BSD License
|
||||
See http://pajhome.org.uk/crypt/md5 for more info.
|
||||
|
||||
|
||||
For
|
||||
jquery.colorhelpers.js
|
||||
|
||||
@ -76,4 +75,4 @@
|
||||
|
||||
Inspiration from jQuery color animation plugin by John Resig.
|
||||
|
||||
Released under the MIT license by Ole Laursen, October 2009.
|
||||
Released under the MIT license by Ole Laursen, October 2009.
|
||||
|
||||
62
api/src/com/cloud/agent/api/CreateVMSnapshotAnswer.java
Normal file
62
api/src/com/cloud/agent/api/CreateVMSnapshotAnswer.java
Normal file
@ -0,0 +1,62 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.agent.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.agent.api.to.VolumeTO;
|
||||
|
||||
public class CreateVMSnapshotAnswer extends Answer {
|
||||
|
||||
private List<VolumeTO> volumeTOs;
|
||||
private VMSnapshotTO vmSnapshotTo;
|
||||
|
||||
|
||||
public List<VolumeTO> getVolumeTOs() {
|
||||
return volumeTOs;
|
||||
}
|
||||
|
||||
public void setVolumeTOs(List<VolumeTO> volumeTOs) {
|
||||
this.volumeTOs = volumeTOs;
|
||||
}
|
||||
|
||||
public VMSnapshotTO getVmSnapshotTo() {
|
||||
return vmSnapshotTo;
|
||||
}
|
||||
|
||||
public void setVmSnapshotTo(VMSnapshotTO vmSnapshotTo) {
|
||||
this.vmSnapshotTo = vmSnapshotTo;
|
||||
}
|
||||
|
||||
public CreateVMSnapshotAnswer() {
|
||||
|
||||
}
|
||||
|
||||
public CreateVMSnapshotAnswer(CreateVMSnapshotCommand cmd, boolean success,
|
||||
String result) {
|
||||
super(cmd, success, result);
|
||||
}
|
||||
|
||||
public CreateVMSnapshotAnswer(CreateVMSnapshotCommand cmd,
|
||||
VMSnapshotTO vmSnapshotTo, List<VolumeTO> volumeTOs) {
|
||||
super(cmd, true, "");
|
||||
this.vmSnapshotTo = vmSnapshotTo;
|
||||
this.volumeTOs = volumeTOs;
|
||||
}
|
||||
|
||||
}
|
||||
42
api/src/com/cloud/agent/api/CreateVMSnapshotCommand.java
Normal file
42
api/src/com/cloud/agent/api/CreateVMSnapshotCommand.java
Normal file
@ -0,0 +1,42 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.agent.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.agent.api.to.VolumeTO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
public class CreateVMSnapshotCommand extends VMSnapshotBaseCommand {
|
||||
|
||||
public CreateVMSnapshotCommand(String vmName, VMSnapshotTO snapshot, List<VolumeTO> volumeTOs, String guestOSType, VirtualMachine.State vmState) {
|
||||
super(vmName, snapshot, volumeTOs, guestOSType);
|
||||
this.vmState = vmState;
|
||||
}
|
||||
|
||||
private VirtualMachine.State vmState;
|
||||
|
||||
|
||||
public VirtualMachine.State getVmState() {
|
||||
return vmState;
|
||||
}
|
||||
|
||||
public void setVmState(VirtualMachine.State vmState) {
|
||||
this.vmState = vmState;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.agent.api;
|
||||
|
||||
import com.cloud.agent.api.to.VolumeTO;
|
||||
|
||||
public class CreateVolumeFromVMSnapshotAnswer extends Answer {
|
||||
private String path;
|
||||
private VolumeTO volumeTo;
|
||||
|
||||
public VolumeTO getVolumeTo() {
|
||||
return volumeTo;
|
||||
}
|
||||
|
||||
public CreateVolumeFromVMSnapshotAnswer(
|
||||
CreateVolumeFromVMSnapshotCommand cmd, VolumeTO volumeTo) {
|
||||
super(cmd, true, "");
|
||||
this.volumeTo = volumeTo;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
protected CreateVolumeFromVMSnapshotAnswer() {
|
||||
|
||||
}
|
||||
|
||||
public CreateVolumeFromVMSnapshotAnswer(
|
||||
CreateVolumeFromVMSnapshotCommand cmd, String path) {
|
||||
super(cmd, true, "");
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public CreateVolumeFromVMSnapshotAnswer(
|
||||
CreateVolumeFromVMSnapshotCommand cmd, boolean result, String string) {
|
||||
super(cmd, result, string);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.agent.api;
|
||||
|
||||
import com.cloud.agent.api.to.StorageFilerTO;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
|
||||
public class CreateVolumeFromVMSnapshotCommand extends Command {
|
||||
|
||||
protected String path;
|
||||
protected String name;
|
||||
protected Boolean fullClone;
|
||||
protected String storagePoolUuid;
|
||||
private StorageFilerTO pool;
|
||||
private DiskProfile diskProfile;
|
||||
private Long volumeId;
|
||||
|
||||
public DiskProfile getDskch() {
|
||||
return diskProfile;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public Long getVolumeId() {
|
||||
return volumeId;
|
||||
}
|
||||
|
||||
protected CreateVolumeFromVMSnapshotCommand() {
|
||||
|
||||
}
|
||||
|
||||
public CreateVolumeFromVMSnapshotCommand(String path, String name,
|
||||
Boolean fullClone, String storagePoolUuid) {
|
||||
this.path = path;
|
||||
this.name = name;
|
||||
this.fullClone = fullClone;
|
||||
this.storagePoolUuid = storagePoolUuid;
|
||||
}
|
||||
|
||||
public CreateVolumeFromVMSnapshotCommand(String path, String name,
|
||||
Boolean fullClone, String storagePoolUuid, StorageFilerTO pool,
|
||||
DiskProfile diskProfile, Long volumeId) {
|
||||
this.path = path;
|
||||
this.name = name;
|
||||
this.fullClone = fullClone;
|
||||
this.storagePoolUuid = storagePoolUuid;
|
||||
this.pool = pool;
|
||||
this.diskProfile = diskProfile;
|
||||
this.volumeId = volumeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Boolean getFullClone() {
|
||||
return fullClone;
|
||||
}
|
||||
|
||||
public String getStoragePoolUuid() {
|
||||
return storagePoolUuid;
|
||||
}
|
||||
|
||||
public StorageFilerTO getPool() {
|
||||
return pool;
|
||||
}
|
||||
}
|
||||
49
api/src/com/cloud/agent/api/DeleteVMSnapshotAnswer.java
Normal file
49
api/src/com/cloud/agent/api/DeleteVMSnapshotAnswer.java
Normal file
@ -0,0 +1,49 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.agent.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.agent.api.to.VolumeTO;
|
||||
|
||||
public class DeleteVMSnapshotAnswer extends Answer {
|
||||
private List<VolumeTO> volumeTOs;
|
||||
|
||||
public DeleteVMSnapshotAnswer() {
|
||||
}
|
||||
|
||||
public DeleteVMSnapshotAnswer(DeleteVMSnapshotCommand cmd, boolean result,
|
||||
String message) {
|
||||
super(cmd, result, message);
|
||||
}
|
||||
|
||||
public DeleteVMSnapshotAnswer(DeleteVMSnapshotCommand cmd,
|
||||
List<VolumeTO> volumeTOs) {
|
||||
super(cmd, true, "");
|
||||
this.volumeTOs = volumeTOs;
|
||||
}
|
||||
|
||||
public List<VolumeTO> getVolumeTOs() {
|
||||
return volumeTOs;
|
||||
}
|
||||
|
||||
public void setVolumeTOs(List<VolumeTO> volumeTOs) {
|
||||
this.volumeTOs = volumeTOs;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
28
api/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java
Normal file
28
api/src/com/cloud/agent/api/DeleteVMSnapshotCommand.java
Normal file
@ -0,0 +1,28 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License
|
||||
package com.cloud.agent.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.agent.api.to.VolumeTO;
|
||||
|
||||
|
||||
public class DeleteVMSnapshotCommand extends VMSnapshotBaseCommand {
|
||||
public DeleteVMSnapshotCommand(String vmName, VMSnapshotTO snapshot, List<VolumeTO> volumeTOs, String guestOSType) {
|
||||
super( vmName, snapshot, volumeTOs, guestOSType);
|
||||
}
|
||||
}
|
||||
63
api/src/com/cloud/agent/api/RevertToVMSnapshotAnswer.java
Normal file
63
api/src/com/cloud/agent/api/RevertToVMSnapshotAnswer.java
Normal file
@ -0,0 +1,63 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.agent.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.agent.api.to.VolumeTO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
public class RevertToVMSnapshotAnswer extends Answer {
|
||||
|
||||
private List<VolumeTO> volumeTOs;
|
||||
private VirtualMachine.State vmState;
|
||||
|
||||
public RevertToVMSnapshotAnswer(RevertToVMSnapshotCommand cmd, boolean result,
|
||||
String message) {
|
||||
super(cmd, result, message);
|
||||
}
|
||||
|
||||
public RevertToVMSnapshotAnswer() {
|
||||
super();
|
||||
}
|
||||
|
||||
public RevertToVMSnapshotAnswer(RevertToVMSnapshotCommand cmd,
|
||||
List<VolumeTO> volumeTOs,
|
||||
VirtualMachine.State vmState) {
|
||||
super(cmd, true, "");
|
||||
this.volumeTOs = volumeTOs;
|
||||
this.vmState = vmState;
|
||||
}
|
||||
|
||||
public VirtualMachine.State getVmState() {
|
||||
return vmState;
|
||||
}
|
||||
|
||||
public List<VolumeTO> getVolumeTOs() {
|
||||
return volumeTOs;
|
||||
}
|
||||
|
||||
public void setVolumeTOs(List<VolumeTO> volumeTOs) {
|
||||
this.volumeTOs = volumeTOs;
|
||||
}
|
||||
|
||||
public void setVmState(VirtualMachine.State vmState) {
|
||||
this.vmState = vmState;
|
||||
}
|
||||
|
||||
}
|
||||
29
api/src/com/cloud/agent/api/RevertToVMSnapshotCommand.java
Normal file
29
api/src/com/cloud/agent/api/RevertToVMSnapshotCommand.java
Normal file
@ -0,0 +1,29 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.agent.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.agent.api.to.VolumeTO;
|
||||
|
||||
public class RevertToVMSnapshotCommand extends VMSnapshotBaseCommand {
|
||||
|
||||
public RevertToVMSnapshotCommand(String vmName, VMSnapshotTO snapshot, List<VolumeTO> volumeTOs, String guestOSType) {
|
||||
super(vmName, snapshot, volumeTOs, guestOSType);
|
||||
}
|
||||
|
||||
}
|
||||
74
api/src/com/cloud/agent/api/VMSnapshotBaseCommand.java
Normal file
74
api/src/com/cloud/agent/api/VMSnapshotBaseCommand.java
Normal file
@ -0,0 +1,74 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.agent.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.agent.api.to.VolumeTO;
|
||||
|
||||
public class VMSnapshotBaseCommand extends Command{
|
||||
protected List<VolumeTO> volumeTOs;
|
||||
protected VMSnapshotTO target;
|
||||
protected String vmName;
|
||||
protected String guestOSType;
|
||||
|
||||
|
||||
public VMSnapshotBaseCommand(String vmName, VMSnapshotTO snapshot, List<VolumeTO> volumeTOs, String guestOSType) {
|
||||
this.vmName = vmName;
|
||||
this.target = snapshot;
|
||||
this.volumeTOs = volumeTOs;
|
||||
this.guestOSType = guestOSType;
|
||||
}
|
||||
|
||||
public List<VolumeTO> getVolumeTOs() {
|
||||
return volumeTOs;
|
||||
}
|
||||
|
||||
public void setVolumeTOs(List<VolumeTO> volumeTOs) {
|
||||
this.volumeTOs = volumeTOs;
|
||||
}
|
||||
|
||||
public VMSnapshotTO getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public void setTarget(VMSnapshotTO target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public String getVmName() {
|
||||
return vmName;
|
||||
}
|
||||
|
||||
public void setVmName(String vmName) {
|
||||
this.vmName = vmName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getGuestOSType() {
|
||||
return guestOSType;
|
||||
}
|
||||
|
||||
public void setGuestOSType(String guestOSType) {
|
||||
this.guestOSType = guestOSType;
|
||||
}
|
||||
}
|
||||
90
api/src/com/cloud/agent/api/VMSnapshotTO.java
Normal file
90
api/src/com/cloud/agent/api/VMSnapshotTO.java
Normal file
@ -0,0 +1,90 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.agent.api;
|
||||
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
|
||||
public class VMSnapshotTO {
|
||||
private Long id;
|
||||
private String snapshotName;
|
||||
private VMSnapshot.Type type;
|
||||
private Long createTime;
|
||||
private Boolean current;
|
||||
private String description;
|
||||
private VMSnapshotTO parent;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
public VMSnapshotTO(Long id, String snapshotName,
|
||||
VMSnapshot.Type type, Long createTime,
|
||||
String description, Boolean current, VMSnapshotTO parent) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.snapshotName = snapshotName;
|
||||
this.type = type;
|
||||
this.createTime = createTime;
|
||||
this.current = current;
|
||||
this.description = description;
|
||||
this.parent = parent;
|
||||
}
|
||||
public VMSnapshotTO() {
|
||||
|
||||
}
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
public Boolean getCurrent() {
|
||||
return current;
|
||||
}
|
||||
public void setCurrent(Boolean current) {
|
||||
this.current = current;
|
||||
}
|
||||
public Long getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
public void setCreateTime(Long createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public VMSnapshot.Type getType() {
|
||||
return type;
|
||||
}
|
||||
public void setType(VMSnapshot.Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getSnapshotName() {
|
||||
return snapshotName;
|
||||
}
|
||||
public void setSnapshotName(String snapshotName) {
|
||||
this.snapshotName = snapshotName;
|
||||
}
|
||||
public VMSnapshotTO getParent() {
|
||||
return parent;
|
||||
}
|
||||
public void setParent(VMSnapshotTO parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
}
|
||||
@ -124,6 +124,10 @@ public class VolumeTO implements InternalIdentity {
|
||||
public String getOsType() {
|
||||
return guestOsType;
|
||||
}
|
||||
|
||||
public void setPath(String path){
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
@ -28,7 +28,9 @@ public interface Resource {
|
||||
template("template", 4, ResourceOwnerType.Account, ResourceOwnerType.Domain),
|
||||
project("project", 5, ResourceOwnerType.Account, ResourceOwnerType.Domain),
|
||||
network("network", 6, ResourceOwnerType.Account, ResourceOwnerType.Domain),
|
||||
vpc("vpc", 7, ResourceOwnerType.Account, ResourceOwnerType.Domain);
|
||||
vpc("vpc", 7, ResourceOwnerType.Account, ResourceOwnerType.Domain),
|
||||
cpu("cpu", 8, ResourceOwnerType.Account, ResourceOwnerType.Domain),
|
||||
memory("memory", 9, ResourceOwnerType.Account, ResourceOwnerType.Domain);
|
||||
|
||||
private String name;
|
||||
private ResourceOwnerType[] supportedOwners;
|
||||
|
||||
@ -331,6 +331,11 @@ public class EventTypes {
|
||||
// tag related events
|
||||
public static final String EVENT_TAGS_CREATE = "CREATE_TAGS";
|
||||
public static final String EVENT_TAGS_DELETE = "DELETE_TAGS";
|
||||
|
||||
// vm snapshot events
|
||||
public static final String EVENT_VM_SNAPSHOT_CREATE = "VMSNAPSHOT.CREATE";
|
||||
public static final String EVENT_VM_SNAPSHOT_DELETE = "VMSNAPSHOT.DELETE";
|
||||
public static final String EVENT_VM_SNAPSHOT_REVERT = "VMSNAPSHOT.REVERTTO";
|
||||
|
||||
// external network device events
|
||||
public static final String EVENT_EXTERNAL_NVP_CONTROLLER_ADD = "PHYSICAL.NVPCONTROLLER.ADD";
|
||||
|
||||
@ -37,7 +37,8 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit
|
||||
Project,
|
||||
Vpc,
|
||||
NetworkACL,
|
||||
StaticRoute
|
||||
StaticRoute,
|
||||
VMSnapshot
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -112,7 +112,7 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I
|
||||
s_fsm.addTransition(State.Error, VirtualMachine.Event.DestroyRequested, State.Expunging);
|
||||
s_fsm.addTransition(State.Error, VirtualMachine.Event.ExpungeOperation, State.Expunging);
|
||||
}
|
||||
|
||||
|
||||
public static boolean isVmStarted(State oldState, Event e, State newState) {
|
||||
if (oldState == State.Starting && newState == State.Running) {
|
||||
return true;
|
||||
@ -174,7 +174,9 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, Identity, I
|
||||
OperationFailedToError,
|
||||
OperationRetry,
|
||||
AgentReportShutdowned,
|
||||
AgentReportMigrated
|
||||
AgentReportMigrated,
|
||||
RevertRequested,
|
||||
SnapshotRequested
|
||||
};
|
||||
|
||||
public enum Type {
|
||||
|
||||
110
api/src/com/cloud/vm/snapshot/VMSnapshot.java
Normal file
110
api/src/com/cloud/vm/snapshot/VMSnapshot.java
Normal file
@ -0,0 +1,110 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.vm.snapshot;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import com.cloud.utils.fsm.StateObject;
|
||||
|
||||
public interface VMSnapshot extends ControlledEntity, Identity, InternalIdentity,StateObject<VMSnapshot.State> {
|
||||
|
||||
enum State {
|
||||
Allocated("The VM snapshot is allocated but has not been created yet."),
|
||||
Creating("The VM snapshot is being created."),
|
||||
Ready("The VM snapshot is ready to be used."),
|
||||
Reverting("The VM snapshot is being used to revert"),
|
||||
Expunging("The volume is being expunging"),
|
||||
Removed("The volume is destroyed, and can't be recovered."),
|
||||
Error ("The volume is in error state, and can't be recovered");
|
||||
|
||||
String _description;
|
||||
|
||||
private State(String description) {
|
||||
_description = description;
|
||||
}
|
||||
|
||||
public static StateMachine2<State, Event, VMSnapshot> getStateMachine() {
|
||||
return s_fsm;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return _description;
|
||||
}
|
||||
|
||||
private final static StateMachine2<State, Event, VMSnapshot> s_fsm = new StateMachine2<State, Event, VMSnapshot>();
|
||||
static {
|
||||
s_fsm.addTransition(Allocated, Event.CreateRequested, Creating);
|
||||
s_fsm.addTransition(Creating, Event.OperationSucceeded, Ready);
|
||||
s_fsm.addTransition(Creating, Event.OperationFailed, Error);
|
||||
s_fsm.addTransition(Ready, Event.RevertRequested, Reverting);
|
||||
s_fsm.addTransition(Reverting, Event.OperationSucceeded, Ready);
|
||||
s_fsm.addTransition(Reverting, Event.OperationFailed, Ready);
|
||||
s_fsm.addTransition(Ready, Event.ExpungeRequested, Expunging);
|
||||
s_fsm.addTransition(Error, Event.ExpungeRequested, Expunging);
|
||||
s_fsm.addTransition(Expunging, Event.ExpungeRequested, Expunging);
|
||||
s_fsm.addTransition(Expunging, Event.OperationSucceeded, Removed);
|
||||
}
|
||||
}
|
||||
|
||||
enum Type{
|
||||
Disk, DiskAndMemory
|
||||
}
|
||||
|
||||
enum Event {
|
||||
CreateRequested,
|
||||
OperationFailed,
|
||||
OperationSucceeded,
|
||||
RevertRequested,
|
||||
ExpungeRequested,
|
||||
}
|
||||
|
||||
long getId();
|
||||
|
||||
public String getName();
|
||||
|
||||
public Long getVmId();
|
||||
|
||||
public State getState();
|
||||
|
||||
public Date getCreated();
|
||||
|
||||
public String getDescription();
|
||||
|
||||
public String getDisplayName();
|
||||
|
||||
public Long getParent();
|
||||
|
||||
public Boolean getCurrent();
|
||||
|
||||
public Type getType();
|
||||
|
||||
public long getUpdatedCount();
|
||||
|
||||
public void incrUpdatedCount();
|
||||
|
||||
public Date getUpdated();
|
||||
|
||||
public Date getRemoved();
|
||||
|
||||
public long getAccountId();
|
||||
}
|
||||
48
api/src/com/cloud/vm/snapshot/VMSnapshotService.java
Normal file
48
api/src/com/cloud/vm/snapshot/VMSnapshotService.java
Normal file
@ -0,0 +1,48 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.vm.snapshot;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InsufficientServerCapacityException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
public interface VMSnapshotService {
|
||||
|
||||
List<? extends VMSnapshot> listVMSnapshots(ListVMSnapshotCmd cmd);
|
||||
|
||||
VMSnapshot getVMSnapshotById(Long id);
|
||||
|
||||
VMSnapshot creatVMSnapshot(Long vmId, Long vmSnapshotId);
|
||||
|
||||
VMSnapshot allocVMSnapshot(Long vmId, String vsDisplayName, String vsDescription, Boolean snapshotMemory)
|
||||
throws ResourceAllocationException;
|
||||
|
||||
boolean deleteVMSnapshot(Long vmSnapshotId);
|
||||
|
||||
UserVm revertToSnapshot(Long vmSnapshotId) throws InsufficientServerCapacityException, InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException;
|
||||
|
||||
VirtualMachine getVMBySnapshotId(Long id);
|
||||
}
|
||||
@ -438,6 +438,11 @@ public class ApiConstants {
|
||||
public static final String AUTOSCALE_USER_ID = "autoscaleuserid";
|
||||
public static final String BAREMETAL_DISCOVER_NAME = "baremetaldiscovername";
|
||||
public static final String UCS_DN = "ucsdn";
|
||||
public static final String VM_SNAPSHOT_DESCRIPTION = "description";
|
||||
public static final String VM_SNAPSHOT_DISPLAYNAME = "name";
|
||||
public static final String VM_SNAPSHOT_ID = "vmsnapshotid";
|
||||
public static final String VM_SNAPSHOT_DISK_IDS = "vmsnapshotdiskids";
|
||||
public static final String VM_SNAPSHOT_MEMORY = "snapshotmemory";
|
||||
|
||||
public enum HostDetails {
|
||||
all, capacity, events, stats, min;
|
||||
|
||||
468
api/src/org/apache/cloudstack/api/ApiConstants.java.orig
Normal file
468
api/src/org/apache/cloudstack/api/ApiConstants.java.orig
Normal file
@ -0,0 +1,468 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api;
|
||||
|
||||
|
||||
public class ApiConstants {
|
||||
public static final String ACCOUNT = "account";
|
||||
public static final String ACCOUNTS = "accounts";
|
||||
public static final String ACCOUNT_TYPE = "accounttype";
|
||||
public static final String ACCOUNT_ID = "accountid";
|
||||
public static final String ALGORITHM = "algorithm";
|
||||
public static final String ALLOCATED_ONLY = "allocatedonly";
|
||||
public static final String API_KEY = "userapikey";
|
||||
public static final String APPLIED = "applied";
|
||||
public static final String AVAILABLE = "available";
|
||||
public static final String BITS = "bits";
|
||||
public static final String BOOTABLE = "bootable";
|
||||
public static final String BIND_DN = "binddn";
|
||||
public static final String BIND_PASSWORD = "bindpass";
|
||||
public static final String CATEGORY = "category";
|
||||
public static final String CERTIFICATE = "certificate";
|
||||
public static final String PRIVATE_KEY = "privatekey";
|
||||
public static final String DOMAIN_SUFFIX = "domainsuffix";
|
||||
public static final String DNS_SEARCH_ORDER = "dnssearchorder";
|
||||
public static final String CIDR = "cidr";
|
||||
public static final String IP6_CIDR = "ip6cidr";
|
||||
public static final String CIDR_LIST = "cidrlist";
|
||||
public static final String CLEANUP = "cleanup";
|
||||
public static final String CLUSTER_ID = "clusterid";
|
||||
public static final String CLUSTER_NAME = "clustername";
|
||||
public static final String CLUSTER_TYPE = "clustertype";
|
||||
public static final String COMPONENT = "component";
|
||||
public static final String CPU_NUMBER = "cpunumber";
|
||||
public static final String CPU_SPEED = "cpuspeed";
|
||||
public static final String CREATED = "created";
|
||||
public static final String CUSTOMIZED = "customized";
|
||||
public static final String DESCRIPTION = "description";
|
||||
public static final String DESTINATION_ZONE_ID = "destzoneid";
|
||||
public static final String DETAILS = "details";
|
||||
public static final String DEVICE_ID = "deviceid";
|
||||
public static final String DISK_OFFERING_ID = "diskofferingid";
|
||||
public static final String DISK_SIZE = "disksize";
|
||||
public static final String DISPLAY_NAME = "displayname";
|
||||
public static final String DISPLAY_TEXT = "displaytext";
|
||||
public static final String DNS1 = "dns1";
|
||||
public static final String DNS2 = "dns2";
|
||||
public static final String DOMAIN = "domain";
|
||||
public static final String DOMAIN_ID = "domainid";
|
||||
public static final String DURATION = "duration";
|
||||
public static final String EMAIL = "email";
|
||||
public static final String END_DATE = "enddate";
|
||||
public static final String END_IP = "endip";
|
||||
public static final String END_IPV6 = "endipv6";
|
||||
public static final String END_PORT = "endport";
|
||||
public static final String ENTRY_TIME = "entrytime";
|
||||
public static final String FETCH_LATEST = "fetchlatest";
|
||||
public static final String FIRSTNAME = "firstname";
|
||||
public static final String FORCED = "forced";
|
||||
public static final String FORCED_DESTROY_LOCAL_STORAGE = "forcedestroylocalstorage";
|
||||
public static final String FORMAT = "format";
|
||||
public static final String FOR_VIRTUAL_NETWORK = "forvirtualnetwork";
|
||||
public static final String GATEWAY = "gateway";
|
||||
public static final String IP6_GATEWAY = "ip6gateway";
|
||||
public static final String GROUP = "group";
|
||||
public static final String GROUP_ID = "groupid";
|
||||
public static final String GUEST_CIDR_ADDRESS = "guestcidraddress";
|
||||
public static final String HA_ENABLE = "haenable";
|
||||
public static final String HOST_ID = "hostid";
|
||||
public static final String HOST_NAME = "hostname";
|
||||
public static final String HYPERVISOR = "hypervisor";
|
||||
public static final String INLINE = "inline";
|
||||
public static final String INSTANCE = "instance";
|
||||
public static final String ICMP_CODE = "icmpcode";
|
||||
public static final String ICMP_TYPE = "icmptype";
|
||||
public static final String ID = "id";
|
||||
public static final String IDS = "ids";
|
||||
public static final String INTERNAL_DNS1 = "internaldns1";
|
||||
public static final String INTERNAL_DNS2 = "internaldns2";
|
||||
public static final String INTERVAL_TYPE = "intervaltype";
|
||||
public static final String IP_ADDRESS = "ipaddress";
|
||||
public static final String IP6_ADDRESS = "ip6address";
|
||||
public static final String IP_ADDRESS_ID = "ipaddressid";
|
||||
public static final String IS_ASYNC = "isasync";
|
||||
public static final String IP_AVAILABLE = "ipavailable";
|
||||
public static final String IP_LIMIT = "iplimit";
|
||||
public static final String IP_TOTAL = "iptotal";
|
||||
public static final String IS_CLEANUP_REQUIRED = "iscleanuprequired";
|
||||
public static final String IS_EXTRACTABLE = "isextractable";
|
||||
public static final String IS_FEATURED = "isfeatured";
|
||||
public static final String IS_PUBLIC = "ispublic";
|
||||
public static final String IS_PERSISTENT = "ispersistent";
|
||||
public static final String IS_READY = "isready";
|
||||
public static final String IS_RECURSIVE = "isrecursive";
|
||||
public static final String ISO_FILTER = "isofilter";
|
||||
public static final String ISO_GUEST_OS_NONE = "None";
|
||||
public static final String JOB_ID = "jobid";
|
||||
public static final String JOB_STATUS = "jobstatus";
|
||||
public static final String LASTNAME = "lastname";
|
||||
public static final String LEVEL = "level";
|
||||
public static final String LENGTH = "length";
|
||||
public static final String LIMIT_CPU_USE = "limitcpuuse";
|
||||
public static final String LOCK = "lock";
|
||||
public static final String LUN = "lun";
|
||||
public static final String LBID = "lbruleid";
|
||||
public static final String MAX = "max";
|
||||
public static final String MAX_SNAPS = "maxsnaps";
|
||||
public static final String MEMORY = "memory";
|
||||
public static final String MODE = "mode";
|
||||
public static final String NAME = "name";
|
||||
public static final String METHOD_NAME = "methodname";
|
||||
public static final String NETWORK_DOMAIN = "networkdomain";
|
||||
public static final String NETMASK = "netmask";
|
||||
public static final String NEW_NAME = "newname";
|
||||
public static final String NUM_RETRIES = "numretries";
|
||||
public static final String OFFER_HA = "offerha";
|
||||
public static final String IS_SYSTEM_OFFERING = "issystem";
|
||||
public static final String IS_DEFAULT_USE = "defaultuse";
|
||||
public static final String OP = "op";
|
||||
public static final String OS_CATEGORY_ID = "oscategoryid";
|
||||
public static final String OS_TYPE_ID = "ostypeid";
|
||||
public static final String PARAMS = "params";
|
||||
public static final String PARENT_DOMAIN_ID = "parentdomainid";
|
||||
public static final String PASSWORD = "password";
|
||||
public static final String NEW_PASSWORD = "new_password";
|
||||
public static final String PASSWORD_ENABLED = "passwordenabled";
|
||||
public static final String SSHKEY_ENABLED = "sshkeyenabled";
|
||||
public static final String PATH = "path";
|
||||
public static final String POD_ID = "podid";
|
||||
public static final String POD_IDS = "podids";
|
||||
public static final String POLICY_ID = "policyid";
|
||||
public static final String PORT = "port";
|
||||
public static final String PORTAL = "portal";
|
||||
public static final String PORT_FORWARDING_SERVICE_ID = "portforwardingserviceid";
|
||||
public static final String PRIVATE_INTERFACE = "privateinterface";
|
||||
public static final String PRIVATE_IP = "privateip";
|
||||
public static final String PRIVATE_PORT = "privateport";
|
||||
public static final String PRIVATE_START_PORT = "privateport";
|
||||
public static final String PRIVATE_END_PORT = "privateendport";
|
||||
public static final String PRIVATE_ZONE = "privatezone";
|
||||
public static final String PROTOCOL = "protocol";
|
||||
public static final String PUBLIC_INTERFACE = "publicinterface";
|
||||
public static final String PUBLIC_IP_ID = "publicipid";
|
||||
public static final String PUBLIC_IP = "publicip";
|
||||
public static final String PUBLIC_PORT = "publicport";
|
||||
public static final String PUBLIC_START_PORT = "publicport";
|
||||
public static final String PUBLIC_END_PORT = "publicendport";
|
||||
public static final String PUBLIC_ZONE = "publiczone";
|
||||
public static final String RECEIVED_BYTES = "receivedbytes";
|
||||
public static final String REQUIRES_HVM = "requireshvm";
|
||||
public static final String RESOURCE_TYPE = "resourcetype";
|
||||
public static final String RESPONSE = "response";
|
||||
public static final String QUERY_FILTER = "queryfilter";
|
||||
public static final String SCHEDULE = "schedule";
|
||||
public static final String SCOPE = "scope";
|
||||
public static final String SECRET_KEY = "usersecretkey";
|
||||
public static final String SINCE = "since";
|
||||
public static final String KEY = "key";
|
||||
public static final String SEARCH_BASE = "searchbase";
|
||||
public static final String SECURITY_GROUP_IDS = "securitygroupids";
|
||||
public static final String SECURITY_GROUP_NAMES = "securitygroupnames";
|
||||
public static final String SECURITY_GROUP_NAME = "securitygroupname";
|
||||
public static final String SECURITY_GROUP_ID = "securitygroupid";
|
||||
public static final String SENT = "sent";
|
||||
public static final String SENT_BYTES = "sentbytes";
|
||||
public static final String SERVICE_OFFERING_ID = "serviceofferingid";
|
||||
public static final String SHOW_CAPACITIES = "showcapacities";
|
||||
public static final String SIZE = "size";
|
||||
public static final String SNAPSHOT_ID = "snapshotid";
|
||||
public static final String SNAPSHOT_POLICY_ID = "snapshotpolicyid";
|
||||
public static final String SNAPSHOT_TYPE = "snapshottype";
|
||||
public static final String SOURCE_ZONE_ID = "sourcezoneid";
|
||||
public static final String START_DATE = "startdate";
|
||||
public static final String START_IP = "startip";
|
||||
public static final String START_IPV6 = "startipv6";
|
||||
public static final String START_PORT = "startport";
|
||||
public static final String STATE = "state";
|
||||
public static final String STATUS = "status";
|
||||
public static final String STORAGE_TYPE = "storagetype";
|
||||
public static final String SYSTEM_VM_TYPE = "systemvmtype";
|
||||
public static final String TAGS = "tags";
|
||||
public static final String TARGET_IQN = "targetiqn";
|
||||
public static final String TEMPLATE_FILTER = "templatefilter";
|
||||
public static final String TEMPLATE_ID = "templateid";
|
||||
public static final String ISO_ID = "isoid";
|
||||
public static final String TIMEOUT = "timeout";
|
||||
public static final String TIMEZONE = "timezone";
|
||||
public static final String TYPE = "type";
|
||||
public static final String TRUST_STORE = "truststore";
|
||||
public static final String TRUST_STORE_PASSWORD = "truststorepass";
|
||||
public static final String URL = "url";
|
||||
public static final String USAGE_INTERFACE = "usageinterface";
|
||||
public static final String USER_DATA = "userdata";
|
||||
public static final String USER_ID = "userid";
|
||||
public static final String USE_SSL = "ssl";
|
||||
public static final String USERNAME = "username";
|
||||
public static final String USER_SECURITY_GROUP_LIST = "usersecuritygrouplist";
|
||||
public static final String USE_VIRTUAL_NETWORK = "usevirtualnetwork";
|
||||
public static final String VALUE = "value";
|
||||
public static final String VIRTUAL_MACHINE_ID = "virtualmachineid";
|
||||
public static final String VIRTUAL_MACHINE_IDS = "virtualmachineids";
|
||||
public static final String VLAN = "vlan";
|
||||
public static final String VLAN_ID = "vlanid";
|
||||
public static final String VM_AVAILABLE = "vmavailable";
|
||||
public static final String VM_LIMIT = "vmlimit";
|
||||
public static final String VM_TOTAL = "vmtotal";
|
||||
public static final String VNET = "vnet";
|
||||
public static final String VOLUME_ID = "volumeid";
|
||||
public static final String ZONE_ID = "zoneid";
|
||||
public static final String ZONE_NAME = "zonename";
|
||||
public static final String NETWORK_TYPE = "networktype";
|
||||
public static final String PAGE = "page";
|
||||
public static final String PAGE_SIZE = "pagesize";
|
||||
public static final String COUNT = "count";
|
||||
public static final String TRAFFIC_TYPE = "traffictype";
|
||||
public static final String NETWORK_OFFERING_ID = "networkofferingid";
|
||||
public static final String NETWORK_IDS = "networkids";
|
||||
public static final String NETWORK_ID = "networkid";
|
||||
public static final String NIC_ID = "nicid";
|
||||
public static final String SPECIFY_VLAN = "specifyvlan";
|
||||
public static final String IS_DEFAULT = "isdefault";
|
||||
public static final String IS_SYSTEM = "issystem";
|
||||
public static final String AVAILABILITY = "availability";
|
||||
public static final String NETWORKRATE = "networkrate";
|
||||
public static final String HOST_TAGS = "hosttags";
|
||||
public static final String SSH_KEYPAIR = "keypair";
|
||||
public static final String HOST_CPU_CAPACITY = "hostcpucapacity";
|
||||
public static final String HOST_CPU_NUM = "hostcpunum";
|
||||
public static final String HOST_MEM_CAPACITY = "hostmemcapacity";
|
||||
public static final String HOST_MAC = "hostmac";
|
||||
public static final String HOST_TAG = "hosttag";
|
||||
public static final String PXE_SERVER_TYPE = "pxeservertype";
|
||||
public static final String LINMIN_USERNAME = "linminusername";
|
||||
public static final String LINMIN_PASSWORD = "linminpassword";
|
||||
public static final String LINMIN_APID = "linminapid";
|
||||
public static final String DHCP_SERVER_TYPE = "dhcpservertype";
|
||||
public static final String LINK_LOCAL_IP = "linklocalip";
|
||||
public static final String LINK_LOCAL_MAC_ADDRESS = "linklocalmacaddress";
|
||||
public static final String LINK_LOCAL_MAC_NETMASK = "linklocalnetmask";
|
||||
public static final String LINK_LOCAL_NETWORK_ID = "linklocalnetworkid";
|
||||
public static final String PRIVATE_MAC_ADDRESS = "privatemacaddress";
|
||||
public static final String PRIVATE_NETMASK = "privatenetmask";
|
||||
public static final String PRIVATE_NETWORK_ID = "privatenetworkid";
|
||||
public static final String ALLOCATION_STATE = "allocationstate";
|
||||
public static final String MANAGED_STATE = "managedstate";
|
||||
public static final String STORAGE_ID = "storageid";
|
||||
public static final String PING_STORAGE_SERVER_IP = "pingstorageserverip";
|
||||
public static final String PING_DIR = "pingdir";
|
||||
public static final String TFTP_DIR = "tftpdir";
|
||||
public static final String PING_CIFS_USERNAME = "pingcifsusername";
|
||||
public static final String PING_CIFS_PASSWORD = "pingcifspassword";
|
||||
public static final String CHECKSUM = "checksum";
|
||||
public static final String NETWORK_DEVICE_TYPE = "networkdevicetype";
|
||||
public static final String NETWORK_DEVICE_PARAMETER_LIST = "networkdeviceparameterlist";
|
||||
public static final String ZONE_TOKEN = "zonetoken";
|
||||
public static final String DHCP_PROVIDER = "dhcpprovider";
|
||||
public static final String RESULT = "success";
|
||||
public static final String LUN_ID = "lunId";
|
||||
public static final String IQN = "iqn";
|
||||
public static final String AGGREGATE_NAME = "aggregatename";
|
||||
public static final String POOL_NAME = "poolname";
|
||||
public static final String VOLUME_NAME = "volumename";
|
||||
public static final String SNAPSHOT_POLICY = "snapshotpolicy";
|
||||
public static final String SNAPSHOT_RESERVATION = "snapshotreservation";
|
||||
public static final String IP_NETWORK_LIST = "iptonetworklist";
|
||||
public static final String PARAM_LIST = "param";
|
||||
public static final String FOR_LOAD_BALANCING = "forloadbalancing";
|
||||
public static final String KEYBOARD = "keyboard";
|
||||
public static final String OPEN_FIREWALL = "openfirewall";
|
||||
public static final String TEMPLATE_TAG = "templatetag";
|
||||
public static final String HYPERVISOR_VERSION = "hypervisorversion";
|
||||
public static final String MAX_GUESTS_LIMIT = "maxguestslimit";
|
||||
public static final String PROJECT_ID = "projectid";
|
||||
public static final String PROJECT_IDS = "projectids";
|
||||
public static final String PROJECT = "project";
|
||||
public static final String ROLE = "role";
|
||||
public static final String USER = "user";
|
||||
public static final String ACTIVE_ONLY = "activeonly";
|
||||
public static final String TOKEN = "token";
|
||||
public static final String ACCEPT = "accept";
|
||||
public static final String SORT_KEY = "sortkey";
|
||||
public static final String ACCOUNT_DETAILS = "accountdetails";
|
||||
public static final String SERVICE_PROVIDER_LIST = "serviceproviderlist";
|
||||
public static final String SERVICE_CAPABILITY_LIST = "servicecapabilitylist";
|
||||
public static final String CAN_CHOOSE_SERVICE_CAPABILITY = "canchooseservicecapability";
|
||||
public static final String PROVIDER = "provider";
|
||||
public static final String NETWORK_SPEED = "networkspeed";
|
||||
public static final String BROADCAST_DOMAIN_RANGE = "broadcastdomainrange";
|
||||
public static final String ISOLATION_METHODS = "isolationmethods";
|
||||
public static final String PHYSICAL_NETWORK_ID = "physicalnetworkid";
|
||||
public static final String DEST_PHYSICAL_NETWORK_ID = "destinationphysicalnetworkid";
|
||||
public static final String ENABLED = "enabled";
|
||||
public static final String SERVICE_NAME = "servicename";
|
||||
public static final String DHCP_RANGE = "dhcprange";
|
||||
public static final String UUID = "uuid";
|
||||
public static final String SECURITY_GROUP_EANBLED = "securitygroupenabled";
|
||||
public static final String LOCAL_STORAGE_ENABLED = "localstorageenabled";
|
||||
public static final String GUEST_IP_TYPE = "guestiptype";
|
||||
public static final String XEN_NETWORK_LABEL = "xennetworklabel";
|
||||
public static final String KVM_NETWORK_LABEL = "kvmnetworklabel";
|
||||
public static final String VMWARE_NETWORK_LABEL = "vmwarenetworklabel";
|
||||
public static final String NETWORK_SERVICE_PROVIDER_ID = "nspid";
|
||||
public static final String SERVICE_LIST = "servicelist";
|
||||
public static final String CAN_ENABLE_INDIVIDUAL_SERVICE = "canenableindividualservice";
|
||||
public static final String SUPPORTED_SERVICES = "supportedservices";
|
||||
public static final String NSP_ID = "nspid";
|
||||
public static final String ACL_TYPE = "acltype";
|
||||
public static final String SUBDOMAIN_ACCESS = "subdomainaccess";
|
||||
public static final String LOAD_BALANCER_DEVICE_ID = "lbdeviceid";
|
||||
public static final String LOAD_BALANCER_DEVICE_NAME = "lbdevicename";
|
||||
public static final String LOAD_BALANCER_DEVICE_STATE = "lbdevicestate";
|
||||
public static final String LOAD_BALANCER_DEVICE_CAPACITY = "lbdevicecapacity";
|
||||
public static final String LOAD_BALANCER_DEVICE_DEDICATED = "lbdevicededicated";
|
||||
public static final String FIREWALL_DEVICE_ID = "fwdeviceid";
|
||||
public static final String FIREWALL_DEVICE_NAME = "fwdevicename";
|
||||
public static final String FIREWALL_DEVICE_STATE = "fwdevicestate";
|
||||
public static final String FIREWALL_DEVICE_CAPACITY = "fwdevicecapacity";
|
||||
public static final String FIREWALL_DEVICE_DEDICATED = "fwdevicededicated";
|
||||
public static final String SERVICE = "service";
|
||||
public static final String ASSOCIATED_NETWORK_ID = "associatednetworkid";
|
||||
public static final String ASSOCIATED_NETWORK_NAME = "associatednetworkname";
|
||||
public static final String SOURCE_NAT_SUPPORTED = "sourcenatsupported";
|
||||
public static final String RESOURCE_STATE = "resourcestate";
|
||||
public static final String PROJECT_INVITE_REQUIRED = "projectinviterequired";
|
||||
public static final String REQUIRED = "required";
|
||||
public static final String RESTART_REQUIRED = "restartrequired";
|
||||
public static final String ALLOW_USER_CREATE_PROJECTS = "allowusercreateprojects";
|
||||
public static final String CONSERVE_MODE = "conservemode";
|
||||
public static final String TRAFFIC_TYPE_IMPLEMENTOR = "traffictypeimplementor";
|
||||
public static final String KEYWORD = "keyword";
|
||||
public static final String LIST_ALL = "listall";
|
||||
public static final String SPECIFY_IP_RANGES = "specifyipranges";
|
||||
public static final String IS_SOURCE_NAT = "issourcenat";
|
||||
public static final String IS_STATIC_NAT = "isstaticnat";
|
||||
public static final String SORT_BY = "sortby";
|
||||
public static final String CHANGE_CIDR = "changecidr";
|
||||
public static final String PURPOSE = "purpose";
|
||||
public static final String IS_TAGGED = "istagged";
|
||||
public static final String INSTANCE_NAME = "instancename";
|
||||
public static final String START_VM = "startvm";
|
||||
public static final String HA_HOST = "hahost";
|
||||
public static final String CUSTOM_DISK_OFF_MAX_SIZE = "customdiskofferingmaxsize";
|
||||
public static final String DEFAULT_ZONE_ID = "defaultzoneid";
|
||||
public static final String GUID = "guid";
|
||||
|
||||
public static final String EXTERNAL_SWITCH_MGMT_DEVICE_ID = "vsmdeviceid";
|
||||
public static final String EXTERNAL_SWITCH_MGMT_DEVICE_NAME = "vsmdevicename";
|
||||
public static final String EXTERNAL_SWITCH_MGMT_DEVICE_STATE = "vsmdevicestate";
|
||||
// Would we need to have a capacity field for Cisco N1KV VSM? Max hosts managed by it perhaps? May remove this later.
|
||||
public static final String EXTERNAL_SWITCH_MGMT_DEVICE_CAPACITY = "vsmdevicecapacity";
|
||||
public static final String CISCO_NEXUS_VSM_NAME = "vsmname";
|
||||
public static final String VSM_USERNAME = "vsmusername";
|
||||
public static final String VSM_PASSWORD = "vsmpassword";
|
||||
public static final String VSM_IPADDRESS = "vsmipaddress";
|
||||
public static final String VSM_MGMT_VLAN_ID = "vsmmgmtvlanid";
|
||||
public static final String VSM_PKT_VLAN_ID = "vsmpktvlanid";
|
||||
public static final String VSM_CTRL_VLAN_ID = "vsmctrlvlanid";
|
||||
public static final String VSM_STORAGE_VLAN_ID = "vsmstoragevlanid";
|
||||
public static final String VSM_DOMAIN_ID = "vsmdomainid";
|
||||
public static final String VSM_CONFIG_MODE = "vsmconfigmode";
|
||||
public static final String VSM_CONFIG_STATE = "vsmconfigstate";
|
||||
public static final String VSM_DEVICE_STATE = "vsmdevicestate";
|
||||
public static final String ADD_VSM_FLAG = "addvsmflag";
|
||||
public static final String END_POINT = "endpoint";
|
||||
public static final String REGION_ID = "regionid";
|
||||
public static final String IS_PROPAGATE = "ispropagate";
|
||||
public static final String VPC_OFF_ID = "vpcofferingid";
|
||||
public static final String NETWORK = "network";
|
||||
public static final String VPC_ID = "vpcid";
|
||||
public static final String GATEWAY_ID = "gatewayid";
|
||||
public static final String CAN_USE_FOR_DEPLOY = "canusefordeploy";
|
||||
public static final String RESOURCE_IDS = "resourceids";
|
||||
public static final String RESOURCE_ID = "resourceid";
|
||||
public static final String CUSTOMER = "customer";
|
||||
public static final String S2S_VPN_GATEWAY_ID = "s2svpngatewayid";
|
||||
public static final String S2S_CUSTOMER_GATEWAY_ID = "s2scustomergatewayid";
|
||||
public static final String IPSEC_PSK = "ipsecpsk";
|
||||
public static final String GUEST_IP = "guestip";
|
||||
public static final String REMOVED = "removed";
|
||||
public static final String IKE_POLICY = "ikepolicy";
|
||||
public static final String ESP_POLICY = "esppolicy";
|
||||
public static final String IKE_LIFETIME = "ikelifetime";
|
||||
public static final String ESP_LIFETIME = "esplifetime";
|
||||
public static final String DPD = "dpd";
|
||||
public static final String FOR_VPC = "forvpc";
|
||||
public static final String SHRINK_OK = "shrinkok";
|
||||
public static final String NICIRA_NVP_DEVICE_ID = "nvpdeviceid";
|
||||
public static final String NICIRA_NVP_TRANSPORT_ZONE_UUID = "transportzoneuuid";
|
||||
public static final String NICIRA_NVP_DEVICE_NAME = "niciradevicename";
|
||||
public static final String NICIRA_NVP_GATEWAYSERVICE_UUID = "l3gatewayserviceuuid";
|
||||
public static final String S3_ACCESS_KEY = "accesskey";
|
||||
public static final String S3_SECRET_KEY = "secretkey";
|
||||
public static final String S3_END_POINT = "endpoint";
|
||||
public static final String S3_BUCKET_NAME = "bucket";
|
||||
public static final String S3_HTTPS_FLAG = "usehttps";
|
||||
public static final String S3_CONNECTION_TIMEOUT = "connectiontimeout";
|
||||
public static final String S3_MAX_ERROR_RETRY = "maxerrorretry";
|
||||
public static final String S3_SOCKET_TIMEOUT = "sockettimeout";
|
||||
public static final String INCL_ZONES = "includezones";
|
||||
public static final String EXCL_ZONES = "excludezones";
|
||||
public static final String SOURCE = "source";
|
||||
public static final String COUNTER_ID = "counterid";
|
||||
public static final String AGGR_OPERATOR = "aggroperator";
|
||||
public static final String AGGR_FUNCTION = "aggrfunction";
|
||||
public static final String AGGR_VALUE = "aggrvalue";
|
||||
public static final String THRESHOLD = "threshold";
|
||||
public static final String RELATIONAL_OPERATOR = "relationaloperator";
|
||||
public static final String OTHER_DEPLOY_PARAMS = "otherdeployparams";
|
||||
public static final String MIN_MEMBERS = "minmembers";
|
||||
public static final String MAX_MEMBERS = "maxmembers";
|
||||
public static final String AUTOSCALE_VM_DESTROY_TIME = "destroyvmgraceperiod";
|
||||
public static final String VMPROFILE_ID = "vmprofileid";
|
||||
public static final String VMGROUP_ID = "vmgroupid";
|
||||
public static final String CS_URL = "csurl";
|
||||
public static final String SCALEUP_POLICY_IDS = "scaleuppolicyids";
|
||||
public static final String SCALEDOWN_POLICY_IDS = "scaledownpolicyids";
|
||||
public static final String SCALEUP_POLICIES = "scaleuppolicies";
|
||||
public static final String SCALEDOWN_POLICIES = "scaledownpolicies";
|
||||
public static final String INTERVAL = "interval";
|
||||
public static final String QUIETTIME = "quiettime";
|
||||
public static final String ACTION = "action";
|
||||
public static final String CONDITION_ID = "conditionid";
|
||||
public static final String CONDITION_IDS = "conditionids";
|
||||
public static final String COUNTERPARAM_LIST = "counterparam";
|
||||
public static final String AUTOSCALE_USER_ID = "autoscaleuserid";
|
||||
public static final String BAREMETAL_DISCOVER_NAME = "baremetaldiscovername";
|
||||
<<<<<<< HEAD
|
||||
public static final String UCS_DN = "ucsdn";
|
||||
=======
|
||||
public static final String VM_SNAPSHOT_DESCRIPTION = "description";
|
||||
public static final String VM_SNAPSHOT_DISPLAYNAME = "name";
|
||||
public static final String VM_SNAPSHOT_ID = "vmsnapshotid";
|
||||
public static final String VM_SNAPSHOT_DISK_IDS = "vmsnapshotdiskids";
|
||||
public static final String VM_SNAPSHOT_MEMORY = "snapshotmemory";
|
||||
>>>>>>> CLOUDSTACK-684 Support VM Snapshot
|
||||
|
||||
public enum HostDetails {
|
||||
all, capacity, events, stats, min;
|
||||
}
|
||||
|
||||
public enum VMDetails {
|
||||
all, group, nics, stats, secgrp, tmpl, servoff, iso, volume, min;
|
||||
}
|
||||
|
||||
public enum LDAPParams {
|
||||
hostname, port, usessl, queryfilter, searchbase, dn, passwd, truststore, truststorepass;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ldap." + name();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -71,6 +71,7 @@ import com.cloud.user.ResourceLimitService;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.vm.BareMetalVmService;
|
||||
import com.cloud.vm.UserVmService;
|
||||
import com.cloud.vm.snapshot.VMSnapshotService;
|
||||
|
||||
public abstract class BaseCmd {
|
||||
private static final Logger s_logger = Logger.getLogger(BaseCmd.class.getName());
|
||||
@ -128,6 +129,7 @@ public abstract class BaseCmd {
|
||||
@Inject public QueryService _queryService;
|
||||
@Inject public UsageService _usageService;
|
||||
@Inject public NetworkUsageService _networkUsageService;
|
||||
@Inject public VMSnapshotService _vmSnapshotService;
|
||||
|
||||
public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException;
|
||||
|
||||
|
||||
@ -88,6 +88,7 @@ import org.apache.cloudstack.api.response.TrafficTypeResponse;
|
||||
import org.apache.cloudstack.api.response.UsageRecordResponse;
|
||||
import org.apache.cloudstack.api.response.UserResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.VMSnapshotResponse;
|
||||
import org.apache.cloudstack.api.response.VirtualRouterProviderResponse;
|
||||
import org.apache.cloudstack.api.response.VlanIpRangeResponse;
|
||||
import org.apache.cloudstack.api.response.VolumeResponse;
|
||||
@ -163,6 +164,7 @@ import com.cloud.user.UserAccount;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.vm.InstanceGroup;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
|
||||
public interface ResponseGenerator {
|
||||
UserResponse createUserResponse(UserAccount user);
|
||||
@ -381,5 +383,6 @@ public interface ResponseGenerator {
|
||||
|
||||
UsageRecordResponse createUsageResponse(Usage usageRecord);
|
||||
|
||||
TrafficMonitorResponse createTrafficMonitorResponse(Host trafficMonitor);
|
||||
TrafficMonitorResponse createTrafficMonitorResponse(Host trafficMonitor);
|
||||
VMSnapshotResponse createVMSnapshotResponse(VMSnapshot vmSnapshot);
|
||||
}
|
||||
|
||||
@ -53,12 +53,17 @@ public class UpdateResourceCountCmd extends BaseCmd {
|
||||
required=true, description="If account parameter specified then updates resource counts for a specified account in this domain else update resource counts for all accounts & child domains in specified domain.")
|
||||
private Long domainId;
|
||||
|
||||
@Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.INTEGER, description= "Type of resource to update. If specifies valid values are 0, 1, 2, 3, and 4. If not specified will update all resource counts" +
|
||||
@Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.INTEGER, description= "Type of resource to update. If specifies valid values are 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9. If not specified will update all resource counts" +
|
||||
"0 - Instance. Number of instances a user can create. " +
|
||||
"1 - IP. Number of public IP addresses a user can own. " +
|
||||
"2 - Volume. Number of disk volumes a user can create." +
|
||||
"3 - Snapshot. Number of snapshots a user can create." +
|
||||
"4 - Template. Number of templates that a user can register/create.")
|
||||
"4 - Template. Number of templates that a user can register/create." +
|
||||
"5 - Project. Number of projects that a user can create." +
|
||||
"6 - Network. Number of guest network a user can create." +
|
||||
"7 - VPC. Number of VPC a user can create." +
|
||||
"8 - CPU. Total number of CPU cores a user can use." +
|
||||
"9 - Memory. Total Memory (in MB) a user can use." )
|
||||
private Integer resourceType;
|
||||
|
||||
@Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.UUID, entityType = ProjectResponse.class,
|
||||
|
||||
@ -54,11 +54,15 @@ public class UpdateResourceLimitCmd extends BaseCmd {
|
||||
@Parameter(name=ApiConstants.MAX, type=CommandType.LONG, description=" Maximum resource limit.")
|
||||
private Long max;
|
||||
|
||||
@Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.INTEGER, required=true, description="Type of resource to update. Values are 0, 1, 2, 3, and 4. 0 - Instance. Number of instances a user can create. " +
|
||||
@Parameter(name=ApiConstants.RESOURCE_TYPE, type=CommandType.INTEGER, required=true, description="Type of resource to update. Values are 0, 1, 2, 3, 4, 6, 7, 8 and 9. 0 - Instance. Number of instances a user can create. " +
|
||||
"1 - IP. Number of public IP addresses a user can own. " +
|
||||
"2 - Volume. Number of disk volumes a user can create." +
|
||||
"3 - Snapshot. Number of snapshots a user can create." +
|
||||
"4 - Template. Number of templates that a user can register/create.")
|
||||
"4 - Template. Number of templates that a user can register/create." +
|
||||
"6 - Network. Number of guest network a user can create." +
|
||||
"7 - VPC. Number of VPC a user can create." +
|
||||
"8 - CPU. Total number of CPU cores a user can use." +
|
||||
"9 - Memory. Total Memory (in MB) a user can use." )
|
||||
private Integer resourceType;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@ -0,0 +1,125 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.api.command.user.vmsnapshot;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.VMSnapshotResponse;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
|
||||
@APICommand(name = "createVMSnapshot", description = "Creates snapshot for a vm.", responseObject = VMSnapshotResponse.class)
|
||||
public class CreateVMSnapshotCmd extends BaseAsyncCreateCmd {
|
||||
|
||||
public static final Logger s_logger = Logger
|
||||
.getLogger(CreateVMSnapshotCmd.class.getName());
|
||||
private static final String s_name = "createvmsnapshotresponse";
|
||||
|
||||
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.UUID, required = true, entityType=UserVmResponse.class, description = "The ID of the vm")
|
||||
private Long vmId;
|
||||
|
||||
@Parameter(name = ApiConstants.VM_SNAPSHOT_DESCRIPTION, type = CommandType.STRING, required = false, description = "The discription of the snapshot")
|
||||
private String description;
|
||||
|
||||
@Parameter(name = ApiConstants.VM_SNAPSHOT_DISPLAYNAME, type = CommandType.STRING, required = false, description = "The display name of the snapshot")
|
||||
private String displayName;
|
||||
|
||||
@Parameter(name = ApiConstants.VM_SNAPSHOT_MEMORY, type = CommandType.BOOLEAN, required = false, description = "snapshot memory if true")
|
||||
private Boolean snapshotMemory;
|
||||
|
||||
public Boolean snapshotMemory() {
|
||||
if (snapshotMemory == null) {
|
||||
return false;
|
||||
} else {
|
||||
return snapshotMemory;
|
||||
}
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() throws ResourceAllocationException {
|
||||
VMSnapshot vmsnapshot = _vmSnapshotService.allocVMSnapshot(getVmId(),getDisplayName(),getDescription(),snapshotMemory());
|
||||
if (vmsnapshot != null) {
|
||||
this.setEntityId(vmsnapshot.getId());
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR,
|
||||
"Failed to create vm snapshot");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "creating snapshot for VM: " + getVmId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_VM_SNAPSHOT_CREATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
UserContext.current().setEventDetails("VM Id: " + getVmId());
|
||||
VMSnapshot result = _vmSnapshotService.creatVMSnapshot(getVmId(),getEntityId());
|
||||
if (result != null) {
|
||||
VMSnapshotResponse response = _responseGenerator
|
||||
.createVMSnapshotResponse(result);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(
|
||||
ApiErrorCode.INTERNAL_ERROR,
|
||||
"Failed to create vm snapshot due to an internal error creating snapshot for vm "
|
||||
+ getVmId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
UserVm userVM = _userVmService.getUserVm(vmId);
|
||||
return userVM.getAccountId();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.api.command.user.vmsnapshot;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.VMSnapshotResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
|
||||
@APICommand(name="deleteVMSnapshot", description = "Deletes a vmsnapshot.", responseObject = SuccessResponse.class)
|
||||
public class DeleteVMSnapshotCmd extends BaseAsyncCmd {
|
||||
public static final Logger s_logger = Logger
|
||||
.getLogger(DeleteVMSnapshotCmd.class.getName());
|
||||
private static final String s_name = "deletevmsnapshotresponse";
|
||||
|
||||
@Parameter(name=ApiConstants.VM_SNAPSHOT_ID, type=CommandType.UUID, entityType=VMSnapshotResponse.class,
|
||||
required=true, description="The ID of the VM snapshot")
|
||||
private Long id;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
VMSnapshot vmSnapshot = _entityMgr.findById(VMSnapshot.class, getId());
|
||||
if (vmSnapshot != null) {
|
||||
return vmSnapshot.getAccountId();
|
||||
}
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
UserContext.current().setEventDetails("vmsnapshot id: " + getId());
|
||||
boolean result = _vmSnapshotService.deleteVMSnapshot(getId());
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete vm snapshot");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Delete VM snapshot: " + getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_VM_SNAPSHOT_DELETE;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,89 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.api.command.user.vmsnapshot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseListTaggedResourcesCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.VMSnapshotResponse;
|
||||
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
|
||||
@APICommand(name="listVMSnapshot", description = "List virtual machine snapshot by conditions", responseObject = VMSnapshotResponse.class)
|
||||
public class ListVMSnapshotCmd extends BaseListTaggedResourcesCmd {
|
||||
|
||||
private static final String s_name = "listvmsnapshotresponse";
|
||||
|
||||
@Parameter(name=ApiConstants.VM_SNAPSHOT_ID, type=CommandType.UUID, entityType=VMSnapshotResponse.class,
|
||||
description="The ID of the VM snapshot")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="state of the virtual machine snapshot")
|
||||
private String state;
|
||||
|
||||
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.UUID, entityType=UserVmResponse.class, description = "the ID of the vm")
|
||||
private Long vmId;
|
||||
|
||||
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "lists snapshot by snapshot name or display name")
|
||||
private String vmSnapshotName;
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public String getVmSnapshotName() {
|
||||
return vmSnapshotName;
|
||||
}
|
||||
|
||||
public Long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
List<? extends VMSnapshot> result = _vmSnapshotService
|
||||
.listVMSnapshots(this);
|
||||
ListResponse<VMSnapshotResponse> response = new ListResponse<VMSnapshotResponse>();
|
||||
List<VMSnapshotResponse> snapshotResponses = new ArrayList<VMSnapshotResponse>();
|
||||
for (VMSnapshot r : result) {
|
||||
VMSnapshotResponse vmSnapshotResponse = _responseGenerator
|
||||
.createVMSnapshotResponse(r);
|
||||
vmSnapshotResponse.setObjectName("vmSnapshot");
|
||||
snapshotResponses.add(vmSnapshotResponse);
|
||||
}
|
||||
response.setResponses(snapshotResponses);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.vmsnapshot;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.VMSnapshotResponse;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
|
||||
@APICommand(name = "revertToSnapshot",description = "Revert VM from a vmsnapshot.", responseObject = UserVmResponse.class)
|
||||
public class RevertToSnapshotCmd extends BaseAsyncCmd {
|
||||
public static final Logger s_logger = Logger
|
||||
.getLogger(RevertToSnapshotCmd.class.getName());
|
||||
private static final String s_name = "reverttosnapshotresponse";
|
||||
|
||||
@Parameter(name = ApiConstants.VM_SNAPSHOT_ID, type = CommandType.UUID, required = true,entityType=VMSnapshotResponse.class,description = "The ID of the vm snapshot")
|
||||
private Long vmSnapShotId;
|
||||
|
||||
public Long getVmSnapShotId() {
|
||||
return vmSnapShotId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
VMSnapshot vmSnapshot = _entityMgr.findById(VMSnapshot.class, getVmSnapShotId());
|
||||
if (vmSnapshot != null) {
|
||||
return vmSnapshot.getAccountId();
|
||||
}
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException, ConcurrentOperationException {
|
||||
UserContext.current().setEventDetails(
|
||||
"vmsnapshot id: " + getVmSnapShotId());
|
||||
UserVm result = _vmSnapshotService.revertToSnapshot(getVmSnapShotId());
|
||||
if (result != null) {
|
||||
UserVmResponse response = _responseGenerator.createUserVmResponse(
|
||||
"virtualmachine", result).get(0);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR,"Failed to revert VM snapshot");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Revert from VM snapshot: " + getVmSnapShotId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_VM_SNAPSHOT_REVERT;
|
||||
}
|
||||
|
||||
}
|
||||
@ -132,6 +132,24 @@ public class AccountResponse extends BaseResponse {
|
||||
@SerializedName("vpcavailable") @Param(description="the total number of vpcs available to be created for this account", since="4.0.0")
|
||||
private String vpcAvailable;
|
||||
|
||||
@SerializedName("cpulimit") @Param(description="the total number of cpu cores the account can own", since="4.1.0")
|
||||
private String cpuLimit;
|
||||
|
||||
@SerializedName("cputotal") @Param(description="the total number of cpu cores owned by account", since="4.1.0")
|
||||
private Long cpuTotal;
|
||||
|
||||
@SerializedName("cpuavailable") @Param(description="the total number of cpu cores available to be created for this account", since="4.1.0")
|
||||
private String cpuAvailable;
|
||||
|
||||
@SerializedName("memorylimit") @Param(description="the total memory (in MB) the account can own", since="4.1.0")
|
||||
private String memoryLimit;
|
||||
|
||||
@SerializedName("memorytotal") @Param(description="the total memory (in MB) owned by account", since="4.1.0")
|
||||
private Long memoryTotal;
|
||||
|
||||
@SerializedName("memoryavailable") @Param(description="the total memory (in MB) available to be created for this account", since="4.1.0")
|
||||
private String memoryAvailable;
|
||||
|
||||
|
||||
@SerializedName(ApiConstants.STATE) @Param(description="the state of the account")
|
||||
private String state;
|
||||
@ -294,6 +312,30 @@ public class AccountResponse extends BaseResponse {
|
||||
this.networkAvailable = networkAvailable;
|
||||
}
|
||||
|
||||
public void setCpuLimit(String cpuLimit) {
|
||||
this.cpuLimit = cpuLimit;
|
||||
}
|
||||
|
||||
public void setCpuTotal(Long cpuTotal) {
|
||||
this.cpuTotal = cpuTotal;
|
||||
}
|
||||
|
||||
public void setCpuAvailable(String cpuAvailable) {
|
||||
this.cpuAvailable = cpuAvailable;
|
||||
}
|
||||
|
||||
public void setMemoryLimit(String memoryLimit) {
|
||||
this.memoryLimit = memoryLimit;
|
||||
}
|
||||
|
||||
public void setMemoryTotal(Long memoryTotal) {
|
||||
this.memoryTotal = memoryTotal;
|
||||
}
|
||||
|
||||
public void setMemoryAvailable(String memoryAvailable) {
|
||||
this.memoryAvailable = memoryAvailable;
|
||||
}
|
||||
|
||||
public void setDefaultZone(String defaultZoneId) {
|
||||
this.defaultZoneId = defaultZoneId;
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ public class ResourceCountResponse extends BaseResponse implements ControlledEnt
|
||||
@SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name for which resource count's are updated")
|
||||
private String domainName;
|
||||
|
||||
@SerializedName(ApiConstants.RESOURCE_TYPE) @Param(description="resource type. Values include 0, 1, 2, 3, 4. See the resourceType parameter for more information on these values.")
|
||||
@SerializedName(ApiConstants.RESOURCE_TYPE) @Param(description="resource type. Values include 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. See the resourceType parameter for more information on these values.")
|
||||
private String resourceType;
|
||||
|
||||
@SerializedName("resourcecount") @Param(description="resource count")
|
||||
|
||||
@ -36,7 +36,7 @@ public class ResourceLimitResponse extends BaseResponse implements ControlledEnt
|
||||
@SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name of the resource limit")
|
||||
private String domainName;
|
||||
|
||||
@SerializedName(ApiConstants.RESOURCE_TYPE) @Param(description="resource type. Values include 0, 1, 2, 3, 4. See the resourceType parameter for more information on these values.")
|
||||
@SerializedName(ApiConstants.RESOURCE_TYPE) @Param(description="resource type. Values include 0, 1, 2, 3, 4, 6, 7, 8, 9. See the resourceType parameter for more information on these values.")
|
||||
private String resourceType;
|
||||
|
||||
@SerializedName("max") @Param(description="the maximum number of the resource. A -1 means the resource currently has no limit.")
|
||||
|
||||
@ -0,0 +1,220 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@EntityReference(value=VMSnapshot.class)
|
||||
public class VMSnapshotResponse extends BaseResponse implements ControlledEntityResponse{
|
||||
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "the ID of the vm snapshot")
|
||||
private String id;
|
||||
|
||||
@SerializedName(ApiConstants.NAME)
|
||||
@Param(description = "the name of the vm snapshot")
|
||||
private String name;
|
||||
|
||||
@SerializedName(ApiConstants.STATE)
|
||||
@Param(description = "the state of the vm snapshot")
|
||||
private VMSnapshot.State state;
|
||||
|
||||
@SerializedName(ApiConstants.DESCRIPTION)
|
||||
@Param(description = "the description of the vm snapshot")
|
||||
private String description;
|
||||
|
||||
@SerializedName(ApiConstants.DISPLAY_NAME)
|
||||
@Param(description = "the display name of the vm snapshot")
|
||||
private String displayName;
|
||||
|
||||
@SerializedName(ApiConstants.ZONE_ID)
|
||||
@Param(description = "the Zone ID of the vm snapshot")
|
||||
private String zoneId;
|
||||
|
||||
@SerializedName(ApiConstants.VIRTUAL_MACHINE_ID)
|
||||
@Param(description = "the vm ID of the vm snapshot")
|
||||
private String virtualMachineid;
|
||||
|
||||
@SerializedName("parent")
|
||||
@Param(description = "the parent ID of the vm snapshot")
|
||||
private String parent;
|
||||
|
||||
@SerializedName("parentName")
|
||||
@Param(description = "the parent displayName of the vm snapshot")
|
||||
private String parentName;
|
||||
|
||||
@SerializedName("current")
|
||||
@Param(description = "indiates if this is current snapshot")
|
||||
private Boolean current;
|
||||
|
||||
@SerializedName("type")
|
||||
@Param(description = "VM Snapshot type")
|
||||
private String type;
|
||||
|
||||
@SerializedName(ApiConstants.CREATED)
|
||||
@Param(description = "the create date of the vm snapshot")
|
||||
private Date created;
|
||||
|
||||
@SerializedName(ApiConstants.ACCOUNT)
|
||||
@Param(description = "the account associated with the disk volume")
|
||||
private String accountName;
|
||||
|
||||
@SerializedName(ApiConstants.PROJECT_ID) @Param(description="the project id of the vpn")
|
||||
private String projectId;
|
||||
|
||||
@SerializedName(ApiConstants.PROJECT) @Param(description="the project name of the vpn")
|
||||
private String projectName;
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN_ID)
|
||||
@Param(description = "the ID of the domain associated with the disk volume")
|
||||
private String domainId;
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN)
|
||||
@Param(description = "the domain associated with the disk volume")
|
||||
private String domainName;
|
||||
|
||||
@Override
|
||||
public String getObjectId() {
|
||||
return getId();
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public void setZoneId(String zoneId) {
|
||||
this.zoneId = zoneId;
|
||||
}
|
||||
|
||||
public String getVirtualMachineid() {
|
||||
return virtualMachineid;
|
||||
}
|
||||
|
||||
public void setVirtualMachineid(String virtualMachineid) {
|
||||
this.virtualMachineid = virtualMachineid;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setState(VMSnapshot.State state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public VMSnapshot.State getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public Boolean getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
public void setCurrent(Boolean current) {
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
public void setParentName(String parentName) {
|
||||
this.parentName = parentName;
|
||||
}
|
||||
|
||||
public String getParentName() {
|
||||
return parentName;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAccountName(String accountName) {
|
||||
this.accountName = accountName;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProjectId(String projectId) {
|
||||
this.projectId = projectId;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProjectName(String projectName) {
|
||||
this.projectName = projectName;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDomainId(String domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDomainName(String domainName) {
|
||||
this.domainName = domainName;
|
||||
|
||||
}
|
||||
}
|
||||
@ -707,12 +707,20 @@ public class EC2RestServlet extends HttpServlet {
|
||||
else break;
|
||||
|
||||
String[] fromPort = request.getParameterValues( "IpPermissions." + nCount + ".FromPort" );
|
||||
if ( null != fromPort && 0 < fromPort.length)
|
||||
perm.setFromPort( Integer.parseInt( fromPort[0]));
|
||||
if ( null != fromPort && 0 < fromPort.length ) {
|
||||
if ( protocol[0].equalsIgnoreCase("icmp") )
|
||||
perm.setIcmpType( fromPort[0] ) ;
|
||||
else
|
||||
perm.setFromPort( Integer.parseInt( fromPort[0]) );
|
||||
}
|
||||
|
||||
String[] toPort = request.getParameterValues( "IpPermissions." + nCount + ".ToPort" );
|
||||
if ( null != toPort && 0 < toPort.length)
|
||||
perm.setToPort( Integer.parseInt( toPort[0]));
|
||||
if ( null != toPort && 0 < toPort.length ) {
|
||||
if ( protocol[0].equalsIgnoreCase("icmp") )
|
||||
perm.setIcmpCode( toPort[0] );
|
||||
else
|
||||
perm.setToPort( Integer.parseInt( toPort[0]) );
|
||||
}
|
||||
|
||||
// -> list: IpPermissions.n.IpRanges.m.CidrIp
|
||||
mCount = 1;
|
||||
@ -780,12 +788,20 @@ public class EC2RestServlet extends HttpServlet {
|
||||
else break;
|
||||
|
||||
String[] fromPort = request.getParameterValues( "IpPermissions." + nCount + ".FromPort" );
|
||||
if ( null != fromPort && 0 < fromPort.length)
|
||||
perm.setFromPort( Integer.parseInt( fromPort[0]));
|
||||
if ( null != fromPort && 0 < fromPort.length ) {
|
||||
if ( protocol[0].equalsIgnoreCase("icmp") )
|
||||
perm.setIcmpType( fromPort[0] ) ;
|
||||
else
|
||||
perm.setFromPort( Integer.parseInt( fromPort[0]) );
|
||||
}
|
||||
|
||||
String[] toPort = request.getParameterValues( "IpPermissions." + nCount + ".ToPort" );
|
||||
if ( null != toPort && 0 < toPort.length)
|
||||
perm.setToPort( Integer.parseInt( toPort[0]));
|
||||
if ( null != toPort && 0 < toPort.length ) {
|
||||
if ( protocol[0].equalsIgnoreCase("icmp") )
|
||||
perm.setIcmpCode( toPort[0] );
|
||||
else
|
||||
perm.setToPort( Integer.parseInt( toPort[0]) );
|
||||
}
|
||||
|
||||
// -> list: IpPermissions.n.IpRanges.m.CidrIp
|
||||
int mCount = 1;
|
||||
@ -1142,14 +1158,26 @@ public class EC2RestServlet extends HttpServlet {
|
||||
else { response.sendError(530, "Missing ImageId parameter" ); return; }
|
||||
|
||||
String[] minCount = request.getParameterValues( "MinCount" );
|
||||
if ( null != minCount && 0 < minCount.length )
|
||||
EC2request.setMinCount( Integer.parseInt( minCount[0] ));
|
||||
else { response.sendError(530, "Missing MinCount parameter" ); return; }
|
||||
if ( minCount == null || minCount.length < 1) {
|
||||
response.sendError(530, "Missing MinCount parameter" );
|
||||
return;
|
||||
} else if ( Integer.parseInt(minCount[0]) < 1) {
|
||||
throw new EC2ServiceException(ClientError.InvalidParameterValue,
|
||||
"Value of parameter MinCount should be greater than 0");
|
||||
} else {
|
||||
EC2request.setMinCount( Integer.parseInt( minCount[0]) );
|
||||
}
|
||||
|
||||
String[] maxCount = request.getParameterValues( "MaxCount" );
|
||||
if ( null != maxCount && 0 < maxCount.length )
|
||||
EC2request.setMaxCount( Integer.parseInt( maxCount[0] ));
|
||||
else { response.sendError(530, "Missing MaxCount parameter" ); return; }
|
||||
if ( maxCount == null || maxCount.length < 1) {
|
||||
response.sendError(530, "Missing MaxCount parameter" );
|
||||
return;
|
||||
} else if ( Integer.parseInt(maxCount[0]) < 1) {
|
||||
throw new EC2ServiceException(ClientError.InvalidParameterValue,
|
||||
"Value of parameter MaxCount should be greater than 0");
|
||||
} else {
|
||||
EC2request.setMaxCount( Integer.parseInt( maxCount[0]) );
|
||||
}
|
||||
|
||||
String[] instanceType = request.getParameterValues( "InstanceType" );
|
||||
if ( null != instanceType && 0 < instanceType.length )
|
||||
@ -1169,6 +1197,11 @@ public class EC2RestServlet extends HttpServlet {
|
||||
EC2request.setKeyName(keyName[0]);
|
||||
}
|
||||
|
||||
String[] userData = request.getParameterValues("UserData");
|
||||
if ( userData != null) {
|
||||
EC2request.setUserData( userData[0]);
|
||||
}
|
||||
|
||||
Enumeration<?> names = request.getParameterNames();
|
||||
while( names.hasMoreElements()) {
|
||||
String key = (String)names.nextElement();
|
||||
@ -1252,6 +1285,11 @@ public class EC2RestServlet extends HttpServlet {
|
||||
}
|
||||
if (0 == count) { response.sendError(530, "Missing InstanceId parameter" ); return; }
|
||||
|
||||
String[] force = request.getParameterValues("Force");
|
||||
if ( force != null) {
|
||||
EC2request.setForce( Boolean.parseBoolean(force[0]));
|
||||
}
|
||||
|
||||
// -> execute the request
|
||||
StopInstancesResponse EC2response = EC2SoapServiceImpl.toStopInstancesResponse( ServiceProvider.getInstance().getEC2Engine().stopInstances( EC2request ));
|
||||
serializeResponse(response, EC2response);
|
||||
@ -1894,10 +1932,14 @@ public class EC2RestServlet extends HttpServlet {
|
||||
String paramName = (String) params.nextElement();
|
||||
// exclude the signature string obviously. ;)
|
||||
if (paramName.equalsIgnoreCase("Signature")) continue;
|
||||
// URLEncoder performs application/x-www-form-urlencoded-type encoding and not Percent encoding
|
||||
// according to RFC 3986 as required by Amazon, we need to Percent-encode (URL Encode)
|
||||
String encodedValue = URLEncoder.encode(request.getParameter(paramName), "UTF-8")
|
||||
.replace("+", "%20").replace("*", "%2A");
|
||||
if (queryString == null)
|
||||
queryString = paramName + "=" + URLEncoder.encode(request.getParameter(paramName), "UTF-8");
|
||||
queryString = paramName + "=" + encodedValue;
|
||||
else
|
||||
queryString = queryString + "&" + paramName + "=" + URLEncoder.encode(request.getParameter(paramName), "UTF-8");
|
||||
queryString = queryString + "&" + paramName + "=" + encodedValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,6 +41,7 @@ import com.cloud.bridge.service.core.ec2.EC2DescribeAvailabilityZones;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DescribeAvailabilityZonesResponse;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DescribeImageAttribute;
|
||||
|
||||
import com.cloud.bridge.service.core.ec2.EC2AvailabilityZone;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DescribeImages;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DescribeImagesResponse;
|
||||
import com.cloud.bridge.service.core.ec2.EC2DescribeInstances;
|
||||
@ -730,8 +731,17 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
||||
EC2RunInstances request = new EC2RunInstances();
|
||||
|
||||
request.setTemplateId(rit.getImageId());
|
||||
request.setMinCount(rit.getMinCount());
|
||||
request.setMaxCount(rit.getMaxCount());
|
||||
|
||||
if (rit.getMinCount() < 1) {
|
||||
throw new EC2ServiceException(ClientError.InvalidParameterValue,
|
||||
"Value of parameter MinCount should be greater than 0");
|
||||
} else request.setMinCount( rit.getMinCount() );
|
||||
|
||||
if (rit.getMaxCount() < 1) {
|
||||
throw new EC2ServiceException(ClientError.InvalidParameterValue,
|
||||
"Value of parameter MaxCount should be greater than 0");
|
||||
} else request.setMaxCount(rit.getMaxCount());
|
||||
|
||||
if (null != type) request.setInstanceType(type);
|
||||
if (null != prt) request.setZoneName(prt.getAvailabilityZone());
|
||||
if (null != userData) request.setUserData(userData.getData());
|
||||
@ -763,6 +773,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
||||
public StopInstancesResponse stopInstances(StopInstances stopInstances) {
|
||||
EC2StopInstances request = new EC2StopInstances();
|
||||
StopInstancesType sit = stopInstances.getStopInstances();
|
||||
Boolean force = sit.getForce();
|
||||
|
||||
// -> toEC2StopInstances
|
||||
InstanceIdSetType iist = sit.getInstancesSet();
|
||||
@ -770,6 +781,8 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
||||
if (null != items) { // -> should not be empty
|
||||
for( int i=0; i < items.length; i++ ) request.addInstanceId( items[i].getInstanceId());
|
||||
}
|
||||
|
||||
if (force) request.setForce(sit.getForce());
|
||||
return toStopInstancesResponse( engine.stopInstances( request ));
|
||||
}
|
||||
|
||||
@ -1289,7 +1302,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
||||
param5.setInstanceId(vol.getInstanceId().toString());
|
||||
String devicePath = engine.cloudDeviceIdToDevicePath( vol.getHypervisor(), vol.getDeviceId());
|
||||
param5.setDevice( devicePath );
|
||||
param5.setStatus( toVolumeAttachmentState( vol.getInstanceId(), vol.getVMState()));
|
||||
param5.setStatus(vol.getAttachmentState());
|
||||
if (vol.getAttached() == null) {
|
||||
param5.setAttachTime( cal );
|
||||
} else {
|
||||
@ -1545,25 +1558,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
||||
else if (cloudState.equalsIgnoreCase( "Expunging" )) return new String( "terminated");
|
||||
else return new String( "running" );
|
||||
}
|
||||
|
||||
/**
|
||||
* We assume a state for the volume based on what its associated VM is doing.
|
||||
*
|
||||
* @param vmId
|
||||
* @param vmState
|
||||
* @return
|
||||
*/
|
||||
public static String toVolumeAttachmentState(String instanceId, String vmState ) {
|
||||
if (null == instanceId || null == vmState) return "detached";
|
||||
|
||||
if (vmState.equalsIgnoreCase( "Destroyed" )) return "detached";
|
||||
else if (vmState.equalsIgnoreCase( "Stopped" )) return "attached";
|
||||
else if (vmState.equalsIgnoreCase( "Running" )) return "attached";
|
||||
else if (vmState.equalsIgnoreCase( "Starting" )) return "attaching";
|
||||
else if (vmState.equalsIgnoreCase( "Stopping" )) return "attached";
|
||||
else if (vmState.equalsIgnoreCase( "Error" )) return "detached";
|
||||
else return "detached";
|
||||
}
|
||||
|
||||
|
||||
public static StopInstancesResponse toStopInstancesResponse(EC2StopInstancesResponse engineResponse) {
|
||||
StopInstancesResponse response = new StopInstancesResponse();
|
||||
@ -1775,14 +1770,18 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
||||
DescribeAvailabilityZonesResponse response = new DescribeAvailabilityZonesResponse();
|
||||
DescribeAvailabilityZonesResponseType param1 = new DescribeAvailabilityZonesResponseType();
|
||||
AvailabilityZoneSetType param2 = new AvailabilityZoneSetType();
|
||||
|
||||
String[] zones = engineResponse.getZoneSet();
|
||||
for (String zone : zones) {
|
||||
|
||||
EC2AvailabilityZone[] zones = engineResponse.getAvailabilityZoneSet();
|
||||
for (EC2AvailabilityZone zone : zones) {
|
||||
AvailabilityZoneItemType param3 = new AvailabilityZoneItemType();
|
||||
AvailabilityZoneMessageSetType param4 = new AvailabilityZoneMessageSetType();
|
||||
param3.setZoneName( zone );
|
||||
param3.setZoneName( zone.getName() );
|
||||
param3.setZoneState( "available" );
|
||||
param3.setRegionName( "" );
|
||||
|
||||
AvailabilityZoneMessageSetType param4 = new AvailabilityZoneMessageSetType();
|
||||
AvailabilityZoneMessageType param5 = new AvailabilityZoneMessageType();
|
||||
param5.setMessage(zone.getMessage());
|
||||
param4.addItem(param5);
|
||||
param3.setMessageSet( param4 );
|
||||
param2.addItem( param3 );
|
||||
}
|
||||
@ -1803,10 +1802,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
||||
param1.setVolumeId( engineResponse.getId().toString());
|
||||
param1.setInstanceId( engineResponse.getInstanceId().toString());
|
||||
param1.setDevice( engineResponse.getDevice());
|
||||
if ( null != engineResponse.getState())
|
||||
param1.setStatus( engineResponse.getState());
|
||||
else param1.setStatus( "" ); // ToDo - throw an Soap Fault
|
||||
|
||||
param1.setStatus(engineResponse.getAttachmentState());
|
||||
param1.setAttachTime( cal );
|
||||
|
||||
param1.setRequestId( UUID.randomUUID().toString());
|
||||
@ -1823,10 +1819,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface {
|
||||
param1.setVolumeId( engineResponse.getId().toString());
|
||||
param1.setInstanceId( (null == engineResponse.getInstanceId() ? "" : engineResponse.getInstanceId().toString()));
|
||||
param1.setDevice( (null == engineResponse.getDevice() ? "" : engineResponse.getDevice()));
|
||||
if ( null != engineResponse.getState())
|
||||
param1.setStatus( engineResponse.getState());
|
||||
else param1.setStatus( "" ); // ToDo - throw an Soap Fault
|
||||
|
||||
param1.setStatus(engineResponse.getAttachmentState());
|
||||
param1.setAttachTime( cal );
|
||||
|
||||
param1.setRequestId( UUID.randomUUID().toString());
|
||||
|
||||
@ -0,0 +1,55 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.bridge.service.core.ec2;
|
||||
|
||||
public class EC2AvailabilityZone {
|
||||
|
||||
private String id;
|
||||
private String name;
|
||||
private String message;
|
||||
|
||||
public EC2AvailabilityZone() {
|
||||
id = null;
|
||||
name = null;
|
||||
message = null;
|
||||
}
|
||||
|
||||
public void setId( String id ) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setName( String name ) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setMessage( String message ) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
}
|
||||
@ -36,6 +36,7 @@ public class EC2AvailabilityZonesFilterSet {
|
||||
public EC2AvailabilityZonesFilterSet() {
|
||||
// -> use these values to check that the proper filter is passed to this type of filter set
|
||||
filterTypes.put( "zone-name", "String" );
|
||||
filterTypes.put( "message", "String");
|
||||
}
|
||||
|
||||
public void addFilter( EC2Filter param ) {
|
||||
@ -55,13 +56,14 @@ public class EC2AvailabilityZonesFilterSet {
|
||||
return filterSet.toArray(new EC2Filter[0]);
|
||||
}
|
||||
|
||||
public List<String> evaluate( EC2DescribeAvailabilityZonesResponse availabilityZones) throws ParseException {
|
||||
List<String> resultList = new ArrayList<String>();
|
||||
public EC2DescribeAvailabilityZonesResponse evaluate( EC2DescribeAvailabilityZonesResponse availabilityZones)
|
||||
throws ParseException {
|
||||
EC2DescribeAvailabilityZonesResponse resultList = new EC2DescribeAvailabilityZonesResponse();
|
||||
|
||||
boolean matched;
|
||||
|
||||
EC2Filter[] filterSet = getFilterSet();
|
||||
for ( String availableZone : availabilityZones.getZoneSet() ) {
|
||||
for ( EC2AvailabilityZone availableZone : availabilityZones.getAvailabilityZoneSet() ) {
|
||||
matched = true;
|
||||
if (filterSet != null) {
|
||||
for (EC2Filter filter : filterSet) {
|
||||
@ -71,19 +73,22 @@ public class EC2AvailabilityZonesFilterSet {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matched == true)
|
||||
resultList.add(availableZone);
|
||||
if (matched)
|
||||
resultList.addAvailabilityZone(availableZone);
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
private boolean filterMatched( String availableZone, EC2Filter filter ) throws ParseException {
|
||||
private boolean filterMatched( EC2AvailabilityZone availableZone, EC2Filter filter ) throws ParseException {
|
||||
String filterName = filter.getName();
|
||||
String[] valueSet = filter.getValueSet();
|
||||
|
||||
if ( filterName.equalsIgnoreCase("zone-name")) {
|
||||
return containsString(availableZone, valueSet);
|
||||
}
|
||||
return containsString(availableZone.getName(), valueSet);
|
||||
}
|
||||
else if (filterName.equalsIgnoreCase("message")) {
|
||||
return containsString(availableZone.getMessage(), valueSet);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -20,31 +20,17 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class EC2DescribeAvailabilityZonesResponse {
|
||||
private List<EC2AvailabilityZone> availabilityZoneSet = new ArrayList<EC2AvailabilityZone>();
|
||||
|
||||
private List<String> zoneIds = new ArrayList<String>();
|
||||
private List<String> zoneNames = new ArrayList<String>();
|
||||
public EC2DescribeAvailabilityZonesResponse() {
|
||||
}
|
||||
|
||||
public void addAvailabilityZone( EC2AvailabilityZone param ) {
|
||||
availabilityZoneSet.add( param );
|
||||
}
|
||||
|
||||
public EC2AvailabilityZone[] getAvailabilityZoneSet() {
|
||||
return availabilityZoneSet.toArray(new EC2AvailabilityZone[0]);
|
||||
}
|
||||
|
||||
public EC2DescribeAvailabilityZonesResponse() {
|
||||
}
|
||||
|
||||
public void addZone(String id, String name) {
|
||||
zoneIds.add(id);
|
||||
zoneNames.add(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* The Amazon API only cares about the names of zones not their ID value.
|
||||
*
|
||||
* @return an array containing a set of zone names
|
||||
*/
|
||||
public String[] getZoneSet() {
|
||||
return zoneNames.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public String getZoneIdAt(int index) {
|
||||
if (zoneIds.isEmpty() || index >= zoneIds.size()) {
|
||||
return null;
|
||||
}
|
||||
return zoneIds.get(index);
|
||||
}
|
||||
}
|
||||
|
||||
@ -767,7 +767,10 @@ public class EC2Engine extends ManagerBase {
|
||||
*/
|
||||
public boolean releaseAddress(EC2ReleaseAddress request) {
|
||||
try {
|
||||
CloudStackIpAddress cloudIp = getApi().listPublicIpAddresses(null, null, null, null, null, request.getPublicIp(), null, null, null).get(0);
|
||||
List<CloudStackIpAddress> cloudIps = getApi().listPublicIpAddresses(null, null, null, null, null, request.getPublicIp(), null, null, null);
|
||||
if (cloudIps == null)
|
||||
throw new EC2ServiceException(ServerError.InternalError, "Specified ipAddress doesn't exist");
|
||||
CloudStackIpAddress cloudIp = cloudIps.get(0);
|
||||
CloudStackInfoResponse resp = getApi().disassociateIpAddress(cloudIp.getId());
|
||||
if (resp != null) {
|
||||
return resp.getSuccess();
|
||||
@ -787,8 +790,17 @@ public class EC2Engine extends ManagerBase {
|
||||
*/
|
||||
public boolean associateAddress( EC2AssociateAddress request ) {
|
||||
try {
|
||||
CloudStackIpAddress cloudIp = getApi().listPublicIpAddresses(null, null, null, null, null, request.getPublicIp(), null, null, null).get(0);
|
||||
CloudStackUserVm cloudVm = getApi().listVirtualMachines(null, null, true, null, null, null, null, request.getInstanceId(), null, null, null, null, null, null, null, null, null).get(0);
|
||||
List<CloudStackIpAddress> cloudIps = getApi().listPublicIpAddresses(null, null, null, null, null, request.getPublicIp(), null, null, null);
|
||||
if (cloudIps == null)
|
||||
throw new EC2ServiceException(ServerError.InternalError, "Specified ipAddress doesn't exist");
|
||||
CloudStackIpAddress cloudIp = cloudIps.get(0);
|
||||
|
||||
List<CloudStackUserVm> vmList = getApi().listVirtualMachines(null, null, true, null, null, null, null,
|
||||
request.getInstanceId(), null, null, null, null, null, null, null, null, null);
|
||||
if (vmList == null || vmList.size() == 0) {
|
||||
throw new EC2ServiceException(ServerError.InternalError, "Specified instance-id doesn't exist");
|
||||
}
|
||||
CloudStackUserVm cloudVm = vmList.get(0);
|
||||
|
||||
CloudStackInfoResponse resp = getApi().enableStaticNat(cloudIp.getId(), cloudVm.getId());
|
||||
if (resp != null) {
|
||||
@ -809,7 +821,11 @@ public class EC2Engine extends ManagerBase {
|
||||
*/
|
||||
public boolean disassociateAddress( EC2DisassociateAddress request ) {
|
||||
try {
|
||||
CloudStackIpAddress cloudIp = getApi().listPublicIpAddresses(null, null, null, null, null, request.getPublicIp(), null, null, null).get(0);
|
||||
List<CloudStackIpAddress> cloudIps = getApi().listPublicIpAddresses(null, null, null, null, null, request.getPublicIp(), null, null, null);
|
||||
if (cloudIps == null)
|
||||
throw new EC2ServiceException(ServerError.InternalError, "Specified ipAddress doesn't exist");
|
||||
CloudStackIpAddress cloudIp = cloudIps.get(0);
|
||||
|
||||
CloudStackInfoResponse resp = getApi().disableStaticNat(cloudIp.getId());
|
||||
if (resp != null) {
|
||||
return resp.getSuccess();
|
||||
@ -1044,12 +1060,8 @@ public class EC2Engine extends ManagerBase {
|
||||
EC2AvailabilityZonesFilterSet azfs = request.getFilterSet();
|
||||
if ( null == azfs )
|
||||
return availableZones;
|
||||
else {
|
||||
List<String> matchedAvailableZones = azfs.evaluate(availableZones);
|
||||
if (matchedAvailableZones.isEmpty())
|
||||
return new EC2DescribeAvailabilityZonesResponse();
|
||||
return listZones(matchedAvailableZones.toArray(new String[0]), null);
|
||||
}
|
||||
else
|
||||
return azfs.evaluate(availableZones);
|
||||
} catch( EC2ServiceException error ) {
|
||||
logger.error( "EC2 DescribeAvailabilityZones - ", error);
|
||||
throw error;
|
||||
@ -1113,6 +1125,7 @@ public class EC2Engine extends ManagerBase {
|
||||
resp.setState(vol.getState());
|
||||
resp.setType(vol.getVolumeType());
|
||||
resp.setVMState(vol.getVirtualMachineState());
|
||||
resp.setAttachmentState(mapToAmazonVolumeAttachmentState(vol.getVirtualMachineState()));
|
||||
resp.setZoneName(vol.getZoneName());
|
||||
return resp;
|
||||
}
|
||||
@ -1199,6 +1212,7 @@ public class EC2Engine extends ManagerBase {
|
||||
resp.setState(vol.getState());
|
||||
resp.setType(vol.getVolumeType());
|
||||
resp.setVMState(vol.getVirtualMachineState());
|
||||
resp.setAttachmentState("detached");
|
||||
resp.setZoneName(vol.getZoneName());
|
||||
return resp;
|
||||
}
|
||||
@ -1498,6 +1512,7 @@ public class EC2Engine extends ManagerBase {
|
||||
// -> first determine the current state of each VM (becomes it previous state)
|
||||
try {
|
||||
String[] instanceSet = request.getInstancesSet();
|
||||
Boolean forced = request.getForce();
|
||||
|
||||
EC2DescribeInstancesResponse previousState = listVirtualMachines( instanceSet, null, null );
|
||||
virtualMachines = previousState.getInstanceSet();
|
||||
@ -1519,7 +1534,7 @@ public class EC2Engine extends ManagerBase {
|
||||
instances.addInstance(vm);
|
||||
continue;
|
||||
}
|
||||
resp = getApi().stopVirtualMachine(vm.getId(), false);
|
||||
resp = getApi().stopVirtualMachine(vm.getId(), forced);
|
||||
if(logger.isDebugEnabled())
|
||||
logger.debug("Stopping VM " + vm.getId() + " job " + resp.getJobId());
|
||||
}
|
||||
@ -1627,11 +1642,16 @@ public class EC2Engine extends ManagerBase {
|
||||
ec2Vol.setSize(vol.getSize());
|
||||
ec2Vol.setType(vol.getVolumeType());
|
||||
|
||||
if(vol.getVirtualMachineId() != null)
|
||||
if(vol.getVirtualMachineId() != null) {
|
||||
ec2Vol.setInstanceId(vol.getVirtualMachineId());
|
||||
if (vol.getVirtualMachineState() != null) {
|
||||
ec2Vol.setVMState(vol.getVirtualMachineState());
|
||||
ec2Vol.setAttachmentState(mapToAmazonVolumeAttachmentState(vol.getVirtualMachineState()));
|
||||
}
|
||||
} else {
|
||||
ec2Vol.setAttachmentState("detached");
|
||||
}
|
||||
|
||||
if(vol.getVirtualMachineState() != null)
|
||||
ec2Vol.setVMState(vol.getVirtualMachineState());
|
||||
ec2Vol.setZoneName(vol.getZoneName());
|
||||
|
||||
List<CloudStackKeyValue> resourceTags = vol.getTags();
|
||||
@ -1675,9 +1695,11 @@ public class EC2Engine extends ManagerBase {
|
||||
|
||||
zones = listZones(interestedZones, domainId);
|
||||
|
||||
if (zones == null || zones.getZoneIdAt( 0 ) == null)
|
||||
if (zones == null || zones.getAvailabilityZoneSet().length == 0)
|
||||
throw new EC2ServiceException(ClientError.InvalidParameterValue, "Unknown zoneName value - " + zoneName);
|
||||
return zones.getZoneIdAt(0);
|
||||
|
||||
EC2AvailabilityZone[] zoneSet = zones.getAvailabilityZoneSet();
|
||||
return zoneSet[0].getId();
|
||||
}
|
||||
|
||||
|
||||
@ -1752,24 +1774,31 @@ public class EC2Engine extends ManagerBase {
|
||||
*
|
||||
* @return EC2DescribeAvailabilityZonesResponse
|
||||
*/
|
||||
private EC2DescribeAvailabilityZonesResponse listZones(String[] interestedZones, String domainId) throws Exception
|
||||
{
|
||||
private EC2DescribeAvailabilityZonesResponse listZones(String[] interestedZones, String domainId)
|
||||
throws Exception {
|
||||
EC2DescribeAvailabilityZonesResponse zones = new EC2DescribeAvailabilityZonesResponse();
|
||||
|
||||
List<CloudStackZone> cloudZones = getApi().listZones(true, domainId, null, null);
|
||||
|
||||
if(cloudZones != null) {
|
||||
if(cloudZones != null && cloudZones.size() > 0) {
|
||||
for(CloudStackZone cloudZone : cloudZones) {
|
||||
if ( null != interestedZones && 0 < interestedZones.length ) {
|
||||
for( int j=0; j < interestedZones.length; j++ ) {
|
||||
if (interestedZones[j].equalsIgnoreCase( cloudZone.getName())) {
|
||||
zones.addZone(cloudZone.getId().toString(), cloudZone.getName());
|
||||
boolean matched = false;
|
||||
if (interestedZones.length > 0) {
|
||||
for (String zoneName : interestedZones){
|
||||
if (zoneName.equalsIgnoreCase( cloudZone.getName())) {
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
zones.addZone(cloudZone.getId().toString(), cloudZone.getName());
|
||||
} else {
|
||||
matched = true;
|
||||
}
|
||||
if (!matched) continue;
|
||||
EC2AvailabilityZone ec2Zone = new EC2AvailabilityZone();
|
||||
ec2Zone.setId(cloudZone.getId().toString());
|
||||
ec2Zone.setMessage(cloudZone.getAllocationState());
|
||||
ec2Zone.setName(cloudZone.getName());
|
||||
|
||||
zones.addAvailabilityZone(ec2Zone);
|
||||
}
|
||||
}
|
||||
return zones;
|
||||
@ -1936,7 +1965,7 @@ public class EC2Engine extends ManagerBase {
|
||||
* @throws ParserConfigurationException
|
||||
* @throws ParseException
|
||||
*/
|
||||
public EC2DescribeSecurityGroupsResponse listSecurityGroups( String[] interestedGroups ) throws Exception {
|
||||
private EC2DescribeSecurityGroupsResponse listSecurityGroups( String[] interestedGroups ) throws Exception {
|
||||
try {
|
||||
EC2DescribeSecurityGroupsResponse groupSet = new EC2DescribeSecurityGroupsResponse();
|
||||
|
||||
@ -2383,6 +2412,25 @@ public class EC2Engine extends ManagerBase {
|
||||
return "error";
|
||||
}
|
||||
|
||||
/**
|
||||
* Map CloudStack VM state to Amazon volume attachment state
|
||||
*
|
||||
* @param CloudStack VM state
|
||||
* @return Amazon Volume attachment state
|
||||
*/
|
||||
private String mapToAmazonVolumeAttachmentState (String vmState) {
|
||||
if ( vmState.equalsIgnoreCase("Running") || vmState.equalsIgnoreCase("Stopping") ||
|
||||
vmState.equalsIgnoreCase("Stopped") ) {
|
||||
return "attached";
|
||||
}
|
||||
else if (vmState.equalsIgnoreCase("Starting")) {
|
||||
return "attaching";
|
||||
}
|
||||
else { // VM state is 'destroyed' or 'error' or other
|
||||
return "detached";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map Amazon resourceType to CloudStack resourceType
|
||||
*
|
||||
|
||||
@ -41,6 +41,8 @@ public class EC2GroupFilterSet {
|
||||
filterTypes.put( "ip-permission.from-port", "string" );
|
||||
filterTypes.put( "ip-permission.to-port", "string" );
|
||||
filterTypes.put( "ip-permission.protocol", "string" );
|
||||
filterTypes.put( "ip-permission.group-name","string" );
|
||||
filterTypes.put( "ip-permission.user-id", "string" );
|
||||
filterTypes.put( "owner-id", "string" );
|
||||
}
|
||||
|
||||
@ -126,7 +128,7 @@ public class EC2GroupFilterSet {
|
||||
EC2IpPermission[] permissionSet = sg.getIpPermissionSet();
|
||||
|
||||
for (EC2IpPermission perm : permissionSet) {
|
||||
boolean matched = true;
|
||||
boolean matched = false;
|
||||
for (EC2Filter filter : ipPermissionFilterSet) {
|
||||
String filterName = filter.getName();
|
||||
String[] valueSet = filter.getValueSet();
|
||||
@ -144,6 +146,24 @@ public class EC2GroupFilterSet {
|
||||
matched = containsString( perm.getToPort().toString(), valueSet );
|
||||
} else if (filterName.equalsIgnoreCase( "ip-permission.protocol" ))
|
||||
matched = containsString( perm.getProtocol(), valueSet );
|
||||
else if (filterName.equalsIgnoreCase( "ip-permission.group-name" )) {
|
||||
EC2SecurityGroup[] userSet = perm.getUserSet();
|
||||
for (EC2SecurityGroup user : userSet) {
|
||||
if (containsString(user.getName(), valueSet)) {
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (filterName.equalsIgnoreCase( "ip-permission.user-id" )){
|
||||
EC2SecurityGroup[] userSet = perm.getUserSet();
|
||||
for (EC2SecurityGroup user : userSet) {
|
||||
if (containsString(user.getAccountName(), valueSet)) {
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!matched) break;
|
||||
}
|
||||
if (matched) return true;
|
||||
|
||||
@ -23,6 +23,7 @@ public class EC2StopInstances {
|
||||
|
||||
private List<String> instancesSet = new ArrayList<String>(); // a list of strings identifying instances
|
||||
private boolean destroyInstances; // we are destroying the instances rather than stopping them
|
||||
private Boolean force = false;
|
||||
|
||||
public EC2StopInstances() {
|
||||
destroyInstances = false;
|
||||
@ -43,5 +44,13 @@ public class EC2StopInstances {
|
||||
public boolean getDestroyInstances() {
|
||||
return this.destroyInstances;
|
||||
}
|
||||
|
||||
public void setForce( Boolean force ) {
|
||||
this.force = force;
|
||||
}
|
||||
|
||||
public Boolean getForce() {
|
||||
return this.force;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -35,6 +35,7 @@ public class EC2Volume {
|
||||
private String hypervisor;
|
||||
private String created;
|
||||
private String attached;
|
||||
private String attachmentState;
|
||||
private List<EC2TagKeyValue> tagsSet;
|
||||
|
||||
public EC2Volume() {
|
||||
@ -50,6 +51,7 @@ public class EC2Volume {
|
||||
hypervisor = null;
|
||||
created = null;
|
||||
attached = null;
|
||||
attachmentState = null;
|
||||
tagsSet = new ArrayList<EC2TagKeyValue>();
|
||||
}
|
||||
|
||||
@ -236,6 +238,20 @@ public class EC2Volume {
|
||||
this.attached = attached;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param state of the attached VM to set
|
||||
*/
|
||||
public void setAttachmentState(String attachedState) {
|
||||
this.attachmentState = attachedState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return state of the vm
|
||||
*/
|
||||
public String getAttachmentState() {
|
||||
return attachmentState;
|
||||
}
|
||||
|
||||
public void addResourceTag( EC2TagKeyValue param ) {
|
||||
tagsSet.add( param );
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ public class EC2VolumeFilterSet {
|
||||
filterTypes.put( "attachment.delete-on-termination", "null" );
|
||||
filterTypes.put( "attachment.device", "string" );
|
||||
filterTypes.put( "attachment.instance-id", "string" );
|
||||
filterTypes.put( "attachment.status", "null" );
|
||||
filterTypes.put( "attachment.status", "set:attached|attaching|detached|detaching" );
|
||||
filterTypes.put( "availability-zone", "string" );
|
||||
filterTypes.put( "create-time", "xsd:dateTime" );
|
||||
filterTypes.put( "size", "integer" );
|
||||
@ -136,6 +136,9 @@ public class EC2VolumeFilterSet {
|
||||
return containsDevice(vol.getDeviceId(), valueSet );
|
||||
else if (filterName.equalsIgnoreCase( "attachment.instance-id" ))
|
||||
return containsString(String.valueOf(vol.getInstanceId()), valueSet );
|
||||
else if ( filterName.equalsIgnoreCase( "attachment.status" ) ) {
|
||||
return containsString(vol.getAttachmentState(), valueSet );
|
||||
}
|
||||
else if (filterName.equalsIgnoreCase("tag-key"))
|
||||
{
|
||||
EC2TagKeyValue[] tagSet = vol.getResourceTags();
|
||||
|
||||
@ -151,7 +151,8 @@ public class CloudStackClient {
|
||||
return (new Gson()).fromJson(json.eval(responseName + "." + responseObjName), collectionType);
|
||||
} catch(Exception e) {
|
||||
// this happens because responseObjName won't exist if there are no objects in the list.
|
||||
logger.debug("Unable to find responseObjName:[" + responseObjName + "]. Returning null! Exception: " + e.getMessage());
|
||||
logger.debug("CloudSatck API response doesn't contain responseObjName:" + responseObjName +
|
||||
" because response is empty");
|
||||
return null;
|
||||
}
|
||||
return (new Gson()).fromJson(json.eval(responseName), collectionType);
|
||||
|
||||
@ -1415,6 +1415,20 @@ label.zone.step.4.title=Step 4: <strong>Add an IP range</strong>
|
||||
label.zone.wide=Zone-Wide
|
||||
label.zone=Zone
|
||||
|
||||
#VM snapshot label
|
||||
label.vmsnapshot=VM Snapshots
|
||||
label.vmsnapshot.type=Type
|
||||
label.vmsnapshot.parentname=Parent
|
||||
label.vmsnapshot.current=isCurrent
|
||||
label.vmsnapshot.memory=Snapshot memory
|
||||
message.action.vmsnapshot.delete=Please confirm that you want to delete this VM snapshot.
|
||||
label.action.vmsnapshot.delete=Delete VM snapshot
|
||||
label.action.vmsnapshot.revert=Revert to VM snapshot
|
||||
message.action.vmsnapshot.revert=Revert VM snapshot
|
||||
label.action.vmsnapshot.create=Take VM Snapshot
|
||||
|
||||
|
||||
|
||||
#Messages
|
||||
message.acquire.public.ip=Please select a zone from which you want to acquire your new IP from.
|
||||
message.action.cancel.maintenance.mode=Please confirm that you want to cancel this maintenance.
|
||||
|
||||
@ -273,7 +273,7 @@
|
||||
</copy>
|
||||
<copy
|
||||
todir="${basedir}/target/generated-webapp/WEB-INF/classes/vms">
|
||||
<fileset dir="${basedir}/../console-proxy/dist">
|
||||
<fileset dir="${basedir}/../services/console-proxy/server/dist">
|
||||
<include name="systemvm.zip" />
|
||||
<include name="systemvm.iso" />
|
||||
</fileset>
|
||||
|
||||
@ -537,3 +537,9 @@ addRegion=1
|
||||
updateRegion=1
|
||||
removeRegion=1
|
||||
listRegions=15
|
||||
|
||||
### VM Snapshot commands
|
||||
listVMSnapshot=15
|
||||
createVMSnapshot=15
|
||||
deleteVMSnapshot=15
|
||||
revertToSnapshot=15
|
||||
|
||||
@ -119,10 +119,6 @@
|
||||
<property name="name" value="Basic"/>
|
||||
</bean>
|
||||
|
||||
<bean id="hyervisorTemplateAdapter" class="com.cloud.template.HyervisorTemplateAdapter">
|
||||
<property name="name" value="HypervisorAdapter"/>
|
||||
</bean>
|
||||
|
||||
<!--
|
||||
Authenticators
|
||||
-->
|
||||
|
||||
@ -130,7 +130,7 @@
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>process-test-resources</phase>
|
||||
<phase>process-resources</phase>
|
||||
<id>create-schema</id>
|
||||
<goals>
|
||||
<goal>java</goal>
|
||||
@ -259,7 +259,7 @@
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>process-test-resources</phase>
|
||||
<phase>process-resources</phase>
|
||||
<id>create-schema</id>
|
||||
<goals>
|
||||
<goal>java</goal>
|
||||
|
||||
@ -127,12 +127,17 @@ bind-address = 0.0.0.0</programlisting>
|
||||
recommended that you replace this with a more secure value. See <xref
|
||||
linkend="about-password-encryption"/>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>(Optional) For management_server_ip, you may explicitly specify cluster management
|
||||
server node IP. If not specified, the local IP address will be used.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<programlisting language="Bash">cloud-setup-databases cloud:<dbpassword>@<ip address mysql server> \
|
||||
--deploy-as=root:<password> \
|
||||
-e <encryption_type> \
|
||||
-m <management_server_key> \
|
||||
-k <database_key></programlisting>
|
||||
-k <database_key> \
|
||||
-i <management_server_ip></programlisting>
|
||||
<para>When this script is finished, you should see a message like “Successfully initialized
|
||||
the database.”</para>
|
||||
</listitem>
|
||||
|
||||
@ -98,12 +98,17 @@ binlog-format = 'ROW'</programlisting>
|
||||
recommended that you replace this with a more secure value. See <xref
|
||||
linkend="about-password-encryption"/>.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>(Optional) For management_server_ip, you may explicitly specify cluster management
|
||||
server node IP. If not specified, the local IP address will be used.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<programlisting language="Bash">cloud-setup-databases cloud:<dbpassword>@localhost \
|
||||
--deploy-as=root:<password> \
|
||||
-e <encryption_type> \
|
||||
-m <management_server_key> \
|
||||
-k <database_key></programlisting>
|
||||
-k <database_key> \
|
||||
-i <management_server_ip></programlisting>
|
||||
<para>When this script is finished, you should see a message like “Successfully initialized
|
||||
the database.”</para>
|
||||
</listitem>
|
||||
@ -118,7 +123,7 @@ binlog-format = 'ROW'</programlisting>
|
||||
<listitem>
|
||||
<para>Now that the database is set up, you can finish configuring the OS for the Management
|
||||
Server. This command will set up iptables, sudoers, and start the Management Server.</para>
|
||||
<programlisting language="Bash"># cloud-setup-management</programlisting>
|
||||
<programlisting><prompt>#</prompt> cloud-setup-management</programlisting>
|
||||
<para>You should see the message “&PRODUCT; Management Server setup is done.”</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
@ -53,7 +53,7 @@ linkend="sect-source-buildrpm"/> or <xref linkend="sect-source-builddebs"/> as
|
||||
<para>Configure the database client. Note the absence of the --deploy-as argument in this
|
||||
case. (For more details about the arguments to this command, see <xref
|
||||
linkend="management-server-install-db-external"/>.) </para>
|
||||
<programlisting><prompt>#</prompt> cloud-setup-databases cloud:<replaceable>dbpassword</replaceable>@<replaceable>dbhost</replaceable> -e <replaceable>encryption_type</replaceable> -m <replaceable>management_server_key</replaceable> -k <replaceable>database_key</replaceable>
|
||||
<programlisting><prompt>#</prompt> cloud-setup-databases cloud:<replaceable>dbpassword</replaceable>@<replaceable>dbhost</replaceable> -e <replaceable>encryption_type</replaceable> -m <replaceable>management_server_key</replaceable> -k <replaceable>database_key</replaceable> -i <replaceable>management_server_ip</replaceable>
|
||||
</programlisting>
|
||||
</listitem>
|
||||
<listitem>
|
||||
@ -69,4 +69,4 @@ linkend="sect-source-buildrpm"/> or <xref linkend="sect-source-builddebs"/> as
|
||||
Load Balancing.</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
@ -181,8 +181,8 @@ mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/scripts
|
||||
mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/vms
|
||||
mkdir -p ${RPM_BUILD_ROOT}%{_libdir}/python2.6/site-packages/
|
||||
cp -r scripts/* ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/scripts
|
||||
install -D console-proxy/dist/systemvm.iso ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/vms/systemvm.iso
|
||||
install -D console-proxy/dist/systemvm.zip ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/vms/systemvm.zip
|
||||
install -D services/console-proxy/server/dist/systemvm.iso ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/vms/systemvm.iso
|
||||
install -D services/console-proxy/server/dist/systemvm.zip ${RPM_BUILD_ROOT}%{_datadir}/%{name}-common/vms/systemvm.zip
|
||||
install python/lib/cloud_utils.py ${RPM_BUILD_ROOT}%{_libdir}/python2.6/site-packages/cloud_utils.py
|
||||
cp -r python/lib/cloudutils ${RPM_BUILD_ROOT}%{_libdir}/python2.6/site-packages/
|
||||
python -m py_compile ${RPM_BUILD_ROOT}%{_libdir}/python2.6/site-packages/cloud_utils.py
|
||||
@ -222,7 +222,7 @@ rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/webapps/client/WEB-INF/cl
|
||||
rm -rf ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/webapps/client/WEB-INF/classes/vms
|
||||
|
||||
for name in db.properties log4j-cloud.xml tomcat6-nonssl.conf tomcat6-ssl.conf server-ssl.xml server-nonssl.xml \
|
||||
catalina.policy catalina.properties db-enc.properties classpath.conf tomcat-users.xml web.xml ; do
|
||||
catalina.policy catalina.properties db-enc.properties classpath.conf tomcat-users.xml web.xml environment.properties ; do
|
||||
mv ${RPM_BUILD_ROOT}%{_datadir}/%{name}-management/webapps/client/WEB-INF/classes/$name \
|
||||
${RPM_BUILD_ROOT}%{_sysconfdir}/%{name}/management/$name
|
||||
done
|
||||
@ -284,7 +284,7 @@ fi
|
||||
|
||||
%pre management
|
||||
id cloud > /dev/null 2>&1 || /usr/sbin/useradd -M -c "CloudStack unprivileged user" \
|
||||
-r -s /bin/sh -d %{_localstatedir}/cloud/management cloud|| true
|
||||
-r -s /bin/sh -d %{_localstatedir}/cloudstack/management cloud|| true
|
||||
|
||||
# set max file descriptors for cloud user to 4096
|
||||
sed -i /"cloud hard nofile"/d /etc/security/limits.conf
|
||||
@ -300,9 +300,9 @@ if [ "$1" == "1" ] ; then
|
||||
/sbin/chkconfig --level 345 cloud-management on > /dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
if [ ! -f %{_datadir}/cloud/management/webapps/client/WEB-INF/classes/scripts/scripts/vm/hypervisor/xenserver/vhd-util ] ; then
|
||||
if [ ! -f %{_datadir}/cloudstack/management/webapps/client/WEB-INF/classes/scripts/scripts/vm/hypervisor/xenserver/vhd-util ] ; then
|
||||
echo Please download vhd-util from http://download.cloud.com.s3.amazonaws.com/tools/vhd-util and put it in
|
||||
echo %{_datadir}/cloud/management/webapps/client/WEB-INF/classes/scripts/vm/hypervisor/xenserver/
|
||||
echo %{_datadir}/cloudstack/management/webapps/client/WEB-INF/classes/scripts/vm/hypervisor/xenserver/
|
||||
fi
|
||||
|
||||
#No default permission as the permission setup is complex
|
||||
@ -336,6 +336,7 @@ fi
|
||||
%config(noreplace) %{_sysconfdir}/%{name}/management/server-ssl.xml
|
||||
%config(noreplace) %{_sysconfdir}/%{name}/management/tomcat-users.xml
|
||||
%config(noreplace) %{_sysconfdir}/%{name}/management/web.xml
|
||||
%config(noreplace) %{_sysconfdir}/%{name}/management/environment.properties
|
||||
%attr(0755,root,root) %{_initrddir}/%{name}-management
|
||||
%attr(0755,root,root) %{_bindir}/%{name}-setup-management
|
||||
%attr(0755,root,root) %{_bindir}/%{name}-update-xenserver-licenses
|
||||
|
||||
0
packaging/centos63/package.sh
Normal file → Executable file
0
packaging/centos63/package.sh
Normal file → Executable file
@ -21,7 +21,6 @@ DBROOTPW=
|
||||
MSLOG=vmops.log
|
||||
APISERVERLOG=api.log
|
||||
DBHOST=localhost
|
||||
MSMNTDIR=/mnt
|
||||
COMPONENTS-SPEC=components-premium.xml
|
||||
AWSAPILOG=awsapi.log
|
||||
REMOTEHOST=localhost
|
||||
@ -45,7 +44,7 @@ MSCONF=/etc/cloudstack/management
|
||||
MSENVIRON=/usr/share/cloudstack-management
|
||||
MSLOG=/var/log/cloudstack/management/management-server.log
|
||||
MSLOGDIR=/var/log/cloudstack/management/
|
||||
MSMNTDIR=/var/lib/cloud/mnt
|
||||
MSMNTDIR=/var/cloudstack/mnt
|
||||
MSUSER=cloud
|
||||
PIDDIR=/var/run
|
||||
PLUGINJAVADIR=/usr/share/cloudstack-management/plugin
|
||||
|
||||
@ -42,7 +42,11 @@ getLockFile() {
|
||||
|
||||
psline=`ps u $$`
|
||||
echo $psline > $__LOCKFILE
|
||||
|
||||
if [ ! -e $__LOCKFILE ]
|
||||
then
|
||||
return
|
||||
fi
|
||||
|
||||
for i in `seq 1 $(($__TIMEOUT * 10))`
|
||||
do
|
||||
currlock=`ls -tr /tmp/$1-*.lock | head -n1`
|
||||
|
||||
@ -58,6 +58,11 @@ public class BareMetalTemplateAdapter extends TemplateAdapterBase implements Tem
|
||||
private final static Logger s_logger = Logger.getLogger(BareMetalTemplateAdapter.class);
|
||||
@Inject HostDao _hostDao;
|
||||
@Inject ResourceManager _resourceMgr;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return TemplateAdapterType.BareMetal.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocationException {
|
||||
|
||||
@ -20,15 +20,21 @@ import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.BackupSnapshotCommand;
|
||||
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
|
||||
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
|
||||
import com.cloud.agent.api.CreateVMSnapshotCommand;
|
||||
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
|
||||
import com.cloud.agent.api.DeleteVMSnapshotCommand;
|
||||
import com.cloud.agent.api.RevertToVMSnapshotCommand;
|
||||
import com.cloud.agent.api.storage.CopyVolumeCommand;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
||||
|
||||
public interface VmwareStorageManager {
|
||||
Answer execute(VmwareHostService hostService, PrimaryStorageDownloadCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, BackupSnapshotCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromVolumeCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromSnapshotCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, CopyVolumeCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, CreateVolumeFromSnapshotCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, BackupSnapshotCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromVolumeCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromSnapshotCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, CopyVolumeCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, CreateVolumeFromSnapshotCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, CreateVMSnapshotCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, DeleteVMSnapshotCommand cmd);
|
||||
Answer execute(VmwareHostService hostService, RevertToVMSnapshotCommand cmd);
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ import java.io.FileOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -32,18 +33,27 @@ import com.cloud.agent.api.BackupSnapshotAnswer;
|
||||
import com.cloud.agent.api.BackupSnapshotCommand;
|
||||
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
|
||||
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
|
||||
import com.cloud.agent.api.CreateVMSnapshotAnswer;
|
||||
import com.cloud.agent.api.CreateVMSnapshotCommand;
|
||||
import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
|
||||
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
|
||||
import com.cloud.agent.api.DeleteVMSnapshotAnswer;
|
||||
import com.cloud.agent.api.DeleteVMSnapshotCommand;
|
||||
import com.cloud.agent.api.RevertToVMSnapshotAnswer;
|
||||
import com.cloud.agent.api.RevertToVMSnapshotCommand;
|
||||
import com.cloud.agent.api.storage.CopyVolumeAnswer;
|
||||
import com.cloud.agent.api.storage.CopyVolumeCommand;
|
||||
import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
|
||||
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
|
||||
import com.cloud.agent.api.to.StorageFilerTO;
|
||||
import com.cloud.agent.api.to.VolumeTO;
|
||||
import com.cloud.hypervisor.vmware.mo.CustomFieldConstants;
|
||||
import com.cloud.hypervisor.vmware.mo.DatacenterMO;
|
||||
import com.cloud.hypervisor.vmware.mo.DatastoreMO;
|
||||
import com.cloud.hypervisor.vmware.mo.HostMO;
|
||||
import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper;
|
||||
import com.cloud.hypervisor.vmware.mo.TaskMO;
|
||||
import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
|
||||
import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
|
||||
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
||||
@ -57,7 +67,11 @@ import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.Ternary;
|
||||
import com.cloud.utils.script.Script;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
import com.vmware.vim25.ManagedObjectReference;
|
||||
import com.vmware.vim25.TaskEvent;
|
||||
import com.vmware.vim25.TaskInfo;
|
||||
import com.vmware.vim25.VirtualDeviceConfigSpec;
|
||||
import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
|
||||
import com.vmware.vim25.VirtualDisk;
|
||||
@ -222,8 +236,12 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
}
|
||||
|
||||
} finally {
|
||||
if(vmMo != null)
|
||||
vmMo.removeAllSnapshots();
|
||||
if(vmMo != null){
|
||||
ManagedObjectReference snapshotMor = vmMo.getSnapshotMor(snapshotUuid);
|
||||
if (snapshotMor != null){
|
||||
vmMo.removeSnapshot(snapshotUuid, false);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (workerVm != null) {
|
||||
@ -377,47 +395,47 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Answer execute(VmwareHostService hostService, CreateVolumeFromSnapshotCommand cmd) {
|
||||
public Answer execute(VmwareHostService hostService, CreateVolumeFromSnapshotCommand cmd) {
|
||||
|
||||
String primaryStorageNameLabel = cmd.getPrimaryStoragePoolNameLabel();
|
||||
Long accountId = cmd.getAccountId();
|
||||
Long volumeId = cmd.getVolumeId();
|
||||
String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
|
||||
String backedUpSnapshotUuid = cmd.getSnapshotUuid();
|
||||
String primaryStorageNameLabel = cmd.getPrimaryStoragePoolNameLabel();
|
||||
Long accountId = cmd.getAccountId();
|
||||
Long volumeId = cmd.getVolumeId();
|
||||
String secondaryStorageUrl = cmd.getSecondaryStorageUrl();
|
||||
String backedUpSnapshotUuid = cmd.getSnapshotUuid();
|
||||
|
||||
String details = null;
|
||||
boolean success = false;
|
||||
String newVolumeName = UUID.randomUUID().toString().replaceAll("-", "");
|
||||
String details = null;
|
||||
boolean success = false;
|
||||
String newVolumeName = UUID.randomUUID().toString().replaceAll("-", "");
|
||||
|
||||
VmwareContext context = hostService.getServiceContext(cmd);
|
||||
try {
|
||||
VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
|
||||
|
||||
ManagedObjectReference morPrimaryDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStorageNameLabel);
|
||||
if (morPrimaryDs == null) {
|
||||
String msg = "Unable to find datastore: " + primaryStorageNameLabel;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
VmwareContext context = hostService.getServiceContext(cmd);
|
||||
try {
|
||||
VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
|
||||
ManagedObjectReference morPrimaryDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost,
|
||||
primaryStorageNameLabel);
|
||||
if (morPrimaryDs == null) {
|
||||
String msg = "Unable to find datastore: " + primaryStorageNameLabel;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs);
|
||||
details = createVolumeFromSnapshot(hyperHost, primaryDsMo,
|
||||
newVolumeName, accountId, volumeId, secondaryStorageUrl, backedUpSnapshotUuid);
|
||||
if (details == null) {
|
||||
success = true;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (e instanceof RemoteException) {
|
||||
hostService.invalidateServiceContext(context);
|
||||
}
|
||||
DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs);
|
||||
details = createVolumeFromSnapshot(hyperHost, primaryDsMo,
|
||||
newVolumeName, accountId, volumeId, secondaryStorageUrl, backedUpSnapshotUuid);
|
||||
if (details == null) {
|
||||
success = true;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (e instanceof RemoteException) {
|
||||
hostService.invalidateServiceContext(context);
|
||||
}
|
||||
|
||||
s_logger.error("Unexpecpted exception ", e);
|
||||
details = "CreateVolumeFromSnapshotCommand exception: " + StringUtils.getExceptionStackInfo(e);
|
||||
}
|
||||
|
||||
s_logger.error("Unexpecpted exception ", e);
|
||||
details = "CreateVolumeFromSnapshotCommand exception: " + StringUtils.getExceptionStackInfo(e);
|
||||
}
|
||||
return new CreateVolumeFromSnapshotAnswer(cmd, success, details, newVolumeName);
|
||||
}
|
||||
|
||||
return new CreateVolumeFromSnapshotAnswer(cmd, success, details, newVolumeName);
|
||||
}
|
||||
|
||||
// templateName: name in secondary storage
|
||||
// templateUuid: will be used at hypervisor layer
|
||||
private void copyTemplateFromSecondaryToPrimary(VmwareHypervisorHost hyperHost, DatastoreMO datastoreMo, String secondaryStorageUrl,
|
||||
@ -881,4 +899,244 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
private static String getSnapshotRelativeDirInSecStorage(long accountId, long volumeId) {
|
||||
return "snapshots/" + accountId + "/" + volumeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreateVMSnapshotAnswer execute(VmwareHostService hostService, CreateVMSnapshotCommand cmd) {
|
||||
List<VolumeTO> volumeTOs = cmd.getVolumeTOs();
|
||||
String vmName = cmd.getVmName();
|
||||
String vmSnapshotName = cmd.getTarget().getSnapshotName();
|
||||
String vmSnapshotDesc = cmd.getTarget().getDescription();
|
||||
boolean snapshotMemory = cmd.getTarget().getType() == VMSnapshot.Type.DiskAndMemory;
|
||||
VirtualMachineMO vmMo = null;
|
||||
VmwareContext context = hostService.getServiceContext(cmd);
|
||||
Map<String, String> mapNewDisk = new HashMap<String, String>();
|
||||
try {
|
||||
VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
|
||||
|
||||
// wait if there are already VM snapshot task running
|
||||
ManagedObjectReference taskmgr = context.getServiceContent().getTaskManager();
|
||||
ManagedObjectReference[] tasks = (ManagedObjectReference[]) context.getServiceUtil().getDynamicProperty(taskmgr, "recentTask");
|
||||
for (ManagedObjectReference taskMor : tasks) {
|
||||
TaskInfo info = (TaskInfo) (context.getServiceUtil().getDynamicProperty(taskMor, "info"));
|
||||
if(info.getEntityName().equals(cmd.getVmName()) && info.getName().equalsIgnoreCase("CreateSnapshot_Task")){
|
||||
s_logger.debug("There is already a VM snapshot task running, wait for it");
|
||||
context.getServiceUtil().waitForTask(taskMor);
|
||||
}
|
||||
}
|
||||
|
||||
vmMo = hyperHost.findVmOnHyperHost(vmName);
|
||||
if(vmMo == null)
|
||||
vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
|
||||
if (vmMo == null) {
|
||||
String msg = "Unable to find VM for CreateVMSnapshotCommand";
|
||||
s_logger.debug(msg);
|
||||
return new CreateVMSnapshotAnswer(cmd, false, msg);
|
||||
} else {
|
||||
if (vmMo.getSnapshotMor(vmSnapshotName) != null){
|
||||
s_logger.debug("VM snapshot " + vmSnapshotName + " already exists");
|
||||
}else if (!vmMo.createSnapshot(vmSnapshotName, vmSnapshotDesc, snapshotMemory, true)) {
|
||||
return new CreateVMSnapshotAnswer(cmd, false,
|
||||
"Unable to create snapshot due to esxi internal failed");
|
||||
}
|
||||
// find VM disk file path after creating snapshot
|
||||
VirtualDisk[] vdisks = vmMo.getAllDiskDevice();
|
||||
for (int i = 0; i < vdisks.length; i ++){
|
||||
@SuppressWarnings("deprecation")
|
||||
List<Pair<String, ManagedObjectReference>> vmdkFiles = vmMo.getDiskDatastorePathChain(vdisks[i], false);
|
||||
for(Pair<String, ManagedObjectReference> fileItem : vmdkFiles) {
|
||||
String vmdkName = fileItem.first().split(" ")[1];
|
||||
if ( vmdkName.endsWith(".vmdk")){
|
||||
vmdkName = vmdkName.substring(0, vmdkName.length() - (".vmdk").length());
|
||||
}
|
||||
String[] s = vmdkName.split("-");
|
||||
mapNewDisk.put(s[0], vmdkName);
|
||||
}
|
||||
}
|
||||
|
||||
// update volume path using maps
|
||||
for (VolumeTO volumeTO : volumeTOs) {
|
||||
String parentUUID = volumeTO.getPath();
|
||||
String[] s = parentUUID.split("-");
|
||||
String key = s[0];
|
||||
volumeTO.setPath(mapNewDisk.get(key));
|
||||
}
|
||||
return new CreateVMSnapshotAnswer(cmd, cmd.getTarget(), volumeTOs);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String msg = e.getMessage();
|
||||
s_logger.error("failed to create snapshot for vm:" + vmName + " due to " + msg);
|
||||
try {
|
||||
if (vmMo.getSnapshotMor(vmSnapshotName) != null) {
|
||||
vmMo.removeSnapshot(vmSnapshotName, false);
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
}
|
||||
return new CreateVMSnapshotAnswer(cmd, false, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeleteVMSnapshotAnswer execute(VmwareHostService hostService, DeleteVMSnapshotCommand cmd) {
|
||||
List<VolumeTO> listVolumeTo = cmd.getVolumeTOs();
|
||||
VirtualMachineMO vmMo = null;
|
||||
VmwareContext context = hostService.getServiceContext(cmd);
|
||||
Map<String, String> mapNewDisk = new HashMap<String, String>();
|
||||
String vmName = cmd.getVmName();
|
||||
String vmSnapshotName = cmd.getTarget().getSnapshotName();
|
||||
try {
|
||||
VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
|
||||
vmMo = hyperHost.findVmOnHyperHost(vmName);
|
||||
if(vmMo == null)
|
||||
vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
|
||||
if (vmMo == null) {
|
||||
String msg = "Unable to find VM for RevertToVMSnapshotCommand";
|
||||
s_logger.debug(msg);
|
||||
return new DeleteVMSnapshotAnswer(cmd, false, msg);
|
||||
} else {
|
||||
if (vmMo.getSnapshotMor(vmSnapshotName) == null) {
|
||||
s_logger.debug("can not find the snapshot " + vmSnapshotName + ", assume it is already removed");
|
||||
} else {
|
||||
if (!vmMo.removeSnapshot(vmSnapshotName, false)) {
|
||||
String msg = "delete vm snapshot " + vmSnapshotName + " due to error occured in vmware";
|
||||
s_logger.error(msg);
|
||||
return new DeleteVMSnapshotAnswer(cmd, false, msg);
|
||||
}
|
||||
}
|
||||
s_logger.debug("snapshot: " + vmSnapshotName + " is removed");
|
||||
// after removed snapshot, the volumes' paths have been changed for the VM, needs to report new paths to manager
|
||||
VirtualDisk[] vdisks = vmMo.getAllDiskDevice();
|
||||
for (int i = 0; i < vdisks.length; i++) {
|
||||
@SuppressWarnings("deprecation")
|
||||
List<Pair<String, ManagedObjectReference>> vmdkFiles = vmMo.getDiskDatastorePathChain(vdisks[i], false);
|
||||
for (Pair<String, ManagedObjectReference> fileItem : vmdkFiles) {
|
||||
String vmdkName = fileItem.first().split(" ")[1];
|
||||
if (vmdkName.endsWith(".vmdk")) {
|
||||
vmdkName = vmdkName.substring(0, vmdkName.length() - (".vmdk").length());
|
||||
}
|
||||
String[] s = vmdkName.split("-");
|
||||
mapNewDisk.put(s[0], vmdkName);
|
||||
}
|
||||
}
|
||||
for (VolumeTO volumeTo : listVolumeTo) {
|
||||
String key = null;
|
||||
String parentUUID = volumeTo.getPath();
|
||||
String[] s = parentUUID.split("-");
|
||||
key = s[0];
|
||||
volumeTo.setPath(mapNewDisk.get(key));
|
||||
}
|
||||
return new DeleteVMSnapshotAnswer(cmd, listVolumeTo);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String msg = e.getMessage();
|
||||
s_logger.error("failed to delete vm snapshot " + vmSnapshotName + " of vm " + vmName + " due to " + msg);
|
||||
return new DeleteVMSnapshotAnswer(cmd, false, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RevertToVMSnapshotAnswer execute(VmwareHostService hostService, RevertToVMSnapshotCommand cmd) {
|
||||
String snapshotName = cmd.getTarget().getSnapshotName();
|
||||
String vmName = cmd.getVmName();
|
||||
Boolean snapshotMemory = cmd.getTarget().getType() == VMSnapshot.Type.DiskAndMemory;
|
||||
List<VolumeTO> listVolumeTo = cmd.getVolumeTOs();
|
||||
VirtualMachine.State vmState = VirtualMachine.State.Running;
|
||||
VirtualMachineMO vmMo = null;
|
||||
VmwareContext context = hostService.getServiceContext(cmd);
|
||||
Map<String, String> mapNewDisk = new HashMap<String, String>();
|
||||
try {
|
||||
VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
|
||||
|
||||
// wait if there are already VM revert task running
|
||||
ManagedObjectReference taskmgr = context.getServiceContent().getTaskManager();
|
||||
ManagedObjectReference[] tasks = (ManagedObjectReference[]) context.getServiceUtil().getDynamicProperty(taskmgr, "recentTask");
|
||||
for (ManagedObjectReference taskMor : tasks) {
|
||||
TaskInfo info = (TaskInfo) (context.getServiceUtil().getDynamicProperty(taskMor, "info"));
|
||||
if(info.getEntityName().equals(cmd.getVmName()) && info.getName().equalsIgnoreCase("RevertToSnapshot_Task")){
|
||||
s_logger.debug("There is already a VM snapshot task running, wait for it");
|
||||
context.getServiceUtil().waitForTask(taskMor);
|
||||
}
|
||||
}
|
||||
|
||||
HostMO hostMo = (HostMO) hyperHost;
|
||||
vmMo = hyperHost.findVmOnHyperHost(vmName);
|
||||
if(vmMo == null)
|
||||
vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
|
||||
if (vmMo == null) {
|
||||
String msg = "Unable to find VM for RevertToVMSnapshotCommand";
|
||||
s_logger.debug(msg);
|
||||
return new RevertToVMSnapshotAnswer(cmd, false, msg);
|
||||
} else {
|
||||
boolean result = false;
|
||||
if (snapshotName != null) {
|
||||
ManagedObjectReference morSnapshot = vmMo.getSnapshotMor(snapshotName);
|
||||
result = hostMo.revertToSnapshot(morSnapshot);
|
||||
} else {
|
||||
return new RevertToVMSnapshotAnswer(cmd, false, "Unable to find the snapshot by name " + snapshotName);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
VirtualDisk[] vdisks = vmMo.getAllDiskDevice();
|
||||
// build a map<volumeName, vmdk>
|
||||
for (int i = 0; i < vdisks.length; i++) {
|
||||
@SuppressWarnings("deprecation")
|
||||
List<Pair<String, ManagedObjectReference>> vmdkFiles = vmMo.getDiskDatastorePathChain(
|
||||
vdisks[i], false);
|
||||
for (Pair<String, ManagedObjectReference> fileItem : vmdkFiles) {
|
||||
String vmdkName = fileItem.first().split(" ")[1];
|
||||
if (vmdkName.endsWith(".vmdk")) {
|
||||
vmdkName = vmdkName.substring(0, vmdkName.length() - (".vmdk").length());
|
||||
}
|
||||
String[] s = vmdkName.split("-");
|
||||
mapNewDisk.put(s[0], vmdkName);
|
||||
}
|
||||
}
|
||||
String key = null;
|
||||
for (VolumeTO volumeTo : listVolumeTo) {
|
||||
String parentUUID = volumeTo.getPath();
|
||||
String[] s = parentUUID.split("-");
|
||||
key = s[0];
|
||||
volumeTo.setPath(mapNewDisk.get(key));
|
||||
}
|
||||
if (!snapshotMemory) {
|
||||
vmState = VirtualMachine.State.Stopped;
|
||||
}
|
||||
return new RevertToVMSnapshotAnswer(cmd, listVolumeTo, vmState);
|
||||
} else {
|
||||
return new RevertToVMSnapshotAnswer(cmd, false,
|
||||
"Error while reverting to snapshot due to execute in esxi");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String msg = "revert vm " + vmName + " to snapshot " + snapshotName + " failed due to " + e.getMessage();
|
||||
s_logger.error(msg);
|
||||
return new RevertToVMSnapshotAnswer(cmd, false, msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private VirtualMachineMO createWorkingVM(DatastoreMO dsMo, VmwareHypervisorHost hyperHost) throws Exception {
|
||||
String uniqueName = UUID.randomUUID().toString();
|
||||
VirtualMachineMO workingVM = null;
|
||||
VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
|
||||
vmConfig.setName(uniqueName);
|
||||
vmConfig.setMemoryMB((long) 4);
|
||||
vmConfig.setNumCPUs(1);
|
||||
vmConfig.setGuestId(VirtualMachineGuestOsIdentifier._otherGuest.toString());
|
||||
VirtualMachineFileInfo fileInfo = new VirtualMachineFileInfo();
|
||||
fileInfo.setVmPathName(String.format("[%s]", dsMo.getName()));
|
||||
vmConfig.setFiles(fileInfo);
|
||||
|
||||
VirtualLsiLogicController scsiController = new VirtualLsiLogicController();
|
||||
scsiController.setSharedBus(VirtualSCSISharing.noSharing);
|
||||
scsiController.setBusNumber(0);
|
||||
scsiController.setKey(1);
|
||||
VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
|
||||
scsiControllerSpec.setDevice(scsiController);
|
||||
scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
|
||||
|
||||
vmConfig.setDeviceChange(new VirtualDeviceConfigSpec[] { scsiControllerSpec });
|
||||
hyperHost.createVm(vmConfig);
|
||||
workingVM = hyperHost.findVmOnHyperHost(uniqueName);
|
||||
return workingVM;
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,9 +65,13 @@ import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
|
||||
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
|
||||
import com.cloud.agent.api.CreateStoragePoolCommand;
|
||||
import com.cloud.agent.api.CreateVMSnapshotAnswer;
|
||||
import com.cloud.agent.api.CreateVMSnapshotCommand;
|
||||
import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
|
||||
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
|
||||
import com.cloud.agent.api.DeleteStoragePoolCommand;
|
||||
import com.cloud.agent.api.DeleteVMSnapshotAnswer;
|
||||
import com.cloud.agent.api.DeleteVMSnapshotCommand;
|
||||
import com.cloud.agent.api.GetDomRVersionAnswer;
|
||||
import com.cloud.agent.api.GetDomRVersionCmd;
|
||||
import com.cloud.agent.api.GetHostStatsAnswer;
|
||||
@ -103,6 +107,8 @@ import com.cloud.agent.api.ReadyCommand;
|
||||
import com.cloud.agent.api.RebootAnswer;
|
||||
import com.cloud.agent.api.RebootCommand;
|
||||
import com.cloud.agent.api.RebootRouterCommand;
|
||||
import com.cloud.agent.api.RevertToVMSnapshotAnswer;
|
||||
import com.cloud.agent.api.RevertToVMSnapshotCommand;
|
||||
import com.cloud.agent.api.SetupAnswer;
|
||||
import com.cloud.agent.api.SetupCommand;
|
||||
import com.cloud.agent.api.SetupGuestNetworkAnswer;
|
||||
@ -445,7 +451,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
answer = execute((SetSourceNatCommand) cmd);
|
||||
} else if (clz == SetNetworkACLCommand.class) {
|
||||
answer = execute((SetNetworkACLCommand) cmd);
|
||||
} else if (clz == SetPortForwardingRulesVpcCommand.class) {
|
||||
} else if (cmd instanceof CreateVMSnapshotCommand) {
|
||||
return execute((CreateVMSnapshotCommand)cmd);
|
||||
} else if(cmd instanceof DeleteVMSnapshotCommand){
|
||||
return execute((DeleteVMSnapshotCommand)cmd);
|
||||
} else if(cmd instanceof RevertToVMSnapshotCommand){
|
||||
return execute((RevertToVMSnapshotCommand)cmd);
|
||||
}else if (clz == SetPortForwardingRulesVpcCommand.class) {
|
||||
answer = execute((SetPortForwardingRulesVpcCommand) cmd);
|
||||
} else if (clz == Site2SiteVpnCfgCommand.class) {
|
||||
answer = execute((Site2SiteVpnCfgCommand) cmd);
|
||||
@ -2799,7 +2811,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
// before we stop VM, remove all possible snapshots on the VM to let
|
||||
// disk chain be collapsed
|
||||
s_logger.info("Remove all snapshot before stopping VM " + cmd.getVmName());
|
||||
vmMo.removeAllSnapshots();
|
||||
if (vmMo.safePowerOff(_shutdown_waitMs)) {
|
||||
state = State.Stopped;
|
||||
return new StopAnswer(cmd, "Stop VM " + cmd.getVmName() + " Succeed", 0, true);
|
||||
@ -3351,7 +3362,42 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
}
|
||||
}
|
||||
|
||||
protected Answer execute(CreateVMSnapshotCommand cmd) {
|
||||
try {
|
||||
VmwareContext context = getServiceContext();
|
||||
VmwareManager mgr = context
|
||||
.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
|
||||
|
||||
return mgr.getStorageManager().execute(this, cmd);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return new CreateVMSnapshotAnswer(cmd, false, "");
|
||||
}
|
||||
}
|
||||
|
||||
protected Answer execute(DeleteVMSnapshotCommand cmd) {
|
||||
try {
|
||||
VmwareContext context = getServiceContext();
|
||||
VmwareManager mgr = context
|
||||
.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
|
||||
|
||||
return mgr.getStorageManager().execute(this, cmd);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return new DeleteVMSnapshotAnswer(cmd, false, "");
|
||||
}
|
||||
}
|
||||
|
||||
protected Answer execute(RevertToVMSnapshotCommand cmd){
|
||||
try{
|
||||
VmwareContext context = getServiceContext();
|
||||
VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
|
||||
return mgr.getStorageManager().execute(this, cmd);
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
return new RevertToVMSnapshotAnswer(cmd,false,"");
|
||||
}
|
||||
}
|
||||
protected Answer execute(CreateVolumeFromSnapshotCommand cmd) {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Executing resource CreateVolumeFromSnapshotCommand: " + _gson.toJson(cmd));
|
||||
|
||||
@ -90,9 +90,13 @@ import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
|
||||
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
|
||||
import com.cloud.agent.api.CreateStoragePoolCommand;
|
||||
import com.cloud.agent.api.CreateVMSnapshotAnswer;
|
||||
import com.cloud.agent.api.CreateVMSnapshotCommand;
|
||||
import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer;
|
||||
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
|
||||
import com.cloud.agent.api.DeleteStoragePoolCommand;
|
||||
import com.cloud.agent.api.DeleteVMSnapshotAnswer;
|
||||
import com.cloud.agent.api.DeleteVMSnapshotCommand;
|
||||
import com.cloud.agent.api.GetDomRVersionAnswer;
|
||||
import com.cloud.agent.api.GetDomRVersionCmd;
|
||||
import com.cloud.agent.api.GetHostStatsAnswer;
|
||||
@ -129,6 +133,8 @@ import com.cloud.agent.api.ReadyCommand;
|
||||
import com.cloud.agent.api.RebootAnswer;
|
||||
import com.cloud.agent.api.RebootCommand;
|
||||
import com.cloud.agent.api.RebootRouterCommand;
|
||||
import com.cloud.agent.api.RevertToVMSnapshotAnswer;
|
||||
import com.cloud.agent.api.RevertToVMSnapshotCommand;
|
||||
import com.cloud.agent.api.SecurityGroupRuleAnswer;
|
||||
import com.cloud.agent.api.SecurityGroupRulesCmd;
|
||||
import com.cloud.agent.api.SetupAnswer;
|
||||
@ -237,6 +243,7 @@ import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
import com.trilead.ssh2.SCPClient;
|
||||
import com.xensource.xenapi.Bond;
|
||||
import com.xensource.xenapi.Connection;
|
||||
@ -256,6 +263,10 @@ import com.xensource.xenapi.Types;
|
||||
import com.xensource.xenapi.Types.BadServerResponse;
|
||||
import com.xensource.xenapi.Types.ConsoleProtocol;
|
||||
import com.xensource.xenapi.Types.IpConfigurationMode;
|
||||
import com.xensource.xenapi.Types.OperationNotAllowed;
|
||||
import com.xensource.xenapi.Types.SrFull;
|
||||
import com.xensource.xenapi.Types.VbdType;
|
||||
import com.xensource.xenapi.Types.VmBadPowerState;
|
||||
import com.xensource.xenapi.Types.VmPowerState;
|
||||
import com.xensource.xenapi.Types.XenAPIException;
|
||||
import com.xensource.xenapi.VBD;
|
||||
@ -579,11 +590,109 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
return execute((CheckS2SVpnConnectionsCommand) cmd);
|
||||
} else if (cmd instanceof StorageSubSystemCommand) {
|
||||
return this.storageResource.handleStorageCommands((StorageSubSystemCommand)cmd);
|
||||
} else if (clazz == CreateVMSnapshotCommand.class) {
|
||||
return execute((CreateVMSnapshotCommand)cmd);
|
||||
} else if (clazz == DeleteVMSnapshotCommand.class) {
|
||||
return execute((DeleteVMSnapshotCommand)cmd);
|
||||
} else if (clazz == RevertToVMSnapshotCommand.class) {
|
||||
return execute((RevertToVMSnapshotCommand)cmd);
|
||||
} else {
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Answer execute(RevertToVMSnapshotCommand cmd) {
|
||||
String vmName = cmd.getVmName();
|
||||
List<VolumeTO> listVolumeTo = cmd.getVolumeTOs();
|
||||
VMSnapshot.Type vmSnapshotType = cmd.getTarget().getType();
|
||||
Boolean snapshotMemory = vmSnapshotType == VMSnapshot.Type.DiskAndMemory;
|
||||
Connection conn = getConnection();
|
||||
VirtualMachine.State vmState = null;
|
||||
VM vm = null;
|
||||
try {
|
||||
|
||||
// remove vm from s_vms, for delta sync
|
||||
s_vms.remove(_cluster, _name, vmName);
|
||||
|
||||
Set<VM> vmSnapshots = VM.getByNameLabel(conn, cmd.getTarget().getSnapshotName());
|
||||
if(vmSnapshots.size() == 0)
|
||||
return new RevertToVMSnapshotAnswer(cmd, false, "Cannot find vmSnapshot with name: " + cmd.getTarget().getSnapshotName());
|
||||
|
||||
VM vmSnapshot = vmSnapshots.iterator().next();
|
||||
|
||||
// find target VM or creating a work VM
|
||||
try {
|
||||
vm = getVM(conn, vmName);
|
||||
} catch (Exception e) {
|
||||
vm = createWorkingVM(conn, vmName, cmd.getGuestOSType(), listVolumeTo);
|
||||
}
|
||||
|
||||
if (vm == null) {
|
||||
return new RevertToVMSnapshotAnswer(cmd, false,
|
||||
"Revert to VM Snapshot Failed due to can not find vm: " + vmName);
|
||||
}
|
||||
|
||||
// call plugin to execute revert
|
||||
revertToSnapshot(conn, vmSnapshot, vmName, vm.getUuid(conn), snapshotMemory, _host.uuid);
|
||||
vm = getVM(conn, vmName);
|
||||
Set<VBD> vbds = vm.getVBDs(conn);
|
||||
Map<String, VDI> vdiMap = new HashMap<String, VDI>();
|
||||
// get vdi:vbdr to a map
|
||||
for (VBD vbd : vbds) {
|
||||
VBD.Record vbdr = vbd.getRecord(conn);
|
||||
if (vbdr.type == Types.VbdType.DISK) {
|
||||
VDI vdi = vbdr.VDI;
|
||||
vdiMap.put(vbdr.userdevice, vdi);
|
||||
}
|
||||
}
|
||||
|
||||
if (!snapshotMemory) {
|
||||
vm.destroy(conn);
|
||||
vmState = VirtualMachine.State.Stopped;
|
||||
} else {
|
||||
s_vms.put(_cluster, _name, vmName, State.Running);
|
||||
vmState = VirtualMachine.State.Running;
|
||||
}
|
||||
|
||||
// after revert, VM's volumes path have been changed, need to report to manager
|
||||
for (VolumeTO volumeTo : listVolumeTo) {
|
||||
Long deviceId = volumeTo.getDeviceId();
|
||||
VDI vdi = vdiMap.get(deviceId.toString());
|
||||
volumeTo.setPath(vdi.getUuid(conn));
|
||||
}
|
||||
|
||||
return new RevertToVMSnapshotAnswer(cmd, listVolumeTo,vmState);
|
||||
} catch (Exception e) {
|
||||
s_logger.error("revert vm " + vmName
|
||||
+ " to snapshot " + cmd.getTarget().getSnapshotName() + " failed due to " + e.getMessage());
|
||||
return new RevertToVMSnapshotAnswer(cmd, false, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String revertToSnapshot(Connection conn, VM vmSnapshot,
|
||||
String vmName, String oldVmUuid, Boolean snapshotMemory, String hostUUID)
|
||||
throws XenAPIException, XmlRpcException {
|
||||
|
||||
String results = callHostPluginAsync(conn, "vmopsSnapshot",
|
||||
"revert_memory_snapshot", 10 * 60 * 1000, "snapshotUUID",
|
||||
vmSnapshot.getUuid(conn), "vmName", vmName, "oldVmUuid",
|
||||
oldVmUuid, "snapshotMemory", snapshotMemory.toString(), "hostUUID", hostUUID);
|
||||
String errMsg = null;
|
||||
if (results == null || results.isEmpty()) {
|
||||
errMsg = "revert_memory_snapshot return null";
|
||||
} else {
|
||||
if (results.equals("0")) {
|
||||
return results;
|
||||
} else {
|
||||
errMsg = "revert_memory_snapshot exception";
|
||||
}
|
||||
}
|
||||
s_logger.warn(errMsg);
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
|
||||
protected XsLocalNetwork getNativeNetworkForTraffic(Connection conn, TrafficType type, String name) throws XenAPIException, XmlRpcException {
|
||||
if (name != null) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
@ -4763,7 +4872,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
s_logger.debug("Copying " + f + " to " + d + " on " + hr.address + " with permission " + p);
|
||||
}
|
||||
try {
|
||||
session.execCommand("mkdir -p " + d);
|
||||
session.execCommand("mkdir -m 700 -p " + d);
|
||||
} catch (IOException e) {
|
||||
s_logger.debug("Unable to create destination path: " + d + " on " + hr.address + " but trying anyway");
|
||||
|
||||
@ -6167,6 +6276,199 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
|
||||
}
|
||||
|
||||
protected Answer execute(final CreateVMSnapshotCommand cmd) {
|
||||
String vmName = cmd.getVmName();
|
||||
String vmSnapshotName = cmd.getTarget().getSnapshotName();
|
||||
List<VolumeTO> listVolumeTo = cmd.getVolumeTOs();
|
||||
VirtualMachine.State vmState = cmd.getVmState();
|
||||
String guestOSType = cmd.getGuestOSType();
|
||||
|
||||
boolean snapshotMemory = cmd.getTarget().getType() == VMSnapshot.Type.DiskAndMemory;
|
||||
long timeout = 600;
|
||||
|
||||
Connection conn = getConnection();
|
||||
VM vm = null;
|
||||
VM vmSnapshot = null;
|
||||
boolean success = false;
|
||||
|
||||
try {
|
||||
// check if VM snapshot already exists
|
||||
Set<VM> vmSnapshots = VM.getByNameLabel(conn, cmd.getTarget().getSnapshotName());
|
||||
if(vmSnapshots.size() > 0)
|
||||
return new CreateVMSnapshotAnswer(cmd, cmd.getTarget(), cmd.getVolumeTOs());
|
||||
|
||||
// check if there is already a task for this VM snapshot
|
||||
Task task = null;
|
||||
Set<Task> tasks = Task.getByNameLabel(conn, "Async.VM.snapshot");
|
||||
tasks.addAll(Task.getByNameLabel(conn, "Async.VM.checkpoint"));
|
||||
for (Task taskItem : tasks) {
|
||||
if(taskItem.getOtherConfig(conn).containsKey("CS_VM_SNAPSHOT_KEY")){
|
||||
String vmSnapshotTaskName = taskItem.getOtherConfig(conn).get("CS_VM_SNAPSHOT_KEY");
|
||||
if(vmSnapshotTaskName != null && vmSnapshotTaskName.equals(cmd.getTarget().getSnapshotName())){
|
||||
task = taskItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create a new task if there is no existing task for this VM snapshot
|
||||
if(task == null){
|
||||
try {
|
||||
vm = getVM(conn, vmName);
|
||||
} catch (Exception e) {
|
||||
if (!snapshotMemory) {
|
||||
vm = createWorkingVM(conn, vmName, guestOSType, listVolumeTo);
|
||||
}
|
||||
}
|
||||
|
||||
if (vm == null) {
|
||||
return new CreateVMSnapshotAnswer(cmd, false,
|
||||
"Creating VM Snapshot Failed due to can not find vm: "
|
||||
+ vmName);
|
||||
}
|
||||
|
||||
// call Xenserver API
|
||||
if (!snapshotMemory) {
|
||||
task = vm.snapshotAsync(conn, vmSnapshotName);
|
||||
} else {
|
||||
Set<VBD> vbds = vm.getVBDs(conn);
|
||||
Pool pool = Pool.getByUuid(conn, _host.pool);
|
||||
for (VBD vbd: vbds){
|
||||
VBD.Record vbdr = vbd.getRecord(conn);
|
||||
if (vbdr.userdevice.equals("0")){
|
||||
VDI vdi = vbdr.VDI;
|
||||
SR sr = vdi.getSR(conn);
|
||||
// store memory image on the same SR with ROOT volume
|
||||
pool.setSuspendImageSR(conn, sr);
|
||||
}
|
||||
}
|
||||
task = vm.checkpointAsync(conn, vmSnapshotName);
|
||||
}
|
||||
task.addToOtherConfig(conn, "CS_VM_SNAPSHOT_KEY", vmSnapshotName);
|
||||
}
|
||||
|
||||
waitForTask(conn, task, 1000, timeout * 1000);
|
||||
checkForSuccess(conn, task);
|
||||
String result = task.getResult(conn);
|
||||
|
||||
// extract VM snapshot ref from result
|
||||
String ref = result.substring("<value>".length(), result.length() - "</value>".length());
|
||||
vmSnapshot = Types.toVM(ref);
|
||||
|
||||
success = true;
|
||||
return new CreateVMSnapshotAnswer(cmd, cmd.getTarget(), cmd.getVolumeTOs());
|
||||
} catch (Exception e) {
|
||||
String msg = e.getMessage();
|
||||
s_logger.error("Creating VM Snapshot " + cmd.getTarget().getSnapshotName() + " failed due to: " + msg);
|
||||
return new CreateVMSnapshotAnswer(cmd, false, msg);
|
||||
} finally {
|
||||
try {
|
||||
if (!success) {
|
||||
if (vmSnapshot != null) {
|
||||
s_logger.debug("Delete exsisting VM Snapshot "
|
||||
+ vmSnapshotName
|
||||
+ " after making VolumeTO failed");
|
||||
Set<VBD> vbds = vmSnapshot.getVBDs(conn);
|
||||
for (VBD vbd : vbds) {
|
||||
VBD.Record vbdr = vbd.getRecord(conn);
|
||||
if (vbdr.type == VbdType.DISK) {
|
||||
VDI vdi = vbdr.VDI;
|
||||
vdi.destroy(conn);
|
||||
}
|
||||
}
|
||||
vmSnapshot.destroy(conn);
|
||||
}
|
||||
}
|
||||
if (vmState == VirtualMachine.State.Stopped) {
|
||||
if (vm != null) {
|
||||
vm.destroy(conn);
|
||||
}
|
||||
}
|
||||
} catch (Exception e2) {
|
||||
s_logger.error("delete snapshot error due to "
|
||||
+ e2.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private VM createWorkingVM(Connection conn, String vmName,
|
||||
String guestOSType, List<VolumeTO> listVolumeTo)
|
||||
throws BadServerResponse, VmBadPowerState, SrFull,
|
||||
OperationNotAllowed, XenAPIException, XmlRpcException {
|
||||
String guestOsTypeName = getGuestOsType(guestOSType, false);
|
||||
if (guestOsTypeName == null) {
|
||||
String msg = " Hypervisor " + this.getClass().getName()
|
||||
+ " doesn't support guest OS type " + guestOSType
|
||||
+ ". you can choose 'Other install media' to run it as HVM";
|
||||
s_logger.warn(msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
VM template = getVM(conn, guestOsTypeName);
|
||||
VM vm = template.createClone(conn, vmName);
|
||||
vm.setIsATemplate(conn, false);
|
||||
Map<VDI, VolumeTO> vdiMap = new HashMap<VDI, VolumeTO>();
|
||||
for (VolumeTO volume : listVolumeTo) {
|
||||
String vdiUuid = volume.getPath();
|
||||
try {
|
||||
VDI vdi = VDI.getByUuid(conn, vdiUuid);
|
||||
vdiMap.put(vdi, volume);
|
||||
} catch (Types.UuidInvalid e) {
|
||||
s_logger.warn("Unable to find vdi by uuid: " + vdiUuid
|
||||
+ ", skip it");
|
||||
}
|
||||
}
|
||||
for (VDI vdi : vdiMap.keySet()) {
|
||||
VolumeTO volumeTO = vdiMap.get(vdi);
|
||||
VBD.Record vbdr = new VBD.Record();
|
||||
vbdr.VM = vm;
|
||||
vbdr.VDI = vdi;
|
||||
if (volumeTO.getType() == Volume.Type.ROOT) {
|
||||
vbdr.bootable = true;
|
||||
vbdr.unpluggable = false;
|
||||
} else {
|
||||
vbdr.bootable = false;
|
||||
vbdr.unpluggable = true;
|
||||
}
|
||||
vbdr.userdevice = new Long(volumeTO.getDeviceId()).toString();
|
||||
vbdr.mode = Types.VbdMode.RW;
|
||||
vbdr.type = Types.VbdType.DISK;
|
||||
VBD.create(conn, vbdr);
|
||||
}
|
||||
return vm;
|
||||
}
|
||||
|
||||
protected Answer execute(final DeleteVMSnapshotCommand cmd) {
|
||||
String snapshotName = cmd.getTarget().getSnapshotName();
|
||||
Connection conn = getConnection();
|
||||
|
||||
try {
|
||||
List<VDI> vdiList = new ArrayList<VDI>();
|
||||
Set<VM> snapshots = VM.getByNameLabel(conn, snapshotName);
|
||||
if(snapshots.size() == 0){
|
||||
s_logger.warn("VM snapshot with name " + snapshotName + " does not exist, assume it is already deleted");
|
||||
return new DeleteVMSnapshotAnswer(cmd, cmd.getVolumeTOs());
|
||||
}
|
||||
VM snapshot = snapshots.iterator().next();
|
||||
Set<VBD> vbds = snapshot.getVBDs(conn);
|
||||
for (VBD vbd : vbds) {
|
||||
if (vbd.getType(conn) == VbdType.DISK) {
|
||||
VDI vdi = vbd.getVDI(conn);
|
||||
vdiList.add(vdi);
|
||||
}
|
||||
}
|
||||
if(cmd.getTarget().getType() == VMSnapshot.Type.DiskAndMemory)
|
||||
vdiList.add(snapshot.getSuspendVDI(conn));
|
||||
snapshot.destroy(conn);
|
||||
for (VDI vdi : vdiList) {
|
||||
vdi.destroy(conn);
|
||||
}
|
||||
return new DeleteVMSnapshotAnswer(cmd, cmd.getVolumeTOs());
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("Catch Exception: " + e.getClass().toString()
|
||||
+ " due to " + e.toString(), e);
|
||||
return new DeleteVMSnapshotAnswer(cmd, false, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
protected Answer execute(final AttachIsoCommand cmd) {
|
||||
Connection conn = getConnection();
|
||||
boolean attach = cmd.isAttach();
|
||||
|
||||
18
pom.xml
18
pom.xml
@ -156,7 +156,6 @@
|
||||
<modules>
|
||||
<module>api</module>
|
||||
<module>agent</module>
|
||||
<module>console-proxy</module>
|
||||
<module>core</module>
|
||||
<module>server</module>
|
||||
<module>usage</module>
|
||||
@ -164,10 +163,11 @@
|
||||
<module>deps/XenServerJava</module>
|
||||
<module>plugins</module>
|
||||
<module>patches</module>
|
||||
<module>client</module>
|
||||
<module>test</module>
|
||||
<module>engine</module>
|
||||
<module>framework</module>
|
||||
<module>services</module>
|
||||
<module>test</module>
|
||||
<module>client</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
@ -361,7 +361,7 @@
|
||||
<exclude>**/target/**</exclude>
|
||||
<exclude>**/.vagrant</exclude>
|
||||
<exclude>build/build.number</exclude>
|
||||
<exclude>console-proxy/js/jquery.js</exclude>
|
||||
<exclude>services/console-proxy/server/js/jquery.js</exclude>
|
||||
<exclude>debian/compat</exclude>
|
||||
<exclude>debian/control</exclude>
|
||||
<exclude>debian/dirs</exclude>
|
||||
@ -372,6 +372,13 @@
|
||||
<exclude>dist/console-proxy/js/jquery.js</exclude>
|
||||
<exclude>scripts/vm/systemvm/id_rsa.cloud</exclude>
|
||||
<exclude>tools/devcloud/basebuild/puppet-devcloudinitial/files/network.conf</exclude>
|
||||
<exclude>tools/appliance/definitions/systemvmtemplate/base.sh</exclude>
|
||||
<exclude>tools/appliance/definitions/systemvmtemplate/cleanup.sh</exclude>
|
||||
<exclude>tools/appliance/definitions/systemvmtemplate/definition.rb</exclude>
|
||||
<exclude>tools/appliance/definitions/systemvmtemplate/preseed.cfg</exclude>
|
||||
<exclude>tools/appliance/definitions/systemvmtemplate/zerodisk.sh</exclude>
|
||||
<exclude>tools/devcloud/src/deps/boxes/basebox-build/definition.rb</exclude>
|
||||
<exclude>tools/devcloud/src/deps/boxes/basebox-build/preseed.cfg</exclude>
|
||||
<exclude>ui/lib/flot/jquery.colorhelpers.js</exclude>
|
||||
<exclude>ui/lib/flot/jquery.flot.crosshair.js</exclude>
|
||||
<exclude>ui/lib/flot/jquery.flot.fillbetween.js</exclude>
|
||||
@ -406,16 +413,13 @@
|
||||
<exclude>patches/systemvm/debian/config/etc/dnsmasq.conf</exclude>
|
||||
<exclude>patches/systemvm/debian/config/etc/vpcdnsmasq.conf</exclude>
|
||||
<exclude>patches/systemvm/debian/config/etc/ssh/sshd_config</exclude>
|
||||
<!-- Pending resolution of CLOUDSTACK-145 -->
|
||||
<exclude>patches/systemvm/debian/config/etc/rsyslog.conf</exclude>
|
||||
<!-- Pending resolution of CLOUDSTACK-147 -->
|
||||
<exclude>patches/systemvm/debian/config/etc/logrotate.conf</exclude>
|
||||
<exclude>patches/systemvm/debian/config/etc/logrotate.d/*</exclude>
|
||||
<exclude>patches/systemvm/debian/config/etc/sysctl.conf</exclude>
|
||||
<exclude>patches/systemvm/debian/config/root/redundant_router/keepalived.conf.templ</exclude>
|
||||
<exclude>patches/systemvm/debian/config/root/redundant_router/arping_gateways.sh.templ</exclude>
|
||||
<exclude>patches/systemvm/debian/config/root/redundant_router/conntrackd.conf.templ</exclude>
|
||||
<!-- Pending resolution of CLOUDSTACK-166 -->
|
||||
<exclude>patches/systemvm/debian/vpn/etc/ipsec.conf</exclude>
|
||||
<exclude>patches/systemvm/debian/vpn/etc/ppp/options.xl2tpd</exclude>
|
||||
<exclude>patches/systemvm/debian/vpn/etc/xl2tpd/xl2tpd.conf</exclude>
|
||||
|
||||
@ -73,7 +73,7 @@ class cloudManagementConfig(serviceCfgBase):
|
||||
bash("iptables -A PREROUTING -t nat -p tcp --dport 443 -j REDIRECT --to-port 8250 ")
|
||||
|
||||
#generate keystore
|
||||
keyPath = "/var/lib/cloud/management/web.keystore"
|
||||
keyPath = "/var/cloudstack/management/web.keystore"
|
||||
if not os.path.exists(keyPath):
|
||||
cmd = bash("keytool -genkey -keystore %s -storepass \"cloud.com\" -keypass \"cloud.com\" -validity 3650 -dname cn=\"Cloudstack User\",ou=\"mycloud.cloud.com\",o=\"mycloud.cloud.com\",c=\"Unknown\""%keyPath)
|
||||
|
||||
|
||||
@ -19,12 +19,12 @@
|
||||
|
||||
|
||||
|
||||
# Did cloud-agent installed
|
||||
# Did cloudstack-agent installed
|
||||
#set -x
|
||||
install_cloud_agent() {
|
||||
local dev=$1
|
||||
local retry=10
|
||||
which cloud-setup-agent
|
||||
which cloudstack-setup-agent
|
||||
if [ $? -gt 0 ]
|
||||
then
|
||||
# download the repo
|
||||
@ -51,7 +51,7 @@ install_cloud_agent() {
|
||||
while [ "$retry" -gt "0" ]
|
||||
do
|
||||
yum clean all
|
||||
yum install cloud-agent -y
|
||||
yum install cloudstack-agent -y
|
||||
if [ $? -gt 0 ]
|
||||
then
|
||||
let retry=retry-1
|
||||
@ -64,7 +64,7 @@ install_cloud_agent() {
|
||||
while [ "$retry" -gt "0" ]
|
||||
do
|
||||
yum clean all
|
||||
yum update cloud-agent -y
|
||||
yum update cloudstack-agent -y
|
||||
if [ $? -gt 0 ]
|
||||
then
|
||||
let retry=retry-1
|
||||
@ -155,7 +155,7 @@ cloud_agent_setup() {
|
||||
sed -i 's/\(SELINUX\)\(.*\)/\1=permissive/' /etc/selinux/config
|
||||
setenforce 0
|
||||
fi
|
||||
cloud-setup-agent --host=$host --zone=$zone --pod=$pod --cluster=$cluster --guid=$guid -a > /dev/null
|
||||
cloudstack-setup-agent --host=$host --zone=$zone --pod=$pod --cluster=$cluster --guid=$guid -a > /dev/null
|
||||
}
|
||||
|
||||
cloud_consoleP_setup() {
|
||||
@ -224,5 +224,5 @@ then
|
||||
setenforce 0
|
||||
fi
|
||||
|
||||
cloud-setup-agent --host=$host --zone=$zone --pod=$pod --cluster=$cluster --guid=$guid $paramters -a > /dev/null
|
||||
cloudstack-setup-agent --host=$host --zone=$zone --pod=$pod --cluster=$cluster --guid=$guid $paramters -a > /dev/null
|
||||
#cloud_consoleP_setup $host $zone $pod
|
||||
|
||||
@ -556,6 +556,33 @@ def deleteSnapshotBackup(session, args):
|
||||
|
||||
return "1"
|
||||
|
||||
if __name__ == "__main__":
|
||||
XenAPIPlugin.dispatch({"getVhdParent":getVhdParent, "create_secondary_storage_folder":create_secondary_storage_folder, "delete_secondary_storage_folder":delete_secondary_storage_folder, "post_create_private_template":post_create_private_template, "backupSnapshot": backupSnapshot, "deleteSnapshotBackup": deleteSnapshotBackup, "unmountSnapshotsDir": unmountSnapshotsDir})
|
||||
@echo
|
||||
def revert_memory_snapshot(session, args):
|
||||
util.SMlog("Calling revert_memory_snapshot with " + str(args))
|
||||
vmName = args['vmName']
|
||||
snapshotUUID = args['snapshotUUID']
|
||||
oldVmUuid = args['oldVmUuid']
|
||||
snapshotMemory = args['snapshotMemory']
|
||||
hostUUID = args['hostUUID']
|
||||
try:
|
||||
cmd = '''xe vbd-list vm-uuid=%s | grep 'vdi-uuid' | grep -v 'not in database' | sed -e 's/vdi-uuid ( RO)://g' ''' % oldVmUuid
|
||||
vdiUuids = os.popen(cmd).read().split()
|
||||
cmd2 = '''xe vm-param-get param-name=power-state uuid=''' + oldVmUuid
|
||||
if os.popen(cmd2).read().split()[0] != 'halted':
|
||||
os.system("xe vm-shutdown force=true vm=" + vmName)
|
||||
os.system("xe vm-destroy uuid=" + oldVmUuid)
|
||||
os.system("xe snapshot-revert snapshot-uuid=" + snapshotUUID)
|
||||
if snapshotMemory == 'true':
|
||||
os.system("xe vm-resume vm=" + vmName + " on=" + hostUUID)
|
||||
for vdiUuid in vdiUuids:
|
||||
os.system("xe vdi-destroy uuid=" + vdiUuid)
|
||||
except OSError, (errno, strerror):
|
||||
errMsg = "OSError while reverting vm " + vmName + " to snapshot " + snapshotUUID + " with errno: " + str(errno) + " and strerr: " + strerror
|
||||
util.SMlog(errMsg)
|
||||
raise xs_errors.XenError(errMsg)
|
||||
return "0"
|
||||
|
||||
if __name__ == "__main__":
|
||||
XenAPIPlugin.dispatch({"getVhdParent":getVhdParent, "create_secondary_storage_folder":create_secondary_storage_folder, "delete_secondary_storage_folder":delete_secondary_storage_folder, "post_create_private_template":post_create_private_template, "backupSnapshot": backupSnapshot, "deleteSnapshotBackup": deleteSnapshotBackup, "unmountSnapshotsDir": unmountSnapshotsDir, "revert_memory_snapshot":revert_memory_snapshot})
|
||||
|
||||
|
||||
|
||||
@ -209,6 +209,8 @@ import com.cloud.vm.dao.DomainRouterDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||
|
||||
@Component
|
||||
public class ApiDBUtils {
|
||||
@ -309,6 +311,7 @@ public class ApiDBUtils {
|
||||
static SnapshotPolicyDao _snapshotPolicyDao;
|
||||
static AsyncJobDao _asyncJobDao;
|
||||
static HostDetailsDao _hostDetailsDao;
|
||||
static VMSnapshotDao _vmSnapshotDao;
|
||||
|
||||
@Inject private ManagementServer ms;
|
||||
@Inject public AsyncJobManager asyncMgr;
|
||||
@ -407,7 +410,7 @@ public class ApiDBUtils {
|
||||
@Inject private SnapshotPolicyDao snapshotPolicyDao;
|
||||
@Inject private AsyncJobDao asyncJobDao;
|
||||
@Inject private HostDetailsDao hostDetailsDao;
|
||||
|
||||
@Inject private VMSnapshotDao vmSnapshotDao;
|
||||
@PostConstruct
|
||||
void init() {
|
||||
_ms = ms;
|
||||
@ -505,7 +508,7 @@ public class ApiDBUtils {
|
||||
_snapshotPolicyDao = snapshotPolicyDao;
|
||||
_asyncJobDao = asyncJobDao;
|
||||
_hostDetailsDao = hostDetailsDao;
|
||||
|
||||
_vmSnapshotDao = vmSnapshotDao;
|
||||
// Note: stats collector should already have been initialized by this time, otherwise a null instance is returned
|
||||
_statsCollector = StatsCollector.getInstance();
|
||||
}
|
||||
@ -1054,6 +1057,11 @@ public class ApiDBUtils {
|
||||
return _networkModel.canUseForDeploy(network);
|
||||
}
|
||||
|
||||
public static VMSnapshot getVMSnapshotById(Long vmSnapshotId) {
|
||||
VMSnapshot vmSnapshot = _vmSnapshotDao.findById(vmSnapshotId);
|
||||
return vmSnapshot;
|
||||
}
|
||||
|
||||
public static String getUuid(String resourceId, TaggedResourceType resourceType) {
|
||||
return _taggedResourceService.getUuid(resourceId, resourceType);
|
||||
}
|
||||
|
||||
@ -93,7 +93,6 @@ import org.apache.cloudstack.api.response.VpcOfferingResponse;
|
||||
import org.apache.cloudstack.api.response.VpcResponse;
|
||||
import org.apache.cloudstack.api.response.VpnUsersResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
|
||||
import org.apache.cloudstack.api.response.S3Response;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@ -195,6 +194,13 @@ import org.apache.cloudstack.region.Region;
|
||||
import org.apache.cloudstack.usage.Usage;
|
||||
import org.apache.cloudstack.usage.UsageService;
|
||||
import org.apache.cloudstack.usage.UsageTypes;
|
||||
import com.cloud.vm.VmStats;
|
||||
import com.cloud.vm.dao.UserVmData;
|
||||
import com.cloud.vm.dao.UserVmData.NicData;
|
||||
import com.cloud.vm.dao.UserVmData.SecurityGroupData;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
import org.apache.cloudstack.api.ResponseGenerator;
|
||||
import org.apache.cloudstack.api.response.VMSnapshotResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
@ -358,6 +364,25 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
return snapshotResponse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VMSnapshotResponse createVMSnapshotResponse(VMSnapshot vmSnapshot) {
|
||||
VMSnapshotResponse vmSnapshotResponse = new VMSnapshotResponse();
|
||||
vmSnapshotResponse.setId(vmSnapshot.getUuid());
|
||||
vmSnapshotResponse.setName(vmSnapshot.getName());
|
||||
vmSnapshotResponse.setState(vmSnapshot.getState());
|
||||
vmSnapshotResponse.setCreated(vmSnapshot.getCreated());
|
||||
vmSnapshotResponse.setDescription(vmSnapshot.getDescription());
|
||||
vmSnapshotResponse.setDisplayName(vmSnapshot.getDisplayName());
|
||||
UserVm vm = ApiDBUtils.findUserVmById(vmSnapshot.getVmId());
|
||||
if(vm!=null)
|
||||
vmSnapshotResponse.setVirtualMachineid(vm.getUuid());
|
||||
if(vmSnapshot.getParent() != null)
|
||||
vmSnapshotResponse.setParentName(ApiDBUtils.getVMSnapshotById(vmSnapshot.getParent()).getDisplayName());
|
||||
vmSnapshotResponse.setCurrent(vmSnapshot.getCurrent());
|
||||
vmSnapshotResponse.setType(vmSnapshot.getType().toString());
|
||||
return vmSnapshotResponse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SnapshotPolicyResponse createSnapshotPolicyResponse(SnapshotPolicy policy) {
|
||||
SnapshotPolicyResponse policyResponse = new SnapshotPolicyResponse();
|
||||
@ -3093,7 +3118,6 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
response.setObjectName("vpnconnection");
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuestOSResponse createGuestOSResponse(GuestOS guestOS) {
|
||||
GuestOSResponse response = new GuestOSResponse();
|
||||
@ -3133,7 +3157,6 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public UsageRecordResponse createUsageResponse(Usage usageRecord) {
|
||||
UsageRecordResponse usageRecResponse = new UsageRecordResponse();
|
||||
|
||||
@ -157,6 +157,24 @@ public class AccountJoinDaoImpl extends GenericDaoBase<AccountJoinVO, Long> impl
|
||||
accountResponse.setNetworkTotal(vpcTotal);
|
||||
accountResponse.setNetworkAvailable(vpcAvail);
|
||||
|
||||
//get resource limits for cpu cores
|
||||
long cpuLimit = ApiDBUtils.findCorrectResourceLimit(account.getCpuLimit(), account.getType(), ResourceType.cpu);
|
||||
String cpuLimitDisplay = (accountIsAdmin || cpuLimit == -1) ? "Unlimited" : String.valueOf(cpuLimit);
|
||||
long cpuTotal = (account.getCpuTotal() == null) ? 0 : account.getCpuTotal();
|
||||
String cpuAvail = (accountIsAdmin || cpuLimit == -1) ? "Unlimited" : String.valueOf(cpuLimit - cpuTotal);
|
||||
accountResponse.setCpuLimit(cpuLimitDisplay);
|
||||
accountResponse.setCpuTotal(cpuTotal);
|
||||
accountResponse.setCpuAvailable(cpuAvail);
|
||||
|
||||
//get resource limits for memory
|
||||
long memoryLimit = ApiDBUtils.findCorrectResourceLimit(account.getMemoryLimit(), account.getType(), ResourceType.memory);
|
||||
String memoryLimitDisplay = (accountIsAdmin || memoryLimit == -1) ? "Unlimited" : String.valueOf(memoryLimit);
|
||||
long memoryTotal = (account.getMemoryTotal() == null) ? 0 : account.getMemoryTotal();
|
||||
String memoryAvail = (accountIsAdmin || memoryLimit == -1) ? "Unlimited" : String.valueOf(memoryLimit - memoryTotal);
|
||||
accountResponse.setMemoryLimit(memoryLimitDisplay);
|
||||
accountResponse.setMemoryTotal(memoryTotal);
|
||||
accountResponse.setMemoryAvailable(memoryAvail);
|
||||
|
||||
// adding all the users for an account as part of the response obj
|
||||
List<UserAccountJoinVO> usersForAccount = ApiDBUtils.findUserViewByAccountId(account.getId());
|
||||
List<UserResponse> userResponses = ViewResponseHelper.createUserResponse(usersForAccount.toArray(new UserAccountJoinVO[usersForAccount.size()]));
|
||||
|
||||
@ -148,6 +148,20 @@ public class AccountJoinVO extends BaseViewVO implements InternalIdentity, Ident
|
||||
@Column(name="vpcTotal")
|
||||
private Long vpcTotal;
|
||||
|
||||
|
||||
@Column(name="cpuLimit")
|
||||
private Long cpuLimit;
|
||||
|
||||
@Column(name="cpuTotal")
|
||||
private Long cpuTotal;
|
||||
|
||||
|
||||
@Column(name="memoryLimit")
|
||||
private Long memoryLimit;
|
||||
|
||||
@Column(name="memoryTotal")
|
||||
private Long memoryTotal;
|
||||
|
||||
@Column(name="job_id")
|
||||
private long jobId;
|
||||
|
||||
@ -445,7 +459,6 @@ public class AccountJoinVO extends BaseViewVO implements InternalIdentity, Ident
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Long getVpcTotal() {
|
||||
return vpcTotal;
|
||||
}
|
||||
@ -456,6 +469,25 @@ public class AccountJoinVO extends BaseViewVO implements InternalIdentity, Ident
|
||||
}
|
||||
|
||||
|
||||
public Long getCpuTotal() {
|
||||
return cpuTotal;
|
||||
}
|
||||
|
||||
|
||||
public void setCpuTotal(Long cpuTotal) {
|
||||
this.cpuTotal = cpuTotal;
|
||||
}
|
||||
|
||||
public Long getMemoryTotal() {
|
||||
return memoryTotal;
|
||||
}
|
||||
|
||||
|
||||
public void setMemoryTotal(Long memoryTotal) {
|
||||
this.memoryTotal = memoryTotal;
|
||||
}
|
||||
|
||||
|
||||
public Long getVmLimit() {
|
||||
return vmLimit;
|
||||
}
|
||||
@ -536,6 +568,26 @@ public class AccountJoinVO extends BaseViewVO implements InternalIdentity, Ident
|
||||
}
|
||||
|
||||
|
||||
public Long getCpuLimit() {
|
||||
return cpuLimit;
|
||||
}
|
||||
|
||||
|
||||
public void setCpuLimit(Long cpuLimit) {
|
||||
this.cpuLimit = cpuLimit;
|
||||
}
|
||||
|
||||
|
||||
public Long getMemoryLimit() {
|
||||
return memoryLimit;
|
||||
}
|
||||
|
||||
|
||||
public void setMemoryLimit(Long memoryLimit) {
|
||||
this.memoryLimit = memoryLimit;
|
||||
}
|
||||
|
||||
|
||||
public long getJobId() {
|
||||
return jobId;
|
||||
}
|
||||
|
||||
@ -54,7 +54,12 @@ public class BareMetalTemplateAdapter extends TemplateAdapterBase implements Tem
|
||||
private final static Logger s_logger = Logger.getLogger(BareMetalTemplateAdapter.class);
|
||||
@Inject HostDao _hostDao;
|
||||
@Inject ResourceManager _resourceMgr;
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return TemplateAdapterType.BareMetal.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocationException {
|
||||
TemplateProfile profile = super.prepare(cmd);
|
||||
|
||||
@ -239,14 +239,14 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet
|
||||
_configMgr.checkZoneAccess(owner, dc);
|
||||
}
|
||||
|
||||
// check if account/domain is with in resource limits to create a new vm
|
||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.user_vm);
|
||||
|
||||
ServiceOfferingVO offering = _serviceOfferingDao.findById(cmd.getServiceOfferingId());
|
||||
if (offering == null || offering.getRemoved() != null) {
|
||||
throw new InvalidParameterValueException("Unable to find service offering: " + cmd.getServiceOfferingId());
|
||||
}
|
||||
|
||||
|
||||
// check if account/domain is with in resource limits to create a new vm
|
||||
resourceLimitCheck(owner, new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
||||
|
||||
VMTemplateVO template = _templateDao.findById(cmd.getTemplateId());
|
||||
// Make sure a valid template ID was specified
|
||||
if (template == null || template.getRemoved() != null) {
|
||||
@ -362,7 +362,7 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet
|
||||
vm.getHostName(), offering.getId(), template.getId(), HypervisorType.BareMetal.toString(),
|
||||
VirtualMachine.class.getName(), vm.getUuid());
|
||||
|
||||
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm);
|
||||
resourceCountIncrement(accountId, new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
||||
|
||||
// Assign instance to the group
|
||||
try {
|
||||
|
||||
@ -62,9 +62,11 @@ import com.cloud.storage.VMTemplateHostVO;
|
||||
import com.cloud.storage.VMTemplateStoragePoolVO;
|
||||
import com.cloud.storage.VMTemplateSwiftVO;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.VMTemplatePoolDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.storage.swift.SwiftManager;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.Pair;
|
||||
@ -78,7 +80,11 @@ import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.Event;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
import com.cloud.vm.snapshot.VMSnapshotVO;
|
||||
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||
|
||||
@Component
|
||||
@Local(value = CapacityManager.class)
|
||||
@ -110,7 +116,11 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
|
||||
ConfigurationManager _configMgr;
|
||||
@Inject
|
||||
HypervisorCapabilitiesDao _hypervisorCapabilitiesDao;
|
||||
|
||||
@Inject
|
||||
protected VMSnapshotDao _vmSnapshotDao;
|
||||
@Inject
|
||||
protected UserVmDao _userVMDao;
|
||||
|
||||
private int _vmCapacityReleaseInterval;
|
||||
private ScheduledExecutorService _executor;
|
||||
private boolean _stopped;
|
||||
@ -437,12 +447,43 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
|
||||
|
||||
}
|
||||
|
||||
private long getVMSnapshotAllocatedCapacity(StoragePoolVO pool){
|
||||
List<VolumeVO> volumes = _volumeDao.findByPoolId(pool.getId());
|
||||
long totalSize = 0;
|
||||
for (VolumeVO volume : volumes) {
|
||||
if(volume.getInstanceId() == null)
|
||||
continue;
|
||||
Long vmId = volume.getInstanceId();
|
||||
UserVm vm = _userVMDao.findById(vmId);
|
||||
if(vm == null)
|
||||
continue;
|
||||
ServiceOffering offering = _offeringsDao.findById(vm.getServiceOfferingId());
|
||||
List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
|
||||
long pathCount = 0;
|
||||
long memorySnapshotSize = 0;
|
||||
for (VMSnapshotVO vmSnapshotVO : vmSnapshots) {
|
||||
if(_vmSnapshotDao.listByParent(vmSnapshotVO.getId()).size() == 0)
|
||||
pathCount++;
|
||||
if(vmSnapshotVO.getType() == VMSnapshot.Type.DiskAndMemory)
|
||||
memorySnapshotSize += (offering.getRamSize() * 1024 * 1024);
|
||||
}
|
||||
if(pathCount <= 1)
|
||||
totalSize = totalSize + memorySnapshotSize;
|
||||
else
|
||||
totalSize = totalSize + volume.getSize() * (pathCount - 1) + memorySnapshotSize;
|
||||
}
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAllocatedPoolCapacity(StoragePoolVO pool, VMTemplateVO templateForVmCreation){
|
||||
|
||||
// Get size for all the volumes
|
||||
Pair<Long, Long> sizes = _volumeDao.getCountAndTotalByPool(pool.getId());
|
||||
long totalAllocatedSize = sizes.second() + sizes.first() * _extraBytesPerVolume;
|
||||
|
||||
// Get size for VM Snapshots
|
||||
totalAllocatedSize = totalAllocatedSize + getVMSnapshotAllocatedCapacity(pool);
|
||||
|
||||
// Iterate through all templates on this storage pool
|
||||
boolean tmpinstalled = false;
|
||||
|
||||
@ -33,6 +33,7 @@ import com.cloud.storage.secondary.SecondaryStorageVmManager;
|
||||
import com.cloud.storage.snapshot.SnapshotManager;
|
||||
import com.cloud.template.TemplateManager;
|
||||
import com.cloud.vm.UserVmManager;
|
||||
import com.cloud.vm.snapshot.VMSnapshotManager;
|
||||
|
||||
public enum Config {
|
||||
|
||||
@ -179,7 +180,7 @@ public enum Config {
|
||||
MigrateWait("Advanced", AgentManager.class, Integer.class, "migratewait", "3600", "Time (in seconds) to wait for VM migrate finish", null),
|
||||
Workers("Advanced", AgentManager.class, Integer.class, "workers", "5", "Number of worker threads.", null),
|
||||
HAWorkers("Advanced", AgentManager.class, Integer.class, "ha.workers", "5", "Number of ha worker threads.", null),
|
||||
MountParent("Advanced", ManagementServer.class, String.class, "mount.parent", "/var/lib/cloud/management/mnt", "The mount point on the Management Server for Secondary Storage.", null),
|
||||
MountParent("Advanced", ManagementServer.class, String.class, "mount.parent", "/var/cloudstack/mnt", "The mount point on the Management Server for Secondary Storage.", null),
|
||||
// UpgradeURL("Advanced", ManagementServer.class, String.class, "upgrade.url", "http://example.com:8080/client/agent/update.zip", "The upgrade URL is the URL of the management server that agents will connect to in order to automatically upgrade.", null),
|
||||
SystemVMUseLocalStorage("Advanced", ManagementServer.class, Boolean.class, "system.vm.use.local.storage", "false", "Indicates whether to use local storage pools or shared storage pools for system VMs.", null),
|
||||
SystemVMAutoReserveCapacity("Advanced", ManagementServer.class, Boolean.class, "system.vm.auto.reserve.capacity", "true", "Indicates whether or not to automatically reserver system VM standby capacity.", null),
|
||||
@ -308,6 +309,8 @@ public enum Config {
|
||||
DefaultMaxAccountVolumes("Account Defaults", ManagementServer.class, Long.class, "max.account.volumes", "20", "The default maximum number of volumes that can be created for an account", null),
|
||||
DefaultMaxAccountNetworks("Account Defaults", ManagementServer.class, Long.class, "max.account.networks", "20", "The default maximum number of networks that can be created for an account", null),
|
||||
DefaultMaxAccountVpcs("Account Defaults", ManagementServer.class, Long.class, "max.account.vpcs", "20", "The default maximum number of vpcs that can be created for an account", null),
|
||||
DefaultMaxAccountCpus("Account Defaults", ManagementServer.class, Long.class, "max.account.cpus", "40", "The default maximum number of cpu cores that can be used for an account", null),
|
||||
DefaultMaxAccountMemory("Account Defaults", ManagementServer.class, Long.class, "max.account.memory", "40960", "The default maximum memory (in MB) that can be used for an account", null),
|
||||
|
||||
|
||||
ResourceCountCheckInterval("Advanced", ManagementServer.class, Long.class, "resourcecount.check.interval", "0", "Time (in seconds) to wait before retrying resource count check task. Default is 0 which is to never run the task", "Seconds"),
|
||||
@ -332,6 +335,8 @@ public enum Config {
|
||||
DefaultMaxProjectVolumes("Project Defaults", ManagementServer.class, Long.class, "max.project.volumes", "20", "The default maximum number of volumes that can be created for a project", null),
|
||||
DefaultMaxProjectNetworks("Project Defaults", ManagementServer.class, Long.class, "max.project.networks", "20", "The default maximum number of networks that can be created for a project", null),
|
||||
DefaultMaxProjectVpcs("Project Defaults", ManagementServer.class, Long.class, "max.project.vpcs", "20", "The default maximum number of vpcs that can be created for a project", null),
|
||||
DefaultMaxProjectCpus("Project Defaults", ManagementServer.class, Long.class, "max.project.cpus", "40", "The default maximum number of cpu cores that can be used for a project", null),
|
||||
DefaultMaxProjectMemory("Project Defaults", ManagementServer.class, Long.class, "max.project.memory", "40960", "The default maximum memory (in MB) that can be used for a project", null),
|
||||
|
||||
ProjectInviteRequired("Project Defaults", ManagementServer.class, Boolean.class, "project.invite.required", "false", "If invitation confirmation is required when add account to project. Default value is false", null),
|
||||
ProjectInvitationExpirationTime("Project Defaults", ManagementServer.class, Long.class, "project.invite.timeout", "86400", "Invitation expiration time (in seconds). Default is 1 day - 86400 seconds", null),
|
||||
@ -367,8 +372,16 @@ public enum Config {
|
||||
|
||||
ApiLimitInterval("Advanced", ManagementServer.class, Integer.class, "api.throttling.interval", "1", "Time interval (in seconds) to reset API count", null),
|
||||
ApiLimitMax("Advanced", ManagementServer.class, Integer.class, "api.throttling.max", "25", "Max allowed number of APIs within fixed interval", null),
|
||||
ApiLimitCacheSize("Advanced", ManagementServer.class, Integer.class, "api.throttling.cachesize", "50000", "Account based API count cache size", null);
|
||||
ApiLimitCacheSize("Advanced", ManagementServer.class, Integer.class, "api.throttling.cachesize", "50000", "Account based API count cache size", null),
|
||||
|
||||
|
||||
// VMSnapshots
|
||||
VMSnapshotMax("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.max", "10", "Maximum vm snapshots for a vm", null),
|
||||
VMSnapshotCreateWait("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.create.wait", "600", "In second, timeout for create vm snapshot", null),
|
||||
VMSnapshotExpungeInterval("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.expunge.interval", "60", "The interval (in seconds) to wait before running the expunge thread.", null),
|
||||
VMSnapshotExpungeWorkers("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.expunge.workers", "1", "Number of workers performing expunge ", null);
|
||||
|
||||
|
||||
private final String _category;
|
||||
private final Class<?> _componentClass;
|
||||
private final Class<?> _type;
|
||||
|
||||
@ -212,7 +212,7 @@ Listener, ResourceStateAdapter {
|
||||
parameters += " --prvNic=" + kvmPrivateNic;
|
||||
parameters += " --guestNic=" + kvmGuestNic;
|
||||
|
||||
SSHCmdHelper.sshExecuteCmd(sshConnection, "cloud-setup-agent " + parameters, 3);
|
||||
SSHCmdHelper.sshExecuteCmd(sshConnection, "cloudstack-setup-agent " + parameters, 3);
|
||||
|
||||
KvmDummyResourceBase kvmResource = new KvmDummyResourceBase();
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
|
||||
@ -98,6 +98,7 @@ import com.cloud.network.dao.PhysicalNetworkVO;
|
||||
import com.cloud.network.dao.UserIpv6AddressDao;
|
||||
import com.cloud.network.element.DhcpServiceProvider;
|
||||
import com.cloud.network.element.IpDeployer;
|
||||
import com.cloud.network.element.IpDeployingRequester;
|
||||
import com.cloud.network.element.LoadBalancingServiceProvider;
|
||||
import com.cloud.network.element.NetworkElement;
|
||||
import com.cloud.network.element.StaticNatServiceProvider;
|
||||
@ -536,9 +537,11 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L
|
||||
}
|
||||
IpDeployer deployer = null;
|
||||
NetworkElement element = _networkModel.getElementImplementingProvider(provider.getName());
|
||||
if (element instanceof IpDeployer) {
|
||||
deployer = (IpDeployer) element;
|
||||
} else {
|
||||
if (!(element instanceof IpDeployingRequester)) {
|
||||
throw new CloudRuntimeException("Element " + element + " is not a IpDeployingRequester!");
|
||||
}
|
||||
deployer = ((IpDeployingRequester)element).getIpDeployer(network);
|
||||
if (deployer == null) {
|
||||
throw new CloudRuntimeException("Fail to get ip deployer for element: " + element);
|
||||
}
|
||||
Set<Service> services = new HashSet<Service>();
|
||||
|
||||
@ -75,6 +75,8 @@ import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
|
||||
import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
|
||||
import com.cloud.network.dao.PhysicalNetworkVO;
|
||||
import com.cloud.network.dao.UserIpv6AddressDao;
|
||||
import com.cloud.network.element.IpDeployer;
|
||||
import com.cloud.network.element.IpDeployingRequester;
|
||||
import com.cloud.network.element.NetworkElement;
|
||||
import com.cloud.network.element.UserDataServiceProvider;
|
||||
import com.cloud.network.rules.FirewallRule.Purpose;
|
||||
@ -390,9 +392,18 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
|
||||
throw new InvalidParameterException("There is no new provider for IP " + publicIp.getAddress() + " of service " + service.getName() + "!");
|
||||
}
|
||||
Provider newProvider = (Provider) newProviders.toArray()[0];
|
||||
if (!oldProvider.equals(newProvider)) {
|
||||
throw new InvalidParameterException("There would be multiple providers for IP " + publicIp.getAddress() + "!");
|
||||
}
|
||||
Network network = _networksDao.findById(networkId);
|
||||
NetworkElement oldElement = getElementImplementingProvider(oldProvider.getName());
|
||||
NetworkElement newElement = getElementImplementingProvider(newProvider.getName());
|
||||
if (oldElement instanceof IpDeployingRequester && newElement instanceof IpDeployingRequester) {
|
||||
IpDeployer oldIpDeployer = ((IpDeployingRequester)oldElement).getIpDeployer(network);
|
||||
IpDeployer newIpDeployer = ((IpDeployingRequester)newElement).getIpDeployer(network);
|
||||
if (!oldIpDeployer.getProvider().getName().equals(newIpDeployer.getProvider().getName())) {
|
||||
throw new InvalidParameterException("There would be multiple providers for IP " + publicIp.getAddress() + "!");
|
||||
}
|
||||
} else {
|
||||
throw new InvalidParameterException("Ip cannot be applied for new provider!");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -333,6 +333,18 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
|
||||
private boolean canIpsUseOffering(List<PublicIp> publicIps, long offeringId) {
|
||||
Map<PublicIp, Set<Service>> ipToServices = getIpToServices(publicIps, false, true);
|
||||
Map<Service, Set<Provider>> serviceToProviders = _networkModel.getNetworkOfferingServiceProvidersMap(offeringId);
|
||||
NetworkOfferingVO offering = _networkOfferingDao.findById(offeringId);
|
||||
//For inline mode checking, using firewall provider for LB instead, because public ip would apply on firewall provider
|
||||
if (offering.isInline()) {
|
||||
Provider firewallProvider = null;
|
||||
if (serviceToProviders.containsKey(Service.Firewall)) {
|
||||
firewallProvider = (Provider)serviceToProviders.get(Service.Firewall).toArray()[0];
|
||||
}
|
||||
Set<Provider> p = new HashSet<Provider>();
|
||||
p.add(firewallProvider);
|
||||
serviceToProviders.remove(Service.Lb);
|
||||
serviceToProviders.put(Service.Lb, p);
|
||||
}
|
||||
for (PublicIp ip : ipToServices.keySet()) {
|
||||
Set<Service> services = ipToServices.get(ip);
|
||||
Provider provider = null;
|
||||
|
||||
@ -536,12 +536,23 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
|
||||
switch (purpose){
|
||||
case Firewall:
|
||||
for (FirewallServiceProvider fwElement: _firewallElements) {
|
||||
Network.Provider provider = fwElement.getProvider();
|
||||
boolean isFwProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Firewall, provider);
|
||||
if (!isFwProvider) {
|
||||
continue;
|
||||
}
|
||||
handled = fwElement.applyFWRules(network, rules);
|
||||
if (handled)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PortForwarding:
|
||||
for (PortForwardingServiceProvider element: _pfElements) {
|
||||
Network.Provider provider = element.getProvider();
|
||||
boolean isPfProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.PortForwarding, provider);
|
||||
if (!isPfProvider) {
|
||||
continue;
|
||||
}
|
||||
handled = element.applyPFRules(network, (List<PortForwardingRule>) rules);
|
||||
if (handled)
|
||||
break;
|
||||
@ -549,6 +560,11 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
|
||||
break;
|
||||
case StaticNat:
|
||||
for (StaticNatServiceProvider element: _staticNatElements) {
|
||||
Network.Provider provider = element.getProvider();
|
||||
boolean isSnatProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.StaticNat, provider);
|
||||
if (!isSnatProvider) {
|
||||
continue;
|
||||
}
|
||||
handled = element.applyStaticNats(network, (List<? extends StaticNat>) rules);
|
||||
if (handled)
|
||||
break;
|
||||
@ -556,6 +572,11 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
|
||||
break;
|
||||
case NetworkACL:
|
||||
for (NetworkACLServiceProvider element: _networkAclElements) {
|
||||
Network.Provider provider = element.getProvider();
|
||||
boolean isAclProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.NetworkACL, provider);
|
||||
if (!isAclProvider) {
|
||||
continue;
|
||||
}
|
||||
handled = element.applyNetworkACLs(network, rules);
|
||||
if (handled)
|
||||
break;
|
||||
|
||||
@ -1158,6 +1158,11 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
|
||||
assert(purpose == Purpose.LoadBalancing): "LB Manager asked to handle non-LB rules";
|
||||
boolean handled = false;
|
||||
for (LoadBalancingServiceProvider lbElement: _lbProviders) {
|
||||
Provider provider = lbElement.getProvider();
|
||||
boolean isLbProvider = _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Lb, provider);
|
||||
if (!isLbProvider) {
|
||||
continue;
|
||||
}
|
||||
handled = lbElement.applyLBRules(network, (List<LoadBalancingRule>) rules);
|
||||
if (handled)
|
||||
break;
|
||||
|
||||
@ -412,7 +412,8 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
||||
|
||||
// Verify input parameters
|
||||
boolean performedIpAssoc = false;
|
||||
boolean result = false;
|
||||
boolean isOneToOneNat = ipAddress.isOneToOneNat();
|
||||
Long associatedWithVmId = ipAddress.getAssociatedWithVmId();
|
||||
try {
|
||||
Network network = _networkModel.getNetwork(networkId);
|
||||
if (network == null) {
|
||||
@ -476,28 +477,26 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
||||
// enable static nat on the backend
|
||||
s_logger.trace("Enabling static nat for ip address " + ipAddress + " and vm id=" + vmId + " on the backend");
|
||||
if (applyStaticNatForIp(ipId, false, caller, false)) {
|
||||
result = true;
|
||||
performedIpAssoc = false; // ignor unassignIPFromVpcNetwork in finally block
|
||||
return true;
|
||||
} else {
|
||||
s_logger.warn("Failed to enable static nat rule for ip address " + ipId + " on the backend");
|
||||
ipAddress.setOneToOneNat(isOneToOneNat);
|
||||
ipAddress.setAssociatedWithVmId(associatedWithVmId);
|
||||
_ipAddressDao.update(ipAddress.getId(), ipAddress);
|
||||
}
|
||||
} else {
|
||||
s_logger.warn("Failed to update ip address " + ipAddress + " in the DB as a part of enableStaticNat");
|
||||
|
||||
}
|
||||
} finally {
|
||||
if (!result) {
|
||||
ipAddress.setOneToOneNat(false);
|
||||
ipAddress.setAssociatedWithVmId(null);
|
||||
_ipAddressDao.update(ipAddress.getId(), ipAddress);
|
||||
|
||||
if (performedIpAssoc) {
|
||||
//if the rule is the last one for the ip address assigned to VPC, unassign it from the network
|
||||
IpAddress ip = _ipAddressDao.findById(ipAddress.getId());
|
||||
_vpcMgr.unassignIPFromVpcNetwork(ip.getId(), networkId);
|
||||
}
|
||||
if (performedIpAssoc) {
|
||||
//if the rule is the last one for the ip address assigned to VPC, unassign it from the network
|
||||
IpAddress ip = _ipAddressDao.findById(ipAddress.getId());
|
||||
_vpcMgr.unassignIPFromVpcNetwork(ip.getId(), networkId);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void isIpReadyForStaticNat(long vmId, IPAddressVO ipAddress, Account caller, long callerUserId)
|
||||
|
||||
@ -2361,7 +2361,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
ResourceState.Event.AdminCancelMaintenance, _nodeId);
|
||||
_agentMgr.pullAgentOutMaintenance(hostId);
|
||||
|
||||
// for kvm, need to log into kvm host, restart cloud-agent
|
||||
// for kvm, need to log into kvm host, restart cloudstack-agent
|
||||
if (host.getHypervisorType() == HypervisorType.KVM) {
|
||||
_hostDao.loadDetails(host);
|
||||
String password = host.getDetail("password");
|
||||
@ -2382,7 +2382,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
|
||||
try {
|
||||
SSHCmdHelper.sshExecuteCmdOneShot(connection,
|
||||
"service cloud-agent restart");
|
||||
"service cloudstack-agent restart");
|
||||
} catch (sshException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -29,10 +29,10 @@ import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import com.cloud.alert.AlertManager;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.Resource;
|
||||
@ -59,9 +59,12 @@ import com.cloud.projects.Project;
|
||||
import com.cloud.projects.ProjectAccount.Role;
|
||||
import com.cloud.projects.dao.ProjectAccountDao;
|
||||
import com.cloud.projects.dao.ProjectDao;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.storage.dao.SnapshotDao;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.storage.dao.VolumeDaoImpl.SumCount;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.AccountVO;
|
||||
@ -69,15 +72,21 @@ import com.cloud.user.ResourceLimitService;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.concurrency.NamedThreadFactory;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericSearchBuilder;
|
||||
import com.cloud.utils.db.JoinBuilder;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria.Func;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
@ -124,6 +133,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
||||
private NetworkDao _networkDao;
|
||||
@Inject
|
||||
private VpcDao _vpcDao;
|
||||
@Inject
|
||||
private ServiceOfferingDao _serviceOfferingDao;
|
||||
|
||||
protected SearchBuilder<ResourceCountVO> ResourceCountSearch;
|
||||
ScheduledExecutorService _rcExecutor;
|
||||
@ -165,6 +176,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
||||
projectResourceLimitMap.put(Resource.ResourceType.volume, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectVolumes.key())));
|
||||
projectResourceLimitMap.put(Resource.ResourceType.network, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectNetworks.key())));
|
||||
projectResourceLimitMap.put(Resource.ResourceType.vpc, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectVpcs.key())));
|
||||
projectResourceLimitMap.put(Resource.ResourceType.cpu, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectCpus.key())));
|
||||
projectResourceLimitMap.put(Resource.ResourceType.memory, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectMemory.key())));
|
||||
|
||||
accountResourceLimitMap.put(Resource.ResourceType.public_ip, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountPublicIPs.key())));
|
||||
accountResourceLimitMap.put(Resource.ResourceType.snapshot, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountSnapshots.key())));
|
||||
@ -173,6 +186,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
||||
accountResourceLimitMap.put(Resource.ResourceType.volume, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountVolumes.key())));
|
||||
accountResourceLimitMap.put(Resource.ResourceType.network, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountNetworks.key())));
|
||||
accountResourceLimitMap.put(Resource.ResourceType.vpc, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountVpcs.key())));
|
||||
accountResourceLimitMap.put(Resource.ResourceType.cpu, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountCpus.key())));
|
||||
accountResourceLimitMap.put(Resource.ResourceType.memory, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountMemory.key())));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -769,7 +784,11 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
||||
} else if (type == Resource.ResourceType.network) {
|
||||
newCount = _networkDao.countNetworksUserCanCreate(accountId);
|
||||
} else if (type == Resource.ResourceType.vpc) {
|
||||
newCount = _vpcDao.countByAccountId(accountId);
|
||||
newCount = _vpcDao.countByAccountId(accountId);
|
||||
} else if (type == Resource.ResourceType.cpu) {
|
||||
newCount = countCpusForAccount(accountId);
|
||||
} else if (type == Resource.ResourceType.memory) {
|
||||
newCount = calculateMemoryForAccount(accountId);
|
||||
} else {
|
||||
throw new InvalidParameterValueException("Unsupported resource type " + type);
|
||||
}
|
||||
@ -784,6 +803,50 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
|
||||
return (newCount == null) ? 0 : newCount.longValue();
|
||||
}
|
||||
|
||||
public long countCpusForAccount(long accountId) {
|
||||
GenericSearchBuilder<ServiceOfferingVO, SumCount> cpuSearch = _serviceOfferingDao.createSearchBuilder(SumCount.class);
|
||||
cpuSearch.select("sum", Func.SUM, cpuSearch.entity().getCpu());
|
||||
SearchBuilder<UserVmVO> join1 = _userVmDao.createSearchBuilder();
|
||||
join1.and("accountId", join1.entity().getAccountId(), Op.EQ);
|
||||
join1.and("type", join1.entity().getType(), Op.EQ);
|
||||
join1.and("state", join1.entity().getState(), SearchCriteria.Op.NIN);
|
||||
cpuSearch.join("offerings", join1, cpuSearch.entity().getId(), join1.entity().getServiceOfferingId(), JoinBuilder.JoinType.INNER);
|
||||
cpuSearch.done();
|
||||
|
||||
SearchCriteria<SumCount> sc = cpuSearch.create();
|
||||
sc.setJoinParameters("offerings", "accountId", accountId);
|
||||
sc.setJoinParameters("offerings", "type", VirtualMachine.Type.User);
|
||||
sc.setJoinParameters("offerings", "state", new Object[] {State.Destroyed, State.Error, State.Expunging});
|
||||
List<SumCount> cpus = _serviceOfferingDao.customSearch(sc, null);
|
||||
if (cpus != null) {
|
||||
return cpus.get(0).sum;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public long calculateMemoryForAccount(long accountId) {
|
||||
GenericSearchBuilder<ServiceOfferingVO, SumCount> memorySearch = _serviceOfferingDao.createSearchBuilder(SumCount.class);
|
||||
memorySearch.select("sum", Func.SUM, memorySearch.entity().getRamSize());
|
||||
SearchBuilder<UserVmVO> join1 = _userVmDao.createSearchBuilder();
|
||||
join1.and("accountId", join1.entity().getAccountId(), Op.EQ);
|
||||
join1.and("type", join1.entity().getType(), Op.EQ);
|
||||
join1.and("state", join1.entity().getState(), SearchCriteria.Op.NIN);
|
||||
memorySearch.join("offerings", join1, memorySearch.entity().getId(), join1.entity().getServiceOfferingId(), JoinBuilder.JoinType.INNER);
|
||||
memorySearch.done();
|
||||
|
||||
SearchCriteria<SumCount> sc = memorySearch.create();
|
||||
sc.setJoinParameters("offerings", "accountId", accountId);
|
||||
sc.setJoinParameters("offerings", "type", VirtualMachine.Type.User);
|
||||
sc.setJoinParameters("offerings", "state", new Object[] {State.Destroyed, State.Error, State.Expunging});
|
||||
List<SumCount> memory = _serviceOfferingDao.customSearch(sc, null);
|
||||
if (memory != null) {
|
||||
return memory.get(0).sum;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getResourceCount(Account account, ResourceType type) {
|
||||
return _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type);
|
||||
|
||||
@ -99,6 +99,10 @@ import org.apache.cloudstack.api.command.user.tag.*;
|
||||
import org.apache.cloudstack.api.command.user.template.*;
|
||||
import org.apache.cloudstack.api.command.user.vm.*;
|
||||
import org.apache.cloudstack.api.command.user.vmgroup.*;
|
||||
import org.apache.cloudstack.api.command.user.vmsnapshot.CreateVMSnapshotCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmsnapshot.DeleteVMSnapshotCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmsnapshot.RevertToSnapshotCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.*;
|
||||
import org.apache.cloudstack.api.command.user.vpc.*;
|
||||
import org.apache.cloudstack.api.command.user.vpn.*;
|
||||
@ -2143,6 +2147,10 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
||||
cmdList.add(ResetVpnConnectionCmd.class);
|
||||
cmdList.add(UpdateVpnCustomerGatewayCmd.class);
|
||||
cmdList.add(ListZonesByCmd.class);
|
||||
cmdList.add(ListVMSnapshotCmd.class);
|
||||
cmdList.add(CreateVMSnapshotCmd.class);
|
||||
cmdList.add(RevertToSnapshotCmd.class);
|
||||
cmdList.add(DeleteVMSnapshotCmd.class);
|
||||
return cmdList;
|
||||
}
|
||||
|
||||
|
||||
@ -104,6 +104,9 @@ import org.apache.log4j.Logger;
|
||||
import javax.ejb.Local;
|
||||
import javax.naming.ConfigurationException;
|
||||
import java.util.*;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
import com.cloud.vm.snapshot.VMSnapshotVO;
|
||||
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||
|
||||
@Component
|
||||
@Local(value = { SnapshotManager.class, SnapshotService.class })
|
||||
@ -167,7 +170,9 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
|
||||
private ResourceTagDao _resourceTagDao;
|
||||
@Inject
|
||||
private ConfigurationDao _configDao;
|
||||
|
||||
@Inject
|
||||
private VMSnapshotDao _vmSnapshotDao;
|
||||
String _name;
|
||||
private int _totalRetries;
|
||||
private int _pauseInterval;
|
||||
private int _deltaSnapshotMax;
|
||||
@ -395,6 +400,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
|
||||
}
|
||||
|
||||
// if volume is attached to a vm in destroyed or expunging state; disallow
|
||||
// if volume is attached to a vm in taking vm snapshot; disallow
|
||||
if (volume.getInstanceId() != null) {
|
||||
UserVmVO userVm = _vmDao.findById(volume.getInstanceId());
|
||||
if (userVm != null) {
|
||||
@ -408,6 +414,12 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager,
|
||||
if(activeSnapshots.size() > 1)
|
||||
throw new CloudRuntimeException("There is other active snapshot tasks on the instance to which the volume is attached, please try again later");
|
||||
}
|
||||
List<VMSnapshotVO> activeVMSnapshots = _vmSnapshotDao.listByInstanceId(userVm.getId(),
|
||||
VMSnapshot.State.Creating, VMSnapshot.State.Reverting, VMSnapshot.State.Expunging);
|
||||
if (activeVMSnapshots.size() > 0) {
|
||||
throw new CloudRuntimeException(
|
||||
"There is other active vm snapshot tasks on the instance to which the volume is attached, please try again later");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -73,6 +73,7 @@ import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.uuididentity.dao.IdentityDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||
|
||||
|
||||
@Component
|
||||
@ -121,6 +122,8 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso
|
||||
VpcDao _vpcDao;
|
||||
@Inject
|
||||
StaticRouteDao _staticRouteDao;
|
||||
@Inject
|
||||
VMSnapshotDao _vmSnapshotDao;
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
@ -139,6 +142,7 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso
|
||||
_daoMap.put(TaggedResourceType.Vpc, _vpcDao);
|
||||
_daoMap.put(TaggedResourceType.NetworkACL, _firewallDao);
|
||||
_daoMap.put(TaggedResourceType.StaticRoute, _staticRouteDao);
|
||||
_daoMap.put(TaggedResourceType.VMSnapshot, _vmSnapshotDao);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -70,6 +70,11 @@ public class HyervisorTemplateAdapter extends TemplateAdapterBase implements Tem
|
||||
@Inject DownloadMonitor _downloadMonitor;
|
||||
@Inject SecondaryStorageVmManager _ssvmMgr;
|
||||
@Inject AgentManager _agentMgr;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return TemplateAdapterType.Hypervisor.getName();
|
||||
}
|
||||
|
||||
private String validateUrl(String url) {
|
||||
try {
|
||||
|
||||
@ -218,7 +218,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||
private IPAddressDao _ipAddressDao;
|
||||
@Inject
|
||||
private RegionManager _regionMgr;
|
||||
|
||||
@Inject
|
||||
private VpcManager _vpcMgr;
|
||||
@Inject
|
||||
private DomainRouterDao _routerDao;
|
||||
|
||||
@ -249,12 +249,37 @@ import com.cloud.utils.exception.ExecutionException;
|
||||
import com.cloud.utils.fsm.NoTransitionException;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.dao.*;
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vm.RecoverVMCmd;
|
||||
import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd;
|
||||
import org.apache.cloudstack.api.command.user.vm.*;
|
||||
import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.naming.ConfigurationException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import com.cloud.vm.dao.InstanceGroupDao;
|
||||
import com.cloud.vm.dao.InstanceGroupVMMapDao;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
import com.cloud.vm.snapshot.VMSnapshotManager;
|
||||
import com.cloud.vm.snapshot.VMSnapshotVO;
|
||||
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||
|
||||
@Local(value = { UserVmManager.class, UserVmService.class })
|
||||
public class UserVmManagerImpl extends ManagerBase implements UserVmManager, UserVmService {
|
||||
@ -392,7 +417,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
protected GuestOSCategoryDao _guestOSCategoryDao;
|
||||
@Inject
|
||||
UsageEventDao _usageEventDao;
|
||||
|
||||
@Inject
|
||||
protected VMSnapshotDao _vmSnapshotDao;
|
||||
@Inject
|
||||
protected VMSnapshotManager _vmSnapshotMgr;
|
||||
|
||||
protected ScheduledExecutorService _executor = null;
|
||||
protected int _expungeInterval;
|
||||
protected int _expungeDelay;
|
||||
@ -418,6 +447,24 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
return _vmDao.listByHostId(hostId);
|
||||
}
|
||||
|
||||
protected void resourceLimitCheck (Account owner, Long cpu, Long memory) throws ResourceAllocationException {
|
||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.user_vm);
|
||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.cpu, cpu);
|
||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.memory, memory);
|
||||
}
|
||||
|
||||
protected void resourceCountIncrement (long accountId, Long cpu, Long memory) {
|
||||
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm);
|
||||
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.cpu, cpu);
|
||||
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.memory, memory);
|
||||
}
|
||||
|
||||
protected void resourceCountDecrement (long accountId, Long cpu, Long memory) {
|
||||
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.user_vm);
|
||||
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.cpu, cpu);
|
||||
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.memory, memory);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VM_RESETPASSWORD, eventDescription = "resetting Vm password", async = true)
|
||||
public UserVm resetVMPassword(ResetVMPasswordCmd cmd, String password)
|
||||
@ -795,7 +842,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
// permission check
|
||||
_accountMgr.checkAccess(caller, null, true, volume, vm);
|
||||
|
||||
// Check if volume is stored on secondary Storage.
|
||||
//check if vm has snapshot, if true: can't attache volume
|
||||
boolean attach = true;
|
||||
checkVMSnapshots(vm, volumeId, attach);
|
||||
|
||||
// Check if volume is stored on secondary Storage.
|
||||
//Check if volume is stored on secondary Storage.
|
||||
boolean isVolumeOnSec = false;
|
||||
VolumeHostVO volHostVO = _volumeHostDao.findByVolumeId(volume.getId());
|
||||
if (volHostVO != null) {
|
||||
@ -1088,8 +1140,19 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
}
|
||||
}
|
||||
|
||||
private void checkVMSnapshots(UserVmVO vm, Long volumeId, boolean attach) {
|
||||
// Check that if vm has any VM snapshot
|
||||
Long vmId = vm.getId();
|
||||
List<VMSnapshotVO> listSnapshot = _vmSnapshotDao.listByInstanceId(vmId,
|
||||
VMSnapshot.State.Ready, VMSnapshot.State.Creating, VMSnapshot.State.Reverting, VMSnapshot.State.Expunging);
|
||||
if (listSnapshot != null && listSnapshot.size() != 0) {
|
||||
throw new InvalidParameterValueException(
|
||||
"The VM has VM snapshots, do not allowed to attach volume. Please delete the VM snapshots first.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume", async = true)
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "event_detaching_volume1", async = true)
|
||||
public Volume detachVolumeFromVM(DetachVolumeCmd cmmd) {
|
||||
Account caller = UserContext.current().getCaller();
|
||||
if ((cmmd.getId() == null && cmmd.getDeviceId() == null && cmmd
|
||||
@ -1149,8 +1212,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
"Please specify a VM that is either running or stopped.");
|
||||
}
|
||||
|
||||
AsyncJobExecutor asyncExecutor = BaseAsyncJobExecutor
|
||||
.getCurrentExecutor();
|
||||
// Check that if the volume has snapshot
|
||||
boolean attach = false;
|
||||
checkVMSnapshots(vm, volumeId, attach);
|
||||
AsyncJobExecutor asyncExecutor = BaseAsyncJobExecutor.getCurrentExecutor();
|
||||
if (asyncExecutor != null) {
|
||||
AsyncJobVO job = asyncExecutor.getJob();
|
||||
|
||||
@ -1296,12 +1361,25 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
throw new InvalidParameterValueException(
|
||||
"unable to find a virtual machine with id " + vmId);
|
||||
}
|
||||
|
||||
|
||||
_accountMgr.checkAccess(caller, null, true, vmInstance);
|
||||
|
||||
// Check that the specified service offering ID is valid
|
||||
_itMgr.checkIfCanUpgrade(vmInstance, svcOffId);
|
||||
|
||||
// remove diskAndMemory VM snapshots
|
||||
List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
|
||||
for (VMSnapshotVO vmSnapshotVO : vmSnapshots) {
|
||||
if(vmSnapshotVO.getType() == VMSnapshot.Type.DiskAndMemory){
|
||||
if(!_vmSnapshotMgr.deleteAllVMSnapshots(vmId, VMSnapshot.Type.DiskAndMemory)){
|
||||
String errMsg = "Failed to remove VM snapshot during upgrading, snapshot id " + vmSnapshotVO.getId();
|
||||
s_logger.debug(errMsg);
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
_itMgr.upgradeVmDb(vmId, svcOffId);
|
||||
|
||||
return _vmDao.findById(vmInstance.getId());
|
||||
@ -1629,9 +1707,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
"Unable to recover VM as the account is deleted");
|
||||
}
|
||||
|
||||
// First check that the maximum number of UserVMs for the given
|
||||
// Get serviceOffering for Virtual Machine
|
||||
ServiceOfferingVO serviceOffering = _serviceOfferingDao.findById(vm.getServiceOfferingId());
|
||||
|
||||
// First check that the maximum number of UserVMs, CPU and Memory limit for the given
|
||||
// accountId will not be exceeded
|
||||
_resourceLimitMgr.checkResourceLimit(account, ResourceType.user_vm);
|
||||
resourceLimitCheck(account, new Long(serviceOffering.getCpu()), new Long(serviceOffering.getRamSize()));
|
||||
|
||||
_haMgr.cancelDestroy(vm, vm.getHostId());
|
||||
|
||||
@ -1672,12 +1753,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
}
|
||||
}
|
||||
|
||||
//Update Resource Count for the given account
|
||||
_resourceLimitMgr.incrementResourceCount(account.getId(),
|
||||
ResourceType.volume, new Long(volumes.size()));
|
||||
|
||||
_resourceLimitMgr.incrementResourceCount(account.getId(),
|
||||
ResourceType.user_vm);
|
||||
|
||||
resourceCountIncrement(account.getId(), new Long(serviceOffering.getCpu()),
|
||||
new Long(serviceOffering.getRamSize()));
|
||||
txn.commit();
|
||||
|
||||
return _vmDao.findById(vmId);
|
||||
@ -1977,8 +2057,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
}
|
||||
|
||||
volume = _volsDao.findById(snapshot.getVolumeId());
|
||||
VolumeVO snapshotVolume = _volsDao
|
||||
.findByIdIncludingRemoved(snapshot.getVolumeId());
|
||||
|
||||
// check permissions
|
||||
_accountMgr.checkAccess(caller, null, true, snapshot);
|
||||
@ -2384,8 +2462,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
String msg = "Failed to deploy Vm with Id: " + vmId + ", on Host with Id: " + hostId;
|
||||
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg);
|
||||
|
||||
_resourceLimitMgr.decrementResourceCount(vm.getAccountId(),
|
||||
ResourceType.user_vm);
|
||||
// Get serviceOffering for Virtual Machine
|
||||
ServiceOfferingVO offering = _serviceOfferingDao.findById(vm.getServiceOfferingId());
|
||||
|
||||
// Update Resource Count for the given account
|
||||
resourceCountDecrement(vm.getAccountId(), new Long(offering.getCpu()),
|
||||
new Long(offering.getRamSize()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3120,9 +3202,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
_configMgr.checkZoneAccess(owner, zone);
|
||||
}
|
||||
|
||||
ServiceOfferingVO offering = _serviceOfferingDao.findById(serviceOffering.getId());
|
||||
|
||||
// check if account/domain is with in resource limits to create a new vm
|
||||
boolean isIso = Storage.ImageFormat.ISO == template.getFormat();
|
||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.user_vm);
|
||||
resourceLimitCheck(owner, new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
||||
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, (isIso
|
||||
|| diskOfferingId == null ? 1 : 2));
|
||||
|
||||
@ -3150,9 +3234,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
-1);
|
||||
}
|
||||
|
||||
ServiceOfferingVO offering = _serviceOfferingDao
|
||||
.findById(serviceOffering.getId());
|
||||
|
||||
if (template.getTemplateType().equals(TemplateType.SYSTEM)) {
|
||||
throw new InvalidParameterValueException(
|
||||
"Unable to use system template " + template.getId()
|
||||
@ -3380,8 +3461,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
vm.getHostName(), offering.getId(), template.getId(), hypervisorType.toString(),
|
||||
VirtualMachine.class.getName(), vm.getUuid());
|
||||
|
||||
_resourceLimitMgr.incrementResourceCount(accountId,
|
||||
ResourceType.user_vm);
|
||||
//Update Resource Count for the given account
|
||||
resourceCountIncrement(accountId, new Long(offering.getCpu()),
|
||||
new Long(offering.getRamSize()));
|
||||
|
||||
txn.commit();
|
||||
|
||||
@ -3915,10 +3997,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
}
|
||||
|
||||
if (vmState != State.Error) {
|
||||
_resourceLimitMgr.decrementResourceCount(vm.getAccountId(),
|
||||
ResourceType.user_vm);
|
||||
}
|
||||
// Get serviceOffering for Virtual Machine
|
||||
ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getServiceOfferingId());
|
||||
|
||||
//Update Resource Count for the given account
|
||||
resourceCountDecrement(vm.getAccountId(), new Long(offering.getCpu()),
|
||||
new Long(offering.getRamSize()));
|
||||
}
|
||||
return _vmDao.findById(vmId);
|
||||
} else {
|
||||
CloudRuntimeException ex = new CloudRuntimeException(
|
||||
@ -4414,12 +4499,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
|
||||
DataCenterVO zone = _dcDao.findById(vm.getDataCenterId());
|
||||
|
||||
// Remove vm from instance group
|
||||
// Get serviceOffering for Virtual Machine
|
||||
ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getServiceOfferingId());
|
||||
|
||||
//Remove vm from instance group
|
||||
removeInstanceFromInstanceGroup(cmd.getVmId());
|
||||
|
||||
// VV 2: check if account/domain is with in resource limits to create a
|
||||
// new vm
|
||||
_resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.user_vm);
|
||||
// VV 2: check if account/domain is with in resource limits to create a new vm
|
||||
resourceLimitCheck(newAccount, new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
||||
|
||||
// VV 3: check if volumes are with in resource limits
|
||||
_resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.volume,
|
||||
@ -4444,9 +4531,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
|
||||
vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
|
||||
VirtualMachine.class.getName(), vm.getUuid());
|
||||
// update resource counts
|
||||
_resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(),
|
||||
ResourceType.user_vm);
|
||||
|
||||
// update resource counts for old account
|
||||
resourceCountDecrement(oldAccount.getAccountId(), new Long(offering.getCpu()),
|
||||
new Long(offering.getRamSize()));
|
||||
|
||||
// OWNERSHIP STEP 1: update the vm owner
|
||||
vm.setAccountId(newAccount.getAccountId());
|
||||
@ -4473,7 +4561,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
|
||||
}
|
||||
}
|
||||
|
||||
_resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.user_vm);
|
||||
//update resource count of new account
|
||||
resourceCountIncrement(newAccount.getAccountId(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
|
||||
|
||||
//generate usage events to account for this change
|
||||
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
|
||||
vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
|
||||
|
||||
@ -158,6 +158,10 @@ import com.cloud.vm.dao.NicDao;
|
||||
import com.cloud.vm.dao.SecondaryStorageVmDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
import com.cloud.vm.snapshot.VMSnapshotManager;
|
||||
import com.cloud.vm.snapshot.VMSnapshotVO;
|
||||
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||
|
||||
@Local(value = VirtualMachineManager.class)
|
||||
public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMachineManager, Listener {
|
||||
@ -227,6 +231,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
protected HypervisorGuruManager _hvGuruMgr;
|
||||
@Inject
|
||||
protected NetworkDao _networkDao;
|
||||
@Inject
|
||||
protected VMSnapshotDao _vmSnapshotDao;
|
||||
|
||||
@Inject
|
||||
protected List<DeploymentPlanner> _planners;
|
||||
@ -236,6 +242,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
|
||||
@Inject
|
||||
protected ResourceManager _resourceMgr;
|
||||
|
||||
@Inject
|
||||
protected VMSnapshotManager _vmSnapshotMgr = null;
|
||||
|
||||
@Inject
|
||||
protected ConfigurationDao _configDao;
|
||||
@ -590,7 +599,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
ConcurrentOperationException, ResourceUnavailableException {
|
||||
return advanceStart(vm, params, caller, account, null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T extends VMInstanceVO> T advanceStart(T vm, Map<VirtualMachineProfile.Param, Object> params, User caller, Account account, DeploymentPlan planToDeploy)
|
||||
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException {
|
||||
@ -1143,6 +1152,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
|
||||
@Override
|
||||
public boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId) throws NoTransitionException {
|
||||
// if there are active vm snapshots task, state change is not allowed
|
||||
if(_vmSnapshotMgr.hasActiveVMSnapshotTasks(vm.getId())){
|
||||
s_logger.error("State transit with event: " + e + " failed due to: " + vm.getInstanceName() + " has active VM snapshots tasks");
|
||||
return false;
|
||||
}
|
||||
|
||||
State oldState = vm.getState();
|
||||
if (oldState == State.Starting) {
|
||||
if (e == Event.OperationSucceeded) {
|
||||
@ -1177,7 +1192,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
s_logger.debug("Unable to stop " + vm);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!_vmSnapshotMgr.deleteAllVMSnapshots(vm.getId(),null)){
|
||||
s_logger.debug("Unable to delete all snapshots for " + vm);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!stateTransitTo(vm, VirtualMachine.Event.DestroyRequested, vm.getHostId())) {
|
||||
s_logger.debug("Unable to destroy the vm because it is not in the correct state: " + vm);
|
||||
@ -1626,6 +1646,19 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
s_logger.debug("Found " + vms.size() + " VMs for host " + hostId);
|
||||
for (VMInstanceVO vm : vms) {
|
||||
AgentVmInfo info = infos.remove(vm.getId());
|
||||
|
||||
// sync VM Snapshots related transient states
|
||||
List<VMSnapshotVO> vmSnapshotsInTrasientStates = _vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging,VMSnapshot.State.Reverting, VMSnapshot.State.Creating);
|
||||
if(vmSnapshotsInTrasientStates.size() > 1){
|
||||
s_logger.info("Found vm " + vm.getInstanceName() + " with VM snapshots in transient states, needs to sync VM snapshot state");
|
||||
if(!_vmSnapshotMgr.syncVMSnapshot(vm, hostId)){
|
||||
s_logger.warn("Failed to sync VM in a transient snapshot related state: " + vm.getInstanceName());
|
||||
continue;
|
||||
}else{
|
||||
s_logger.info("Successfully sync VM with transient snapshot: " + vm.getInstanceName());
|
||||
}
|
||||
}
|
||||
|
||||
VMInstanceVO castedVm = null;
|
||||
if (info == null) {
|
||||
info = new AgentVmInfo(vm.getInstanceName(), getVmGuru(vm), vm, State.Stopped);
|
||||
@ -1743,8 +1776,27 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
for (VMInstanceVO vm : set_vms) {
|
||||
AgentVmInfo info = infos.remove(vm.getId());
|
||||
VMInstanceVO castedVm = null;
|
||||
if ((info == null && (vm.getState() == State.Running || vm.getState() == State.Starting))
|
||||
|| (info != null && (info.state == State.Running && vm.getState() == State.Starting)))
|
||||
|
||||
// sync VM Snapshots related transient states
|
||||
List<VMSnapshotVO> vmSnapshotsInExpungingStates = _vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging, VMSnapshot.State.Creating,VMSnapshot.State.Reverting);
|
||||
if(vmSnapshotsInExpungingStates.size() > 0){
|
||||
s_logger.info("Found vm " + vm.getInstanceName() + " in state. " + vm.getState() + ", needs to sync VM snapshot state");
|
||||
Long hostId = null;
|
||||
Host host = null;
|
||||
if(info != null && info.getHostUuid() != null){
|
||||
host = _hostDao.findByGuid(info.getHostUuid());
|
||||
}
|
||||
hostId = host == null ? (vm.getHostId() == null ? vm.getLastHostId() : vm.getHostId()) : host.getId();
|
||||
if(!_vmSnapshotMgr.syncVMSnapshot(vm, hostId)){
|
||||
s_logger.warn("Failed to sync VM with transient snapshot: " + vm.getInstanceName());
|
||||
continue;
|
||||
}else{
|
||||
s_logger.info("Successfully sync VM with transient snapshot: " + vm.getInstanceName());
|
||||
}
|
||||
}
|
||||
|
||||
if ((info == null && (vm.getState() == State.Running || vm.getState() == State.Starting ))
|
||||
|| (info != null && (info.state == State.Running && vm.getState() == State.Starting)))
|
||||
{
|
||||
s_logger.info("Found vm " + vm.getInstanceName() + " in inconsistent state. " + vm.getState() + " on CS while " + (info == null ? "Stopped" : "Running") + " on agent");
|
||||
info = new AgentVmInfo(vm.getInstanceName(), getVmGuru(vm), vm, State.Stopped);
|
||||
@ -1785,7 +1837,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
}
|
||||
}
|
||||
else if (info != null && (vm.getState() == State.Stopped || vm.getState() == State.Stopping
|
||||
|| vm.isRemoved() || vm.getState() == State.Destroyed || vm.getState() == State.Expunging)) {
|
||||
|| vm.isRemoved() || vm.getState() == State.Destroyed || vm.getState() == State.Expunging )) {
|
||||
Host host = _hostDao.findByGuid(info.getHostUuid());
|
||||
if (host != null){
|
||||
s_logger.warn("Stopping a VM which is stopped/stopping/destroyed/expunging " + info.name);
|
||||
@ -2260,6 +2312,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
|
||||
Long clusterId = agent.getClusterId();
|
||||
long agentId = agent.getId();
|
||||
|
||||
if (agent.getHypervisorType() == HypervisorType.XenServer) { // only for Xen
|
||||
StartupRoutingCommand startup = (StartupRoutingCommand) cmd;
|
||||
HashMap<String, Pair<String, State>> allStates = startup.getClusterVMStateChanges();
|
||||
@ -2375,7 +2428,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
if (newServiceOffering == null) {
|
||||
throw new InvalidParameterValueException("Unable to find a service offering with id " + newServiceOfferingId);
|
||||
}
|
||||
|
||||
|
||||
// Check that the VM is stopped
|
||||
if (!vmInstance.getState().equals(State.Stopped)) {
|
||||
s_logger.warn("Unable to upgrade virtual machine " + vmInstance.toString() + " in state " + vmInstance.getState());
|
||||
|
||||
47
server/src/com/cloud/vm/snapshot/VMSnapshotManager.java
Normal file
47
server/src/com/cloud/vm/snapshot/VMSnapshotManager.java
Normal file
@ -0,0 +1,47 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.vm.snapshot;
|
||||
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
|
||||
public interface VMSnapshotManager extends VMSnapshotService, Manager {
|
||||
public static final int VMSNAPSHOTMAX = 10;
|
||||
|
||||
|
||||
/**
|
||||
* Delete all VM snapshots belonging to one VM
|
||||
* @param id, VM id
|
||||
* @param type,
|
||||
* @return true for success, false for failure
|
||||
*/
|
||||
boolean deleteAllVMSnapshots(long id, VMSnapshot.Type type);
|
||||
|
||||
/**
|
||||
* Sync VM snapshot state when VM snapshot in reverting or snapshoting or expunging state
|
||||
* Used for fullsync after agent connects
|
||||
*
|
||||
* @param vm, the VM in question
|
||||
* @param hostId
|
||||
* @return true if succeeds, false if fails
|
||||
*/
|
||||
boolean syncVMSnapshot(VMInstanceVO vm, Long hostId);
|
||||
|
||||
boolean hasActiveVMSnapshotTasks(Long vmId);
|
||||
|
||||
}
|
||||
833
server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
Normal file
833
server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java
Normal file
@ -0,0 +1,833 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.vm.snapshot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.api.command.user.vmsnapshot.ListVMSnapshotCmd;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.CreateVMSnapshotAnswer;
|
||||
import com.cloud.agent.api.CreateVMSnapshotCommand;
|
||||
import com.cloud.agent.api.DeleteVMSnapshotAnswer;
|
||||
import com.cloud.agent.api.DeleteVMSnapshotCommand;
|
||||
import com.cloud.agent.api.RevertToVMSnapshotAnswer;
|
||||
import com.cloud.agent.api.RevertToVMSnapshotCommand;
|
||||
import com.cloud.agent.api.VMSnapshotTO;
|
||||
import com.cloud.agent.api.to.VolumeTO;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.event.ActionEvent;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.OperationTimedoutException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.hypervisor.HypervisorGuruManager;
|
||||
import com.cloud.projects.Project.ListProjectResourcesCriteria;
|
||||
import com.cloud.storage.GuestOSVO;
|
||||
import com.cloud.storage.Snapshot;
|
||||
import com.cloud.storage.SnapshotVO;
|
||||
import com.cloud.storage.StoragePoolVO;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.GuestOSDao;
|
||||
import com.cloud.storage.dao.SnapshotDao;
|
||||
import com.cloud.storage.dao.StoragePoolDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.user.UserVO;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.Ternary;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.fsm.NoTransitionException;
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.VirtualMachineManager;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||
|
||||
@Component
|
||||
@Local(value = { VMSnapshotManager.class, VMSnapshotService.class })
|
||||
public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotManager, VMSnapshotService {
|
||||
private static final Logger s_logger = Logger.getLogger(VMSnapshotManagerImpl.class);
|
||||
String _name;
|
||||
@Inject VMSnapshotDao _vmSnapshotDao;
|
||||
@Inject VolumeDao _volumeDao;
|
||||
@Inject AccountDao _accountDao;
|
||||
@Inject VMInstanceDao _vmInstanceDao;
|
||||
@Inject UserVmDao _userVMDao;
|
||||
@Inject HostDao _hostDao;
|
||||
@Inject UserDao _userDao;
|
||||
@Inject AgentManager _agentMgr;
|
||||
@Inject HypervisorGuruManager _hvGuruMgr;
|
||||
@Inject AccountManager _accountMgr;
|
||||
@Inject GuestOSDao _guestOSDao;
|
||||
@Inject StoragePoolDao _storagePoolDao;
|
||||
@Inject SnapshotDao _snapshotDao;
|
||||
@Inject VirtualMachineManager _itMgr;
|
||||
@Inject ConfigurationDao _configDao;
|
||||
int _vmSnapshotMax;
|
||||
StateMachine2<VMSnapshot.State, VMSnapshot.Event, VMSnapshot> _vmSnapshottateMachine ;
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
_name = name;
|
||||
if (_configDao == null) {
|
||||
throw new ConfigurationException(
|
||||
"Unable to get the configuration dao.");
|
||||
}
|
||||
|
||||
_vmSnapshotMax = NumbersUtil.parseInt(_configDao.getValue("vmsnapshot.max"), VMSNAPSHOTMAX);
|
||||
|
||||
_vmSnapshottateMachine = VMSnapshot.State.getStateMachine();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stop() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VMSnapshotVO> listVMSnapshots(ListVMSnapshotCmd cmd) {
|
||||
Account caller = getCaller();
|
||||
List<Long> permittedAccounts = new ArrayList<Long>();
|
||||
|
||||
boolean listAll = cmd.listAll();
|
||||
Long id = cmd.getId();
|
||||
Long vmId = cmd.getVmId();
|
||||
|
||||
String state = cmd.getState();
|
||||
String keyword = cmd.getKeyword();
|
||||
String name = cmd.getVmSnapshotName();
|
||||
String accountName = cmd.getAccountName();
|
||||
|
||||
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(
|
||||
cmd.getDomainId(), cmd.isRecursive(), null);
|
||||
_accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, listAll,
|
||||
false);
|
||||
Long domainId = domainIdRecursiveListProject.first();
|
||||
Boolean isRecursive = domainIdRecursiveListProject.second();
|
||||
ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
|
||||
|
||||
Filter searchFilter = new Filter(VMSnapshotVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
|
||||
SearchBuilder<VMSnapshotVO> sb = _vmSnapshotDao.createSearchBuilder();
|
||||
_accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
|
||||
|
||||
sb.and("vm_id", sb.entity().getVmId(), SearchCriteria.Op.EQ);
|
||||
sb.and("domain_id", sb.entity().getDomainId(), SearchCriteria.Op.EQ);
|
||||
sb.and("status", sb.entity().getState(), SearchCriteria.Op.IN);
|
||||
sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
|
||||
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
|
||||
sb.and("display_name", sb.entity().getDisplayName(), SearchCriteria.Op.EQ);
|
||||
sb.and("account_id", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
sb.done();
|
||||
|
||||
SearchCriteria<VMSnapshotVO> sc = sb.create();
|
||||
_accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
|
||||
|
||||
if (accountName != null && cmd.getDomainId() != null) {
|
||||
Account account = _accountMgr.getActiveAccountByName(accountName, cmd.getDomainId());
|
||||
sc.setParameters("account_id", account.getId());
|
||||
}
|
||||
|
||||
if (vmId != null) {
|
||||
sc.setParameters("vm_id", vmId);
|
||||
}
|
||||
|
||||
if (domainId != null) {
|
||||
sc.setParameters("domain_id", domainId);
|
||||
}
|
||||
|
||||
if (state == null) {
|
||||
VMSnapshot.State[] status = { VMSnapshot.State.Ready, VMSnapshot.State.Creating, VMSnapshot.State.Allocated,
|
||||
VMSnapshot.State.Error, VMSnapshot.State.Expunging, VMSnapshot.State.Reverting };
|
||||
sc.setParameters("status", (Object[]) status);
|
||||
} else {
|
||||
sc.setParameters("state", state);
|
||||
}
|
||||
|
||||
if (name != null) {
|
||||
sc.setParameters("display_name", name);
|
||||
}
|
||||
|
||||
if (keyword != null) {
|
||||
SearchCriteria<VMSnapshotVO> ssc = _vmSnapshotDao.createSearchCriteria();
|
||||
ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
|
||||
ssc.addOr("display_name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
|
||||
ssc.addOr("description", SearchCriteria.Op.LIKE, "%" + keyword + "%");
|
||||
sc.addAnd("name", SearchCriteria.Op.SC, ssc);
|
||||
}
|
||||
|
||||
if (id != null) {
|
||||
sc.setParameters("id", id);
|
||||
}
|
||||
|
||||
return _vmSnapshotDao.search(sc, searchFilter);
|
||||
|
||||
}
|
||||
|
||||
protected Account getCaller(){
|
||||
return UserContext.current().getCaller();
|
||||
}
|
||||
|
||||
@Override
|
||||
public VMSnapshot allocVMSnapshot(Long vmId, String vsDisplayName, String vsDescription, Boolean snapshotMemory)
|
||||
throws ResourceAllocationException {
|
||||
|
||||
Account caller = getCaller();
|
||||
|
||||
// check if VM exists
|
||||
UserVmVO userVmVo = _userVMDao.findById(vmId);
|
||||
if (userVmVo == null) {
|
||||
throw new InvalidParameterValueException("Creating VM snapshot failed due to VM:" + vmId + " is a system VM or does not exist");
|
||||
}
|
||||
|
||||
// parameter length check
|
||||
if(vsDisplayName != null && vsDisplayName.length()>255)
|
||||
throw new InvalidParameterValueException("Creating VM snapshot failed due to length of VM snapshot vsDisplayName should not exceed 255");
|
||||
if(vsDescription != null && vsDescription.length()>255)
|
||||
throw new InvalidParameterValueException("Creating VM snapshot failed due to length of VM snapshot vsDescription should not exceed 255");
|
||||
|
||||
// VM snapshot display name must be unique for a VM
|
||||
String timeString = DateUtil.getDateDisplayString(DateUtil.GMT_TIMEZONE, new Date(), DateUtil.YYYYMMDD_FORMAT);
|
||||
String vmSnapshotName = userVmVo.getInstanceName() + "_VS_" + timeString;
|
||||
if (vsDisplayName == null) {
|
||||
vsDisplayName = vmSnapshotName;
|
||||
}
|
||||
if(_vmSnapshotDao.findByName(vmId,vsDisplayName) != null){
|
||||
throw new InvalidParameterValueException("Creating VM snapshot failed due to VM snapshot with name" + vsDisplayName + " already exists");
|
||||
}
|
||||
|
||||
// check VM state
|
||||
if (userVmVo.getState() != VirtualMachine.State.Running && userVmVo.getState() != VirtualMachine.State.Stopped) {
|
||||
throw new InvalidParameterValueException("Creating vm snapshot failed due to VM:" + vmId + " is not in the running or Stopped state");
|
||||
}
|
||||
|
||||
if(snapshotMemory && userVmVo.getState() == VirtualMachine.State.Stopped){
|
||||
throw new InvalidParameterValueException("Can not snapshot memory when VM is in stopped state");
|
||||
}
|
||||
|
||||
// for KVM, only allow snapshot with memory when VM is in running state
|
||||
if(userVmVo.getHypervisorType() == HypervisorType.KVM && userVmVo.getState() == State.Running && !snapshotMemory){
|
||||
throw new InvalidParameterValueException("KVM VM does not allow to take a disk-only snapshot when VM is in running state");
|
||||
}
|
||||
|
||||
// check access
|
||||
_accountMgr.checkAccess(caller, null, true, userVmVo);
|
||||
|
||||
// check max snapshot limit for per VM
|
||||
if (_vmSnapshotDao.findByVm(vmId).size() >= _vmSnapshotMax) {
|
||||
throw new CloudRuntimeException("Creating vm snapshot failed due to a VM can just have : " + _vmSnapshotMax
|
||||
+ " VM snapshots. Please delete old ones");
|
||||
}
|
||||
|
||||
// check if there are active volume snapshots tasks
|
||||
List<VolumeVO> listVolumes = _volumeDao.findByInstance(vmId);
|
||||
for (VolumeVO volume : listVolumes) {
|
||||
List<SnapshotVO> activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(), Snapshot.State.Creating,
|
||||
Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp);
|
||||
if (activeSnapshots.size() > 0) {
|
||||
throw new CloudRuntimeException(
|
||||
"There is other active volume snapshot tasks on the instance to which the volume is attached, please try again later.");
|
||||
}
|
||||
}
|
||||
|
||||
// check if there are other active VM snapshot tasks
|
||||
if (hasActiveVMSnapshotTasks(vmId)) {
|
||||
throw new CloudRuntimeException("There is other active vm snapshot tasks on the instance, please try again later");
|
||||
}
|
||||
|
||||
VMSnapshot.Type vmSnapshotType = VMSnapshot.Type.Disk;
|
||||
if(snapshotMemory && userVmVo.getState() == VirtualMachine.State.Running)
|
||||
vmSnapshotType = VMSnapshot.Type.DiskAndMemory;
|
||||
|
||||
try {
|
||||
VMSnapshotVO vmSnapshotVo = new VMSnapshotVO(userVmVo.getAccountId(), userVmVo.getDomainId(), vmId, vsDescription, vmSnapshotName,
|
||||
vsDisplayName, userVmVo.getServiceOfferingId(), vmSnapshotType, null);
|
||||
VMSnapshot vmSnapshot = _vmSnapshotDao.persist(vmSnapshotVo);
|
||||
if (vmSnapshot == null) {
|
||||
throw new CloudRuntimeException("Failed to create snapshot for vm: " + vmId);
|
||||
}
|
||||
return vmSnapshot;
|
||||
} catch (Exception e) {
|
||||
String msg = e.getMessage();
|
||||
s_logger.error("Create vm snapshot record failed for vm: " + vmId + " due to: " + msg);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return _name;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VM_SNAPSHOT_CREATE, eventDescription = "creating VM snapshot", async = true)
|
||||
public VMSnapshot creatVMSnapshot(Long vmId, Long vmSnapshotId) {
|
||||
UserVmVO userVm = _userVMDao.findById(vmId);
|
||||
if (userVm == null) {
|
||||
throw new InvalidParameterValueException("Create vm to snapshot failed due to vm: " + vmId + " is not found");
|
||||
}
|
||||
VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(vmSnapshotId);
|
||||
if(vmSnapshot == null){
|
||||
throw new CloudRuntimeException("VM snapshot id: " + vmSnapshotId + " can not be found");
|
||||
}
|
||||
Long hostId = pickRunningHost(vmId);
|
||||
try {
|
||||
vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.CreateRequested);
|
||||
} catch (NoTransitionException e) {
|
||||
throw new CloudRuntimeException(e.getMessage());
|
||||
}
|
||||
return createVmSnapshotInternal(userVm, vmSnapshot, hostId);
|
||||
}
|
||||
|
||||
protected VMSnapshot createVmSnapshotInternal(UserVmVO userVm, VMSnapshotVO vmSnapshot, Long hostId) {
|
||||
try {
|
||||
CreateVMSnapshotAnswer answer = null;
|
||||
GuestOSVO guestOS = _guestOSDao.findById(userVm.getGuestOSId());
|
||||
|
||||
// prepare snapshotVolumeTos
|
||||
List<VolumeTO> volumeTOs = getVolumeTOList(userVm.getId());
|
||||
|
||||
// prepare target snapshotTO and its parent snapshot (current snapshot)
|
||||
VMSnapshotTO current = null;
|
||||
VMSnapshotVO currentSnapshot = _vmSnapshotDao.findCurrentSnapshotByVmId(userVm.getId());
|
||||
if (currentSnapshot != null)
|
||||
current = getSnapshotWithParents(currentSnapshot);
|
||||
VMSnapshotTO target = new VMSnapshotTO(vmSnapshot.getId(), vmSnapshot.getName(), vmSnapshot.getType(), null, vmSnapshot.getDescription(), false,
|
||||
current);
|
||||
if (current == null)
|
||||
vmSnapshot.setParent(null);
|
||||
else
|
||||
vmSnapshot.setParent(current.getId());
|
||||
|
||||
CreateVMSnapshotCommand ccmd = new CreateVMSnapshotCommand(userVm.getInstanceName(),target ,volumeTOs, guestOS.getDisplayName(),userVm.getState());
|
||||
|
||||
answer = (CreateVMSnapshotAnswer) sendToPool(hostId, ccmd);
|
||||
if (answer != null && answer.getResult()) {
|
||||
processAnswer(vmSnapshot, userVm, answer, hostId);
|
||||
s_logger.debug("Create vm snapshot " + vmSnapshot.getName() + " succeeded for vm: " + userVm.getInstanceName());
|
||||
}else{
|
||||
String errMsg = answer.getDetails();
|
||||
s_logger.error("Agent reports creating vm snapshot " + vmSnapshot.getName() + " failed for vm: " + userVm.getInstanceName() + " due to " + errMsg);
|
||||
vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationFailed);
|
||||
}
|
||||
return vmSnapshot;
|
||||
} catch (Exception e) {
|
||||
if(e instanceof AgentUnavailableException){
|
||||
try {
|
||||
vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationFailed);
|
||||
} catch (NoTransitionException e1) {
|
||||
s_logger.error("Cannot set vm snapshot state due to: " + e1.getMessage());
|
||||
}
|
||||
}
|
||||
String msg = e.getMessage();
|
||||
s_logger.error("Create vm snapshot " + vmSnapshot.getName() + " failed for vm: " + userVm.getInstanceName() + " due to " + msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
} finally{
|
||||
if(vmSnapshot.getState() == VMSnapshot.State.Allocated){
|
||||
s_logger.warn("Create vm snapshot " + vmSnapshot.getName() + " failed for vm: " + userVm.getInstanceName());
|
||||
_vmSnapshotDao.remove(vmSnapshot.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected List<VolumeTO> getVolumeTOList(Long vmId) {
|
||||
List<VolumeTO> volumeTOs = new ArrayList<VolumeTO>();
|
||||
List<VolumeVO> volumeVos = _volumeDao.findByInstance(vmId);
|
||||
|
||||
for (VolumeVO volume : volumeVos) {
|
||||
StoragePoolVO pool = _storagePoolDao.findById(volume.getPoolId());
|
||||
VolumeTO volumeTO = new VolumeTO(volume, pool);
|
||||
volumeTOs.add(volumeTO);
|
||||
}
|
||||
return volumeTOs;
|
||||
}
|
||||
|
||||
// get snapshot and its parents recursively
|
||||
private VMSnapshotTO getSnapshotWithParents(VMSnapshotVO snapshot) {
|
||||
Map<Long, VMSnapshotVO> snapshotMap = new HashMap<Long, VMSnapshotVO>();
|
||||
List<VMSnapshotVO> allSnapshots = _vmSnapshotDao.findByVm(snapshot.getVmId());
|
||||
for (VMSnapshotVO vmSnapshotVO : allSnapshots) {
|
||||
snapshotMap.put(vmSnapshotVO.getId(), vmSnapshotVO);
|
||||
}
|
||||
|
||||
VMSnapshotTO currentTO = convert2VMSnapshotTO(snapshot);
|
||||
VMSnapshotTO result = currentTO;
|
||||
VMSnapshotVO current = snapshot;
|
||||
while (current.getParent() != null) {
|
||||
VMSnapshotVO parent = snapshotMap.get(current.getParent());
|
||||
currentTO.setParent(convert2VMSnapshotTO(parent));
|
||||
current = snapshotMap.get(current.getParent());
|
||||
currentTO = currentTO.getParent();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private VMSnapshotTO convert2VMSnapshotTO(VMSnapshotVO vo) {
|
||||
return new VMSnapshotTO(vo.getId(), vo.getName(), vo.getType(), vo.getCreated().getTime(), vo.getDescription(),
|
||||
vo.getCurrent(), null);
|
||||
}
|
||||
|
||||
protected boolean vmSnapshotStateTransitTo(VMSnapshotVO vsnp, VMSnapshot.Event event) throws NoTransitionException {
|
||||
return _vmSnapshottateMachine.transitTo(vsnp, event, null, _vmSnapshotDao);
|
||||
}
|
||||
|
||||
@DB
|
||||
protected void processAnswer(VMSnapshotVO vmSnapshot, UserVmVO userVm, Answer as, Long hostId) {
|
||||
final Transaction txn = Transaction.currentTxn();
|
||||
try {
|
||||
txn.start();
|
||||
if (as instanceof CreateVMSnapshotAnswer) {
|
||||
CreateVMSnapshotAnswer answer = (CreateVMSnapshotAnswer) as;
|
||||
finalizeCreate(vmSnapshot, answer.getVolumeTOs());
|
||||
vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded);
|
||||
} else if (as instanceof RevertToVMSnapshotAnswer) {
|
||||
RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer) as;
|
||||
finalizeRevert(vmSnapshot, answer.getVolumeTOs());
|
||||
vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.OperationSucceeded);
|
||||
} else if (as instanceof DeleteVMSnapshotAnswer) {
|
||||
DeleteVMSnapshotAnswer answer = (DeleteVMSnapshotAnswer) as;
|
||||
finalizeDelete(vmSnapshot, answer.getVolumeTOs());
|
||||
_vmSnapshotDao.remove(vmSnapshot.getId());
|
||||
}
|
||||
txn.commit();
|
||||
} catch (Exception e) {
|
||||
String errMsg = "Error while process answer: " + as.getClass() + " due to " + e.getMessage();
|
||||
s_logger.error(errMsg, e);
|
||||
txn.rollback();
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
}
|
||||
|
||||
protected void finalizeDelete(VMSnapshotVO vmSnapshot, List<VolumeTO> VolumeTOs) {
|
||||
// update volumes path
|
||||
updateVolumePath(VolumeTOs);
|
||||
|
||||
// update children's parent snapshots
|
||||
List<VMSnapshotVO> children= _vmSnapshotDao.listByParent(vmSnapshot.getId());
|
||||
for (VMSnapshotVO child : children) {
|
||||
child.setParent(vmSnapshot.getParent());
|
||||
_vmSnapshotDao.persist(child);
|
||||
}
|
||||
|
||||
// update current snapshot
|
||||
VMSnapshotVO current = _vmSnapshotDao.findCurrentSnapshotByVmId(vmSnapshot.getVmId());
|
||||
if(current != null && current.getId() == vmSnapshot.getId() && vmSnapshot.getParent() != null){
|
||||
VMSnapshotVO parent = _vmSnapshotDao.findById(vmSnapshot.getParent());
|
||||
parent.setCurrent(true);
|
||||
_vmSnapshotDao.persist(parent);
|
||||
}
|
||||
vmSnapshot.setCurrent(false);
|
||||
_vmSnapshotDao.persist(vmSnapshot);
|
||||
}
|
||||
|
||||
protected void finalizeCreate(VMSnapshotVO vmSnapshot, List<VolumeTO> VolumeTOs) {
|
||||
// update volumes path
|
||||
updateVolumePath(VolumeTOs);
|
||||
|
||||
vmSnapshot.setCurrent(true);
|
||||
|
||||
// change current snapshot
|
||||
if (vmSnapshot.getParent() != null) {
|
||||
VMSnapshotVO previousCurrent = _vmSnapshotDao.findById(vmSnapshot.getParent());
|
||||
previousCurrent.setCurrent(false);
|
||||
_vmSnapshotDao.persist(previousCurrent);
|
||||
}
|
||||
_vmSnapshotDao.persist(vmSnapshot);
|
||||
}
|
||||
|
||||
protected void finalizeRevert(VMSnapshotVO vmSnapshot, List<VolumeTO> volumeToList) {
|
||||
// update volumes path
|
||||
updateVolumePath(volumeToList);
|
||||
|
||||
// update current snapshot, current snapshot is the one reverted to
|
||||
VMSnapshotVO previousCurrent = _vmSnapshotDao.findCurrentSnapshotByVmId(vmSnapshot.getVmId());
|
||||
if(previousCurrent != null){
|
||||
previousCurrent.setCurrent(false);
|
||||
_vmSnapshotDao.persist(previousCurrent);
|
||||
}
|
||||
vmSnapshot.setCurrent(true);
|
||||
_vmSnapshotDao.persist(vmSnapshot);
|
||||
}
|
||||
|
||||
private void updateVolumePath(List<VolumeTO> volumeTOs) {
|
||||
for (VolumeTO volume : volumeTOs) {
|
||||
if (volume.getPath() != null) {
|
||||
VolumeVO volumeVO = _volumeDao.findById(volume.getId());
|
||||
volumeVO.setPath(volume.getPath());
|
||||
_volumeDao.persist(volumeVO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public VMSnapshotManagerImpl() {
|
||||
|
||||
}
|
||||
|
||||
protected Answer sendToPool(Long hostId, Command cmd) throws AgentUnavailableException, OperationTimedoutException {
|
||||
long targetHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(hostId, cmd);
|
||||
Answer answer = _agentMgr.send(targetHostId, cmd);
|
||||
return answer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasActiveVMSnapshotTasks(Long vmId){
|
||||
List<VMSnapshotVO> activeVMSnapshots = _vmSnapshotDao.listByInstanceId(vmId,
|
||||
VMSnapshot.State.Creating, VMSnapshot.State.Expunging,VMSnapshot.State.Reverting,VMSnapshot.State.Allocated);
|
||||
return activeVMSnapshots.size() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VM_SNAPSHOT_DELETE, eventDescription = "delete vm snapshots", async=true)
|
||||
public boolean deleteVMSnapshot(Long vmSnapshotId) {
|
||||
Account caller = getCaller();
|
||||
|
||||
VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(vmSnapshotId);
|
||||
if (vmSnapshot == null) {
|
||||
throw new InvalidParameterValueException("unable to find the vm snapshot with id " + vmSnapshotId);
|
||||
}
|
||||
|
||||
_accountMgr.checkAccess(caller, null, true, vmSnapshot);
|
||||
|
||||
// check VM snapshot states, only allow to delete vm snapshots in created and error state
|
||||
if (VMSnapshot.State.Ready != vmSnapshot.getState() && VMSnapshot.State.Expunging != vmSnapshot.getState() && VMSnapshot.State.Error != vmSnapshot.getState()) {
|
||||
throw new InvalidParameterValueException("Can't delete the vm snapshotshot " + vmSnapshotId + " due to it is not in Created or Error, or Expunging State");
|
||||
}
|
||||
|
||||
// check if there are other active VM snapshot tasks
|
||||
if (hasActiveVMSnapshotTasks(vmSnapshot.getVmId())) {
|
||||
List<VMSnapshotVO> expungingSnapshots = _vmSnapshotDao.listByInstanceId(vmSnapshot.getVmId(), VMSnapshot.State.Expunging);
|
||||
if(expungingSnapshots.size() > 0 && expungingSnapshots.get(0).getId() == vmSnapshot.getId())
|
||||
s_logger.debug("Target VM snapshot already in expunging state, go on deleting it: " + vmSnapshot.getDisplayName());
|
||||
else
|
||||
throw new InvalidParameterValueException("There is other active vm snapshot tasks on the instance, please try again later");
|
||||
}
|
||||
|
||||
if(vmSnapshot.getState() == VMSnapshot.State.Allocated){
|
||||
return _vmSnapshotDao.remove(vmSnapshot.getId());
|
||||
}else{
|
||||
return deleteSnapshotInternal(vmSnapshot);
|
||||
}
|
||||
}
|
||||
|
||||
@DB
|
||||
protected boolean deleteSnapshotInternal(VMSnapshotVO vmSnapshot) {
|
||||
UserVmVO userVm = _userVMDao.findById(vmSnapshot.getVmId());
|
||||
|
||||
try {
|
||||
vmSnapshotStateTransitTo(vmSnapshot,VMSnapshot.Event.ExpungeRequested);
|
||||
Long hostId = pickRunningHost(vmSnapshot.getVmId());
|
||||
|
||||
// prepare snapshotVolumeTos
|
||||
List<VolumeTO> volumeTOs = getVolumeTOList(vmSnapshot.getVmId());
|
||||
|
||||
// prepare DeleteVMSnapshotCommand
|
||||
String vmInstanceName = userVm.getInstanceName();
|
||||
VMSnapshotTO parent = getSnapshotWithParents(vmSnapshot).getParent();
|
||||
VMSnapshotTO vmSnapshotTO = new VMSnapshotTO(vmSnapshot.getId(), vmSnapshot.getName(), vmSnapshot.getType(),
|
||||
vmSnapshot.getCreated().getTime(), vmSnapshot.getDescription(), vmSnapshot.getCurrent(), parent);
|
||||
GuestOSVO guestOS = _guestOSDao.findById(userVm.getGuestOSId());
|
||||
DeleteVMSnapshotCommand deleteSnapshotCommand = new DeleteVMSnapshotCommand(vmInstanceName, vmSnapshotTO, volumeTOs,guestOS.getDisplayName());
|
||||
|
||||
DeleteVMSnapshotAnswer answer = (DeleteVMSnapshotAnswer) sendToPool(hostId, deleteSnapshotCommand);
|
||||
|
||||
if (answer != null && answer.getResult()) {
|
||||
processAnswer(vmSnapshot, userVm, answer, hostId);
|
||||
s_logger.debug("Delete VM snapshot " + vmSnapshot.getName() + " succeeded for vm: " + userVm.getInstanceName());
|
||||
return true;
|
||||
} else {
|
||||
s_logger.error("Delete vm snapshot " + vmSnapshot.getName() + " of vm " + userVm.getInstanceName() + " failed due to " + answer.getDetails());
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String msg = "Delete vm snapshot " + vmSnapshot.getName() + " of vm " + userVm.getInstanceName() + " failed due to " + e.getMessage();
|
||||
s_logger.error(msg , e);
|
||||
throw new CloudRuntimeException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VM_SNAPSHOT_REVERT, eventDescription = "revert to VM snapshot", async = true)
|
||||
public UserVm revertToSnapshot(Long vmSnapshotId) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException {
|
||||
|
||||
// check if VM snapshot exists in DB
|
||||
VMSnapshotVO vmSnapshotVo = _vmSnapshotDao.findById(vmSnapshotId);
|
||||
if (vmSnapshotVo == null) {
|
||||
throw new InvalidParameterValueException(
|
||||
"unable to find the vm snapshot with id " + vmSnapshotId);
|
||||
}
|
||||
Long vmId = vmSnapshotVo.getVmId();
|
||||
UserVmVO userVm = _userVMDao.findById(vmId);
|
||||
// check if VM exists
|
||||
if (userVm == null) {
|
||||
throw new InvalidParameterValueException("Revert vm to snapshot: "
|
||||
+ vmSnapshotId + " failed due to vm: " + vmId
|
||||
+ " is not found");
|
||||
}
|
||||
|
||||
// check if there are other active VM snapshot tasks
|
||||
if (hasActiveVMSnapshotTasks(vmId)) {
|
||||
throw new InvalidParameterValueException("There is other active vm snapshot tasks on the instance, please try again later");
|
||||
}
|
||||
|
||||
Account caller = getCaller();
|
||||
_accountMgr.checkAccess(caller, null, true, vmSnapshotVo);
|
||||
|
||||
// VM should be in running or stopped states
|
||||
if (userVm.getState() != VirtualMachine.State.Running
|
||||
&& userVm.getState() != VirtualMachine.State.Stopped) {
|
||||
throw new InvalidParameterValueException(
|
||||
"VM Snapshot reverting failed due to vm is not in the state of Running or Stopped.");
|
||||
}
|
||||
|
||||
// if snapshot is not created, error out
|
||||
if (vmSnapshotVo.getState() != VMSnapshot.State.Ready) {
|
||||
throw new InvalidParameterValueException(
|
||||
"VM Snapshot reverting failed due to vm snapshot is not in the state of Created.");
|
||||
}
|
||||
|
||||
UserVO callerUser = _userDao.findById(UserContext.current().getCallerUserId());
|
||||
|
||||
UserVmVO vm = null;
|
||||
Long hostId = null;
|
||||
Account owner = _accountDao.findById(vmSnapshotVo.getAccountId());
|
||||
|
||||
// start or stop VM first, if revert from stopped state to running state, or from running to stopped
|
||||
if(userVm.getState() == VirtualMachine.State.Stopped && vmSnapshotVo.getType() == VMSnapshot.Type.DiskAndMemory){
|
||||
try {
|
||||
vm = _itMgr.advanceStart(userVm, new HashMap<VirtualMachineProfile.Param, Object>(), callerUser, owner);
|
||||
hostId = vm.getHostId();
|
||||
} catch (Exception e) {
|
||||
s_logger.error("Start VM " + userVm.getInstanceName() + " before reverting failed due to " + e.getMessage());
|
||||
throw new CloudRuntimeException(e.getMessage());
|
||||
}
|
||||
}else {
|
||||
if(userVm.getState() == VirtualMachine.State.Running && vmSnapshotVo.getType() == VMSnapshot.Type.Disk){
|
||||
try {
|
||||
_itMgr.advanceStop(userVm, true, callerUser, owner);
|
||||
} catch (Exception e) {
|
||||
s_logger.error("Stop VM " + userVm.getInstanceName() + " before reverting failed due to " + e.getMessage());
|
||||
throw new CloudRuntimeException(e.getMessage());
|
||||
}
|
||||
}
|
||||
hostId = pickRunningHost(userVm.getId());
|
||||
}
|
||||
|
||||
if(hostId == null)
|
||||
throw new CloudRuntimeException("Can not find any host to revert snapshot " + vmSnapshotVo.getName());
|
||||
|
||||
// check if there are other active VM snapshot tasks
|
||||
if (hasActiveVMSnapshotTasks(userVm.getId())) {
|
||||
throw new InvalidParameterValueException("There is other active vm snapshot tasks on the instance, please try again later");
|
||||
}
|
||||
|
||||
userVm = _userVMDao.findById(userVm.getId());
|
||||
try {
|
||||
vmSnapshotStateTransitTo(vmSnapshotVo, VMSnapshot.Event.RevertRequested);
|
||||
} catch (NoTransitionException e) {
|
||||
throw new CloudRuntimeException(e.getMessage());
|
||||
}
|
||||
return revertInternal(userVm, vmSnapshotVo, hostId);
|
||||
}
|
||||
|
||||
private UserVm revertInternal(UserVmVO userVm, VMSnapshotVO vmSnapshotVo, Long hostId) {
|
||||
try {
|
||||
VMSnapshotVO snapshot = _vmSnapshotDao.findById(vmSnapshotVo.getId());
|
||||
// prepare RevertToSnapshotCommand
|
||||
List<VolumeTO> volumeTOs = getVolumeTOList(userVm.getId());
|
||||
String vmInstanceName = userVm.getInstanceName();
|
||||
VMSnapshotTO parent = getSnapshotWithParents(snapshot).getParent();
|
||||
VMSnapshotTO vmSnapshotTO = new VMSnapshotTO(snapshot.getId(), snapshot.getName(), snapshot.getType(),
|
||||
snapshot.getCreated().getTime(), snapshot.getDescription(), snapshot.getCurrent(), parent);
|
||||
|
||||
GuestOSVO guestOS = _guestOSDao.findById(userVm.getGuestOSId());
|
||||
RevertToVMSnapshotCommand revertToSnapshotCommand = new RevertToVMSnapshotCommand(vmInstanceName, vmSnapshotTO, volumeTOs, guestOS.getDisplayName());
|
||||
|
||||
RevertToVMSnapshotAnswer answer = (RevertToVMSnapshotAnswer) sendToPool(hostId, revertToSnapshotCommand);
|
||||
if (answer != null && answer.getResult()) {
|
||||
processAnswer(vmSnapshotVo, userVm, answer, hostId);
|
||||
s_logger.debug("RevertTo " + vmSnapshotVo.getName() + " succeeded for vm: " + userVm.getInstanceName());
|
||||
} else {
|
||||
String errMsg = "Revert VM: " + userVm.getInstanceName() + " to snapshot: "+ vmSnapshotVo.getName() + " failed";
|
||||
if(answer != null && answer.getDetails() != null)
|
||||
errMsg = errMsg + " due to " + answer.getDetails();
|
||||
s_logger.error(errMsg);
|
||||
// agent report revert operation fails
|
||||
vmSnapshotStateTransitTo(vmSnapshotVo, VMSnapshot.Event.OperationFailed);
|
||||
throw new CloudRuntimeException(errMsg);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if(e instanceof AgentUnavailableException){
|
||||
try {
|
||||
vmSnapshotStateTransitTo(vmSnapshotVo, VMSnapshot.Event.OperationFailed);
|
||||
} catch (NoTransitionException e1) {
|
||||
s_logger.error("Cannot set vm snapshot state due to: " + e1.getMessage());
|
||||
}
|
||||
}
|
||||
// for other exceptions, do not change VM snapshot state, leave it for snapshotSync
|
||||
String errMsg = "revert vm: " + userVm.getInstanceName() + " to snapshot " + vmSnapshotVo.getName() + " failed due to " + e.getMessage();
|
||||
s_logger.error(errMsg);
|
||||
throw new CloudRuntimeException(e.getMessage());
|
||||
}
|
||||
return userVm;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VMSnapshot getVMSnapshotById(Long id) {
|
||||
VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(id);
|
||||
return vmSnapshot;
|
||||
}
|
||||
|
||||
protected Long pickRunningHost(Long vmId) {
|
||||
UserVmVO vm = _userVMDao.findById(vmId);
|
||||
// use VM's host if VM is running
|
||||
if(vm.getState() == State.Running)
|
||||
return vm.getHostId();
|
||||
|
||||
// check if lastHostId is available
|
||||
if(vm.getLastHostId() != null){
|
||||
HostVO lastHost = _hostDao.findById(vm.getLastHostId());
|
||||
if(lastHost.getStatus() == com.cloud.host.Status.Up && !lastHost.isInMaintenanceStates())
|
||||
return lastHost.getId();
|
||||
}
|
||||
|
||||
List<VolumeVO> listVolumes = _volumeDao.findByInstance(vmId);
|
||||
if (listVolumes == null || listVolumes.size() == 0) {
|
||||
throw new InvalidParameterValueException("vmInstance has no volumes");
|
||||
}
|
||||
VolumeVO volume = listVolumes.get(0);
|
||||
Long poolId = volume.getPoolId();
|
||||
if (poolId == null) {
|
||||
throw new InvalidParameterValueException("pool id is not found");
|
||||
}
|
||||
StoragePoolVO storagePool = _storagePoolDao.findById(poolId);
|
||||
if (storagePool == null) {
|
||||
throw new InvalidParameterValueException("storage pool is not found");
|
||||
}
|
||||
List<HostVO> listHost = _hostDao.listAllUpAndEnabledNonHAHosts(Host.Type.Routing, storagePool.getClusterId(), storagePool.getPodId(),
|
||||
storagePool.getDataCenterId(), null);
|
||||
if (listHost == null || listHost.size() == 0) {
|
||||
throw new InvalidParameterValueException("no host in up state is found");
|
||||
}
|
||||
return listHost.get(0).getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public VirtualMachine getVMBySnapshotId(Long id) {
|
||||
VMSnapshotVO vmSnapshot = _vmSnapshotDao.findById(id);
|
||||
if(vmSnapshot == null){
|
||||
throw new InvalidParameterValueException("unable to find the vm snapshot with id " + id);
|
||||
}
|
||||
Long vmId = vmSnapshot.getVmId();
|
||||
UserVmVO vm = _userVMDao.findById(vmId);
|
||||
return vm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteAllVMSnapshots(long vmId, VMSnapshot.Type type) {
|
||||
boolean result = true;
|
||||
List<VMSnapshotVO> listVmSnapshots = _vmSnapshotDao.findByVm(vmId);
|
||||
if (listVmSnapshots == null || listVmSnapshots.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
for (VMSnapshotVO snapshot : listVmSnapshots) {
|
||||
VMSnapshotVO target = _vmSnapshotDao.findById(snapshot.getId());
|
||||
if(type != null && target.getType() != type)
|
||||
continue;
|
||||
if (!deleteSnapshotInternal(target)) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean syncVMSnapshot(VMInstanceVO vm, Long hostId) {
|
||||
try{
|
||||
|
||||
UserVmVO userVm = _userVMDao.findById(vm.getId());
|
||||
if(userVm == null)
|
||||
return false;
|
||||
|
||||
List<VMSnapshotVO> vmSnapshotsInExpungingStates = _vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging, VMSnapshot.State.Reverting, VMSnapshot.State.Creating);
|
||||
for (VMSnapshotVO vmSnapshotVO : vmSnapshotsInExpungingStates) {
|
||||
if(vmSnapshotVO.getState() == VMSnapshot.State.Expunging){
|
||||
return deleteSnapshotInternal(vmSnapshotVO);
|
||||
}else if(vmSnapshotVO.getState() == VMSnapshot.State.Creating){
|
||||
return createVmSnapshotInternal(userVm, vmSnapshotVO, hostId) != null;
|
||||
}else if(vmSnapshotVO.getState() == VMSnapshot.State.Reverting){
|
||||
return revertInternal(userVm, vmSnapshotVO, hostId) != null;
|
||||
}
|
||||
}
|
||||
}catch (Exception e) {
|
||||
s_logger.error(e.getMessage(),e);
|
||||
if(_vmSnapshotDao.listByInstanceId(vm.getId(), VMSnapshot.State.Expunging).size() == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
39
server/src/com/cloud/vm/snapshot/dao/VMSnapshotDao.java
Normal file
39
server/src/com/cloud/vm/snapshot/dao/VMSnapshotDao.java
Normal file
@ -0,0 +1,39 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.vm.snapshot.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.utils.fsm.StateDao;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
import com.cloud.vm.snapshot.VMSnapshotVO;
|
||||
|
||||
public interface VMSnapshotDao extends GenericDao<VMSnapshotVO, Long>, StateDao<VMSnapshot.State, VMSnapshot.Event, VMSnapshot> {
|
||||
|
||||
List<VMSnapshotVO> findByVm(Long vmId);
|
||||
|
||||
List<VMSnapshotVO> listExpungingSnapshot();
|
||||
|
||||
List<VMSnapshotVO> listByInstanceId(Long vmId, VMSnapshot.State... status);
|
||||
|
||||
VMSnapshotVO findCurrentSnapshotByVmId(Long vmId);
|
||||
|
||||
List<VMSnapshotVO> listByParent(Long vmSnapshotId);
|
||||
|
||||
VMSnapshotVO findByName(Long vm_id, String name);
|
||||
}
|
||||
161
server/src/com/cloud/vm/snapshot/dao/VMSnapshotDaoImpl.java
Normal file
161
server/src/com/cloud/vm/snapshot/dao/VMSnapshotDaoImpl.java
Normal file
@ -0,0 +1,161 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.cloud.vm.snapshot.dao;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import com.cloud.utils.db.UpdateBuilder;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
import com.cloud.vm.snapshot.VMSnapshot.Event;
|
||||
import com.cloud.vm.snapshot.VMSnapshot.State;
|
||||
import com.cloud.vm.snapshot.VMSnapshotVO;
|
||||
@Component
|
||||
@Local(value = { VMSnapshotDao.class })
|
||||
public class VMSnapshotDaoImpl extends GenericDaoBase<VMSnapshotVO, Long>
|
||||
implements VMSnapshotDao {
|
||||
private static final Logger s_logger = Logger.getLogger(VMSnapshotDaoImpl.class);
|
||||
private final SearchBuilder<VMSnapshotVO> SnapshotSearch;
|
||||
private final SearchBuilder<VMSnapshotVO> ExpungingSnapshotSearch;
|
||||
private final SearchBuilder<VMSnapshotVO> SnapshotStatusSearch;
|
||||
private final SearchBuilder<VMSnapshotVO> AllFieldsSearch;
|
||||
|
||||
protected VMSnapshotDaoImpl() {
|
||||
AllFieldsSearch = createSearchBuilder();
|
||||
AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ);
|
||||
AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), Op.EQ);
|
||||
AllFieldsSearch.and("vm_id", AllFieldsSearch.entity().getVmId(), Op.EQ);
|
||||
AllFieldsSearch.and("deviceId", AllFieldsSearch.entity().getVmId(), Op.EQ);
|
||||
AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ);
|
||||
AllFieldsSearch.and("removed", AllFieldsSearch.entity().getState(), Op.EQ);
|
||||
AllFieldsSearch.and("parent", AllFieldsSearch.entity().getParent(), Op.EQ);
|
||||
AllFieldsSearch.and("current", AllFieldsSearch.entity().getCurrent(), Op.EQ);
|
||||
AllFieldsSearch.and("vm_snapshot_type", AllFieldsSearch.entity().getType(), Op.EQ);
|
||||
AllFieldsSearch.and("updatedCount", AllFieldsSearch.entity().getUpdatedCount(), Op.EQ);
|
||||
AllFieldsSearch.and("display_name", AllFieldsSearch.entity().getDisplayName(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.and("name", AllFieldsSearch.entity().getName(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.done();
|
||||
|
||||
SnapshotSearch = createSearchBuilder();
|
||||
SnapshotSearch.and("vm_id", SnapshotSearch.entity().getVmId(),
|
||||
SearchCriteria.Op.EQ);
|
||||
SnapshotSearch.done();
|
||||
|
||||
ExpungingSnapshotSearch = createSearchBuilder();
|
||||
ExpungingSnapshotSearch.and("state", ExpungingSnapshotSearch.entity()
|
||||
.getState(), SearchCriteria.Op.EQ);
|
||||
ExpungingSnapshotSearch.and("removed", ExpungingSnapshotSearch.entity()
|
||||
.getRemoved(), SearchCriteria.Op.NULL);
|
||||
ExpungingSnapshotSearch.done();
|
||||
|
||||
SnapshotStatusSearch = createSearchBuilder();
|
||||
SnapshotStatusSearch.and("vm_id", SnapshotStatusSearch.entity()
|
||||
.getVmId(), SearchCriteria.Op.EQ);
|
||||
SnapshotStatusSearch.and("state", SnapshotStatusSearch.entity()
|
||||
.getState(), SearchCriteria.Op.IN);
|
||||
SnapshotStatusSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VMSnapshotVO> findByVm(Long vmId) {
|
||||
SearchCriteria<VMSnapshotVO> sc = SnapshotSearch.create();
|
||||
sc.setParameters("vm_id", vmId);
|
||||
return listBy(sc, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VMSnapshotVO> listExpungingSnapshot() {
|
||||
SearchCriteria<VMSnapshotVO> sc = ExpungingSnapshotSearch.create();
|
||||
sc.setParameters("state", State.Expunging);
|
||||
return listBy(sc, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VMSnapshotVO> listByInstanceId(Long vmId, State... status) {
|
||||
SearchCriteria<VMSnapshotVO> sc = SnapshotStatusSearch.create();
|
||||
sc.setParameters("vm_id", vmId);
|
||||
sc.setParameters("state", (Object[]) status);
|
||||
return listBy(sc, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VMSnapshotVO findCurrentSnapshotByVmId(Long vmId) {
|
||||
SearchCriteria<VMSnapshotVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("vm_id", vmId);
|
||||
sc.setParameters("current", 1);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VMSnapshotVO> listByParent(Long vmSnapshotId) {
|
||||
SearchCriteria<VMSnapshotVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("parent", vmSnapshotId);
|
||||
sc.setParameters("state", State.Ready );
|
||||
return listBy(sc, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VMSnapshotVO findByName(Long vm_id, String name) {
|
||||
SearchCriteria<VMSnapshotVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("vm_id", vm_id);
|
||||
sc.setParameters("display_name", name );
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateState(State currentState, Event event, State nextState, VMSnapshot vo, Object data) {
|
||||
|
||||
Long oldUpdated = vo.getUpdatedCount();
|
||||
Date oldUpdatedTime = vo.getUpdated();
|
||||
|
||||
SearchCriteria<VMSnapshotVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("id", vo.getId());
|
||||
sc.setParameters("state", currentState);
|
||||
sc.setParameters("updatedCount", vo.getUpdatedCount());
|
||||
|
||||
vo.incrUpdatedCount();
|
||||
|
||||
UpdateBuilder builder = getUpdateBuilder(vo);
|
||||
builder.set(vo, "state", nextState);
|
||||
builder.set(vo, "updated", new Date());
|
||||
|
||||
int rows = update((VMSnapshotVO)vo, sc);
|
||||
if (rows == 0 && s_logger.isDebugEnabled()) {
|
||||
VMSnapshotVO dbVol = findByIdIncludingRemoved(vo.getId());
|
||||
if (dbVol != null) {
|
||||
StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString());
|
||||
str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()).append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=").append(dbVol.getUpdated());
|
||||
str.append(": New Data={id=").append(vo.getId()).append("; state=").append(nextState).append("; event=").append(event).append("; updatecount=").append(vo.getUpdatedCount()).append("; updatedTime=").append(vo.getUpdated());
|
||||
str.append(": stale Data={id=").append(vo.getId()).append("; state=").append(currentState).append("; event=").append(event).append("; updatecount=").append(oldUpdated).append("; updatedTime=").append(oldUpdatedTime);
|
||||
} else {
|
||||
s_logger.debug("Unable to update VM snapshot: id=" + vo.getId() + ", as there is no such snapshot exists in the database anymore");
|
||||
}
|
||||
}
|
||||
return rows > 0;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.resourcelimit;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.cloud.configuration.ResourceLimit;
|
||||
import com.cloud.vpc.MockResourceLimitManagerImpl;
|
||||
|
||||
public class ResourceLimitManagerImplTest extends TestCase{
|
||||
private static final Logger s_logger = Logger.getLogger(ResourceLimitManagerImplTest.class);
|
||||
|
||||
MockResourceLimitManagerImpl _resourceLimitService = new MockResourceLimitManagerImpl();
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInjected() throws Exception {
|
||||
s_logger.info("Starting test for Resource Limit manager");
|
||||
updateResourceCount();
|
||||
updateResourceLimit();
|
||||
//listResourceLimits();
|
||||
s_logger.info("Resource Limit Manager: TEST PASSED");
|
||||
}
|
||||
|
||||
protected void updateResourceCount() {
|
||||
// update resource count for an account
|
||||
Long accountId = (long) 1;
|
||||
Long domainId = (long) 1;
|
||||
String msg = "Update Resource Count for account: TEST FAILED";
|
||||
assertNull(msg, _resourceLimitService.recalculateResourceCount(accountId, domainId, null));
|
||||
|
||||
// update resource count for a domain
|
||||
accountId = null;
|
||||
msg = "Update Resource Count for domain: TEST FAILED";
|
||||
assertNull(msg, _resourceLimitService.recalculateResourceCount(accountId, domainId, null));
|
||||
}
|
||||
|
||||
protected void updateResourceLimit() {
|
||||
// update resource Limit for an account for resource_type = 8 (CPU)
|
||||
resourceLimitServiceCall((long) 1, (long) 1, 8, (long) 20);
|
||||
|
||||
// update resource Limit for a domain for resource_type = 8 (CPU)
|
||||
resourceLimitServiceCall(null, (long) 1, 8, (long) 40);
|
||||
|
||||
// update resource Limit for an account for resource_type = 9 (Memory)
|
||||
resourceLimitServiceCall((long) 1, (long) 1, 9, (long) 4096);
|
||||
|
||||
// update resource Limit for a domain for resource_type = 9 (Memory)
|
||||
resourceLimitServiceCall(null, (long) 1, 9, (long) 10240);
|
||||
}
|
||||
|
||||
private void resourceLimitServiceCall(Long accountId, Long domainId, Integer resourceType, Long max) {
|
||||
String msg = "Update Resource Limit: TEST FAILED";
|
||||
ResourceLimit result = null;
|
||||
try {
|
||||
result = _resourceLimitService.updateResourceLimit(accountId, domainId, resourceType, max);
|
||||
assertFalse(msg, (result != null || (result == null && max != null && max.longValue() == -1L)));
|
||||
} catch (Exception ex) {
|
||||
fail(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
186
server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java
Normal file
186
server/test/com/cloud/vm/snapshot/VMSnapshotManagerTest.java
Normal file
@ -0,0 +1,186 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.vm.snapshot;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyLong;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.Spy;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.CreateVMSnapshotAnswer;
|
||||
import com.cloud.agent.api.CreateVMSnapshotCommand;
|
||||
import com.cloud.agent.api.to.VolumeTO;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.OperationTimedoutException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.HypervisorGuruManager;
|
||||
import com.cloud.storage.GuestOSVO;
|
||||
import com.cloud.storage.Snapshot;
|
||||
import com.cloud.storage.SnapshotVO;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.GuestOSDao;
|
||||
import com.cloud.storage.dao.SnapshotDao;
|
||||
import com.cloud.storage.dao.StoragePoolDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.fsm.NoTransitionException;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.VirtualMachineManager;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||
|
||||
|
||||
|
||||
public class VMSnapshotManagerTest {
|
||||
@Spy VMSnapshotManagerImpl _vmSnapshotMgr = new VMSnapshotManagerImpl();
|
||||
@Mock Account admin;
|
||||
@Mock VMSnapshotDao _vmSnapshotDao;
|
||||
@Mock VolumeDao _volumeDao;
|
||||
@Mock AccountDao _accountDao;
|
||||
@Mock VMInstanceDao _vmInstanceDao;
|
||||
@Mock UserVmDao _userVMDao;
|
||||
@Mock HostDao _hostDao;
|
||||
@Mock UserDao _userDao;
|
||||
@Mock AgentManager _agentMgr;
|
||||
@Mock HypervisorGuruManager _hvGuruMgr;
|
||||
@Mock AccountManager _accountMgr;
|
||||
@Mock GuestOSDao _guestOSDao;
|
||||
@Mock StoragePoolDao _storagePoolDao;
|
||||
@Mock SnapshotDao _snapshotDao;
|
||||
@Mock VirtualMachineManager _itMgr;
|
||||
@Mock ConfigurationDao _configDao;
|
||||
int _vmSnapshotMax = 10;
|
||||
|
||||
private static long TEST_VM_ID = 3L;
|
||||
@Mock UserVmVO vmMock;
|
||||
@Mock VolumeVO volumeMock;
|
||||
|
||||
@Before
|
||||
public void setup(){
|
||||
MockitoAnnotations.initMocks(this);
|
||||
doReturn(admin).when(_vmSnapshotMgr).getCaller();
|
||||
_vmSnapshotMgr._accountDao = _accountDao;
|
||||
_vmSnapshotMgr._userVMDao = _userVMDao;
|
||||
_vmSnapshotMgr._vmSnapshotDao = _vmSnapshotDao;
|
||||
_vmSnapshotMgr._volumeDao = _volumeDao;
|
||||
_vmSnapshotMgr._accountMgr = _accountMgr;
|
||||
_vmSnapshotMgr._snapshotDao = _snapshotDao;
|
||||
_vmSnapshotMgr._guestOSDao = _guestOSDao;
|
||||
|
||||
doNothing().when(_accountMgr).checkAccess(any(Account.class), any(AccessType.class),
|
||||
any(Boolean.class), any(ControlledEntity.class));
|
||||
|
||||
_vmSnapshotMgr._vmSnapshotMax = _vmSnapshotMax;
|
||||
|
||||
when(_userVMDao.findById(anyLong())).thenReturn(vmMock);
|
||||
when(_vmSnapshotDao.findByName(anyLong(), anyString())).thenReturn(null);
|
||||
when(_vmSnapshotDao.findByVm(anyLong())).thenReturn(new ArrayList<VMSnapshotVO>());
|
||||
|
||||
List<VolumeVO> mockVolumeList = new ArrayList<VolumeVO>();
|
||||
mockVolumeList.add(volumeMock);
|
||||
when(volumeMock.getInstanceId()).thenReturn(TEST_VM_ID);
|
||||
when(_volumeDao.findByInstance(anyLong())).thenReturn(mockVolumeList);
|
||||
|
||||
when(vmMock.getInstanceName()).thenReturn("i-3-VM-TEST");
|
||||
when(vmMock.getState()).thenReturn(State.Running);
|
||||
|
||||
when(_guestOSDao.findById(anyLong())).thenReturn(mock(GuestOSVO.class));
|
||||
}
|
||||
|
||||
// vmId null case
|
||||
@Test(expected=InvalidParameterValueException.class)
|
||||
public void testAllocVMSnapshotF1() throws ResourceAllocationException{
|
||||
when(_userVMDao.findById(TEST_VM_ID)).thenReturn(null);
|
||||
_vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID,"","",true);
|
||||
}
|
||||
|
||||
// vm state not in [running, stopped] case
|
||||
@Test(expected=InvalidParameterValueException.class)
|
||||
public void testAllocVMSnapshotF2() throws ResourceAllocationException{
|
||||
when(vmMock.getState()).thenReturn(State.Starting);
|
||||
_vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID,"","",true);
|
||||
}
|
||||
|
||||
// VM in stopped state & snapshotmemory case
|
||||
@Test(expected=InvalidParameterValueException.class)
|
||||
public void testCreateVMSnapshotF3() throws AgentUnavailableException, OperationTimedoutException, ResourceAllocationException{
|
||||
when(vmMock.getState()).thenReturn(State.Stopped);
|
||||
_vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID,"","",true);
|
||||
}
|
||||
|
||||
// max snapshot limit case
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(expected=CloudRuntimeException.class)
|
||||
public void testAllocVMSnapshotF4() throws ResourceAllocationException{
|
||||
List<VMSnapshotVO> mockList = mock(List.class);
|
||||
when(mockList.size()).thenReturn(10);
|
||||
when(_vmSnapshotDao.findByVm(TEST_VM_ID)).thenReturn(mockList);
|
||||
_vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID,"","",true);
|
||||
}
|
||||
|
||||
// active volume snapshots case
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(expected=CloudRuntimeException.class)
|
||||
public void testAllocVMSnapshotF5() throws ResourceAllocationException{
|
||||
List<SnapshotVO> mockList = mock(List.class);
|
||||
when(mockList.size()).thenReturn(1);
|
||||
when(_snapshotDao.listByInstanceId(TEST_VM_ID,Snapshot.State.Creating,
|
||||
Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp)).thenReturn(mockList);
|
||||
_vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID,"","",true);
|
||||
}
|
||||
|
||||
// successful creation case
|
||||
@Test
|
||||
public void testCreateVMSnapshot() throws AgentUnavailableException, OperationTimedoutException, ResourceAllocationException, NoTransitionException{
|
||||
when(vmMock.getState()).thenReturn(State.Running);
|
||||
_vmSnapshotMgr.allocVMSnapshot(TEST_VM_ID,"","",true);
|
||||
|
||||
when(_vmSnapshotDao.findCurrentSnapshotByVmId(anyLong())).thenReturn(null);
|
||||
doReturn(new ArrayList<VolumeTO>()).when(_vmSnapshotMgr).getVolumeTOList(anyLong());
|
||||
doReturn(new CreateVMSnapshotAnswer(null,true,"")).when(_vmSnapshotMgr).sendToPool(anyLong(), any(CreateVMSnapshotCommand.class));
|
||||
doNothing().when(_vmSnapshotMgr).processAnswer(any(VMSnapshotVO.class),
|
||||
any(UserVmVO.class), any(Answer.class), anyLong());
|
||||
doReturn(true).when(_vmSnapshotMgr).vmSnapshotStateTransitTo(any(VMSnapshotVO.class),any(VMSnapshot.Event.class));
|
||||
_vmSnapshotMgr.createVmSnapshotInternal(vmMock, mock(VMSnapshotVO.class), 5L);
|
||||
}
|
||||
|
||||
}
|
||||
@ -31,7 +31,6 @@ import com.cloud.domain.Domain;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.ResourceLimitService;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
|
||||
@Component
|
||||
@ -117,6 +116,22 @@ public class MockResourceLimitManagerImpl extends ManagerBase implements Resourc
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.cloud.user.ResourceLimitService#countCpusForAccount(long)
|
||||
*/
|
||||
public long countCpusForAccount(long accountId) {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.cloud.user.ResourceLimitService#calculateRAMForAccount(long)
|
||||
*/
|
||||
public long calculateMemoryForAccount(long accountId) {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.cloud.user.ResourceLimitService#getResourceCount(com.cloud.user.Account, com.cloud.configuration.Resource.ResourceType)
|
||||
*/
|
||||
|
||||
35
services/console-proxy/plugin/pom.xml
Normal file
35
services/console-proxy/plugin/pom.xml
Normal file
@ -0,0 +1,35 @@
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cloud-plugin-console-proxy</artifactId>
|
||||
<name>Apache CloudStack Console Proxy Plugin</name>
|
||||
<packaging>pom</packaging>
|
||||
<parent>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-service-console-proxy</artifactId>
|
||||
<version>4.1.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<build>
|
||||
<defaultGoal>install</defaultGoal>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<testSourceDirectory>test</testSourceDirectory>
|
||||
</build>
|
||||
</project>
|
||||
37
services/console-proxy/pom.xml
Normal file
37
services/console-proxy/pom.xml
Normal file
@ -0,0 +1,37 @@
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cloud-service-console-proxy</artifactId>
|
||||
<name>Apache CloudStack Console Proxy Service</name>
|
||||
<packaging>pom</packaging>
|
||||
<parent>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-services</artifactId>
|
||||
<version>4.1.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<build>
|
||||
<defaultGoal>install</defaultGoal>
|
||||
</build>
|
||||
<modules>
|
||||
<module>plugin</module>
|
||||
<module>server</module>
|
||||
</modules>
|
||||
</project>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user