diff --git a/build/build-cloud.xml b/build/build-cloud.xml index 0204e78165a..fae75e09724 100755 --- a/build/build-cloud.xml +++ b/build/build-cloud.xml @@ -261,6 +261,7 @@ + diff --git a/build/package.xml b/build/package.xml index 82781c61a2f..5579a3d148c 100755 --- a/build/package.xml +++ b/build/package.xml @@ -56,6 +56,7 @@ + @@ -154,6 +155,7 @@ + diff --git a/client/WEB-INF/ui-library.txt b/client/WEB-INF/ui-library.txt new file mode 100644 index 00000000000..e74fd4f9330 --- /dev/null +++ b/client/WEB-INF/ui-library.txt @@ -0,0 +1,2 @@ +jquery : 1.4.2 +jquery-ui : 1.8.2 \ No newline at end of file diff --git a/cloud.spec b/cloud.spec index 1e5d2ddc11b..140a089b258 100644 --- a/cloud.spec +++ b/cloud.spec @@ -296,6 +296,14 @@ Group: System Environment/Libraries The Cloud.com usage monitor provides usage accounting across the entire cloud for cloud operators to charge based on usage parameters. +%package cli +Summary: Cloud.com command line tools +Requires: python +Group: System Environment/Libraries +%description cli +The Cloud.com command line tools contain a few Python modules that can call cloudStack APIs. + + %endif %prep @@ -516,6 +524,7 @@ fi %{_javadir}/%{name}-xenserver-5.5.0-1.jar %{_javadir}/%{name}-xmlrpc-common-3.*.jar %{_javadir}/%{name}-xmlrpc-client-3.*.jar +%{_javadir}/%{name}-manageontap.jar %doc README %doc HACKING %doc debian/copyright @@ -538,7 +547,9 @@ fi %files python %defattr(0644,root,root,0755) -%{_prefix}/lib*/python*/site-packages/%{name}* +%{_prefix}/lib*/python*/site-packages/%{name}_PrettyPrint.* +%{_prefix}/lib*/python*/site-packages/%{name}_sxp.* +%{_prefix}/lib*/python*/site-packages/%{name}_utils.* %doc README %doc HACKING %doc debian/copyright @@ -546,6 +557,7 @@ fi %files setup %attr(0755,root,root) %{_bindir}/%{name}-setup-databases %attr(0755,root,root) %{_bindir}/%{name}-migrate-databases +%attr(0755,root,root) %{_bindir}/%{name}-migrate-snapshot %dir %{_datadir}/%{name}/setup %{_datadir}/%{name}/setup/create-database.sql %{_datadir}/%{name}/setup/create-index-fk.sql @@ -560,6 +572,7 @@ fi %{_datadir}/%{name}/setup/index-212to213.sql %{_datadir}/%{name}/setup/postprocess-20to21.sql %{_datadir}/%{name}/setup/schema-20to21.sql +%{_datadir}/%{name}/setup/schema-213to214.sql %{_datadir}/%{name}/setup/schema-level.sql %doc README %doc HACKING @@ -696,6 +709,17 @@ fi %doc HACKING %doc debian/copyright +%files cli +%{_bindir}/%{name}-tool +%{_bindir}/%{name}voladm +%{_sysconfdir}/%{name}/cli/commands.xml +%dir %{_prefix}/lib*/python*/site-packages/%{name}tool +%{_prefix}/lib*/python*/site-packages/%{name}tool/* +%{_prefix}/lib*/python*/site-packages/%{name}apis.py +%doc README +%doc HACKING +%doc debian/copyright + %endif %changelog diff --git a/core/src/com/cloud/agent/api/NetworkRulesSystemVmCommand.java b/core/src/com/cloud/agent/api/NetworkRulesSystemVmCommand.java new file mode 100644 index 00000000000..9c5618f94a5 --- /dev/null +++ b/core/src/com/cloud/agent/api/NetworkRulesSystemVmCommand.java @@ -0,0 +1,41 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.agent.api; + +public class NetworkRulesSystemVmCommand extends Command { + + private String vmName; + + protected NetworkRulesSystemVmCommand() { + + } + + public NetworkRulesSystemVmCommand(String vmName) { + this.vmName = vmName; + } + + public String getVmName() { + return vmName; + } + + @Override + public boolean executeInSequence() { + return false; + } + +} diff --git a/core/src/com/cloud/alert/AlertManager.java b/core/src/com/cloud/alert/AlertManager.java index e2aee90d1d4..6378bf5b3eb 100644 --- a/core/src/com/cloud/alert/AlertManager.java +++ b/core/src/com/cloud/alert/AlertManager.java @@ -40,7 +40,8 @@ public interface AlertManager extends Manager { public static final short ALERT_TYPE_CONSOLE_PROXY_MIGRATE = 15; public static final short ALERT_TYPE_USERVM_MIGRATE = 16; public static final short ALERT_TYPE_VLAN = 17; - public static final short ALERT_TYPE_SSVM = 18; + public static final short ALERT_TYPE_SSVM = 18; + public static final short ALERT_TYPE_USAGE_SERVER_RESULT = 19; // Usage job result void clearAlert(short alertType, long dataCenterId, long podId); void sendAlert(short alertType, long dataCenterId, Long podId, String subject, String body); diff --git a/core/src/com/cloud/configuration/dao/ConfigurationDaoImpl.java b/core/src/com/cloud/configuration/dao/ConfigurationDaoImpl.java index 83c751a47f0..52ab1924630 100644 --- a/core/src/com/cloud/configuration/dao/ConfigurationDaoImpl.java +++ b/core/src/com/cloud/configuration/dao/ConfigurationDaoImpl.java @@ -133,12 +133,8 @@ public class ConfigurationDaoImpl extends GenericDaoBase. + * + */ +package com.cloud.exception; + +public class UsageServerException extends Exception { + + public UsageServerException() { + + } + + public UsageServerException(String message) { + super(message); + } + + + + +} diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 325d1b7a2fe..ca47e3f8bf1 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -96,6 +96,7 @@ import com.cloud.agent.api.ModifyStoragePoolAnswer; import com.cloud.agent.api.ModifyStoragePoolCommand; import com.cloud.agent.api.NetworkIngressRuleAnswer; import com.cloud.agent.api.NetworkIngressRulesCmd; +import com.cloud.agent.api.NetworkRulesSystemVmCommand; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingRoutingCommand; import com.cloud.agent.api.PingRoutingWithNwGroupsCommand; @@ -317,9 +318,6 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } try { - if (isRefNull(record.affinity) || !record.affinity.getUuid(conn).equals(_host.uuid)) { - continue; - } vmentry.getKey().destroy(conn); } catch (Exception e) { String msg = "VM destroy failed for " + record.nameLabel + " due to " + e.getMessage(); @@ -648,6 +646,8 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR return execute((ModifySshKeysCommand) cmd); } else if (cmd instanceof NetworkIngressRulesCmd) { return execute((NetworkIngressRulesCmd) cmd); + } else if (cmd instanceof NetworkRulesSystemVmCommand) { + return execute((NetworkRulesSystemVmCommand) cmd); } else if (cmd instanceof PoolEjectCommand) { return execute((PoolEjectCommand) cmd); } else { @@ -2487,6 +2487,11 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR vm.setActionsAfterCrash(conn, Types.OnCrashBehaviour.DESTROY); vm.start(conn, false, true); + + if(!vm.getResidentOn(conn).getUuid(conn).equals(_host.uuid)){ + startvmfailhandle(vm, null); + throw new Exception("can not start VM " + cmd.getVmName() + " On host " + _host.ip); + } if (_canBridgeFirewall) { String result = callHostPlugin("default_network_rules", @@ -2687,6 +2692,10 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR disableVlanNetwork(network); } } + } else { + String msg = "VM " + vmName + " shutdown succeed, but this vm is not in halted state, it is in " + vm.getPowerState(conn) + " state"; + s_logger.warn(msg); + return new StopAnswer(cmd, msg); } } catch (XenAPIException e) { String msg = "VM destroy failed in Stop " + vmName + " Command due to " + e.toString(); @@ -3126,18 +3135,18 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR if (s_logger.isTraceEnabled()) { s_logger.trace("callHostPlugin executing for command " + cmd + " with " + getArgsString(args)); } - if( _host.host == null ) { - _host.host = Host.getByUuid(conn, _host.uuid); - } - String result = _host.host.callPlugin(conn, plugin, cmd, args); + Host host = Host.getByUuid(conn, _host.uuid); + String result = host.callPlugin(conn, plugin, cmd, args); if (s_logger.isTraceEnabled()) { s_logger.trace("callHostPlugin Result: " + result); } return result.replace("\n", ""); + } catch ( Types.HandleInvalid e) { + s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to HandleInvalid clazz:" + e.clazz + ", handle:" + e.handle); } catch (XenAPIException e) { - s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString()); + s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString(), e); } catch (XmlRpcException e) { - s_logger.debug("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.getMessage()); + s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.getMessage(), e); } return null; } @@ -3334,7 +3343,6 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR PIF.Record pifr = pif.getRecord(conn); if(pifr.host.equals(nPifr.host)) { if (pifr.device.equals(nPifr.device) ) { - pif.plug(conn); return vlanNetwork; } else { throw new CloudRuntimeException("Creating VLAN " + tag + " on " + nPifr.device + " failed due to this VLAN is already created on " + pifr.device); @@ -3348,10 +3356,6 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR s_logger.debug("Creating VLAN " + tag + " on host " + _host.ip); } VLAN vlan = VLAN.create(conn, nPif, tag, vlanNetwork); - PIF untaggedPif = vlan.getUntaggedPIF(conn); - if (!untaggedPif.getCurrentlyAttached(conn)) { - untaggedPif.plug(conn); - } if (s_logger.isDebugEnabled()) { s_logger.debug("Created VLAN " + tag + " on host " + _host.ip); } @@ -3566,6 +3570,8 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR s_logger.warn("Unable to get private network " + name); return false; } + } else { + _privateNetworkName = name; } name = privateNic.nr.nameLabel; @@ -3923,12 +3929,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } finally { sshConnection.close(); } - try { - // wait 2 seconds before call plugin - Thread.sleep(2000); - } catch (final InterruptedException ex) { - } if (!setIptables()) { s_logger.warn("set xenserver Iptable failed"); } @@ -4247,7 +4248,6 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } catch (NumberFormatException e) { throw new ConfigurationException("Unable to get the zone " + params.get("zone")); } - _host.host = null; _name = _host.uuid; _host.ip = (String) params.get("url"); _host.pool = (String) params.get("pool"); @@ -5094,7 +5094,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR protected String getVhdParent(String primaryStorageSRUuid, String snapshotUuid, Boolean isISCSI) { - String parentUuid = callHostPlugin("vmopsSnapshot", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, + String parentUuid = callHostPlugin("getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid, "isISCSI", isISCSI.toString()); if (parentUuid == null || parentUuid.isEmpty()) { @@ -5156,12 +5156,6 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } } - - VDI.Record vdir = snapshot.getRecord(conn); - snapshotUUID = vdir.uuid; - - success = true; - details = null; } else if (cmd.getCommandSwitch().equals(ManageSnapshotCommand.DESTROY_SNAPSHOT)) { // Look up the snapshot snapshotUUID = cmd.getSnapshotPath(); @@ -5169,9 +5163,9 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR snapshot.destroy(conn); snapshotUUID = null; - success = true; - details = null; } + success = true; + details = null; } catch (XenAPIException e) { details += ", reason: " + e.toString(); s_logger.warn(details, e); @@ -6062,6 +6056,23 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } } + private Answer execute(NetworkRulesSystemVmCommand cmd) { + boolean success = false; + if (_canBridgeFirewall) { + String result = callHostPlugin("default_network_rules_systemvm", "vmName", cmd.getVmName()); + if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { + s_logger.warn("Failed to program default system vm network rules for " + cmd.getVmName()); + success = false; + } else { + s_logger.info("Programmed default system vm network rules for " + cmd.getVmName()); + success = true; + } + } else { + s_logger.warn("Cannot program ingress rules for system vm -- bridge firewalling not supported on host"); + } + return new Answer(cmd, success, ""); + } + private Answer execute(PoolEjectCommand cmd) { Connection conn = getConnection(); String hostuuid = cmd.getHostuuid(); @@ -6079,15 +6090,20 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR return new Answer(cmd); } Host host = Host.getByUuid(conn, hostuuid); - Pool.eject(conn, host); + try { + Pool.eject(conn, host); + } catch (XenAPIException e) { + String msg = "Unable to eject host " + _host.uuid + " due to " + e.toString(); + s_logger.warn(msg); + host.destroy(conn); + } return new Answer(cmd); } catch (XenAPIException e) { - String msg = "Unable to eject host " + _host.uuid + " due to " + e.toString(); + String msg = "XenAPIException Unable to destroy host " + _host.uuid + " in xenserver database due to " + e.toString(); s_logger.warn(msg, e); return new Answer(cmd, false, msg); } catch (Exception e) { - s_logger.warn("Unable to eject host " + _host.uuid, e); - String msg = "Unable to eject host " + _host.uuid + " due to " + e.getMessage(); + String msg = "Exception Unable to destroy host " + _host.uuid + " in xenserver database due to " + e.getMessage(); s_logger.warn(msg, e); return new Answer(cmd, false, msg); } @@ -6114,7 +6130,6 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR protected class XenServerHost { public String uuid; public String ip; - public Host host; public String publicNetwork; public String privateNetwork; public String linkLocalNetwork; @@ -6129,7 +6144,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR public String pool; } - private class VHDInfo { + class VHDInfo { private final String uuid; private final Long virtualSize; diff --git a/core/src/com/cloud/vm/State.java b/core/src/com/cloud/vm/State.java index 81692497d9f..c8bbb140f10 100644 --- a/core/src/com/cloud/vm/State.java +++ b/core/src/com/cloud/vm/State.java @@ -21,6 +21,7 @@ package com.cloud.vm; import java.util.List; import com.cloud.utils.fsm.StateMachine; +import com.cloud.vm.VirtualMachine.Event; public enum State { Creating(true), @@ -66,7 +67,7 @@ public enum State { static { s_fsm.addTransition(null, VirtualMachine.Event.CreateRequested, State.Creating); s_fsm.addTransition(State.Creating, VirtualMachine.Event.OperationSucceeded, State.Stopped); - s_fsm.addTransition(State.Creating, VirtualMachine.Event.OperationFailed, State.Destroyed); + s_fsm.addTransition(State.Creating, VirtualMachine.Event.OperationFailed, State.Error); s_fsm.addTransition(State.Stopped, VirtualMachine.Event.StartRequested, State.Starting); s_fsm.addTransition(State.Stopped, VirtualMachine.Event.DestroyRequested, State.Destroyed); s_fsm.addTransition(State.Stopped, VirtualMachine.Event.StopRequested, State.Stopped); @@ -95,5 +96,6 @@ public enum State { s_fsm.addTransition(State.Stopping, VirtualMachine.Event.StopRequested, State.Stopping); s_fsm.addTransition(State.Expunging, VirtualMachine.Event.OperationFailed, State.Expunging); s_fsm.addTransition(State.Expunging, VirtualMachine.Event.ExpungeOperation, State.Expunging); + s_fsm.addTransition(State.Error, VirtualMachine.Event.ExpungeOperation, State.Expunging); } } diff --git a/core/src/com/cloud/vm/UserVmVO.java b/core/src/com/cloud/vm/UserVmVO.java index 062c0f0a59e..a7f47f01ae3 100755 --- a/core/src/com/cloud/vm/UserVmVO.java +++ b/core/src/com/cloud/vm/UserVmVO.java @@ -144,7 +144,7 @@ public class UserVmVO extends VMInstanceVO implements UserVm { String externalMacAddress, Long vlanDbId, Long routerId, - long podId, + Long podId, long dcId, boolean haEnabled, String displayName, diff --git a/core/src/com/cloud/vm/VMInstanceVO.java b/core/src/com/cloud/vm/VMInstanceVO.java index 6dd7bf0ba38..e12a00c65f5 100644 --- a/core/src/com/cloud/vm/VMInstanceVO.java +++ b/core/src/com/cloud/vm/VMInstanceVO.java @@ -99,8 +99,8 @@ public class VMInstanceVO implements VirtualMachine { @Column(name="last_host_id", updatable=true, nullable=true) private Long lastHostId; - @Column(name="pod_id", updatable=true, nullable=false) - private long podId; + @Column(name="pod_id", updatable=true, nullable=true) + private Long podId; @Column(name="private_mac_address", updatable=true, nullable=true) String privateMacAddress; @@ -143,7 +143,7 @@ public class VMInstanceVO implements VirtualMachine { String privateIpAddress, String privateNetmask, long dataCenterId, - long podId, + Long podId, boolean haEnabled, Long hostId, String displayName, @@ -162,7 +162,7 @@ public class VMInstanceVO implements VirtualMachine { String privateIpAddress, String privateNetmask, long dataCenterId, - long podId, + Long podId, boolean haEnabled, Long hostId, String displayName, @@ -363,7 +363,7 @@ public class VMInstanceVO implements VirtualMachine { } @Override - public long getPodId() { + public Long getPodId() { return podId; } diff --git a/core/src/com/cloud/vm/VirtualMachine.java b/core/src/com/cloud/vm/VirtualMachine.java index 67dc85e5fb3..b5d960a1e50 100755 --- a/core/src/com/cloud/vm/VirtualMachine.java +++ b/core/src/com/cloud/vm/VirtualMachine.java @@ -107,7 +107,7 @@ public interface VirtualMachine { /** * @return pod id. */ - public long getPodId(); + public Long getPodId(); /** * @return data center id. diff --git a/core/src/com/cloud/vm/dao/DomainRouterDaoImpl.java b/core/src/com/cloud/vm/dao/DomainRouterDaoImpl.java index a12d32e964a..f3cf21c8033 100755 --- a/core/src/com/cloud/vm/dao/DomainRouterDaoImpl.java +++ b/core/src/com/cloud/vm/dao/DomainRouterDaoImpl.java @@ -292,6 +292,6 @@ public class DomainRouterDaoImpl extends GenericDaoBase im public List listByVlanDbId(Long vlanDbId) { SearchCriteria sc = VlanDbIdSearch.create(); sc.setParameters("vlanDbId", vlanDbId); - return listBy(sc); + return listActiveBy(sc); } } diff --git a/core/src/com/cloud/vm/dao/UserVmDaoImpl.java b/core/src/com/cloud/vm/dao/UserVmDaoImpl.java index 956b8ca149f..54cf7f6b5f4 100755 --- a/core/src/com/cloud/vm/dao/UserVmDaoImpl.java +++ b/core/src/com/cloud/vm/dao/UserVmDaoImpl.java @@ -229,7 +229,7 @@ public class UserVmDaoImpl extends GenericDaoBase implements Use @Override public List findDestroyedVms(Date date) { SearchCriteria sc = DestroySearch.create(); - sc.setParameters("state", State.Destroyed, State.Expunging); + sc.setParameters("state", State.Destroyed, State.Expunging, State.Error); sc.setParameters("updateTime", date); return listActiveBy(sc); diff --git a/debian/cloud-deps.install b/debian/cloud-deps.install index 9484d1a65e9..274a3133536 100644 --- a/debian/cloud-deps.install +++ b/debian/cloud-deps.install @@ -15,3 +15,4 @@ /usr/share/java/cloud-xenserver-5.5.0-1.jar /usr/share/java/cloud-xmlrpc-common-3.*.jar /usr/share/java/cloud-xmlrpc-client-3.*.jar +/usr/share/java/cloud-manageontap.jar diff --git a/debian/cloud-setup.install b/debian/cloud-setup.install index 1b3275bb555..af551327c74 100644 --- a/debian/cloud-setup.install +++ b/debian/cloud-setup.install @@ -13,4 +13,5 @@ /usr/share/cloud/setup/index-212to213.sql /usr/share/cloud/setup/postprocess-20to21.sql /usr/share/cloud/setup/schema-20to21.sql +/usr/share/cloud/setup/schema-213to214.sql /usr/share/cloud/setup/schema-level.sql diff --git a/deps/cloud-manageontap.jar b/deps/cloud-manageontap.jar new file mode 100644 index 00000000000..3f2a6712186 Binary files /dev/null and b/deps/cloud-manageontap.jar differ diff --git a/patches/xenserver/etc/init.d/seteth1 b/patches/xenserver/etc/init.d/seteth1 index 01ae5724950..ec52803a44b 100755 --- a/patches/xenserver/etc/init.d/seteth1 +++ b/patches/xenserver/etc/init.d/seteth1 @@ -95,6 +95,7 @@ setup_router() { fi sed -i -e "s/^dhcp-range=.*$/dhcp-range=$DHCP_RANGE,static/" /etc/dnsmasq.conf sed -i -e "s/^[#]*listen-address=.*$/listen-address=$ETH0_IP/" /etc/dnsmasq.conf + sed -i -e "s/^log-queries.*$/#log-queries/" /etc/dnsmasq.conf sed -i /gateway/d /etc/hosts echo "$ETH0_IP $NAME" >> /etc/hosts [ -f /etc/httpd/conf/httpd.conf ] && sed -i -e "s/^Listen.*$/Listen $ETH0_IP:80/" /etc/httpd/conf/httpd.conf diff --git a/patches/xenserver/etc/logrotate.conf b/patches/xenserver/etc/logrotate.conf new file mode 100644 index 00000000000..f5a660964d3 --- /dev/null +++ b/patches/xenserver/etc/logrotate.conf @@ -0,0 +1,37 @@ +# see "man logrotate" for details +# rotate log files daily +daily + +# keep 5 days worth +rotate 5 + +# create new (empty) log files after rotating old ones +create + +# use date as a suffix of the rotated file +dateext + +# uncomment this if you want your log files compressed +#compress + +# max size 50M +size 50M + +# RPM packages drop log rotation information into this directory +include /etc/logrotate.d + +# no packages own wtmp and btmp -- we'll rotate them here +/var/log/wtmp { + monthly + create 0664 root utmp + rotate 1 +} + +/var/log/btmp { + missingok + monthly + create 0600 root utmp + rotate 1 +} + +# system-specific logs may be also be configured here. diff --git a/patches/xenserver/etc/logrotate.d/dnsmasq b/patches/xenserver/etc/logrotate.d/dnsmasq new file mode 100644 index 00000000000..f448420e176 --- /dev/null +++ b/patches/xenserver/etc/logrotate.d/dnsmasq @@ -0,0 +1,13 @@ +/var/log/dnsmasq.log { + daily + missingok + rotate 5 + notifempty + delaycompress + sharedscripts + postrotate + [ ! -f /var/run/dnsmasq.pid ] || kill -USR2 `cat /var/run/dnsmasq.pid` + endscript + create 0640 nobody root +} + diff --git a/patches/xenserver/etc/logrotate.d/haproxy b/patches/xenserver/etc/logrotate.d/haproxy new file mode 100644 index 00000000000..858fe2a1c3a --- /dev/null +++ b/patches/xenserver/etc/logrotate.d/haproxy @@ -0,0 +1,10 @@ +/var/log/haproxy.log { + daily + rotate 5 + missingok + notifempty + size 10M + postrotate + /bin/kill -HUP `cat /var/run/rsyslog.pid 2> /dev/null` 2> /dev/null || true + endscript +} diff --git a/patches/xenserver/etc/rsyslog.conf b/patches/xenserver/etc/rsyslog.conf new file mode 100644 index 00000000000..fe02d1f696f --- /dev/null +++ b/patches/xenserver/etc/rsyslog.conf @@ -0,0 +1,29 @@ +# Log all kernel messages to the console. +# Logging much else clutters up the screen. +#kern.* /dev/console + +# Log anything (except mail) of level info or higher. +# Don't log private authentication messages! +*.info;mail.none;authpriv.none;cron.none;local0.none /var/log/messages + +# The authpriv file has restricted access. +authpriv.* /var/log/secure + +# Log all the mail messages in one place. +mail.* -/var/log/maillog + + +# Log cron stuff +cron.* /var/log/cron + +# Everybody gets emergency messages +*.emerg * + +# Save news errors of level crit and higher in a special file. +uucp,news.crit /var/log/spooler + +# Save boot messages also to boot.log +local7.* /var/log/boot.log + +#haproxy +local0.* /var/log/haproxy.log diff --git a/patches/xenserver/etc/sysconfig/iptables b/patches/xenserver/etc/sysconfig/iptables new file mode 100644 index 00000000000..bcbd3fa40cc --- /dev/null +++ b/patches/xenserver/etc/sysconfig/iptables @@ -0,0 +1,23 @@ +*nat +:PREROUTING ACCEPT [0:0] +:POSTROUTING ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +COMMIT +*filter +:INPUT DROP [0:0] +:FORWARD DROP [0:0] +:OUTPUT ACCEPT [0:0] +-A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT +-A INPUT -i eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT +-A INPUT -p icmp -j ACCEPT +-A INPUT -i lo -j ACCEPT +-A INPUT -i eth0 -p udp -m udp --dport 67 -j ACCEPT +-A INPUT -i eth0 -p udp -m udp --dport 53 -j ACCEPT +-A INPUT -i eth1 -p tcp -m state --state NEW --dport 3922 -j ACCEPT +-A INPUT -i eth0 -p tcp -m state --state NEW --dport 8080 -j ACCEPT +-A INPUT -i eth0 -p tcp -m state --state NEW --dport 80 -j ACCEPT +-A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT +-A FORWARD -i eth0 -o eth2 -j ACCEPT +-A FORWARD -i eth2 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT +COMMIT + diff --git a/patches/xenserver/etc/sysconfig/iptables-domr b/patches/xenserver/etc/sysconfig/iptables-domr new file mode 100644 index 00000000000..3bc7b50f74a --- /dev/null +++ b/patches/xenserver/etc/sysconfig/iptables-domr @@ -0,0 +1,24 @@ +*nat +:PREROUTING ACCEPT [0:0] +:POSTROUTING ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +COMMIT +*filter +:INPUT DROP [0:0] +:FORWARD DROP [0:0] +:OUTPUT ACCEPT [0:0] +-A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT +-A INPUT -i eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT +-A INPUT -i eth2 -m state --state RELATED,ESTABLISHED -j ACCEPT +-A INPUT -p icmp -j ACCEPT +-A INPUT -i lo -j ACCEPT +-A INPUT -i eth0 -p udp -m udp --dport 67 -j ACCEPT +-A INPUT -i eth0 -p udp -m udp --dport 53 -j ACCEPT +-A INPUT -i eth1 -p tcp -m state --state NEW --dport 3922 -j ACCEPT +-A INPUT -i eth0 -p tcp -m state --state NEW --dport 8080 -j ACCEPT +-A INPUT -i eth0 -p tcp -m state --state NEW --dport 80 -j ACCEPT +-A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT +-A FORWARD -i eth0 -o eth2 -j ACCEPT +-A FORWARD -i eth2 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT +COMMIT + diff --git a/scripts/vm/hypervisor/xenserver/setupxenserver.sh b/scripts/vm/hypervisor/xenserver/setupxenserver.sh index 0a4b45f6173..29aff15b290 100755 --- a/scripts/vm/hypervisor/xenserver/setupxenserver.sh +++ b/scripts/vm/hypervisor/xenserver/setupxenserver.sh @@ -26,7 +26,7 @@ sed -i 's/127\.0\.0\.1/0\.0\.0\.0/' /opt/xensource/libexec/qemu-dm-wrapper 2>&1 # disable the default link local on xenserver sed -i /NOZEROCONF/d /etc/sysconfig/network echo "NOZEROCONF=yes" >> /etc/sysconfig/network - +rm /opt/xensource/bin/heartbeat echo "success" diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index 09b9ed77268..3dc8bef3087 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -29,6 +29,7 @@ import tempfile VHD_UTIL = '/usr/sbin/vhd-util' VHD_PREFIX = 'VHD-' +CLOUD_DIR = '/var/run/cloud_mount' def echo(fn): def wrapped(*v, **k): @@ -76,7 +77,7 @@ def create_secondary_storage_folder(session, args): try: # Mount the remote resource folder locally remote_mount_path = args["remoteMountPath"] - local_mount_path = os.path.join(SR.MOUNT_BASE, "mount" + str(int(random.random() * 1000000))) + local_mount_path = os.path.join(CLOUD_DIR, "mount" + str(int(random.random() * 1000000))) mount(remote_mount_path, local_mount_path) # Create the new folder @@ -112,7 +113,7 @@ def delete_secondary_storage_folder(session, args): try: # Mount the remote resource folder locally remote_mount_path = args["remoteMountPath"] - local_mount_path = os.path.join(SR.MOUNT_BASE, "mount" + str(int(random.random() * 1000000))) + local_mount_path = os.path.join(CLOUD_DIR, "mount" + str(int(random.random() * 1000000))) mount(remote_mount_path, local_mount_path) # Delete the specified folder @@ -148,7 +149,7 @@ def post_create_private_template(session, args): try: # Mount the remote templates folder locally remote_mount_path = args["remoteTemplateMountPath"] - local_mount_path = os.path.join(SR.MOUNT_BASE, "template" + str(int(random.random() * 10000))) + local_mount_path = os.path.join(CLOUD_DIR, "template" + str(int(random.random() * 10000))) mount(remote_mount_path, local_mount_path) util.SMlog("Mounted secondary storage template folder") @@ -757,7 +758,7 @@ def mountTemplatesDir(secondaryStorageMountPath, templatePath): absoluteTemplateDir = os.path.dirname(absoluteTemplatePath) randomUUID = util.gen_uuid() - localTemplateDir = os.path.join(SR.MOUNT_BASE, randomUUID) + localTemplateDir = os.path.join(CLOUD_DIR, randomUUID) # create the temp dir makedirs(localTemplateDir) # mount @@ -777,7 +778,7 @@ def mountSnapshotsDir(secondaryStorageMountPath, relativeDir, dcId, accountId, i snapshotsDir = os.path.join(secondaryStorageMountPath, relativeDir) # Mkdir local mount point dir, if it doesn't exist. - localMountPointPath = os.path.join(SR.MOUNT_BASE, dcId) + localMountPointPath = os.path.join(CLOUD_DIR, dcId) localMountPointPath = os.path.join(localMountPointPath, relativeDir) makedirs(localMountPointPath) @@ -800,7 +801,7 @@ def mountSnapshotsDir(secondaryStorageMountPath, relativeDir, dcId, accountId, i @echo def unmountSnapshotsDir(session, args): dcId = args['dcId'] - localMountPointPath = os.path.join(SR.MOUNT_BASE, dcId) + localMountPointPath = os.path.join(CLOUD_DIR, dcId) localMountPointPath = os.path.join(localMountPointPath, "snapshots") try: umount(localMountPointPath) @@ -845,12 +846,12 @@ def manageAvailability(path, value): util.pread2(cmd) except: #CommandException, (rc, cmdListStr, stderr): #errMsg = "CommandException thrown while executing: " + cmdListStr + " with return code: " + str(rc) + " and stderr: " + stderr - errMsg = "Unexpected exception thrown by lvchange" - util.SMlog(errMsg) if value == "-ay": # Raise an error only if we are trying to make it available. # Just warn if we are trying to make it unavailable after the # snapshot operation is done. + errMsg = "Unexpected exception thrown by lvchange" + util.SMlog(errMsg) raise xs_errors.XenError(errMsg) return @@ -1108,13 +1109,6 @@ def backupSnapshot(session, args): backupVHD = getVHD(baseCopyUuid, False) backupFile = os.path.join(backupsDir, backupVHD) copyfile(baseCopyPath, backupFile, isISCSI) - - # Now set the availability of the snapshotPath and the baseCopyPath to false - makeUnavailable(snapshotUuid, primarySRPath, isISCSI) - manageAvailability(baseCopyPath, '-an') - if prevSnapshotUuid: - makeUnavailable(prevSnapshotUuid, primarySRPath, isISCSI) - makeUnavailable(prevBaseCopyUuid, primarySRPath, isISCSI) if isFirstSnapshotOfRootVolume: # First snapshot of the root volume. @@ -1122,6 +1116,13 @@ def backupSnapshot(session, args): # Create a dummy empty vhd and set the parent of backupVHD to it. # This will prevent deleteSnapshotBackup and createVolumeFromSnapshot from breaking prevBackupUuid = createDummyVHD(baseCopyPath, backupsDir) + + # Now set the availability of the snapshotPath and the baseCopyPath to false + makeUnavailable(snapshotUuid, primarySRPath, isISCSI) + manageAvailability(baseCopyPath, '-an') + if prevSnapshotUuid: + makeUnavailable(prevSnapshotUuid, primarySRPath, isISCSI) + makeUnavailable(prevBaseCopyUuid, primarySRPath, isISCSI) # Because the primary storage is always scanned, the parent of this base copy is always the first base copy. # We don't want that, we want a chain of VHDs each of which is a delta from the previous. @@ -1221,7 +1222,7 @@ def createVolumeFromSnapshot(session, args): if templateDownloadFolder: # Copy all the vhds to the final destination templates dir # It is some random directory on the primary created for templates. - destDirParent = os.path.join(SR.MOUNT_BASE, "mount" + str(int(random.random() * 1000000))) + destDirParent = os.path.join(CLOUD_DIR, "mount" + str(int(random.random() * 1000000))) destDir = os.path.join(destDirParent, templateDownloadFolder) # create the this directory, if it isn't there makedirs(destDir) @@ -1673,6 +1674,13 @@ def default_network_rules(session, args): return 'false' vif = "vif" + domid + ".0" + tap = "tap" + domid + ".0" + vifs = [vif] + try: + util.pread2(['ifconfig', tap]) + vifs.append(tap) + except: + pass delete_rules_for_vm_in_bridge_firewall_chain(vm_name) @@ -1694,19 +1702,22 @@ def default_network_rules(session, args): util.pread2(['iptables', '-F', vmchain]) try: - util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', vif, '-j', vmchain]) - util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', vif, '-j', vmchain]) + for v in vifs: + util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain]) + util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-j', vmchain]) util.pread2(['iptables', '-A', vmchain, '-m', 'state', '--state', 'RELATED,ESTABLISHED', '-j', 'ACCEPT']) #allow dhcp util.pread2(['iptables', '-A', vmchain, '-p', 'udp', '--dport', '67:68', '--sport', '67:68', '-j', 'ACCEPT']) #don't let vm spoof its ip address - util.pread2(['iptables', '-A', vmchain, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', vif, '--source', vm_ip, '-j', 'RETURN']) + for v in vifs: + util.pread2(['iptables', '-A', vmchain, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', vm_ip, '-j', 'RETURN']) util.pread2(['iptables', '-A', vmchain, '-j', 'DROP']) except: util.SMlog("Failed to program default rules for vm " + vm_name) return 'false' - default_ebtables_rules(vm_name, vif, vm_ip, vm_mac) + for v in vifs: + default_ebtables_rules(vm_name, v, vm_ip, vm_mac) if write_rule_log_for_vm(vmName, vm_id, vm_ip, domid, '_initial_', '-1') == False: util.SMlog("Failed to log default network rules, ignoring") @@ -1781,16 +1792,27 @@ def network_rules_for_rebooted_vm(session, vmName): return True vif = "vif" + curr_domid + ".0" + tap = "tap" + curr_domid + ".0" + vifs = [vif] + try: + util.pread2(['ifconfig', tap]) + vifs.append(tap) + except: + pass vmchain = '-'.join(vm_name.split('-')[:-1]) - util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', vif, '-j', vmchain]) - util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', vif, '-j', vmchain]) + for v in vifs: + util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain]) + util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-j', vmchain]) + #change antispoof rule in vmchain try: delcmd = "iptables -S " + vmchain + " | grep physdev-in | sed 's/-A/-D/'" - inscmd = "iptables -S " + vmchain + " | grep physdev-in | sed -r 's/vif[0-9]+.0/" + vif + "/' | sed 's/-A/-I/'" + inscmd = "iptables -S " + vmchain + " | grep physdev-in | grep vif | sed -r 's/vif[0-9]+.0/" + vif + "/' | sed 's/-A/-I/'" + inscmd2 = "iptables -S " + vmchain + " | grep physdev-in | grep tap | sed -r 's/tap[0-9]+.0/" + tap + "/' | sed 's/-A/-I/'" + ipts = [] - for cmd in [delcmd, inscmd]: + for cmd in [delcmd, inscmd, inscmd2]: cmds = util.pread2(['/bin/bash', '-c', cmd]).split('\n') cmds.pop() for c in cmds: @@ -2009,6 +2031,13 @@ def network_rules(session, args): return 'false' vif = "vif" + domid + ".0" + tap = "tap" + domid + ".0" + vifs = [vif] + try: + util.pread2(['ifconfig', tap]) + vifs.append(tap) + except: + pass vm_name = '-'.join(vm_name.split('-')[:-1]) vmchain = vm_name @@ -2077,7 +2106,8 @@ def network_rules(session, args): util.pread2(['iptables', '-A', vmchain, '-p', 'udp', '--dport', '67:68', '--sport', '67:68', '-j', 'ACCEPT']) - util.pread2(['iptables', '-I', vmchain, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', vif, '--source', vm_ip, '-j', 'RETURN']) + for v in vifs: + util.pread2(['iptables', '-I', vmchain, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '--source', vm_ip, '-j', 'RETURN']) util.pread2(['iptables', '-A', vmchain, '-j', 'DROP']) if write_rule_log_for_vm(vmName, vm_id, vm_ip, domid, signature, seqno) == False: diff --git a/server/src/com/cloud/agent/manager/AgentAttache.java b/server/src/com/cloud/agent/manager/AgentAttache.java index 06353e0b460..6713bec4db1 100644 --- a/server/src/com/cloud/agent/manager/AgentAttache.java +++ b/server/src/com/cloud/agent/manager/AgentAttache.java @@ -124,6 +124,10 @@ public abstract class AgentAttache { _status = Status.Up; } + public boolean isReady() { + return _status == Status.Up; + } + public boolean isConnecting() { return _status == Status.Connecting; } diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java index 682353c455e..39580c745fe 100755 --- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -72,6 +72,7 @@ import com.cloud.agent.transport.UpgradeResponse; import com.cloud.alert.AlertManager; import com.cloud.capacity.CapacityVO; import com.cloud.capacity.dao.CapacityDao; +import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.ClusterVO; import com.cloud.dc.DataCenterIpAddressVO; @@ -196,6 +197,13 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory { @Inject protected GuestOSCategoryDao _guestOSCategoryDao = null; @Inject protected DetailsDao _hostDetailsDao = null; @Inject protected ClusterDao _clusterDao; + + private String _publicNic; + private String _privateNic; + private String _guestNic; + private String _storageNic1; + private String _storageNic2; + protected Adapters _discoverers = null; protected int _port; @@ -237,7 +245,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory { @Inject protected VMTemplateHostDao _vmTemplateHostDao; @Override - public boolean configure(final String name, final Map params) throws ConfigurationException { + public boolean configure(final String name, final Map params) throws ConfigurationException { _name = name; Request.initBuilder(); @@ -249,6 +257,12 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory { } final Map configs = configDao.getConfiguration("AgentManager", params); + + _publicNic = configDao.getValue(Config.XenPublicNetwork.key()); + _privateNic = configDao.getValue(Config.XenPrivateNetwork.key()); + _guestNic = configDao.getValue(Config.XenGuestNetwork.key()); + _storageNic1 = configDao.getValue(Config.XenStorageNetwork1.key()); + _storageNic2 = configDao.getValue(Config.XenStorageNetwork2.key()); _port = NumbersUtil.parseInt(configs.get("port"), 8250); final int workers = NumbersUtil.parseInt(configs.get("workers"), 5); @@ -463,7 +477,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory { long id = server.getId(); AgentAttache attache = createAttache(id, server, resource); - notifyMonitorsOfConnection(attache, startup); + attache = notifyMonitorsOfConnection(attache, startup); return attache; } @@ -856,14 +870,12 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory { if (s_logger.isDebugEnabled()) { s_logger.debug("Deregistering link for " + hostId + " with state " + nextState); } + + _hostDao.disconnect(host, event, _nodeId); + synchronized (_agents) { AgentAttache removed = _agents.remove(hostId); - if (removed != null && removed != attache) { // NOTE: == is intentionally used here. - _agents.put(removed.getId(), removed); - } } - - _hostDao.disconnect(host, event, _nodeId); host = _hostDao.findById(host.getId()); if (host.getStatus() == Status.Alert || host.getStatus() == Status.Down) { _haMgr.scheduleRestartForVmsOnHost(host); @@ -880,7 +892,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory { return true; } - protected void notifyMonitorsOfConnection(AgentAttache attache, final StartupCommand[] cmd) { + protected AgentAttache notifyMonitorsOfConnection(AgentAttache attache, final StartupCommand[] cmd) { long hostId = attache.getId(); HostVO host = _hostDao.findById(hostId); for (Pair monitor : _hostMonitors) { @@ -891,21 +903,24 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory { if (!monitor.second().processConnect(host, cmd[i])) { s_logger.info("Monitor " + monitor.second().getClass().getSimpleName() + " says not to continue the connect process for " + hostId); handleDisconnect(attache, Event.AgentDisconnected, false); - return; + return attache; } } } Long dcId = host.getDataCenterId(); ReadyCommand ready = new ReadyCommand(dcId); - Answer answer = easySend(hostId, ready); + Answer answer = easySend(hostId, ready); if (answer == null) { + // this is tricky part for secondary storage + // make it as disconnected, wait for secondary storage VM to be up + // return the attache instead of null, even it is disconnectede handleDisconnect(attache, Event.AgentDisconnected, false); - return; } _hostDao.updateStatus(host, Event.Ready, _nodeId); attache.ready(); + return attache; } @Override @@ -962,6 +977,13 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory { params.putAll(host.getDetails()); // private.network.device may change when reconnect params.remove("private.network.device"); + params.put("private.network.device", _privateNic); + params.remove("public.network.device"); + params.put("public.network.device", _publicNic); + params.remove("guest.network.device"); + params.put("guest.network.device", _guestNic); + + params.put("guid", host.getGuid()); params.put("zone", Long.toString(host.getDataCenterId())); if (host.getPodId() != null) { @@ -1012,12 +1034,14 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory { resource.disconnected(); return null; } - - StartupAnswer[] answers = new StartupAnswer[cmds.length]; - for (int i = 0; i < answers.length; i++) { - answers[i] = new StartupAnswer(cmds[i], attache.getId(), _pingInterval); + if( attache.isReady()) { + StartupAnswer[] answers = new StartupAnswer[cmds.length]; + for (int i = 0; i < answers.length; i++) { + answers[i] = new StartupAnswer(cmds[i], attache.getId(), _pingInterval); + } + + attache.process(answers); } - attache.process(answers); return attache; } @@ -1136,6 +1160,10 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory { @Override public Answer easySend(final Long hostId, final Command cmd, int timeout) { try { + Host h = _hostDao.findById(hostId); + if( !h.getStatus().equals(Status.Up) ) { + return null; + } final Answer answer = send(hostId, cmd, timeout); if (answer == null) { s_logger.warn("send returns null answer"); @@ -1532,7 +1560,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory { AgentAttache attache = createAttache(id, server, link); - notifyMonitorsOfConnection(attache, startup); + attache = notifyMonitorsOfConnection(attache, startup); return attache; } diff --git a/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java b/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java index b192344bc65..23c83572d67 100755 --- a/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java +++ b/server/src/com/cloud/agent/manager/allocator/impl/FirstFitAllocator.java @@ -35,6 +35,7 @@ import com.cloud.dc.HostPodVO; import com.cloud.host.DetailVO; import com.cloud.host.Host; import com.cloud.host.HostVO; +import com.cloud.host.Status; import com.cloud.host.Host.Type; import com.cloud.host.dao.DetailsDao; import com.cloud.host.dao.HostDao; @@ -97,7 +98,10 @@ public class FirstFitAllocator implements HostAllocator { List poolhosts = _storagePoolHostDao.listByPoolId(sp.getId()); List hosts = new ArrayList(); for( StoragePoolHostVO poolhost : poolhosts ){ - hosts.add(_hostDao.findById(poolhost.getHostId())); + HostVO h = _hostDao.findById(poolhost.getHostId()); + if( h != null && h.getType().equals(Type.Routing) && h.getStatus().equals(Status.Up)) { + hosts.add(h); + } } long podId = pod.getId(); diff --git a/server/src/com/cloud/agent/manager/allocator/impl/RecreateHostAllocator.java b/server/src/com/cloud/agent/manager/allocator/impl/RecreateHostAllocator.java index 50bcaee3b32..508b7237e92 100644 --- a/server/src/com/cloud/agent/manager/allocator/impl/RecreateHostAllocator.java +++ b/server/src/com/cloud/agent/manager/allocator/impl/RecreateHostAllocator.java @@ -18,6 +18,7 @@ package com.cloud.agent.manager.allocator.impl; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Set; @@ -37,7 +38,9 @@ import com.cloud.host.Host; import com.cloud.service.ServiceOffering; import com.cloud.storage.StoragePoolVO; import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.StoragePoolDao; +import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.Pair; import com.cloud.utils.component.Inject; import com.cloud.vm.VirtualMachine; @@ -51,6 +54,7 @@ public class RecreateHostAllocator extends FirstFitRoutingAllocator { @Inject StoragePoolDao _poolDao; @Inject ClusterDao _clusterDao; @Inject AgentManager _agentMgr; + @Inject VolumeDao _volsDao; @Override public Host allocateTo(VmCharacteristics vm, ServiceOffering offering, Host.Type type, DataCenterVO dc, HostPodVO pod, @@ -68,6 +72,18 @@ public class RecreateHostAllocator extends FirstFitRoutingAllocator { } List pcs = _agentMgr.listByDataCenter(dc.getId()); + if (vmType == VirtualMachine.Type.DomainRouter) { + s_logger.debug("VM is a domain router so we can only allow the host to be allocated in the same pod due to problems with the DHCP only domR"); + long podId = sp.getPodId(); + s_logger.debug("Pod id determined is " + podId); + Iterator it = pcs.iterator(); + while (it.hasNext()) { + PodCluster pc = it.next(); + if (pc.getPod().getId() != podId) { + it.remove(); + } + } + } Set> avoidPcs = new HashSet>(); for (Host h : avoid) { avoidPcs.add(new Pair(h.getPodId(), h.getClusterId())); diff --git a/server/src/com/cloud/api/BaseCmd.java b/server/src/com/cloud/api/BaseCmd.java index fa87cc66cd0..14c9f066e5a 100644 --- a/server/src/com/cloud/api/BaseCmd.java +++ b/server/src/com/cloud/api/BaseCmd.java @@ -204,6 +204,7 @@ public abstract class BaseCmd { INTERVAL_TYPE("intervaltype", BaseCmd.TYPE_STRING, "intervalType"), IP_ADDRESS("ipaddress", BaseCmd.TYPE_STRING, "ipAddress"), IP_AVAIL("ipavailable", BaseCmd.TYPE_INT, "ipavailable"), + IGROUP("igroup",BaseCmd.TYPE_STRING,"igroup"), IP_LIMIT("iplimit", BaseCmd.TYPE_INT, "iplimit"), IP_TOTAL("iptotal", BaseCmd.TYPE_INT, "iptotal"), IS_RECURSIVE("isrecursive", BaseCmd.TYPE_BOOLEAN, "isrecursive"), @@ -234,6 +235,7 @@ public abstract class BaseCmd { MEMORY_ALLOCATED("memoryallocated", BaseCmd.TYPE_LONG, "memoryallocated"), MONTHLY_MAX("monthlymax", BaseCmd.TYPE_INT, "monthlyMax"), NAME("name", BaseCmd.TYPE_STRING, "name"), + CLIENT_IQN("clientiqn", BaseCmd.TYPE_STRING, "clientiqn"), NEW_NAME("newname", BaseCmd.TYPE_STRING, "newname"), NETMASK("netmask", BaseCmd.TYPE_STRING, "netmask"), NETWORK_DOMAIN("networkdomain", BaseCmd.TYPE_STRING, "networkdomain"), @@ -252,6 +254,8 @@ public abstract class BaseCmd { PERCENT_USED("percentused", BaseCmd.TYPE_STRING, "percentused"), POD_ID("podid", BaseCmd.TYPE_LONG, "podId"), POD_NAME("podname", BaseCmd.TYPE_STRING, "podName"), + POOL_ID("poolid", BaseCmd.TYPE_LONG, "poolId"), + POOL_NAME("poolname", BaseCmd.TYPE_STRING, "poolName"), PRIVATE_IP("privateip", BaseCmd.TYPE_STRING, "privateIp"), PRIVATE_MAC_ADDRESS("privatemacaddress", BaseCmd.TYPE_STRING, "privatemacaddress"), PRIVATE_NETMASK("privatenetmask", BaseCmd.TYPE_STRING, "privatenetmask"), @@ -285,12 +289,17 @@ public abstract class BaseCmd { START_VLAN("startvlan", BaseCmd.TYPE_LONG, "startvlan"), END_VLAN("endvlan", BaseCmd.TYPE_LONG, "endvlan"), SIZE("size", BaseCmd.TYPE_LONG, "size"), + VOL_SIZE("volsize", BaseCmd.TYPE_INT, "volsize"), + VOL_SIZE_STRING("volsizestr", BaseCmd.TYPE_INT, "volsizestr"), STATE("state", BaseCmd.TYPE_STRING, "state"), STORAGE("storage", BaseCmd.TYPE_LONG, "storage"), SUCCESS("success", BaseCmd.TYPE_BOOLEAN, "success"), SNAPSHOT_ID("snapshotid", BaseCmd.TYPE_LONG, "snapshotid"), + SNAPSHOT_POLICY("snapshotpolicy", BaseCmd.TYPE_STRING, "snapshotPolicy"), + SNAPSHOT_RESERVATION("snapshotreservation", BaseCmd.TYPE_INT, "snapshotReservation"), SNAPSHOT_POLICY_ID("snapshotpolicyid", BaseCmd.TYPE_LONG, "snapshotPolicyId"), SNAPSHOT_TYPE("snapshottype", BaseCmd.TYPE_STRING, "snapshotType"), + SNAPSHOT_STRING("snapshotstring", BaseCmd.TYPE_STRING, "snapshotString"), SCHEDULED("scheduled", BaseCmd.TYPE_DATE, "scheduled"), STORAGE_TYPE("storagetype", BaseCmd.TYPE_STRING, "storageType"), TIMEZONE("timezone", BaseCmd.TYPE_STRING, "timezone"), @@ -310,6 +319,7 @@ public abstract class BaseCmd { USER_ID("userid", BaseCmd.TYPE_LONG, "userId"), USERNAME("username", BaseCmd.TYPE_STRING, "username"), USER_DATA("userdata", BaseCmd.TYPE_STRING, "userData"), + UUID("uuid", BaseCmd.TYPE_STRING, "uuid"), VALUE("value", BaseCmd.TYPE_STRING, "value"), VERSION("version", BaseCmd.TYPE_STRING, "version"), VIRTUAL_MACHINE_ID("virtualmachineid", BaseCmd.TYPE_LONG, "virtualMachineId"), @@ -378,6 +388,8 @@ public abstract class BaseCmd { TAGS("tags", BaseCmd.TYPE_STRING, "tags"), TAKEN("taken", BaseCmd.TYPE_DATE, "taken"), LUN("lun", BaseCmd.TYPE_INT, "lun"), + LUN_SIZE("lunsize", BaseCmd.TYPE_LONG, "lunsize"), + LUN_SIZE_USED("lunsizeused", BaseCmd.TYPE_LONG, "lunsizeused"), DETAILS("details", BaseCmd.TYPE_OBJECT_MAP, "details"), CLUSTER_ID("clusterid", BaseCmd.TYPE_LONG, "clusterid"), CLUSTER_NAME("clustername", BaseCmd.TYPE_STRING, "clustername"), diff --git a/server/src/com/cloud/api/commands/DeployVMCmd.java b/server/src/com/cloud/api/commands/DeployVMCmd.java index ba730dd3549..5958c9ba19c 100644 --- a/server/src/com/cloud/api/commands/DeployVMCmd.java +++ b/server/src/com/cloud/api/commands/DeployVMCmd.java @@ -26,6 +26,7 @@ import org.apache.log4j.Logger; import com.cloud.api.BaseCmd; import com.cloud.api.ServerApiException; +import com.cloud.async.AsyncJobVO; import com.cloud.async.executor.DeployVMResultObject; import com.cloud.dc.DataCenterVO; import com.cloud.network.security.NetworkGroupVO; @@ -166,7 +167,15 @@ public class DeployVMCmd extends BaseCmd { if (s_logger.isDebugEnabled()) s_logger.debug("DeployVMAsync command has been accepted, job id: " + jobId); - vmId = waitInstanceCreation(jobId); + vmId = waitInstanceCreation(jobId); + + if (s_logger.isDebugEnabled()) + s_logger.debug("DeployVMAsync is being executed, job id: " + jobId + ", vmId: " + vmId); + + if(vmId == 0) { + AsyncJobVO job = mgr.findAsyncJobById(jobId); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create VM due to " + job.getResult()); + } } List> returnValues = new ArrayList>(); @@ -174,6 +183,8 @@ public class DeployVMCmd extends BaseCmd { returnValues.add(new Pair(BaseCmd.Properties.JOB_ID.getName(), Long.valueOf(jobId))); return returnValues; + } catch(ServerApiException e) { + throw e; } catch (Exception ex) { s_logger.error("Unhandled exception, ", ex); throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create VM due to unhandled exception"); diff --git a/server/src/com/cloud/api/commands/ListAccountsCmd.java b/server/src/com/cloud/api/commands/ListAccountsCmd.java index 209ade4494b..d384be4100c 100644 --- a/server/src/com/cloud/api/commands/ListAccountsCmd.java +++ b/server/src/com/cloud/api/commands/ListAccountsCmd.java @@ -109,15 +109,12 @@ public class ListAccountsCmd extends BaseCmd{ Criteria c = new Criteria("id", Boolean.TRUE, startIndex, Long.valueOf(pageSizeNum)); if (isAdmin == true) { c.addCriteria(Criteria.ID, id); - if (keyword == null) { - c.addCriteria(Criteria.ACCOUNTNAME, accountName); - c.addCriteria(Criteria.DOMAINID, domainId); - c.addCriteria(Criteria.TYPE, type); - c.addCriteria(Criteria.STATE, state); - c.addCriteria(Criteria.ISCLEANUPREQUIRED, needCleanup); - } else { - c.addCriteria(Criteria.KEYWORD, keyword); - } + c.addCriteria(Criteria.ACCOUNTNAME, accountName); + c.addCriteria(Criteria.DOMAINID, domainId); + c.addCriteria(Criteria.TYPE, type); + c.addCriteria(Criteria.STATE, state); + c.addCriteria(Criteria.ISCLEANUPREQUIRED, needCleanup); + c.addCriteria(Criteria.KEYWORD, keyword); } else { c.addCriteria(Criteria.ID, accountId); } diff --git a/server/src/com/cloud/api/commands/ListAlertsCmd.java b/server/src/com/cloud/api/commands/ListAlertsCmd.java index f20ef270cd6..4654a1f764a 100644 --- a/server/src/com/cloud/api/commands/ListAlertsCmd.java +++ b/server/src/com/cloud/api/commands/ListAlertsCmd.java @@ -73,9 +73,7 @@ public class ListAlertsCmd extends BaseCmd{ Criteria c = new Criteria ("lastSent", Boolean.FALSE, startIndex, Long.valueOf(pageSizeNum)); c.addCriteria(Criteria.KEYWORD, keyword); - - if (keyword == null) - c.addCriteria(Criteria.TYPE, alertType); + c.addCriteria(Criteria.TYPE, alertType); List alerts = getManagementServer().searchForAlerts(c); diff --git a/server/src/com/cloud/api/commands/ListCfgsByCmd.java b/server/src/com/cloud/api/commands/ListCfgsByCmd.java index ae27b6e92f9..7780ed85119 100644 --- a/server/src/com/cloud/api/commands/ListCfgsByCmd.java +++ b/server/src/com/cloud/api/commands/ListCfgsByCmd.java @@ -72,12 +72,9 @@ public class ListCfgsByCmd extends BaseCmd { } Criteria c = new Criteria ("name", Boolean.TRUE, startIndex, Long.valueOf(pageSizeNum)); - if (keyword != null) { - c.addCriteria(Criteria.KEYWORD, keyword); - } else { - c.addCriteria(Criteria.NAME, name); - c.addCriteria(Criteria.CATEGORY, category); - } + c.addCriteria(Criteria.KEYWORD, keyword); + c.addCriteria(Criteria.NAME, name); + c.addCriteria(Criteria.CATEGORY, category); List configs = getManagementServer().searchForConfigurations(c, false); diff --git a/server/src/com/cloud/api/commands/ListDiskOfferingsCmd.java b/server/src/com/cloud/api/commands/ListDiskOfferingsCmd.java index ecab9c4ba2d..4e01bfde306 100644 --- a/server/src/com/cloud/api/commands/ListDiskOfferingsCmd.java +++ b/server/src/com/cloud/api/commands/ListDiskOfferingsCmd.java @@ -76,13 +76,10 @@ public class ListDiskOfferingsCmd extends BaseCmd { } Criteria c = new Criteria("id", Boolean.TRUE, startIndex, Long.valueOf(pageSizeNum)); - if (keyword != null) { - c.addCriteria(Criteria.KEYWORD, keyword); - }else { - c.addCriteria(Criteria.ID, id); - c.addCriteria(Criteria.NAME, name); - c.addCriteria(Criteria.DOMAINID, domainId); - } + c.addCriteria(Criteria.KEYWORD, keyword); + c.addCriteria(Criteria.ID, id); + c.addCriteria(Criteria.NAME, name); + c.addCriteria(Criteria.DOMAINID, domainId); List offerings = getManagementServer().searchForDiskOfferings(c); diff --git a/server/src/com/cloud/api/commands/ListDomainChildrenCmd.java b/server/src/com/cloud/api/commands/ListDomainChildrenCmd.java index fddc1e88647..1063176db74 100644 --- a/server/src/com/cloud/api/commands/ListDomainChildrenCmd.java +++ b/server/src/com/cloud/api/commands/ListDomainChildrenCmd.java @@ -95,16 +95,11 @@ public class ListDomainChildrenCmd extends BaseCmd { c = new Criteria("id", Boolean.TRUE, startIndex, Long.valueOf(pageSizeNum)); else c = new Criteria("id", Boolean.TRUE, null, null); - - - if (keyword != null) { - c.addCriteria(Criteria.KEYWORD, keyword); - } - else { - c.addCriteria(Criteria.ID, domainId); - c.addCriteria(Criteria.NAME, domainName); - c.addCriteria(Criteria.ISRECURSIVE, isRecursive); - } + + c.addCriteria(Criteria.KEYWORD, keyword); + c.addCriteria(Criteria.ID, domainId); + c.addCriteria(Criteria.NAME, domainName); + c.addCriteria(Criteria.ISRECURSIVE, isRecursive); // TODO : Recursive listing is not supported yet List domains = getManagementServer().searchForDomainChildren(c); diff --git a/server/src/com/cloud/api/commands/ListDomainsCmd.java b/server/src/com/cloud/api/commands/ListDomainsCmd.java index 69b281cff4a..7559e47b5bf 100644 --- a/server/src/com/cloud/api/commands/ListDomainsCmd.java +++ b/server/src/com/cloud/api/commands/ListDomainsCmd.java @@ -93,13 +93,10 @@ public class ListDomainsCmd extends BaseCmd { else c = new Criteria("id", Boolean.TRUE, null, null); - if (keyword != null) { - c.addCriteria(Criteria.KEYWORD, keyword); - } else { - c.addCriteria(Criteria.ID, domainId); - c.addCriteria(Criteria.NAME, domainName); - c.addCriteria(Criteria.LEVEL, level); - } + c.addCriteria(Criteria.KEYWORD, keyword); + c.addCriteria(Criteria.ID, domainId); + c.addCriteria(Criteria.NAME, domainName); + c.addCriteria(Criteria.LEVEL, level); List domains = getManagementServer().searchForDomains(c); diff --git a/server/src/com/cloud/api/commands/ListEventsCmd.java b/server/src/com/cloud/api/commands/ListEventsCmd.java index 7cefef97c4a..4f377cf0838 100644 --- a/server/src/com/cloud/api/commands/ListEventsCmd.java +++ b/server/src/com/cloud/api/commands/ListEventsCmd.java @@ -122,17 +122,14 @@ public class ListEventsCmd extends BaseCmd { } Criteria c = new Criteria("createDate", Boolean.FALSE, startIndex, Long.valueOf(pageSizeNum)); c.addCriteria(Criteria.ACCOUNTID, accountIds); - if (keyword != null) { - c.addCriteria(Criteria.KEYWORD, keyword); - } else { - if (isAdmin) { - c.addCriteria(Criteria.DOMAINID, domainId); - } - c.addCriteria(Criteria.TYPE, eventType); - c.addCriteria(Criteria.LEVEL, eventLevel); - c.addCriteria(Criteria.STARTDATE, startDate); - c.addCriteria(Criteria.ENDDATE, endDate); - } + c.addCriteria(Criteria.KEYWORD, keyword); + c.addCriteria(Criteria.TYPE, eventType); + c.addCriteria(Criteria.LEVEL, eventLevel); + c.addCriteria(Criteria.STARTDATE, startDate); + c.addCriteria(Criteria.ENDDATE, endDate); + if (isAdmin) { + c.addCriteria(Criteria.DOMAINID, domainId); + } List events; diff --git a/server/src/com/cloud/api/commands/ListLoadBalancerRulesCmd.java b/server/src/com/cloud/api/commands/ListLoadBalancerRulesCmd.java index 499ec7060ee..30ee3353742 100644 --- a/server/src/com/cloud/api/commands/ListLoadBalancerRulesCmd.java +++ b/server/src/com/cloud/api/commands/ListLoadBalancerRulesCmd.java @@ -124,16 +124,13 @@ public class ListLoadBalancerRulesCmd extends BaseCmd { Criteria c = new Criteria("ipAddress", Boolean.TRUE, startIndex, Long.valueOf(pageSizeNum)); c.addCriteria(Criteria.ACCOUNTID, accountId); - if (keyword == null) { - c.addCriteria(Criteria.ID, id); - c.addCriteria(Criteria.NAME, name); - c.addCriteria(Criteria.INSTANCEID, vmId); - c.addCriteria(Criteria.IPADDRESS, publicIp); - if (isAdmin) { - c.addCriteria(Criteria.DOMAINID, domainId); - } - } else { - c.addCriteria(Criteria.KEYWORD, keyword); + c.addCriteria(Criteria.ID, id); + c.addCriteria(Criteria.NAME, name); + c.addCriteria(Criteria.INSTANCEID, vmId); + c.addCriteria(Criteria.IPADDRESS, publicIp); + c.addCriteria(Criteria.KEYWORD, keyword); + if (isAdmin) { + c.addCriteria(Criteria.DOMAINID, domainId); } // FIXME: this should be constrained by domain to search for all load balancers in a domain if an admin is searching diff --git a/server/src/com/cloud/api/commands/ListPodsByCmd.java b/server/src/com/cloud/api/commands/ListPodsByCmd.java index 2abcfd7906c..84045c63e37 100644 --- a/server/src/com/cloud/api/commands/ListPodsByCmd.java +++ b/server/src/com/cloud/api/commands/ListPodsByCmd.java @@ -60,13 +60,10 @@ public class ListPodsByCmd extends BaseCmd { Criteria c = new Criteria(); - if (keyword != null) { - c.addCriteria(Criteria.KEYWORD, keyword); - } else { - c.addCriteria(Criteria.ID, id); - c.addCriteria(Criteria.NAME, name); - c.addCriteria(Criteria.DATACENTERID, zoneId); - } + c.addCriteria(Criteria.KEYWORD, keyword); + c.addCriteria(Criteria.ID, id); + c.addCriteria(Criteria.NAME, name); + c.addCriteria(Criteria.DATACENTERID, zoneId); List pods = getManagementServer().searchForPods(c); diff --git a/server/src/com/cloud/api/commands/ListPortForwardingServicesByVmCmd.java b/server/src/com/cloud/api/commands/ListPortForwardingServicesByVmCmd.java index 0ea3d835cea..ccfd007a3b1 100644 --- a/server/src/com/cloud/api/commands/ListPortForwardingServicesByVmCmd.java +++ b/server/src/com/cloud/api/commands/ListPortForwardingServicesByVmCmd.java @@ -95,11 +95,8 @@ public class ListPortForwardingServicesByVmCmd extends BaseCmd { Criteria c = new Criteria("id", Boolean.TRUE, null, null); c.addCriteria(Criteria.INSTANCEID, vmId); - if (keyword != null) { - c.addCriteria(Criteria.KEYWORD, keyword); - } else { - c.addCriteria(Criteria.ADDRESS, ipAddress); - } + c.addCriteria(Criteria.KEYWORD, keyword); + c.addCriteria(Criteria.ADDRESS, ipAddress); Map> groups = getManagementServer().searchForSecurityGroupsByVM(c); diff --git a/server/src/com/cloud/api/commands/ListPortForwardingServicesCmd.java b/server/src/com/cloud/api/commands/ListPortForwardingServicesCmd.java index 931a51a9942..5a73bcb8f1f 100644 --- a/server/src/com/cloud/api/commands/ListPortForwardingServicesCmd.java +++ b/server/src/com/cloud/api/commands/ListPortForwardingServicesCmd.java @@ -107,14 +107,11 @@ public class ListPortForwardingServicesCmd extends BaseCmd { Criteria c = new Criteria("id", Boolean.TRUE, startIndex, Long.valueOf(pageSizeNum)); c.addCriteria(Criteria.ACCOUNTID, accountId); - if (keyword != null) { - c.addCriteria(Criteria.KEYWORD, keyword); - } else { - if (isAdmin) { - c.addCriteria(Criteria.DOMAINID, domainId); - } - c.addCriteria(Criteria.ID, id); - c.addCriteria(Criteria.NAME, name); + c.addCriteria(Criteria.KEYWORD, keyword); + c.addCriteria(Criteria.ID, id); + c.addCriteria(Criteria.NAME, name); + if (isAdmin) { + c.addCriteria(Criteria.DOMAINID, domainId); } List groups = getManagementServer().searchForSecurityGroups(c); diff --git a/server/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java b/server/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java index 99c310d6048..b3ab68ab5f1 100644 --- a/server/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java +++ b/server/src/com/cloud/api/commands/ListPublicIpAddressesCmd.java @@ -130,16 +130,13 @@ public class ListPublicIpAddressesCmd extends BaseCmd { c.addCriteria(Criteria.ISALLOCATED, allocatedOnly.booleanValue()); } - if (keyword != null) { - c.addCriteria(Criteria.KEYWORD, keyword); - } else { - if (isAdmin) { - c.addCriteria(Criteria.DOMAINID, domainId); - c.addCriteria(Criteria.VLAN, vlanDbId); - } - c.addCriteria(Criteria.FOR_VIRTUAL_NETWORK, forVirtualNetwork); - c.addCriteria(Criteria.DATACENTERID, zoneId); - c.addCriteria(Criteria.IPADDRESS, ip); + c.addCriteria(Criteria.KEYWORD, keyword); + c.addCriteria(Criteria.FOR_VIRTUAL_NETWORK, forVirtualNetwork); + c.addCriteria(Criteria.DATACENTERID, zoneId); + c.addCriteria(Criteria.IPADDRESS, ip); + if (isAdmin) { + c.addCriteria(Criteria.DOMAINID, domainId); + c.addCriteria(Criteria.VLAN, vlanDbId); } List result = getManagementServer().searchForIPAddresses(c); diff --git a/server/src/com/cloud/api/commands/ListRoutersCmd.java b/server/src/com/cloud/api/commands/ListRoutersCmd.java index 1a184f4dba9..09b0f0ca60a 100644 --- a/server/src/com/cloud/api/commands/ListRoutersCmd.java +++ b/server/src/com/cloud/api/commands/ListRoutersCmd.java @@ -113,16 +113,13 @@ public class ListRoutersCmd extends BaseCmd { Criteria c = new Criteria("id", Boolean.TRUE, startIndex, Long.valueOf(pageSizeNum)); c.addCriteria(Criteria.ACCOUNTID, accountIds); - if (keyword != null) { - c.addCriteria(Criteria.KEYWORD, keyword); - } else { - c.addCriteria(Criteria.DOMAINID, domainId); - c.addCriteria(Criteria.DATACENTERID, zoneId); - c.addCriteria(Criteria.PODID, podId); - c.addCriteria(Criteria.HOSTID, hostId); - c.addCriteria(Criteria.NAME, name); - c.addCriteria(Criteria.STATE, state); - } + c.addCriteria(Criteria.KEYWORD, keyword); + c.addCriteria(Criteria.DOMAINID, domainId); + c.addCriteria(Criteria.DATACENTERID, zoneId); + c.addCriteria(Criteria.PODID, podId); + c.addCriteria(Criteria.HOSTID, hostId); + c.addCriteria(Criteria.NAME, name); + c.addCriteria(Criteria.STATE, state); List routers = getManagementServer().searchForRouters(c); diff --git a/server/src/com/cloud/api/commands/ListServiceOfferingsCmd.java b/server/src/com/cloud/api/commands/ListServiceOfferingsCmd.java index 82eab52ad97..f1ef7a221a0 100644 --- a/server/src/com/cloud/api/commands/ListServiceOfferingsCmd.java +++ b/server/src/com/cloud/api/commands/ListServiceOfferingsCmd.java @@ -78,12 +78,9 @@ public class ListServiceOfferingsCmd extends BaseCmd { } } Criteria c = new Criteria("created", Boolean.FALSE, startIndex, Long.valueOf(pageSizeNum)); - if (keyword != null) { - c.addCriteria(Criteria.KEYWORD, keyword); - } else { - c.addCriteria(Criteria.ID, id); - c.addCriteria(Criteria.NAME, name); - } + c.addCriteria(Criteria.KEYWORD, keyword); + c.addCriteria(Criteria.ID, id); + c.addCriteria(Criteria.NAME, name); //If vmId is present in the list of parameters, verify it if (vmId != null) { diff --git a/server/src/com/cloud/api/commands/ListSnapshotsCmd.java b/server/src/com/cloud/api/commands/ListSnapshotsCmd.java index a71e5b7b36c..c3b5b2a21e4 100644 --- a/server/src/com/cloud/api/commands/ListSnapshotsCmd.java +++ b/server/src/com/cloud/api/commands/ListSnapshotsCmd.java @@ -87,16 +87,13 @@ public class ListSnapshotsCmd extends BaseCmd { } Long accountId = null; - if ((account == null) || isAdmin(account.getType())) { - if(account != null && account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) - accountId = account.getId(); + if (account == null) { if (domainId != null && accountName != null) { - Account userAccount = getManagementServer().findAccountByName(accountName, domainId); - if (userAccount != null) { - accountId = userAccount.getId(); - } + account = getManagementServer().findAccountByName(accountName, domainId); } - } else { + } + + if( account != null && !isAdmin(account.getType())) { accountId = account.getId(); } @@ -118,8 +115,8 @@ public class ListSnapshotsCmd extends BaseCmd { c.addCriteria(Criteria.NAME, name); c.addCriteria(Criteria.ID, id); c.addCriteria(Criteria.KEYWORD, keyword); - c.addCriteria(Criteria.ACCOUNTID, accountId); - + c.addCriteria(Criteria.ACCOUNTID, accountId); + List snapshots = null; try { snapshots = getManagementServer().listSnapshots(c, interval); diff --git a/server/src/com/cloud/api/commands/ListStoragePoolsCmd.java b/server/src/com/cloud/api/commands/ListStoragePoolsCmd.java index ff1a044247e..a69e564d411 100644 --- a/server/src/com/cloud/api/commands/ListStoragePoolsCmd.java +++ b/server/src/com/cloud/api/commands/ListStoragePoolsCmd.java @@ -84,15 +84,12 @@ public class ListStoragePoolsCmd extends BaseCmd{ } } Criteria c = new Criteria("id", Boolean.TRUE, startIndex, Long.valueOf(pageSizeNum)); - if (keyword != null) { - c.addCriteria(Criteria.KEYWORD, keyword); - } else { - c.addCriteria(Criteria.NAME, name); - c.addCriteria(Criteria.DATACENTERID, zoneId); - c.addCriteria(Criteria.PODID, podId); - c.addCriteria(Criteria.ADDRESS, ipAddress); - c.addCriteria(Criteria.PATH, path); - } + c.addCriteria(Criteria.KEYWORD, keyword); + c.addCriteria(Criteria.NAME, name); + c.addCriteria(Criteria.DATACENTERID, zoneId); + c.addCriteria(Criteria.PODID, podId); + c.addCriteria(Criteria.ADDRESS, ipAddress); + c.addCriteria(Criteria.PATH, path); List pools = getManagementServer().searchForStoragePools(c); diff --git a/server/src/com/cloud/api/commands/ListSystemVMsCmd.java b/server/src/com/cloud/api/commands/ListSystemVMsCmd.java index 6f79d056824..6e89a7035e1 100644 --- a/server/src/com/cloud/api/commands/ListSystemVMsCmd.java +++ b/server/src/com/cloud/api/commands/ListSystemVMsCmd.java @@ -84,16 +84,13 @@ public class ListSystemVMsCmd extends BaseCmd { } Criteria c = new Criteria("id", Boolean.TRUE, startIndex, Long.valueOf(pageSizeNum)); - if (keyword != null) { - c.addCriteria(Criteria.KEYWORD, keyword); - } else { - c.addCriteria(Criteria.ID, id); - c.addCriteria(Criteria.DATACENTERID, zoneId); - c.addCriteria(Criteria.PODID, podId); - c.addCriteria(Criteria.HOSTID, hostId); - c.addCriteria(Criteria.NAME, name); - c.addCriteria(Criteria.STATE, state); - } + c.addCriteria(Criteria.KEYWORD, keyword); + c.addCriteria(Criteria.ID, id); + c.addCriteria(Criteria.DATACENTERID, zoneId); + c.addCriteria(Criteria.PODID, podId); + c.addCriteria(Criteria.HOSTID, hostId); + c.addCriteria(Criteria.NAME, name); + c.addCriteria(Criteria.STATE, state); List proxies = getManagementServer().searchForConsoleProxy(c); List ssVms = getManagementServer().searchForSecondaryStorageVm(c); diff --git a/server/src/com/cloud/api/commands/ListUsersCmd.java b/server/src/com/cloud/api/commands/ListUsersCmd.java index 559b3831712..5fbaf8b0e9b 100644 --- a/server/src/com/cloud/api/commands/ListUsersCmd.java +++ b/server/src/com/cloud/api/commands/ListUsersCmd.java @@ -91,18 +91,16 @@ public class ListUsersCmd extends BaseCmd { startIndex = Long.valueOf(pageSizeNum * (pageNum-1)); } } + Criteria c = new Criteria("id", Boolean.TRUE, startIndex, Long.valueOf(pageSizeNum)); - if (keyword != null) { - c.addCriteria(Criteria.KEYWORD, keyword); - } - else { - c.addCriteria(Criteria.ID, id); - c.addCriteria(Criteria.ACCOUNTNAME, accountName); - c.addCriteria(Criteria.DOMAINID, domainId); - c.addCriteria(Criteria.USERNAME, userName); - c.addCriteria(Criteria.TYPE, type); - c.addCriteria(Criteria.STATE, state); - } + c.addCriteria(Criteria.KEYWORD, keyword); + c.addCriteria(Criteria.ID, id); + c.addCriteria(Criteria.ACCOUNTNAME, accountName); + c.addCriteria(Criteria.DOMAINID, domainId); + c.addCriteria(Criteria.USERNAME, userName); + c.addCriteria(Criteria.TYPE, type); + c.addCriteria(Criteria.STATE, state); + List users = getManagementServer().searchForUsers(c); List> userTags = new ArrayList>(); diff --git a/server/src/com/cloud/api/commands/ListVMsCmd.java b/server/src/com/cloud/api/commands/ListVMsCmd.java index e90b066819b..3cb8299e5e7 100644 --- a/server/src/com/cloud/api/commands/ListVMsCmd.java +++ b/server/src/com/cloud/api/commands/ListVMsCmd.java @@ -130,24 +130,20 @@ public class ListVMsCmd extends BaseCmd { } Criteria c = new Criteria("id", Boolean.TRUE, startIndex, Long.valueOf(pageSizeNum)); - if (keyword != null) { - c.addCriteria(Criteria.KEYWORD, keyword); - } else { - c.addCriteria(Criteria.ID, id); - c.addCriteria(Criteria.NAME, name); - c.addCriteria(Criteria.STATE, state); - c.addCriteria(Criteria.DATACENTERID, zoneId); - - // ignore these search requests if it's not an admin - if (isAdmin == true) { - c.addCriteria(Criteria.DOMAINID, domainId); - c.addCriteria(Criteria.PODID, podId); - c.addCriteria(Criteria.HOSTID, hostId); - } - } - c.addCriteria(Criteria.ACCOUNTID, accountIds); c.addCriteria(Criteria.ISADMIN, isAdmin); + c.addCriteria(Criteria.KEYWORD, keyword); + c.addCriteria(Criteria.ID, id); + c.addCriteria(Criteria.NAME, name); + c.addCriteria(Criteria.STATE, state); + c.addCriteria(Criteria.DATACENTERID, zoneId); + + // ignore these search requests if it's not an admin + if (isAdmin == true) { + c.addCriteria(Criteria.DOMAINID, domainId); + c.addCriteria(Criteria.PODID, podId); + c.addCriteria(Criteria.HOSTID, hostId); + } List virtualMachines = getManagementServer().searchForUserVMs(c); diff --git a/server/src/com/cloud/api/commands/ListVlanIpRangesCmd.java b/server/src/com/cloud/api/commands/ListVlanIpRangesCmd.java index 69b6dc311d8..5e50421003e 100644 --- a/server/src/com/cloud/api/commands/ListVlanIpRangesCmd.java +++ b/server/src/com/cloud/api/commands/ListVlanIpRangesCmd.java @@ -97,19 +97,16 @@ public class ListVlanIpRangesCmd extends BaseCmd { accountId = account.getId(); } } - + Criteria c = new Criteria("id", Boolean.TRUE, startIndex, Long.valueOf(pageSizeNum)); - - if (keyword != null) { - c.addCriteria(Criteria.KEYWORD, keyword); - } else { - c.addCriteria(Criteria.ID, id); - c.addCriteria(Criteria.VLAN, vlanId); - c.addCriteria(Criteria.DATACENTERID, zoneId); - c.addCriteria(Criteria.ACCOUNTID, accountId); - c.addCriteria(Criteria.PODID, podId); - } - + + c.addCriteria(Criteria.KEYWORD, keyword); + c.addCriteria(Criteria.ID, id); + c.addCriteria(Criteria.VLAN, vlanId); + c.addCriteria(Criteria.DATACENTERID, zoneId); + c.addCriteria(Criteria.ACCOUNTID, accountId); + c.addCriteria(Criteria.PODID, podId); + List vlans = getManagementServer().searchForVlans(c); if (vlans == null) { diff --git a/server/src/com/cloud/api/commands/ListVolumesCmd.java b/server/src/com/cloud/api/commands/ListVolumesCmd.java index 403654ef300..cc3e885dec6 100644 --- a/server/src/com/cloud/api/commands/ListVolumesCmd.java +++ b/server/src/com/cloud/api/commands/ListVolumesCmd.java @@ -123,19 +123,16 @@ public class ListVolumesCmd extends BaseCmd{ Criteria c = new Criteria("created", Boolean.FALSE, startIndex, Long.valueOf(pageSizeNum)); c.addCriteria(Criteria.ACCOUNTID, accountIds); - if (keyword != null) { - c.addCriteria(Criteria.KEYWORD, keyword); - } else { - c.addCriteria(Criteria.ID, id); - c.addCriteria(Criteria.INSTANCEID, vmId); - c.addCriteria(Criteria.NAME, name); - if (isAdmin) { - c.addCriteria(Criteria.VTYPE, type); - c.addCriteria(Criteria.DATACENTERID, zoneId); - c.addCriteria(Criteria.PODID, podId); - c.addCriteria(Criteria.HOSTID, hostId); - c.addCriteria(Criteria.DOMAINID, domainId); - } + c.addCriteria(Criteria.KEYWORD, keyword); + c.addCriteria(Criteria.ID, id); + c.addCriteria(Criteria.INSTANCEID, vmId); + c.addCriteria(Criteria.NAME, name); + if (isAdmin) { + c.addCriteria(Criteria.VTYPE, type); + c.addCriteria(Criteria.DATACENTERID, zoneId); + c.addCriteria(Criteria.PODID, podId); + c.addCriteria(Criteria.HOSTID, hostId); + c.addCriteria(Criteria.DOMAINID, domainId); } List volumes = getManagementServer().searchForVolumes(c); diff --git a/server/src/com/cloud/async/executor/CreateSnapshotExecutor.java b/server/src/com/cloud/async/executor/CreateSnapshotExecutor.java index d32aada79e4..4fa8b75d26b 100644 --- a/server/src/com/cloud/async/executor/CreateSnapshotExecutor.java +++ b/server/src/com/cloud/async/executor/CreateSnapshotExecutor.java @@ -68,17 +68,21 @@ public class CreateSnapshotExecutor extends BaseAsyncJobExecutor { try { SnapshotVO snapshot = snapshotManager.createSnapshot(userId, param.getVolumeId(), param.getPolicyIds()); - - if (snapshot != null && snapshot.getStatus() == Snapshot.Status.CreatedOnPrimary) { + Snapshot.Status status = snapshot.getStatus(); + if (snapshot != null && ( status == Snapshot.Status.CreatedOnPrimary + || status == Snapshot.Status.BackedUp) ) { snapshotId = snapshot.getId(); - asyncMgr.updateAsyncJobStatus(jobId, BaseCmd.PROGRESS_INSTANCE_CREATED, snapshotId); - backedUp = snapshotManager.backupSnapshotToSecondaryStorage(userId, snapshot); + if( status == Snapshot.Status.CreatedOnPrimary ) { + asyncMgr.updateAsyncJobStatus(jobId, BaseCmd.PROGRESS_INSTANCE_CREATED, snapshotId); + backedUp = snapshotManager.backupSnapshotToSecondaryStorage(userId, snapshot); + } else { + backedUp = true; + } if (backedUp) { result = AsyncJobResult.STATUS_SUCCEEDED; errorCode = 0; // Success resultObject = composeResultObject(snapshot); - } - else { + } else { // More specific error resultObject = "Created snapshot: " + snapshotId + " on primary but failed to backup on secondary"; } diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 8d050fe4a12..6e3bc31a4be 100644 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -1054,10 +1054,12 @@ public class ConfigurationManagerImpl implements ConfigurationManager { } if (vlanId.equals(vlan.getVlanId()) && newVlanSubnet.equals(otherVlanSubnet)) { - if (NetUtils.ipRangesOverlap(startIP, endIP, otherVlanStartIP, otherVlanEndIP)) { - throw new InvalidParameterValueException("The VLAN with ID " + vlan.getVlanId() + " already has IPs that overlap with the new range. Please specify a different start IP/end IP."); + if (!(vlanType.equals(VlanType.DirectAttached) && !vlanId.equals(Vlan.UNTAGGED))) + { + if (NetUtils.ipRangesOverlap(startIP, endIP, otherVlanStartIP, otherVlanEndIP)) { + throw new InvalidParameterValueException("The VLAN with ID " + vlan.getVlanId() + " already has IPs that overlap with the new range. Please specify a different start IP/end IP."); + } } - if (!vlanGateway.equals(otherVlanGateway)) { throw new InvalidParameterValueException("The VLAN with ID " + vlan.getVlanId() + " has already been added with gateway " + otherVlanGateway + ". Please specify a different VLAN ID."); } diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 33750a082fa..cef5fec9a16 100644 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -50,6 +50,7 @@ import com.cloud.agent.api.ConsoleAccessAuthenticationAnswer; import com.cloud.agent.api.ConsoleAccessAuthenticationCommand; import com.cloud.agent.api.ConsoleProxyLoadReportCommand; import com.cloud.agent.api.MigrateCommand; +import com.cloud.agent.api.NetworkRulesSystemVmCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.StartConsoleProxyAnswer; @@ -1247,8 +1248,13 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleAccessAuthenticationCommand cmd) { long vmId = 0; - String ticket = ConsoleProxyServlet.genAccessTicket(cmd.getHost(), cmd.getPort(), cmd.getSid(), cmd.getVmId()); String ticketInUrl = cmd.getTicket(); + if(ticketInUrl == null) { + s_logger.error("No access ticket found, you could be running an old console proxy. vmId: " + cmd.getVmId()); + return new ConsoleAccessAuthenticationAnswer(cmd, false); + } + + String ticket = ConsoleProxyServlet.genAccessTicket(cmd.getHost(), cmd.getPort(), cmd.getSid(), cmd.getVmId()); if(!ticket.startsWith(ticketInUrl)) { s_logger.error("Access ticket expired or has been modified. vmId: " + cmd.getVmId()); return new ConsoleAccessAuthenticationAnswer(cmd, false); @@ -2460,15 +2466,16 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(proxy .getInstanceName()); - CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer) _agentMgr - .send(host.getId(), cvm); - if (!answer.getResult()) { + NetworkRulesSystemVmCommand nrsvm = new NetworkRulesSystemVmCommand(proxy.getInstanceName()); + Answer [] answers = _agentMgr.send(host.getId(), new Command[]{cvm, nrsvm}, true); + CheckVirtualMachineAnswer checkAnswer = (CheckVirtualMachineAnswer)answers[0]; + if (!checkAnswer.getResult()) { s_logger.debug("Unable to complete migration for " + proxy.getId()); _consoleProxyDao.updateIf(proxy, Event.AgentReportStopped, null); return false; } - State state = answer.getState(); + State state = checkAnswer.getState(); if (state == State.Stopped) { s_logger.warn("Unable to complete migration as we can not detect it on " + host.getId()); _consoleProxyDao.updateIf(proxy, Event.AgentReportStopped, null); @@ -2476,6 +2483,12 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, } _consoleProxyDao.updateIf(proxy, Event.OperationSucceeded, host.getId()); + + if (! answers[1].getResult()) { + s_logger.warn("Migration complete: Failed to program default network rules for system vm " + proxy.getInstanceName()); + } else { + s_logger.info("Migration complete: Programmed default network rules for system vm " + proxy.getInstanceName()); + } return true; } diff --git a/server/src/com/cloud/ha/XenServerInvestigator.java b/server/src/com/cloud/ha/XenServerInvestigator.java index c0ad109c6e2..7b9e22df995 100644 --- a/server/src/com/cloud/ha/XenServerInvestigator.java +++ b/server/src/com/cloud/ha/XenServerInvestigator.java @@ -52,7 +52,7 @@ public class XenServerInvestigator extends AdapterBase implements Investigator { } CheckOnHostCommand cmd = new CheckOnHostCommand(agent); - List neighbors = _hostDao.listByHostPod(agent.getPodId()); + List neighbors = _hostDao.listByCluster(agent.getClusterId()); for (HostVO neighbor : neighbors) { if (neighbor.getId() == agent.getId() || neighbor.getHypervisorType() != Hypervisor.Type.XenServer) { continue; diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index c4ac9a1a934..7cbac7738a6 100644 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -40,6 +40,7 @@ import com.cloud.agent.api.CreateZoneVlanAnswer; import com.cloud.agent.api.CreateZoneVlanCommand; import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.ModifySshKeysCommand; +import com.cloud.agent.api.NetworkRulesSystemVmCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.RebootAnswer; import com.cloud.agent.api.RebootRouterCommand; @@ -561,7 +562,7 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager Set avoids = new HashSet(); boolean found = false; while ((pod = _agentMgr.findPod(template, offering, dc, accountId, avoids)) != null) { - + avoids.add(pod.first().getId()); if (s_logger.isDebugEnabled()) { s_logger.debug("Attempting to create in pod " + pod.first().getName()); } @@ -605,7 +606,6 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager if (s_logger.isDebugEnabled()) { s_logger.debug("Unable to find storage host or pool in pod " + pod.first().getName() + " (id:" + pod.first().getId() + "), checking other pods"); } - avoids.add(pod.first().getId()); } final EventVO event = new EventVO(); @@ -2245,14 +2245,16 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager @Override public boolean completeMigration(final DomainRouterVO router, final HostVO host) throws OperationTimedoutException, AgentUnavailableException { final CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(router.getInstanceName()); - final CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer)_agentMgr.send(host.getId(), cvm); - if (answer == null || !answer.getResult()) { + final NetworkRulesSystemVmCommand nrsvm = new NetworkRulesSystemVmCommand(router.getInstanceName()); + final Answer [] answers = _agentMgr.send(host.getId(), new Command[]{cvm, nrsvm}, true); + final CheckVirtualMachineAnswer checkAnswer = (CheckVirtualMachineAnswer)answers[0]; + if (checkAnswer == null || !checkAnswer.getResult()) { s_logger.debug("Unable to complete migration for " + router.getId()); _routerDao.updateIf(router, Event.AgentReportStopped, null); return false; } - final State state = answer.getState(); + final State state = checkAnswer.getState(); if (state == State.Stopped) { s_logger.warn("Unable to complete migration as we can not detect it on " + host.getId()); _routerDao.updateIf(router, Event.AgentReportStopped, null); @@ -2260,7 +2262,12 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager } _routerDao.updateIf(router, Event.OperationSucceeded, host.getId()); - + + if (! answers[1].getResult()) { + s_logger.warn("Migration complete: Failed to program default network rules for system vm " + router.getInstanceName()); + } else { + s_logger.info("Migration complete: Programmed default network rules for system vm " + router.getInstanceName()); + } return true; } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 08b7948144e..2da4f1d34a7 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -264,7 +264,9 @@ import com.cloud.vm.UserVmManager; import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineName; import com.cloud.vm.VmStats; +import com.cloud.vm.VirtualMachine.Event; import com.cloud.vm.dao.ConsoleProxyDao; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.SecondaryStorageVmDao; @@ -356,6 +358,7 @@ public class ManagementServerImpl implements ManagementServer { private final int _routerRamSize; private final int _proxyRamSize; private final int _ssRamSize; + private String _instance; private final int _maxVolumeSizeInGb; private final Map _availableIdsMap; @@ -492,6 +495,11 @@ public class ManagementServerImpl implements ManagementServer { String hypervisorType = _configDao.getValue("hypervisor.type"); _isHypervisorSnapshotCapable = hypervisorType.equals(Hypervisor.Type.XenServer.name()); + + _instance = _configs.get("instance.name"); + if (_instance == null) { + _instance = "DEFAULT"; + } } protected Map getConfigs() { @@ -2237,6 +2245,14 @@ public class ManagementServerImpl implements ManagementServer { if (password == null || password.equals("") || (!validPassword(password))) { throw new InvalidParameterValueException("A valid password for this virtual machine was not provided."); } + + long guestOSId; + if (template != null) { + guestOSId = template.getGuestOSId(); + } else { + throw new InternalErrorException("No template or ISO was specified for the VM."); + } + List networkGroupVOs = new ArrayList(); if (networkGroups != null) { for (String groupName: networkGroups) { @@ -2253,64 +2269,70 @@ public class ManagementServerImpl implements ManagementServer { stats = new UserStatisticsVO(account.getId(), dataCenterId); _userStatsDao.persist(stats); } - - Long vmId = _vmDao.getNextInSequence(Long.class, "id"); - - // check if we are within context of async-execution - AsyncJobExecutor asyncExecutor = BaseAsyncJobExecutor.getCurrentExecutor(); - if (asyncExecutor != null) { - AsyncJobVO job = asyncExecutor.getJob(); - - if (s_logger.isInfoEnabled()) - s_logger.info("DeployVM acquired a new instance " + vmId + ", update async job-" + job.getId() + " progress status"); - - _asyncMgr.updateAsyncJobAttachment(job.getId(), "vm_instance", vmId); - _asyncMgr.updateAsyncJobStatus(job.getId(), BaseCmd.PROGRESS_INSTANCE_CREATED, vmId); - } HashMap avoids = new HashMap(); - // Pod allocator now allocate VM based on a reservation style allocation, disable retry here for now + // Pod allocator now allocate VM based on a reservation style allocation, disable retry here for (int retry = 0; retry < 1; retry++) { String externalIp = null; UserVmVO created = null; + + Long vmId = _vmDao.getNextInSequence(Long.class, "id"); + String name = VirtualMachineName.getVmName(vmId, accountId, _instance); + + // router id and router mask + UserVmVO initial = new UserVmVO(vmId, name, template.getId(), guestOSId, accountId, account.getDomainId().longValue(), + serviceOfferingId, null, null, null, + null,null,null, + null, null, dataCenterId, + offering.getOfferHA(), displayName, group, userData); + if (diskOffering != null) { + initial.setMirroredVols(diskOffering.isMirrored()); + } + initial = _vmDao.persist(initial); + + AsyncJobExecutor asyncExecutor = BaseAsyncJobExecutor.getCurrentExecutor(); + if (asyncExecutor != null) { + AsyncJobVO job = asyncExecutor.getJob(); + + if (s_logger.isInfoEnabled()) + s_logger.info("DeployVM acquired a new instance " + vmId + ", update async job-" + job.getId() + " progress status"); + + _asyncMgr.updateAsyncJobAttachment(job.getId(), "vm_instance", vmId); + _asyncMgr.updateAsyncJobStatus(job.getId(), BaseCmd.PROGRESS_INSTANCE_CREATED, vmId); + } ArrayList a = new ArrayList(avoids.values()); - if (_directAttachNetworkExternalIpAllocator) { - try { - created = _vmMgr.createDirectlyAttachedVMExternal(vmId, userId, account, dc, offering, template, diskOffering, displayName, group, userData, a, networkGroupVOs, startEventId); - } catch (ResourceAllocationException rae) { - throw rae; - } - } else { - if (offering.getGuestIpType() == GuestIpType.Virtualized) { - try { - externalIp = _networkMgr.assignSourceNatIpAddress(account, dc, domain, offering); - } catch (ResourceAllocationException rae) { - throw rae; - } - if (externalIp == null) { - throw new InternalErrorException("Unable to allocate a source nat ip address"); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Source Nat acquired: " + externalIp); - } - - try { - created = _vmMgr.createVirtualMachine(vmId, userId, account, dc, offering, template, diskOffering, displayName, group, userData, a, startEventId); - } catch (ResourceAllocationException rae) { - throw rae; - } catch (InternalErrorException iee){ - throw iee; - } - } else { - try { - created = _vmMgr.createDirectlyAttachedVM(vmId, userId, account, dc, offering, template, diskOffering, displayName, group, userData, a, networkGroupVOs, startEventId); - } catch (ResourceAllocationException rae) { - throw rae; - } + try { + if (_directAttachNetworkExternalIpAllocator) { + created = _vmMgr.createDirectlyAttachedVMExternal(initial, userId, account, dc, offering, template, diskOffering, displayName, group, userData, a, networkGroupVOs, startEventId); + } else { + if (offering.getGuestIpType() == GuestIpType.Virtualized) { + externalIp = _networkMgr.assignSourceNatIpAddress(account, dc, domain, offering); + if (externalIp == null) { + throw new InternalErrorException("Unable to allocate a source nat ip address"); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Source Nat acquired: " + externalIp); + } + + created = _vmMgr.createVirtualMachine(initial, userId, account, dc, offering, template, diskOffering, displayName, group, userData, a, startEventId); + } else { + created = _vmMgr.createDirectlyAttachedVM(initial, userId, account, dc, offering, template, diskOffering, displayName, group, userData, a, networkGroupVOs, startEventId); + } + } + } catch(ResourceAllocationException rae) { + s_logger.error("Resource allocation failure ", rae); + throw rae; + } catch(InternalErrorException iee) { + s_logger.error("Internal error ", iee); + throw iee; + } finally { + if(created == null) { + s_logger.warn("Failed to create VM, mark VM into destroyed state, vmId: " + initial.getId()); + _vmDao.updateIf(initial, Event.OperationFailed, null); } } @@ -2328,57 +2350,48 @@ public class ManagementServerImpl implements ManagementServer { String storageUnavailableExceptionMsg = ""; String concurrentOperationExceptionMsg = ""; UserVm started = null; - if (isIso) - { + if (isIso) { String isoPath = _storageMgr.getAbsoluteIsoPath(templateId, dataCenterId); - try - { + try { started = _vmMgr.startVirtualMachine(userId, created.getId(), password, isoPath); - } - catch (ExecutionException e) - { + } catch (ExecutionException e) { executionExceptionFlag = true; executionExceptionMsg = e.getMessage(); - } - catch (StorageUnavailableException e) - { + } catch (StorageUnavailableException e) { storageUnavailableExceptionFlag = true; storageUnavailableExceptionMsg = e.getMessage(); + } catch (ConcurrentOperationException e) { + concurrentOperationExceptionFlag = true; + concurrentOperationExceptionMsg = e.getMessage(); } - catch (ConcurrentOperationException e) - { + } else { + try { + started = _vmMgr.startVirtualMachine(userId, created.getId(), password, null); + } catch (ExecutionException e) { + executionExceptionFlag = true; + executionExceptionMsg = e.getMessage(); + } catch (StorageUnavailableException e) { + storageUnavailableExceptionFlag = true; + storageUnavailableExceptionMsg = e.getMessage(); + } catch (ConcurrentOperationException e) { concurrentOperationExceptionFlag = true; concurrentOperationExceptionMsg = e.getMessage(); } } - else - { - try - { - started = _vmMgr.startVirtualMachine(userId, created.getId(), password, null); - } - catch (ExecutionException e) - { - executionExceptionFlag = true; - executionExceptionMsg = e.getMessage(); - } - catch (StorageUnavailableException e) - { - storageUnavailableExceptionFlag = true; - storageUnavailableExceptionMsg = e.getMessage(); - } - catch (ConcurrentOperationException e) - { - concurrentOperationExceptionFlag = true; - concurrentOperationExceptionMsg = e.getMessage(); - } - - } + if (started == null) { - List> disks = _storageMgr.isStoredOn(created); + + List> disks = new ArrayList>(); // NOTE: We now destroy a VM if the deploy process fails at any step. We now // have a lazy delete so there is still some time to figure out what's wrong. - _vmMgr.destroyVirtualMachine(userId, created.getId()); + disks = _storageMgr.isStoredOn(created); + + // make sure we cleanup last host id + UserVmVO vmTmp = _vmDao.createForUpdate(created.getId()); + vmTmp.setLastHostId(null); + _vmDao.update(created.getId(), vmTmp); + + _vmMgr.destroyVirtualMachine(userId, created.getId()); boolean retryCreate = true; for (Pair disk : disks) { @@ -2395,13 +2408,11 @@ public class ManagementServerImpl implements ManagementServer { throw new ExecutionException(executionExceptionMsg); } else if (storageUnavailableExceptionFlag){ throw new StorageUnavailableException(storageUnavailableExceptionMsg); - }else if (concurrentOperationExceptionFlag){ + } else if (concurrentOperationExceptionFlag){ throw new ConcurrentOperationException(concurrentOperationExceptionMsg); - } - else{ + } else { throw new InternalErrorException("Unable to start the VM " + created.getId() + "-" + created.getName()); } - } else { if (isIso) { VMInstanceVO updatedInstance = _vmInstanceDao.createForUpdate(); @@ -5485,7 +5496,6 @@ public class ManagementServerImpl implements ManagementServer { if (keyword != null) { SearchCriteria ssc = _volumeDao.createSearchCriteria(); ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - ssc.addOr("nameLabel", SearchCriteria.Op.LIKE, "%" + keyword + "%"); ssc.addOr("volumeType", SearchCriteria.Op.LIKE, "%" + keyword + "%"); sc.addAnd("name", SearchCriteria.Op.SC, ssc); diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 332640ce2de..257ef4be10f 100644 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -421,7 +421,7 @@ public class StorageManagerImpl implements StorageManager { _asyncMgr.updateAsyncJobStatus(job.getId(), BaseCmd.PROGRESS_INSTANCE_CREATED, volumeId); } - final HashSet poolsToAvoid = new HashSet(); + StoragePoolVO pool = null; boolean success = false; Set podsToAvoid = new HashSet(); @@ -436,6 +436,7 @@ public class StorageManagerImpl implements StorageManager { while ((pod = _agentMgr.findPod(null, null, dc, account.getId(), podsToAvoid)) != null) { podsToAvoid.add(pod.first().getId()); // Determine what storage pool to store the volume in + HashSet poolsToAvoid = new HashSet(); while ((pool = findStoragePool(dskCh, dc, pod.first(), null, null, null, null, poolsToAvoid)) != null) { poolsToAvoid.add(pool); volumeFolder = pool.getPath(); @@ -531,11 +532,9 @@ public class StorageManagerImpl implements StorageManager { String templatePath = null; VMTemplateVO template = null; if(originalVolume.getVolumeType().equals(Volume.VolumeType.ROOT)){ - if(originalVolume.getTemplateId() == null){ - details = "Null Template Id for Root Volume Id: " + origVolumeId + ". Cannot create volume from snapshot of root disk."; - s_logger.error(details); - } - else { + + ImageFormat format = _snapshotMgr.getImageFormat(origVolumeId); + if (format != null && format != ImageFormat.ISO) { Long templateId = originalVolume.getTemplateId(); template = _templateDao.findById(templateId); if(template == null) { @@ -555,43 +554,40 @@ public class StorageManagerImpl implements StorageManager { (templatePath = templateHostVO.getInstallPath()) == null) { details = "Template id: " + templateId + " is not present on secondaryStorageHost Id: " + secondaryStorageHost.getId() + ". Can't create volume from ROOT DISK"; + s_logger.warn(details); + throw new CloudRuntimeException(details); } } } - } - if (details == null) { - // everything went well till now - DataCenterVO dc = _dcDao.findById(originalVolume.getDataCenterId()); - DiskOfferingVO diskOffering = null; + } + // everything went well till now + DataCenterVO dc = _dcDao.findById(originalVolume.getDataCenterId()); + DiskOfferingVO diskOffering = null; + + if (originalVolume.getVolumeType() == VolumeType.DATADISK + || originalVolume.getVolumeType() == VolumeType.ROOT) { + Long diskOfferingId = originalVolume.getDiskOfferingId(); + if (diskOfferingId != null) { + diskOffering = _diskOfferingDao.findById(diskOfferingId); + } + } else { + // The code never reaches here. + s_logger + .error("Original volume must have been a ROOT DISK or a DATA DISK"); + return null; + } + Pair volumeDetails = createVolumeFromSnapshot(userId, + accountId, volumeName, dc, diskOffering, snapshot, + templatePath, originalVolume.getSize(), template); + createdVolume = volumeDetails.first(); + if (createdVolume != null) { + volumeId = createdVolume.getId(); + } else { + details = "Creating volume failed due to " + volumeDetails.second(); + s_logger.warn(details); + throw new CloudRuntimeException(details); + } - if (originalVolume.getVolumeType() == VolumeType.DATADISK || originalVolume.getVolumeType() == VolumeType.ROOT) { - Long diskOfferingId = originalVolume.getDiskOfferingId(); - if (diskOfferingId != null) { - diskOffering = _diskOfferingDao.findById(diskOfferingId); - } - } -// else if (originalVolume.getVolumeType() == VolumeType.ROOT) { -// // Create a temporary disk offering with the same size as the ROOT DISK -// Long rootDiskSize = originalVolume.getSize(); -// Long rootDiskSizeInMB = rootDiskSize/(1024*1024); -// Long sizeInGB = rootDiskSizeInMB/1024; -// String name = "Root Disk Offering"; -// String displayText = "Temporary Disk Offering for Snapshot from Root Disk: " + originalVolume.getId() + "[" + sizeInGB + "GB Disk]"; -// diskOffering = new DiskOfferingVO(originalVolume.getDomainId(), name, displayText, rootDiskSizeInMB, false, null); -// } - else { - // The code never reaches here. - s_logger.error("Original volume must have been a ROOT DISK or a DATA DISK"); - return null; - } - Pair volumeDetails = createVolumeFromSnapshot(userId, accountId, volumeName, dc, diskOffering, snapshot, templatePath, originalVolume.getSize(), template); - createdVolume = volumeDetails.first(); - if (createdVolume != null) { - volumeId = createdVolume.getId(); - } - details = volumeDetails.second(); - } - Transaction txn = Transaction.currentTxn(); txn.start(); // Create an event @@ -973,7 +969,7 @@ public class StorageManagerImpl implements StorageManager { _storagePoolAcquisitionWaitSeconds = NumbersUtil.parseInt(configs.get("pool.acquisition.wait.seconds"), 1800); s_logger.info("pool.acquisition.wait.seconds is configured as " + _storagePoolAcquisitionWaitSeconds + " seconds"); - _totalRetries = NumbersUtil.parseInt(configDao.getValue("total.retries"), 4); + _totalRetries = NumbersUtil.parseInt(configDao.getValue("total.retries"), 2); _pauseInterval = 2*NumbersUtil.parseInt(configDao.getValue("ping.interval"), 60); _hypervisorType = configDao.getValue("hypervisor.type"); @@ -1148,7 +1144,9 @@ public class StorageManagerImpl implements StorageManager { Hypervisor.Type hypervisorType = null; List hosts = null; - if (podId != null) { + if (clusterId != null) { + hosts = _hostDao.listByCluster(clusterId); + } else if (podId != null) { hosts = _hostDao.listByHostPod(podId); } else { hosts = _hostDao.listByDataCenter(zoneId); @@ -1515,11 +1513,10 @@ public class StorageManagerImpl implements StorageManager { VolumeVO createdVolume = null; while ((pod = _agentMgr.findPod(null, null, dc, account.getId(), podsToAvoid)) != null) { + podsToAvoid.add(pod.first().getId()); if ((createdVolume = createVolume(volume, null, null, dc, pod.first(), null, null, diskOffering, poolsToAvoid)) != null) { break; - } else { - podsToAvoid.add(pod.first().getId()); - } + } } // Create an event @@ -1682,13 +1679,13 @@ public class StorageManagerImpl implements StorageManager { } while ((storagePoolHost = chooseHostForStoragePool(storagePool, hostsToAvoid)) != null && tryCount++ < totalRetries) { String errMsg = basicErrMsg + " on host: " + hostId + " try: " + tryCount + ", reason: "; + hostsToAvoid.add(hostId); try { hostId = storagePoolHost.getHostId(); HostVO hostVO = _hostDao.findById(hostId); if (shouldBeSnapshotCapable) { if (hostVO == null || hostVO.getHypervisorType() != Hypervisor.Type.XenServer) { // Only XenServer hosts are snapshot capable. - hostsToAvoid.add(hostId); continue; } } diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index a43505dda39..3ec1fdf933c 100644 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -40,6 +40,7 @@ import com.cloud.agent.api.CheckVirtualMachineAnswer; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.MigrateCommand; +import com.cloud.agent.api.NetworkRulesSystemVmCommand; import com.cloud.agent.api.PrepareForMigrationCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.SecStorageFirewallCfgCommand; @@ -701,13 +702,13 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V dataCenterId, (1L << 31)); String guestMacAddress = macAddresses[0]; while ((pod = _agentMgr.findPod(_template, _serviceOffering, dc, Account.ACCOUNT_ID_SYSTEM, avoidPods)) != null){ + avoidPods.add(pod.first().getId()); publicIpAndVlan = allocPublicIpAddress(dataCenterId, pod.first().getId(), publicMacAddress); - if (publicIpAndVlan == null) { - s_logger.warn("Unable to allocate public IP address for secondary storage vm in data center : " + dataCenterId + ", pod="+ pod.first().getId()); - avoidPods.add(pod.first().getId()); - } else { + if (publicIpAndVlan != null) { break; } + s_logger.warn("Unable to allocate public IP address for secondary storage vm in data center : " + dataCenterId + ", pod="+ pod.first().getId()); + } if (pod == null || publicIpAndVlan == null) { @@ -1748,14 +1749,16 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V public boolean completeMigration(SecondaryStorageVmVO secStorageVm, HostVO host) throws AgentUnavailableException, OperationTimedoutException { CheckVirtualMachineCommand cvm = new CheckVirtualMachineCommand(secStorageVm.getInstanceName()); - CheckVirtualMachineAnswer answer = (CheckVirtualMachineAnswer) _agentMgr.send(host.getId(), cvm); - if (!answer.getResult()) { + NetworkRulesSystemVmCommand nrsvm = new NetworkRulesSystemVmCommand(secStorageVm.getInstanceName()); + Answer [] answers = _agentMgr.send(host.getId(), new Command[]{cvm, nrsvm}, true); + CheckVirtualMachineAnswer checkAnswer = (CheckVirtualMachineAnswer)answers[0]; + if (!checkAnswer.getResult()) { s_logger.debug("Unable to complete migration for " + secStorageVm.getId()); _secStorageVmDao.updateIf(secStorageVm, Event.AgentReportStopped, null); return false; } - State state = answer.getState(); + State state = checkAnswer.getState(); if (state == State.Stopped) { s_logger.warn("Unable to complete migration as we can not detect it on " + host.getId()); _secStorageVmDao.updateIf(secStorageVm, Event.AgentReportStopped, null); @@ -1763,6 +1766,11 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V } _secStorageVmDao.updateIf(secStorageVm, Event.OperationSucceeded, host.getId()); + if (! answers[1].getResult()) { + s_logger.warn("Migration complete: Failed to program default network rules for system vm " + secStorageVm.getInstanceName()); + } else { + s_logger.info("Migration complete: Programmed default network rules for system vm " + secStorageVm.getInstanceName()); + } return true; } diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 0debbc65135..fb1078bb3f7 100644 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -382,41 +382,53 @@ public class SnapshotManagerImpl implements SnapshotManager { txn = Transaction.currentTxn(); txn.start(); - // Update the snapshot in the database - if ((answer != null) && answer.getResult()) { - // The snapshot was successfully created - if( preSnapshotPath != null && preSnapshotPath == answer.getSnapshotPath() ){ - //empty snapshot - s_logger.debug("CreateSnapshot: this is empty snapshot, remove it "); + try { + // Update the snapshot in the database + if ((answer != null) && answer.getResult()) { + // The snapshot was successfully created + if (preSnapshotPath != null && preSnapshotPath == answer.getSnapshotPath()) { + + if( preSnapshotVO.getRemoved() != null ) { + String backupPath = preSnapshotVO.getBackupSnapshotId(); + _snapshotDao.delete(preId); + createdSnapshot = updateDBOnCreateDuplicate(id, answer.getSnapshotPath(), backupPath); + } else { + // empty snapshot + s_logger.debug("CreateSnapshot: this is empty snapshot, remove it "); + // delete from the snapshots table + _snapshotDao.delete(id); + throw new CloudRuntimeException( + " There is no change since last snapshot, please use last snapshot " + preSnapshotPath); + } + + } else { + createdSnapshot = updateDBOnCreate(id, answer.getSnapshotPath()); + } + } else { + String msg = "createSnapshotCommand returns null"; + if (answer != null) { + msg = answer.getDetails(); + s_logger.error(msg); + } // delete from the snapshots table _snapshotDao.delete(id); - throw new CloudRuntimeException(" There is no change since last snapshot, please use last snapshot " + preSnapshotPath); - - } else { - createdSnapshot = updateDBOnCreate(id, answer.getSnapshotPath()); + throw new CloudRuntimeException(" CreateSnapshot failed due to " + msg); } - } else { - if (answer != null) { - s_logger.error(answer.getDetails()); + + // Update async status after snapshot creation and before backup + if (asyncExecutor != null) { + AsyncJobVO job = asyncExecutor.getJob(); + + if (s_logger.isDebugEnabled()) + s_logger.debug("CreateSnapshot created a new instance " + id + ", update async job-" + job.getId() + + " progress status"); + + _asyncMgr.updateAsyncJobAttachment(job.getId(), "snapshot", id); + _asyncMgr.updateAsyncJobStatus(job.getId(), BaseCmd.PROGRESS_INSTANCE_CREATED, id); } - // The snapshot was not successfully created - createdSnapshot = _snapshotDao.findById(id); - // delete from the snapshots table - _snapshotDao.delete(id); - + } finally { + txn.commit(); } - - // Update async status after snapshot creation and before backup - if(asyncExecutor != null) { - AsyncJobVO job = asyncExecutor.getJob(); - - if(s_logger.isDebugEnabled()) - s_logger.debug("CreateSnapshot created a new instance " + id + ", update async job-" + job.getId() + " progress status"); - - _asyncMgr.updateAsyncJobAttachment(job.getId(), "snapshot", id); - _asyncMgr.updateAsyncJobStatus(job.getId(), BaseCmd.PROGRESS_INSTANCE_CREATED, id); - } - txn.commit(); return createdSnapshot; } @@ -431,6 +443,17 @@ public class SnapshotManagerImpl implements SnapshotManager { return createdSnapshot; } + private SnapshotVO updateDBOnCreateDuplicate(Long id, String snapshotPath, String backUpSnapshotPath) { + SnapshotVO createdSnapshot = _snapshotDao.findById(id); + Long volumeId = createdSnapshot.getVolumeId(); + createdSnapshot.setPath(snapshotPath); + createdSnapshot.setBackupSnapshotId(backUpSnapshotPath); + createdSnapshot.setStatus(Snapshot.Status.BackedUp); + createdSnapshot.setPrevSnapshotId(_snapshotDao.getLastSnapshot(volumeId, id)); + _snapshotDao.update(id, createdSnapshot); + return createdSnapshot; + } + @Override @DB @SuppressWarnings("fallthrough") diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index f4ec7d530e7..db15b644f50 100644 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -633,6 +633,9 @@ public class TemplateManagerImpl implements TemplateManager { // Check if there are any snapshots for the template in the template host ref's zone List volumes = _volumeDao.findByTemplateAndZone(templateId, zoneId); + if( volumes.size() > 0 ) { + return false; + } for (VolumeVO volume : volumes) { List snapshots = _snapshotDao.listByVolumeId(volume.getId()); if (!snapshots.isEmpty()) { diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java index 286b8b6034e..2dc8c52894e 100644 --- a/server/src/com/cloud/vm/UserVmManager.java +++ b/server/src/com/cloud/vm/UserVmManager.java @@ -77,11 +77,11 @@ public interface UserVmManager extends Manager, VirtualMachineManager * @param diskOffering the disk offering for the root disk (deploying from ISO) or the data disk (deploying from a normal template) * @return UserVmVO if created; null if not. */ - UserVmVO createVirtualMachine(Long vmId, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String group, String userData, List avoids, long startEventId) throws InsufficientStorageCapacityException, InternalErrorException, ResourceAllocationException; + UserVmVO createVirtualMachine(UserVmVO vm, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String group, String userData, List avoids, long startEventId) throws InsufficientStorageCapacityException, InternalErrorException, ResourceAllocationException; - UserVmVO createDirectlyAttachedVM(Long vmId, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String group, String userData, List a, List networkGroupVO, long startEventId) throws InternalErrorException, ResourceAllocationException; + UserVmVO createDirectlyAttachedVM(UserVmVO vm, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String group, String userData, List a, List networkGroupVO, long startEventId) throws InternalErrorException, ResourceAllocationException; - UserVmVO createDirectlyAttachedVMExternal(Long vmId, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String group, String userData, List a, List networkGroupVO, long startEventId) throws InternalErrorException, ResourceAllocationException; + UserVmVO createDirectlyAttachedVMExternal(UserVmVO vm, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String group, String userData, List a, List networkGroupVO, long startEventId) throws InternalErrorException, ResourceAllocationException; /** * Destroys one virtual machine diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 5ec095d85cc..cadc71ec47b 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -177,6 +177,7 @@ import com.cloud.vm.VirtualMachine.Event; import com.cloud.vm.VirtualMachine.Type; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.UserVmDao; +import com.xensource.xenapi.Types.UserIsNotLocalSuperuser; @Local(value={UserVmManager.class}) public class UserVmManagerImpl implements UserVmManager { @@ -1187,11 +1188,10 @@ public class UserVmManagerImpl implements UserVmManager { } @Override @DB - public UserVmVO createVirtualMachine(Long vmId, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String group, String userData, List avoids, long startEventId) throws InternalErrorException, ResourceAllocationException { + public UserVmVO createVirtualMachine(UserVmVO vm, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String group, String userData, List avoids, long startEventId) throws InternalErrorException, ResourceAllocationException { long accountId = account.getId(); long dataCenterId = dc.getId(); long serviceOfferingId = offering.getId(); - UserVmVO vm = null; if (s_logger.isDebugEnabled()) { s_logger.debug("Creating vm for account id=" + account.getId() + @@ -1237,7 +1237,8 @@ public class UserVmManagerImpl implements UserVmManager { _accountMgr.incrementResourceCount(account.getId(), ResourceType.user_vm); _accountMgr.incrementResourceCount(account.getId(), ResourceType.volume, numVolumes); txn.commit(); - + + Long vmId = vm.getId(); name = VirtualMachineName.getVmName(vmId, accountId, _instance); String diskOfferingIdentifier = (diskOffering != null) ? String.valueOf(diskOffering.getId()) : "-1"; @@ -1256,25 +1257,12 @@ public class UserVmManagerImpl implements UserVmManager { Set podsToAvoid = new HashSet(); while ((pod = _agentMgr.findPod(template, offering, dc, account.getId(), podsToAvoid)) != null) { - if (vm == null) { - vm = new UserVmVO(vmId, name, template.getId(), guestOSId, accountId, account.getDomainId().longValue(), - serviceOfferingId, null, null, router.getGuestNetmask(), - null,null,null, - routerId, pod.first().getId(), dataCenterId, - offering.getOfferHA(), displayName, group, userData); - - if (diskOffering != null) { - vm.setMirroredVols(diskOffering.isMirrored()); - } - - vm.setLastHostId(pod.second()); - - vm = _vmDao.persist(vm); - } else { - vm.setPodId(pod.first().getId()); - _vmDao.updateIf(vm, Event.OperationRetry, null); - } - + vm.setDomainRouterId(routerId); + vm.setGuestNetmask(router.getGuestNetmask()); + vm.setPodId(pod.first().getId()); + vm.setLastHostId(pod.second()); + _vmDao.update(vm.getId(), vm); + String ipAddressStr = acquireGuestIpAddress(dataCenterId, accountId, vm); if (ipAddressStr == null) { s_logger.warn("Failed user vm creation : no guest ip address available"); @@ -1332,9 +1320,11 @@ public class UserVmManagerImpl implements UserVmManager { return _vmDao.findById(vmId); } catch (Throwable th) { s_logger.error("Unable to create vm", th); +/* if (vm != null) { _vmDao.delete(vmId); } +*/ _accountMgr.decrementResourceCount(account.getId(), ResourceType.user_vm); _accountMgr.decrementResourceCount(account.getId(), ResourceType.volume, numVolumes); @@ -1374,9 +1364,11 @@ public class UserVmManagerImpl implements UserVmManager { s_logger.debug("Destroying vm " + vmId); } - if (!stop(userId, vm, 0)) { - s_logger.error("Unable to stop vm so we can't destroy it: " + vmId); - return false; + if(vm.getState() != State.Creating) { + if (!stop(userId, vm, 0)) { + s_logger.error("Unable to stop vm so we can't destroy it: " + vmId); + return false; + } } Transaction txn = Transaction.currentTxn(); @@ -1941,6 +1933,7 @@ public class UserVmManagerImpl implements UserVmManager { s_logger.info("Found " + vms.size() + " vms to expunge."); for (UserVmVO vm : vms) { + boolean deleteRules = true; String privateIpAddress = vm.getPrivateIpAddress(); long vmId = vm.getId(); releaseGuestIpAddress(vm); @@ -1950,24 +1943,38 @@ public class UserVmManagerImpl implements UserVmManager { s_logger.info("vm " + vmId + " is skipped because it is no longer in Destroyed state"); continue; } + + if(VirtualMachineName.isValidRouterName(vm.getName()) && !vm.getState().equals(State.Running)){ + deleteRules = false; + } - List forwardingRules = null; - forwardingRules = _rulesDao.listByPrivateIp(privateIpAddress); - - for(FirewallRuleVO rule: forwardingRules) - { - try + if(deleteRules) + { + List forwardingRules = null; + forwardingRules = _rulesDao.listByPrivateIp(privateIpAddress); + + for(FirewallRuleVO rule: forwardingRules) { - _networkMgr.deleteRule(rule.getId(), Long.valueOf(User.UID_SYSTEM), Long.valueOf(User.UID_SYSTEM)); - if(s_logger.isDebugEnabled()) - s_logger.debug("Rule "+rule.getId()+" for vm:"+vm.getName()+" is deleted successfully during expunge operation"); + try + { + IPAddressVO publicIp = _ipAddressDao.findById(rule.getPublicIpAddress()); + + if(publicIp!=null) + { + if((publicIp.getAccountId().longValue() == vm.getAccountId())) + { + _networkMgr.deleteRule(rule.getId(), Long.valueOf(User.UID_SYSTEM), Long.valueOf(User.UID_SYSTEM)); + if(s_logger.isDebugEnabled()) + s_logger.debug("Rule "+rule.getId()+" for vm:"+vm.getName()+" is deleted successfully during expunge operation"); + } + } + } + catch(Exception e) + { + s_logger.warn("Failed to delete rule:"+rule.getId()+" for vm:"+vm.getName()); + } } - catch(Exception e) - { - s_logger.warn("Failed to delete rule:"+rule.getId()+" for vm:"+vm.getName()); - } - } - + } List vols = null; try { @@ -2014,7 +2021,7 @@ public class UserVmManagerImpl implements UserVmManager { txn.start(); _vmDao.updateIf(vm, Event.OperationSucceeded, host.getId()); txn.commit(); - + _networkGroupManager.handleVmStateTransition(vm, State.Running); return true; } catch(Exception e) { s_logger.warn("Exception during completion of migration process " + vm.toString()); @@ -2213,8 +2220,8 @@ public class UserVmManagerImpl implements UserVmManager { String origTemplateInstallPath = null; - - if (ImageFormat.ISO != _snapshotMgr.getImageFormat(volumeId)) { + ImageFormat format = _snapshotMgr.getImageFormat(volumeId); + if (format != null && format != ImageFormat.ISO) { Long origTemplateId = volume.getTemplateId(); VMTemplateHostVO vmTemplateHostVO = _templateHostDao.findByHostTemplate(secondaryStorageHost.getId(), origTemplateId); origTemplateInstallPath = vmTemplateHostVO.getInstallPath(); @@ -2331,8 +2338,7 @@ public class UserVmManagerImpl implements UserVmManager { @DB @Override - public UserVmVO createDirectlyAttachedVM(Long vmId, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String group, String userData, List a, List networkGroups, long startEventId) throws InternalErrorException, ResourceAllocationException { - + public UserVmVO createDirectlyAttachedVM(UserVmVO vm, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String group, String userData, List a, List networkGroups, long startEventId) throws InternalErrorException, ResourceAllocationException { long accountId = account.getId(); long dataCenterId = dc.getId(); long serviceOfferingId = offering.getId(); @@ -2376,8 +2382,9 @@ public class UserVmManagerImpl implements UserVmManager { txn.commit(); try { - UserVmVO vm = null; boolean forZone = false; + + Long vmId = vm.getId(); final String name = VirtualMachineName.getVmName(vmId, accountId, _instance); final String[] macAddresses = _dcDao.getNextAvailableMacAddressPair(dc.getId()); @@ -2439,10 +2446,10 @@ public class UserVmManagerImpl implements UserVmManager { if (s_logger.isDebugEnabled()) { s_logger.debug("Attempting to create direct attached vm in pod " + pod.first().getName()); } + avoids.add(pod.first().getId()); if (!forAccount && !forZone) { vlansForPod = _vlanDao.listVlansForPodByType(pod.first().getId(), VlanType.DirectAttached); if (vlansForPod.size() < 1) { - avoids.add(pod.first().getId()); if (s_logger.isDebugEnabled()) { s_logger.debug("No direct attached vlans available in pod " + pod.first().getName() + " (id:" + pod.first().getId() + "), checking other pods"); } @@ -2459,7 +2466,6 @@ public class UserVmManagerImpl implements UserVmManager { } else if (rtrs.size() == 0) { router = _networkMgr.createDhcpServerForDirectlyAttachedGuests(userId, accountId, dc, pod.first(), pod.second(), guestVlan); if (router == null) { - avoids.add(pod.first().getId()); if (s_logger.isDebugEnabled()) { s_logger.debug("Unable to create DHCP server in vlan " + guestVlan.getVlanId() + ", pod=" + pod.first().getName() + " (podid:" + pod.first().getId() + "), checking other pods"); } @@ -2503,14 +2509,14 @@ public class UserVmManagerImpl implements UserVmManager { if (guestIp == null) { s_logger.debug("No guest IP available in pod id=" + pod.first().getId()); - avoids.add(pod.first().getId()); continue; } s_logger.debug("Acquired a guest IP, ip=" + guestIp); String guestMacAddress = macAddresses[0]; String externalMacAddress = macAddresses[1]; Long externalVlanDbId = null; - + +/* vm = new UserVmVO(vmId, name, templateId, guestOSId, accountId, account.getDomainId().longValue(), serviceOfferingId, guestMacAddress, guestIp, guestVlan.getVlanNetmask(), null, externalMacAddress, externalVlanDbId, @@ -2523,10 +2529,24 @@ public class UserVmManagerImpl implements UserVmManager { vm.setLastHostId(pod.second()); vm = _vmDao.persist(vm); +*/ + vm.setDomainRouterId(routerId); + vm.setGuestNetmask(guestVlan.getVlanNetmask()); + vm.setGuestIpAddress(guestIp); + vm.setGuestMacAddress(guestMacAddress); + vm.setPodId(pod.first().getId()); + vm.setLastHostId(pod.second()); + vm.setExternalMacAddress(externalMacAddress); + vm.setExternalVlanDbId(externalVlanDbId); + _vmDao.update(vm.getId(), vm); + boolean addedToGroups = _networkGroupManager.addInstanceToGroups(vmId, networkGroups); if (!addedToGroups) { s_logger.warn("Not all specified network groups can be found"); - _vmDao.delete(vm.getId()); + +/* + _vmDao.delete(vm.getId()); +*/ throw new InvalidParameterValueException("Not all specified network groups can be found"); } @@ -2534,14 +2554,15 @@ public class UserVmManagerImpl implements UserVmManager { try { poolId = _storageMgr.createUserVM(account, vm, template, dc, pod.first(), offering, diskOffering, a); } catch (CloudRuntimeException e) { +/* _vmDao.delete(vmId); +*/ _ipAddressDao.unassignIpAddress(guestIp); s_logger.debug("Released a guest ip address because we could not find storage: ip=" + guestIp); guestIp = null; if (s_logger.isDebugEnabled()) { s_logger.debug("Unable to find storage host in pod " + pod.first().getName() + " (id:" + pod.first().getId() + "), checking other pods"); } - avoids.add(pod.first().getId()); continue; // didn't find a storage host in pod, go to the next pod } @@ -2613,7 +2634,7 @@ public class UserVmManagerImpl implements UserVmManager { @DB @Override - public UserVmVO createDirectlyAttachedVMExternal(Long vmId, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String group, String userData, List a, List networkGroups, long startEventId) throws InternalErrorException, ResourceAllocationException { + public UserVmVO createDirectlyAttachedVMExternal(UserVmVO vm, long userId, AccountVO account, DataCenterVO dc, ServiceOfferingVO offering, VMTemplateVO template, DiskOfferingVO diskOffering, String displayName, String group, String userData, List a, List networkGroups, long startEventId) throws InternalErrorException, ResourceAllocationException { long accountId = account.getId(); long dataCenterId = dc.getId(); long serviceOfferingId = offering.getId(); @@ -2641,7 +2662,8 @@ public class UserVmManagerImpl implements UserVmManager { Transaction txn = Transaction.currentTxn(); try { - UserVmVO vm = null; + Long vmId = vm.getId(); + txn.start(); account = _accountDao.lock(accountId, true); @@ -2667,7 +2689,7 @@ public class UserVmManagerImpl implements UserVmManager { if (s_logger.isDebugEnabled()) { s_logger.debug("Attempting to create direct attached vm in pod " + pod.first().getName()); } - + avoids.add(pod.first().getId()); String guestMacAddress = macAddresses[0]; String externalMacAddress = macAddresses[1]; @@ -2680,6 +2702,8 @@ public class UserVmManagerImpl implements UserVmManager { publicIpAddr = publicIp.ipaddr; publicIpNetMask = publicIp.netMask; } + + /* vm = new UserVmVO(vmId, name, templateId, guestOSId, accountId, account.getDomainId().longValue(), serviceOfferingId, guestMacAddress, publicIpAddr, publicIpNetMask, null, externalMacAddress, null, @@ -2692,6 +2716,18 @@ public class UserVmManagerImpl implements UserVmManager { vm.setLastHostId(pod.second()); _vmDao.persist(vm); + */ + + vm.setDomainRouterId(routerId); + vm.setGuestMacAddress(guestMacAddress); + vm.setGuestIpAddress(publicIpAddr); + vm.setGuestNetmask(publicIpNetMask); + vm.setExternalMacAddress(externalMacAddress); + vm.setPodId(pod.first().getId()); + vm.setLastHostId(pod.second()); + + _vmDao.update(vm.getId(), vm); + _networkGroupManager.addInstanceToGroups(vmId, networkGroups); _accountMgr.incrementResourceCount(account.getId(), ResourceType.user_vm); @@ -2702,13 +2738,14 @@ public class UserVmManagerImpl implements UserVmManager { try { poolId = _storageMgr.createUserVM(account, vm, template, dc, pod.first(), offering, diskOffering, a); } catch (CloudRuntimeException e) { +/* _vmDao.delete(vmId); +*/ _accountMgr.decrementResourceCount(account.getId(), ResourceType.user_vm); _accountMgr.decrementResourceCount(account.getId(), ResourceType.volume, numVolumes); if (s_logger.isDebugEnabled()) { s_logger.debug("Unable to find storage host in pod " + pod.first().getName() + " (id:" + pod.first().getId() + "), checking other pods"); } - avoids.add(pod.first().getId()); continue; // didn't find a storage host in pod, go to the next pod } break; // if we got here, we found a host and can stop searching the pods diff --git a/setup/bindir/cloud-migrate-snapshot.in b/setup/bindir/cloud-migrate-snapshot.in new file mode 100644 index 00000000000..7b0f309c083 --- /dev/null +++ b/setup/bindir/cloud-migrate-snapshot.in @@ -0,0 +1,158 @@ +#!/bin/bash +#set -x +Usage() { + echo "migrate snapshots created from CloudStack 2.1.3 to 2.1.4 and later:" + echo "$0 -m {secondary-storage mount point} " + exit 1 +} + +if [ "$#" -ne "2" ] +then + Usage +fi + +mountPath= + +while getopts m: OPTION +do + case $OPTION in + m) mountPath="$OPTARG" + ;; + *) + Usage + ;; + esac +done + +which vhd-util >> /dev/null +if [ $? -gt 0 ] +then + echo 'Cant find vhd-utils, please install it or running this tools on a xenserver host' + exit 2 +fi + +if [ ! -f $mountPath ] +then + echo "$mountPath does not exist, please specify a valid path" + exit 2 +fi + +mountPath=$mountPath/snapshots +if [ ! -f $mountPath ] +then + echo "No snapshots exit, nothing to do" + exit 0 +fi + +echo "0: sanity checking all the snapshots under $mountPath" +foundBadTemplt=0 + +for account in `ls $mountPath` +do + for templateId in `ls $mountPath/$account` + do + for template in `ls $mountPath/$account/$templateId` + do + templateFullName=$mountPath/$account/$templateId/$template + + vhd-util check -n $templateFullName >> /dev/null + if [ $? -gt 0 ] + then + echo "snapshot $templateFullName is bad" + foundBadTemplt=1 + fi + + done + done +done + +if [ "$foundBadTemplt" -eq "0" ] +then + echo "All the snapshots under $mountPath are OK" +fi + +# first round, rename template, removing the leading "VHD-" +echo "1: rename all the template to uuid.vhd" + +for account in `ls $mountPath` +do + for templateId in `ls $mountPath/$account` + do + for template in `ls $mountPath/$account/$templateId` + do + templateFullName=$mountPath/$account/$templateId/$template + + echo $template |grep VHD- >> /dev/null + if [ "$?" -eq "0" ] + then + newTemplateName=${template##VHD-}.vhd + mv $mountPath/$account/$templateId/$template $mountPath/$account/$templateId/$newTemplateName + fi + + done + done +done + +foundBadTemplt=0 + +echo "2: modify parent of all the template" + +for account in `ls $mountPath` +do + for templateId in `ls $mountPath/$account` + do + for template in `ls $mountPath/$account/$templateId` + do + templateFullName=$mountPath/$account/$templateId/$template + + vhd-util read -p -n $templateFullName |grep -a "Disk type" |grep -a "Differencing" >> /dev/null + if [ $? -gt 0 ] + then + #skip the one which doesn;t have parent + continue + fi + + parent=`vhd-util read -p -n $templateFullName|grep -a "Parent name"|cut -d : -f 2` + if [ $? -gt 0 ] + then + echo "Failed to get parent of $templateFullName" + continue + fi + + echo $parent |grep VHD- >> /dev/null + if [ $? -gt 0 ] + then + continue + fi + + parent=${parent##*VHD-}.vhd + parentFullName=$mountPath/$account/$templateId/$parent + if [ ! -f $parentFullName ] + then + echo "new parent $parentFullName does not exist, skip to change parent of $templateFullName" + continue + fi + + vhd-util modify -p $parentFullName -n $templateFullName + if [ $? -gt 0 ] + then + echo "Failed to change parent of $templateFullName to $parent" + continue + fi + + vhd-util check -n $templateFullName >> /dev/null + if [ $? -gt 0 ] + then + echo "snapshot $templateFullName is bad, after migration" + foundBadTemplt=1 + continiue + fi + + done + done +done + +if [ "$foundBadTemplt" -eq "0" ] +then + echo "All the snapshots under $mountPath are OK, after migration" +fi diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index a533ab41bc7..3dfae760213 100644 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -74,6 +74,26 @@ DROP TABLE IF EXISTS `cloud`.`storage_pool_details`; DROP TABLE IF EXISTS `cloud`.`ext_lun_details`; DROP TABLE IF EXISTS `cloud`.`cluster`; +/*DO NOT DELETE*/ +/* +DROP TABLE IF EXISTS `cloud`.`netapp_storage_pool`; + +CREATE TABLE `cloud`.`netapp_storage_pool` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', + `ip_address` varchar(15) NOT NULL COMMENT 'ip address of the pool/volume', + `pool_name` varchar(255) NOT NULL COMMENT 'name for the pool/volume', + `aggregate_name` varchar(255) NOT NULL COMMENT 'name for the aggregate', + `volume_name` varchar(255) NOT NULL COMMENT 'name for the volume', + `volume_size` varchar(255) NOT NULL COMMENT 'volume size', + `snapshot_policy` varchar(255) NOT NULL COMMENT 'snapshot policy', + `snapshot_reservation` int NOT NULL COMMENT 'snapshot reservation', + `username` varchar(255) NOT NULL COMMENT 'username', + `password` varchar(200) COMMENT 'password', + `round_robin_marker` int COMMENT 'This marks the volume to be picked up for lun creation, RR fashion', + PRIMARY KEY (`ip_address`,`aggregate_name`,`volume_name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +*/ + CREATE TABLE `cloud`.`cluster` ( `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', `name` varchar(255) NOT NULL COMMENT 'name for the cluster', @@ -478,7 +498,7 @@ CREATE TABLE `cloud`.`vm_instance` ( `private_mac_address` varchar(17), `private_ip_address` varchar(15), `private_netmask` varchar(15), - `pod_id` bigint unsigned NOT NULL, + `pod_id` bigint unsigned, `storage_ip` varchar(15), `data_center_id` bigint unsigned NOT NULL COMMENT 'Data Center the instance belongs to', `host_id` bigint unsigned, diff --git a/setup/db/schema-213to214.sql b/setup/db/schema-213to214.sql new file mode 100755 index 00000000000..8267613085c --- /dev/null +++ b/setup/db/schema-213to214.sql @@ -0,0 +1 @@ +ALTER TABLE `cloud`.`vm_instance` MODIFY COLUMN `pod_id` bigint unsigned; -- remove NOT NULL constraint to allow creating DB record in early time diff --git a/ui/css/jquery-ui-1.8.2.custom.css b/ui/css/jquery-ui.custom.css similarity index 100% rename from ui/css/jquery-ui-1.8.2.custom.css rename to ui/css/jquery-ui.custom.css diff --git a/ui/css/main.css b/ui/css/main.css index 6cf443c0e31..1337a9b7578 100644 --- a/ui/css/main.css +++ b/ui/css/main.css @@ -3482,7 +3482,52 @@ a:hover.add_publicipbutton { .loadingmessage_bottom { width:100%; - height:20px; + height:25px; + float:left; + margin:0; + padding:0; +} + +.loadingmessage_container_vm { + width:30%; + height:66px; + margin:0 auto; + padding:0; + z-index:1000; + float:left; + position:absolute; + background:url(../images/loading_messagebg.gif) #d3d3d3 repeat-x top left; + border:1px solid #CCC; + top:0; + left:38%; + display:inline; +} + + +.loadingmessage_top_vm { + width:99%; + height:45px; + float:left; + margin:0; + padding:2px 5px 0 5px; + overflow:hidden; +} + +.loadingmessage_top_vm p { + width:auto; + height:45px; + margin:0; + padding:0; + color:#333; + text-align:left; + font-weight:normal; + font-size:11px; + display:inline; +} + +.loadingmessage_bottom_vm { + width:100%; + height:25px; float:left; margin:0; padding:0; diff --git a/ui/index.jsp b/ui/index.jsp index 8be1f714663..a0ccc45fad8 100755 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -11,13 +11,12 @@ long milliseconds = new Date().getTime(); - cloud.com - User Console - + - - + + @@ -74,7 +73,7 @@ long milliseconds = new Date().getTime();
  1. - +
  2. diff --git a/ui/jsp/tab_configuration.jsp b/ui/jsp/tab_configuration.jsp index b178cbf314d..4c6a71e764e 100755 --- a/ui/jsp/tab_configuration.jsp +++ b/ui/jsp/tab_configuration.jsp @@ -434,8 +434,8 @@ long milliseconds = new Date().getTime();