Merge branch 'master' into ui-plugins

Conflicts:
	ui/index.jsp
This commit is contained in:
Brian Federle 2013-02-13 14:03:53 -08:00
commit dfaffcebad
250 changed files with 5905 additions and 825 deletions

185
LICENSE
View File

@ -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
View File

@ -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.

View 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;
}
}

View 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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View 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;
}
}

View 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);
}
}

View 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;
}
}

View 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);
}
}

View 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;
}
}

View 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;
}
}

View File

@ -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() {

View File

@ -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;

View File

@ -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";

View File

@ -37,7 +37,8 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit
Project,
Vpc,
NetworkACL,
StaticRoute
StaticRoute,
VMSnapshot
}
/**

View File

@ -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 {

View 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();
}

View 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);
}

View File

@ -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;

View 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();
}
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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,

View File

@ -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;
/////////////////////////////////////////////////////

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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")

View File

@ -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.")

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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());

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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
*

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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 );
}

View File

@ -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();

View File

@ -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);

View File

@ -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.

View File

@ -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>

View File

@ -537,3 +537,9 @@ addRegion=1
updateRegion=1
removeRegion=1
listRegions=15
### VM Snapshot commands
listVMSnapshot=15
createVMSnapshot=15
deleteVMSnapshot=15
revertToSnapshot=15

View File

@ -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
-->

View File

@ -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>

View File

@ -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:&lt;dbpassword&gt;@&lt;ip address mysql server&gt; \
--deploy-as=root:&lt;password&gt; \
-e &lt;encryption_type&gt; \
-m &lt;management_server_key&gt; \
-k &lt;database_key&gt;</programlisting>
-k &lt;database_key&gt; \
-i &lt;management_server_ip&gt;</programlisting>
<para>When this script is finished, you should see a message like “Successfully initialized
the database.”</para>
</listitem>

View File

@ -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:&lt;dbpassword&gt;@localhost \
--deploy-as=root:&lt;password&gt; \
-e &lt;encryption_type&gt; \
-m &lt;management_server_key&gt; \
-k &lt;database_key&gt;</programlisting>
-k &lt;database_key&gt; \
-i &lt;management_server_ip&gt;</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>

View File

@ -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>

View File

@ -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
View File

View 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

View File

@ -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`

View File

@ -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 {

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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));

View File

@ -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
View File

@ -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>

View File

@ -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)

View File

@ -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

View File

@ -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})

View File

@ -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);
}

View File

@ -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();

View File

@ -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()]));

View File

@ -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;
}

View File

@ -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);

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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>();

View File

@ -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>();

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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");
}
}
}

View File

@ -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;
}

View File

@ -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 {

View File

@ -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;

View File

@ -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(),

View File

@ -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());

View 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);
}

View 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;
}
}

View 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);
}

View 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;
}
}

View File

@ -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);
}
}
}

View 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);
}
}

View File

@ -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)
*/

View 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>

View 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