From 503a5f2ccd773ab23358a662bac1bc9fc08a0d1f Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Fri, 21 Dec 2012 11:20:40 -0800 Subject: [PATCH 01/23] cli: Get rid of deprecated sets, go functional, use filter() Signed-off-by: Rohit Yadav --- tools/cli/cloudmonkey/cloudmonkey.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/cli/cloudmonkey/cloudmonkey.py b/tools/cli/cloudmonkey/cloudmonkey.py index e4fe76ff26f..edb62ccc801 100644 --- a/tools/cli/cloudmonkey/cloudmonkey.py +++ b/tools/cli/cloudmonkey/cloudmonkey.py @@ -26,7 +26,6 @@ try: import logging import os import pdb - import sets import shlex import sys import time @@ -332,8 +331,8 @@ class CloudMonkeyShell(cmd.Cmd, object): setattr(api_cmd, attribute, args_dict[attribute]) command = api_cmd() - missing_args = list(sets.Set(command.required).difference( - sets.Set(args_dict.keys()))) + missing_args = filter(lambda x: x not in args_dict.keys(), + command.required) if len(missing_args) > 0: self.print_shell("Missing arguments:", ' '.join(missing_args)) From 7926e66afae2fd1dbd1555fc5fba5688bd6e1ea6 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Fri, 26 Oct 2012 16:25:15 -0700 Subject: [PATCH 02/23] Redundant router: Fix wrong log attend to keepalived.log If something got wrong with passwd_server_ip script, it would output to keepalived.log, thus cause other scripts malfunctional. Also make savepassword.sh using the same lock as serve_password.sh. --- patches/systemvm/debian/config/opt/cloud/bin/passwd_server | 2 +- patches/systemvm/debian/config/root/savepassword.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/patches/systemvm/debian/config/opt/cloud/bin/passwd_server b/patches/systemvm/debian/config/opt/cloud/bin/passwd_server index 71349dd0336..0f4a7728874 100755 --- a/patches/systemvm/debian/config/opt/cloud/bin/passwd_server +++ b/patches/systemvm/debian/config/opt/cloud/bin/passwd_server @@ -19,5 +19,5 @@ ips=$(ip addr show dev eth0 | grep inet | grep eth0 | awk '{print $2}' ); echo $ips for ip in $ips; do addr=$(echo $ip | awk -F'/' '{print $1}') - /opt/cloud/bin/passwd_server_ip $addr & + /opt/cloud/bin/passwd_server_ip $addr >> /var/log/cloud.log 2>&1 & done; diff --git a/patches/systemvm/debian/config/root/savepassword.sh b/patches/systemvm/debian/config/root/savepassword.sh index 80a6928df0e..a096b862fce 100755 --- a/patches/systemvm/debian/config/root/savepassword.sh +++ b/patches/systemvm/debian/config/root/savepassword.sh @@ -24,7 +24,7 @@ source /root/func.sh -lock="biglock" +lock="passwdlock" locked=$(getLockFile $lock) if [ "$locked" != "1" ] then From 9f257aa60b62f24193bba3f7c902e7779632e01e Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Fri, 9 Nov 2012 18:59:32 -0800 Subject: [PATCH 03/23] Using different MAC for a pair of redundant routers In the past, we use same MAC address therefore once MASTER is down, the packet to the same MAC would go to BACKUP ASAP. But now we also have arping after BACKUP become MASTER, which should update the ARP cache of public gateway router quickly. Though it would be a little delay(likely less than 1 second), it's still fine for different MAC. And it would solve some cache issue for same mac on vSwitch different ports. --- .../VirtualNetworkApplianceManagerImpl.java | 26 +++++++++++++++---- server/src/com/cloud/vm/dao/NicDao.java | 2 ++ server/src/com/cloud/vm/dao/NicDaoImpl.java | 8 ++++++ 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 208bd9b7647..a91eda6cd31 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -1409,15 +1409,31 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian offeringId = _offering.getId(); } - PublicIp sourceNatIp = null; - if (publicNetwork) { - sourceNatIp = _networkMgr.assignSourceNatIpAddressToGuestNetwork(owner, guestNetwork); - } - // 3) deploy virtual router(s) int count = routerCount - routers.size(); DeploymentPlan plan = planAndRouters.first(); for (int i = 0; i < count; i++) { + PublicIp sourceNatIp = null; + if (publicNetwork) { + int failCount = 0; + // Generate different MAC for VR + while (sourceNatIp == null) { + sourceNatIp = _networkMgr.assignSourceNatIpAddressToGuestNetwork(owner, guestNetwork); + NicVO nic = _nicDao.findByMacAddress(sourceNatIp.getMacAddress()); + // We got duplicate MAC here, so regenerate the mac + if (nic != null) { + s_logger.debug("Failed to find a different mac for redundant router. Try again. The current mac is " + sourceNatIp.getMacAddress()); + sourceNatIp = null; + failCount ++; + } + //Prevent infinite loop + if (failCount > 3) { + s_logger.error("Failed to find a different mac for redundant router! Abort operation!"); + throw new InsufficientAddressCapacityException("Failed to find a different mac for redundant router", null, offeringId); + } + } + } + List> networks = createRouterNetworks(owner, isRedundant, plan, guestNetwork, new Pair(publicNetwork, sourceNatIp)); //don't start the router as we are holding the network lock that needs to be released at the end of router allocation diff --git a/server/src/com/cloud/vm/dao/NicDao.java b/server/src/com/cloud/vm/dao/NicDao.java index 762048b65bf..af3c7b379c1 100644 --- a/server/src/com/cloud/vm/dao/NicDao.java +++ b/server/src/com/cloud/vm/dao/NicDao.java @@ -58,4 +58,6 @@ public interface NicDao extends GenericDao { NicVO findByNetworkIdInstanceIdAndBroadcastUri(long networkId, long instanceId, String broadcastUri); NicVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId, long instanceId, String ip4Address); + + NicVO findByMacAddress(String macAddress); } diff --git a/server/src/com/cloud/vm/dao/NicDaoImpl.java b/server/src/com/cloud/vm/dao/NicDaoImpl.java index 3cd7fa6b488..00da2eb96a4 100644 --- a/server/src/com/cloud/vm/dao/NicDaoImpl.java +++ b/server/src/com/cloud/vm/dao/NicDaoImpl.java @@ -50,6 +50,7 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { AllFieldsSearch.and("address", AllFieldsSearch.entity().getIp4Address(), Op.EQ); AllFieldsSearch.and("isDefault", AllFieldsSearch.entity().isDefaultNic(), Op.EQ); AllFieldsSearch.and("broadcastUri", AllFieldsSearch.entity().getBroadcastUri(), Op.EQ); + AllFieldsSearch.and("macAddress", AllFieldsSearch.entity().getMacAddress(), Op.EQ); AllFieldsSearch.done(); IpSearch = createSearchBuilder(String.class); @@ -199,4 +200,11 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { sc.setParameters("address", ip4Address); return findOneBy(sc); } + + @Override + public NicVO findByMacAddress(String macAddress) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("macAddress", macAddress); + return findOneBy(sc); + } } From 5eba48919869720f98c1f4912de9d3686b092f49 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Tue, 13 Nov 2012 19:03:36 -0800 Subject: [PATCH 04/23] Redundant Router: Restart vpn related services when redundant router fail-over --- .../config/etc/init.d/cloud-early-config | 1 + .../root/redundant_router/disable_pubip.sh | 2 - .../redundant_router/enable_pubip.sh.templ | 4 +- .../root/redundant_router/master.sh.templ | 6 ++ .../config/root/redundant_router/services.sh | 62 +++++++++++++++++++ 5 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 patches/systemvm/debian/config/root/redundant_router/services.sh diff --git a/patches/systemvm/debian/config/etc/init.d/cloud-early-config b/patches/systemvm/debian/config/etc/init.d/cloud-early-config index 64459fd6118..fe536cbb5a9 100755 --- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config +++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config @@ -477,6 +477,7 @@ setup_redundant_router() { cp /root/redundant_router/check_bumpup.sh $rrouter_bin_path/ cp /root/redundant_router/disable_pubip.sh $rrouter_bin_path/ cp /root/redundant_router/checkrouter.sh.templ /opt/cloud/bin/checkrouter.sh + cp /root/redundant_router/services.sh $rrouter_bin_path/ sed -i "s/\[ROUTER_ID\]/$NAME/g" /etc/keepalived/keepalived.conf sed -i "s/\[ROUTER_IP\]/$GUEST_GW\/$GUEST_CIDR_SIZE/g" /etc/keepalived/keepalived.conf sed -i "s/\[BOARDCAST\]/$GUEST_BRD/g" /etc/keepalived/keepalived.conf diff --git a/patches/systemvm/debian/config/root/redundant_router/disable_pubip.sh b/patches/systemvm/debian/config/root/redundant_router/disable_pubip.sh index af5edbfd2a1..ee4e894ba69 100644 --- a/patches/systemvm/debian/config/root/redundant_router/disable_pubip.sh +++ b/patches/systemvm/debian/config/root/redundant_router/disable_pubip.sh @@ -21,5 +21,3 @@ while read i do ifconfig $i down done < /tmp/iflist -service cloud-passwd-srvr stop -service dnsmasq stop diff --git a/patches/systemvm/debian/config/root/redundant_router/enable_pubip.sh.templ b/patches/systemvm/debian/config/root/redundant_router/enable_pubip.sh.templ index ccdef0b7ea6..0e42ec4968a 100644 --- a/patches/systemvm/debian/config/root/redundant_router/enable_pubip.sh.templ +++ b/patches/systemvm/debian/config/root/redundant_router/enable_pubip.sh.templ @@ -30,6 +30,4 @@ do ifconfig $i up fi done < /tmp/iflist -ip route add default via [GATEWAY] dev eth2 && \ -service cloud-passwd-srvr restart && \ -service dnsmasq restart +ip route add default via [GATEWAY] dev eth2 diff --git a/patches/systemvm/debian/config/root/redundant_router/master.sh.templ b/patches/systemvm/debian/config/root/redundant_router/master.sh.templ index 418fd5d83b8..11ca6284f65 100644 --- a/patches/systemvm/debian/config/root/redundant_router/master.sh.templ +++ b/patches/systemvm/debian/config/root/redundant_router/master.sh.templ @@ -28,12 +28,18 @@ fi echo To master called >> [RROUTER_LOG] [RROUTER_BIN_PATH]/enable_pubip.sh >> [RROUTER_LOG] 2>&1 ret=$? +if [ $ret -eq 0 ] +then + [RROUTER_BIN_PATH]/services.sh restart >> [RROUTER_LOG] 2>&1 + ret=$? +fi last_msg=`tail -n 1 [RROUTER_LOG]` echo Enable public ip returned $ret >> [RROUTER_LOG] if [ $ret -ne 0 ] then echo Fail to enable public ip! >> [RROUTER_LOG] [RROUTER_BIN_PATH]/disable_pubip.sh >> [RROUTER_LOG] 2>&1 + [RROUTER_BIN_PATH]/services.sh stop >> [RROUTER_LOG] 2>&1 service keepalived stop >> [RROUTER_LOG] 2>&1 service conntrackd stop >> [RROUTER_LOG] 2>&1 echo Status: FAULT \($last_msg\) >> [RROUTER_LOG] diff --git a/patches/systemvm/debian/config/root/redundant_router/services.sh b/patches/systemvm/debian/config/root/redundant_router/services.sh new file mode 100644 index 00000000000..4d8949bcc00 --- /dev/null +++ b/patches/systemvm/debian/config/root/redundant_router/services.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# Copyright 2012 Citrix Systems, Inc. Licensed under the +# Apache License, Version 2.0 (the "License"); you may not use this +# file except in compliance with the License. Citrix Systems, Inc. +# reserves all rights not expressly granted by the License. +# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +vpn_service() { + ps aux|grep ipsec | grep -v grep > /dev/null + no_vpn=$? + if [ $no_vpn -eq 1 ] + then + return 0 + fi + r=0 + case "$1" in + stop) + service ipsec stop && \ + service xl2tpd stop + r=$? + ;; + restart) + service ipsec restart && \ + service xl2tpd restart + r=$? + ;; + esac + return $r +} + +ret=0 +case "$1" in + start) + vpn_service restart && \ + service cloud-passwd-srvr start && \ + service dnsmasq start + ret=$? + ;; + stop) + vpn_service stop && \ + service cloud-passwd-srvr stop && \ + service dnsmasq stop + ret=$? + ;; + restart) + vpn_service restart && \ + service cloud-passwd-srvr restart && \ + service dnsmasq restart + ret=$? + ;; + *) + echo "Usage: services {start|stop|restart}" + exit 1 + ;; +esac + +exit $ret From 96c7bbeb86fa0bf2cca720a11da74ba7f19bc0a3 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Wed, 14 Nov 2012 14:23:47 -0800 Subject: [PATCH 05/23] Update the router status after start network Start network can possible start the router as well. If it's already started by start network, then we won't need to start it again. --- .../network/router/VirtualNetworkApplianceManagerImpl.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index a91eda6cd31..966c32de6c2 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -2690,6 +2690,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } + //After start network, check if it's already running + router = _routerDao.findById(routerId); + if (router.getState() == State.Running) { + return router; + } + UserVO user = _userDao.findById(UserContext.current().getCallerUserId()); Map params = new HashMap(); if (reprogramNetwork) { From 911f8c33c5feb08138d5dc5ea502236b555849dc Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Tue, 11 Dec 2012 13:38:36 -0800 Subject: [PATCH 06/23] Fix broadcast address is 0.0.0.0 on additional public vlan issue --- patches/systemvm/debian/config/opt/cloud/bin/ipassoc.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/patches/systemvm/debian/config/opt/cloud/bin/ipassoc.sh b/patches/systemvm/debian/config/opt/cloud/bin/ipassoc.sh index c9a5e14e56b..5af5d9233a7 100755 --- a/patches/systemvm/debian/config/opt/cloud/bin/ipassoc.sh +++ b/patches/systemvm/debian/config/opt/cloud/bin/ipassoc.sh @@ -137,7 +137,7 @@ copy_routes_from_main() { ip_addr_add() { local dev="$1" local ip="$2" - sudo ip addr add dev $dev $ip > /dev/null + sudo ip addr add dev $dev $ip brd + > /dev/null } @@ -294,7 +294,7 @@ remove_an_ip () { then continue fi - sudo ip addr add dev $ethDev $ipMask + sudo ip addr add dev $ethDev $ipMask brd + done remove_routing $1 From 0b60dda1e6dc11af82a3abb8a351d2c818065989 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Fri, 21 Dec 2012 15:32:36 -0800 Subject: [PATCH 07/23] Correct the license information of services.sh --- .../config/root/redundant_router/services.sh | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/patches/systemvm/debian/config/root/redundant_router/services.sh b/patches/systemvm/debian/config/root/redundant_router/services.sh index 4d8949bcc00..b7ebeed264c 100644 --- a/patches/systemvm/debian/config/root/redundant_router/services.sh +++ b/patches/systemvm/debian/config/root/redundant_router/services.sh @@ -1,14 +1,20 @@ #!/bin/bash -# Copyright 2012 Citrix Systems, Inc. Licensed under the -# Apache License, Version 2.0 (the "License"); you may not use this -# file except in compliance with the License. Citrix Systems, Inc. -# reserves all rights not expressly granted by the License. -# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. vpn_service() { ps aux|grep ipsec | grep -v grep > /dev/null From d6083ce51dd53592073efd700186e9ac6a14fb7e Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Sat, 22 Dec 2012 13:01:44 -0800 Subject: [PATCH 08/23] Simulator: moving hypervisor simulator into plugin Simulator just like any hypervisor should be a plugin. resurrecting it to aid api refactoring tests. WIP Signed-off-by: Prasanna Santhanam --- plugins/hypervisors/simulator/pom.xml | 45 ++++++ .../src/com/cloud/agent/MetricsCollector.java | 48 +++--- .../src/com/cloud/agent/MockVmMetrics.java | 75 +++++----- .../src/com/cloud/agent/MultiCaster.java | 50 +++---- .../com/cloud/agent/MultiCasterListener.java | 0 .../src/com/cloud/agent/SimulatorCmd.java | 10 +- .../cloud/agent/SimulatorMigrateVmCmd.java | 10 +- .../cloud/agent/manager/MockAgentManager.java | 0 .../agent/manager/MockAgentManagerImpl.java | 0 .../agent/manager/MockStorageManager.java | 10 +- .../agent/manager/MockStorageManagerImpl.java | 8 +- .../cloud/agent/manager/MockVmManager.java | 18 +-- .../agent/manager/MockVmManagerImpl.java | 88 +++++------ .../cloud/agent/manager/SimulatorInfo.java | 16 +- .../cloud/agent/manager/SimulatorManager.java | 7 +- .../agent/manager/SimulatorManagerImpl.java | 76 +++++----- .../api/commands/ConfigureSimulator.java | 16 +- .../SimulatorComponentLibrary.java | 0 .../com/cloud/resource/AgentResourceBase.java | 44 +++--- .../cloud/resource/AgentRoutingResource.java | 48 +++--- .../cloud/resource/AgentStorageResource.java | 16 +- .../cloud/resource/SimulatorDiscoverer.java | 54 +++---- .../SimulatorSecondaryDiscoverer.java | 14 +- .../server/ManagementServerSimulatorImpl.java | 2 +- .../cloud/simulator/MockConfigurationVO.java | 43 +++--- .../src/com/cloud/simulator/MockHost.java | 44 +++--- .../src/com/cloud/simulator/MockHostVO.java | 138 +++++++++--------- .../com/cloud/simulator/MockSecStorageVO.java | 26 ++-- .../cloud/simulator/MockSecurityRulesVO.java | 38 ++--- .../cloud/simulator/MockStoragePoolVO.java | 36 ++--- .../src/com/cloud/simulator/MockVMVO.java | 56 +++---- .../src/com/cloud/simulator/MockVm.java | 15 +- .../src/com/cloud/simulator/MockVolumeVO.java | 38 ++--- .../com/cloud/simulator/SimulatorGuru.java | 6 +- .../simulator/SimulatorRuntimeException.java | 6 +- .../simulator/dao/MockConfigurationDao.java | 0 .../dao/MockConfigurationDaoImpl.java | 40 ++--- .../com/cloud/simulator/dao/MockHostDao.java | 0 .../cloud/simulator/dao/MockHostDaoImpl.java | 2 +- .../simulator/dao/MockSecStorageDao.java | 0 .../simulator/dao/MockSecStorageDaoImpl.java | 4 +- .../simulator/dao/MockSecurityRulesDao.java | 0 .../dao/MockSecurityRulesDaoImpl.java | 10 +- .../simulator/dao/MockStoragePoolDao.java | 0 .../simulator/dao/MockStoragePoolDaoImpl.java | 4 +- .../com/cloud/simulator/dao/MockVMDao.java | 0 .../cloud/simulator/dao/MockVMDaoImpl.java | 14 +- .../cloud/simulator/dao/MockVolumeDao.java | 0 .../simulator/dao/MockVolumeDaoImpl.java | 22 +-- plugins/pom.xml | 12 ++ 50 files changed, 631 insertions(+), 578 deletions(-) create mode 100644 plugins/hypervisors/simulator/pom.xml rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/agent/MetricsCollector.java (89%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/agent/MockVmMetrics.java (96%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/agent/MultiCaster.java (94%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/agent/MultiCasterListener.java (100%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/agent/SimulatorCmd.java (96%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/agent/SimulatorMigrateVmCmd.java (99%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/agent/manager/MockAgentManager.java (100%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/agent/manager/MockAgentManagerImpl.java (100%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/agent/manager/MockStorageManager.java (99%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/agent/manager/MockStorageManagerImpl.java (99%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/agent/manager/MockVmManager.java (98%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/agent/manager/MockVmManagerImpl.java (94%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/agent/manager/SimulatorInfo.java (98%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/agent/manager/SimulatorManager.java (97%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/agent/manager/SimulatorManagerImpl.java (88%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/api/commands/ConfigureSimulator.java (98%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/configuration/SimulatorComponentLibrary.java (100%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/resource/AgentResourceBase.java (98%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/resource/AgentRoutingResource.java (96%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/resource/AgentStorageResource.java (93%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/resource/SimulatorDiscoverer.java (94%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java (96%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/server/ManagementServerSimulatorImpl.java (99%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/MockConfigurationVO.java (96%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/MockHost.java (93%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/MockHostVO.java (94%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/MockSecStorageVO.java (96%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/MockSecurityRulesVO.java (96%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/MockStoragePoolVO.java (96%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/MockVMVO.java (93%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/MockVm.java (99%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/MockVolumeVO.java (96%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/SimulatorGuru.java (98%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/SimulatorRuntimeException.java (98%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/dao/MockConfigurationDao.java (100%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/dao/MockConfigurationDaoImpl.java (88%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/dao/MockHostDao.java (100%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/dao/MockHostDaoImpl.java (97%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/dao/MockSecStorageDao.java (100%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/dao/MockSecStorageDaoImpl.java (95%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/dao/MockSecurityRulesDao.java (100%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/dao/MockSecurityRulesDaoImpl.java (96%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/dao/MockStoragePoolDao.java (100%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/dao/MockStoragePoolDaoImpl.java (99%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/dao/MockVMDao.java (100%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/dao/MockVMDaoImpl.java (97%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/dao/MockVolumeDao.java (100%) rename {agent-simulator => plugins/hypervisors/simulator}/src/com/cloud/simulator/dao/MockVolumeDaoImpl.java (96%) diff --git a/plugins/hypervisors/simulator/pom.xml b/plugins/hypervisors/simulator/pom.xml new file mode 100644 index 00000000000..15b37900590 --- /dev/null +++ b/plugins/hypervisors/simulator/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + org.apache.cloudstack + cloudstack-plugins + 4.1.0-SNAPSHOT + ../../pom.xml + + org.apache.cloudstack + cloud-plugin-hypervisor-simulator + 4.1.0-SNAPSHOT + Apache CloudStack Plugin - Hypervisor Simulator + Simulator Hypervisor for Cloudstack + + install + src + test + + + + org.apache.cloudstack + cloud-utils + ${project.version} + + + \ No newline at end of file diff --git a/agent-simulator/src/com/cloud/agent/MetricsCollector.java b/plugins/hypervisors/simulator/src/com/cloud/agent/MetricsCollector.java similarity index 89% rename from agent-simulator/src/com/cloud/agent/MetricsCollector.java rename to plugins/hypervisors/simulator/src/com/cloud/agent/MetricsCollector.java index 7d86a0c8e3e..fd611f83b9f 100644 --- a/agent-simulator/src/com/cloud/agent/MetricsCollector.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/MetricsCollector.java @@ -30,43 +30,43 @@ import com.cloud.utils.concurrency.NamedThreadFactory; public class MetricsCollector { private static final Logger s_logger = Logger.getLogger(MetricsCollector.class); - + private final Set vmNames = new HashSet(); private final Set newVMnames = new HashSet(); private final Map metricsMap = new HashMap(); - + private final transient ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("Metrics")); private Set _currentVms; - + public MetricsCollector(Set currentVms) { _currentVms = currentVms; getAllVMNames(); } - + public MetricsCollector() { - + } - + public synchronized void getAllVMNames() { Set currentVMs = _currentVms; - + newVMnames.clear(); newVMnames.addAll(currentVMs); newVMnames.removeAll(vmNames); //leave only new vms - + vmNames.removeAll(currentVMs); //old vms - current vms --> leave non-running vms; for (String vm: vmNames) { - removeVM(vm); + removeVM(vm); } - + vmNames.clear(); vmNames.addAll(currentVMs); } - + public synchronized void submitMetricsJobs() { s_logger.debug("Submit Metric Jobs called"); - + for (String vm : newVMnames) { MockVmMetrics task = new MockVmMetrics(vm); if (!metricsMap.containsKey(vm)) { @@ -77,30 +77,30 @@ public class MetricsCollector { } newVMnames.clear(); } - + public synchronized void addVM(String vmName) { newVMnames.add(vmName); s_logger.debug("Added vm name= " + vmName); } - + public synchronized void removeVM(String vmName) { newVMnames.remove(vmName); vmNames.remove(vmName); MockVmMetrics task = metricsMap.get(vmName); - if (task != null) { - task.stop(); - boolean r1= task.getFuture().cancel(false); - metricsMap.remove(vmName); - s_logger.debug("removeVM: cancel returned " + r1 + " for VM " + vmName); - } else { - s_logger.warn("removeVM called for nonexistent VM " + vmName); - } + if (task != null) { + task.stop(); + boolean r1= task.getFuture().cancel(false); + metricsMap.remove(vmName); + s_logger.debug("removeVM: cancel returned " + r1 + " for VM " + vmName); + } else { + s_logger.warn("removeVM called for nonexistent VM " + vmName); } - + } + public synchronized Set getVMNames() { return vmNames; } - + public synchronized Map getMetricsMap() { return metricsMap; } diff --git a/agent-simulator/src/com/cloud/agent/MockVmMetrics.java b/plugins/hypervisors/simulator/src/com/cloud/agent/MockVmMetrics.java similarity index 96% rename from agent-simulator/src/com/cloud/agent/MockVmMetrics.java rename to plugins/hypervisors/simulator/src/com/cloud/agent/MockVmMetrics.java index f106f367a9c..30b99e753a1 100644 --- a/agent-simulator/src/com/cloud/agent/MockVmMetrics.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/MockVmMetrics.java @@ -25,52 +25,52 @@ import org.apache.log4j.Logger; public class MockVmMetrics implements Runnable { private static final Logger s_logger = Logger.getLogger(MockVmMetrics.class); - + private String vmName; - + public final int MAX_INTERFACES=1; - + public final int MAX_DISKS=8; - + //the last calculated traffic speed (transmit) per interface private Map netTxKBps = new HashMap(); - + //the last calculated traffic speed (receive) per interface private Map netRxKBps = new HashMap(); - + //the last calculated disk write speed per disk (Bytes Per Second) private Map diskWriteKBytesPerSec = new HashMap(); - + //the last calculated disk read speed per disk (Bytes Per Second) private Map diskReadKBytesPerSec = new HashMap(); - + //Total Bytes Transmitted on network interfaces private Map netTxTotalBytes = new HashMap(); - + //Total Bytes Received on network interfaces private Map netRxTotalBytes = new HashMap(); - + //Total Bytes read per disk private Map diskReadTotalBytes = new HashMap(); //Total Bytes written per disk private Map diskWriteTotalBytes = new HashMap(); - + //CPU time in seconds private Double cpuSeconds = new Double(0.0); - + //CPU percentage private Float cpuPercent = new Float(0.0); - + private Map diskMap = new HashMap(); private Map vifMap = new HashMap(); - + private Map diskStatTimestamp = new HashMap(); private Map netStatTimestamp = new HashMap(); - + private long cpuStatTimestamp = 0L; - + private ScheduledFuture future; private boolean stopped = false; private Random randSeed = new Random(); @@ -80,44 +80,44 @@ public class MockVmMetrics implements Runnable { vifMap.put("eth0", "eth0"); vifMap.put("eth1", "eth1"); vifMap.put("eth2", "eth2"); - + Long networkStart = 0L; netTxTotalBytes.put("eth0", networkStart); netRxTotalBytes.put("eth0", networkStart); - + netTxTotalBytes.put("eth1", networkStart); netRxTotalBytes.put("eth1", networkStart); - + netTxTotalBytes.put("eth2", networkStart); - netRxTotalBytes.put("eth2", networkStart); + netRxTotalBytes.put("eth2", networkStart); } - + private int getIncrementor() { return randSeed.nextInt(100); } - + @Override public void run() { if(s_logger.isDebugEnabled()) { s_logger.debug("Generating MockVM metrics"); } for (Map.Entry entry : netRxTotalBytes.entrySet()) { - entry.setValue(entry.getValue() + getIncrementor()); + entry.setValue(entry.getValue() + getIncrementor()); } - + for (Map.Entry entry : netTxTotalBytes.entrySet()) { entry.setValue(entry.getValue() + getIncrementor()); } } - + public String getVmName() { return vmName; } - + public Map getNetTxKBps() { return netTxKBps; } - + public Map getNetRxKBps() { return netRxKBps; } @@ -125,11 +125,11 @@ public class MockVmMetrics implements Runnable { public Map getDiskWriteBytesPerSec() { return diskWriteKBytesPerSec; } - + public Map getDiskReadBytesPerSec() { return diskReadKBytesPerSec; } - + public Map getNetTxTotalBytes() { return netTxTotalBytes; } @@ -137,7 +137,7 @@ public class MockVmMetrics implements Runnable { public Map getNetRxTotalBytes() { return netRxTotalBytes; } - + public Map getDiskReadTotalBytes() { return diskReadTotalBytes; } @@ -145,7 +145,7 @@ public class MockVmMetrics implements Runnable { public Map getDiskWriteTotalBytes() { return diskWriteTotalBytes; } - + public Double getNetTxKBps(String intf) { return netTxKBps.get(intf); } @@ -153,7 +153,7 @@ public class MockVmMetrics implements Runnable { public Double getNetRxKBps(String intf) { return netRxKBps.get(intf); } - + public Double getDiskWriteKBytesPerSec(String disk) { return diskWriteKBytesPerSec.get(disk); } @@ -161,7 +161,7 @@ public class MockVmMetrics implements Runnable { public Double getDiskReadKBytesPerSec(String disk) { return diskReadKBytesPerSec.get(disk); } - + public Long getNetTxTotalBytes(String intf) { return netTxTotalBytes.get(intf); } @@ -169,7 +169,7 @@ public class MockVmMetrics implements Runnable { public Long getNetRxTotalBytes(String intf) { return netRxTotalBytes.get(intf); } - + public Long getDiskReadTotalBytes(String disk) { return diskReadTotalBytes.get(disk); } @@ -177,7 +177,7 @@ public class MockVmMetrics implements Runnable { public Long getDiskWriteTotalBytes(String disk) { return diskWriteTotalBytes.get(disk); } - + public Double getCpuSeconds() { return cpuSeconds; } @@ -189,7 +189,7 @@ public class MockVmMetrics implements Runnable { public Float getCpuPercent() { return cpuPercent; } - + public void setFuture(ScheduledFuture sf) { this.future = sf; } @@ -197,9 +197,8 @@ public class MockVmMetrics implements Runnable { public ScheduledFuture getFuture() { return future; } - + public void stop() { this.stopped = true; } } - diff --git a/agent-simulator/src/com/cloud/agent/MultiCaster.java b/plugins/hypervisors/simulator/src/com/cloud/agent/MultiCaster.java similarity index 94% rename from agent-simulator/src/com/cloud/agent/MultiCaster.java rename to plugins/hypervisors/simulator/src/com/cloud/agent/MultiCaster.java index 9c98ef651be..7d38baf0e68 100644 --- a/agent-simulator/src/com/cloud/agent/MultiCaster.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/MultiCaster.java @@ -30,49 +30,49 @@ import org.apache.log4j.Logger; public class MultiCaster implements Runnable { private static final Logger s_logger = Logger.getLogger(MultiCaster.class); - + public final int MAX_PACKET_SIZE = 8096; - + private List listeners; private DatagramSocket socket; private byte[] recvBuffer; - + private Thread driver; private volatile boolean stopRequested = false; - + public MultiCaster() { listeners = new ArrayList(); recvBuffer = new byte[MAX_PACKET_SIZE]; } - + public void addListener(MultiCasterListener listener) { synchronized(listeners) { listeners.add(listener); } } - + public void removeListener(MultiCasterListener listener) { synchronized(listeners) { listeners.remove(listener); } } - - public void cast(byte[] buf, int off, int len, + + public void cast(byte[] buf, int off, int len, InetAddress toAddress, int nToPort) throws IOException { - + if(socket == null) throw new IOException("multi caster is not started"); - + if(len >= MAX_PACKET_SIZE) throw new IOException("packet size exceeds limit of " + MAX_PACKET_SIZE); - - DatagramPacket packet = new DatagramPacket(buf, off, + + DatagramPacket packet = new DatagramPacket(buf, off, len, toAddress, nToPort); socket.send(packet); } - - public void start(String strOutboundAddress, + + public void start(String strOutboundAddress, String strClusterAddress, int nPort) throws SocketException { assert(socket == null); @@ -82,22 +82,22 @@ public class MultiCaster implements Runnable { } catch(IOException e) { s_logger.error("Unexpected exception " , e); } - + if(addr != null && addr.isMulticastAddress()) { try { socket = new MulticastSocket(nPort); socket.setReuseAddress(true); - + if(s_logger.isInfoEnabled()) s_logger.info("Join multicast group : " + addr); - + ((MulticastSocket)socket).joinGroup(addr); ((MulticastSocket)socket).setTimeToLive(1); - + if(strOutboundAddress != null) { if(s_logger.isInfoEnabled()) s_logger.info("set outgoing interface to : " + strOutboundAddress); - + InetAddress ia = InetAddress.getByName(strOutboundAddress); NetworkInterface ni = NetworkInterface.getByInetAddress(ia); ((MulticastSocket)socket).setNetworkInterface(ni); @@ -109,16 +109,16 @@ public class MultiCaster implements Runnable { socket = new DatagramSocket(nPort); socket.setReuseAddress(true); } - + driver = new Thread(this, "Multi-caster"); driver.setDaemon(true); driver.start(); } - + public void stop() { if(socket != null) { stopRequested = true; - + socket.close(); if(driver != null) { try { @@ -128,17 +128,17 @@ public class MultiCaster implements Runnable { driver = null; } } - + socket = null; stopRequested = false; } - + public void run() { while(!stopRequested) { try { DatagramPacket packet = new DatagramPacket(recvBuffer, recvBuffer.length); socket.receive(packet); - + for(Object listener : listeners.toArray()) { ((MultiCasterListener)listener).onMultiCasting(packet.getData(), packet.getOffset(), packet.getLength(), packet.getAddress()); diff --git a/agent-simulator/src/com/cloud/agent/MultiCasterListener.java b/plugins/hypervisors/simulator/src/com/cloud/agent/MultiCasterListener.java similarity index 100% rename from agent-simulator/src/com/cloud/agent/MultiCasterListener.java rename to plugins/hypervisors/simulator/src/com/cloud/agent/MultiCasterListener.java diff --git a/agent-simulator/src/com/cloud/agent/SimulatorCmd.java b/plugins/hypervisors/simulator/src/com/cloud/agent/SimulatorCmd.java similarity index 96% rename from agent-simulator/src/com/cloud/agent/SimulatorCmd.java rename to plugins/hypervisors/simulator/src/com/cloud/agent/SimulatorCmd.java index 342bfd2491e..caed518dd78 100644 --- a/agent-simulator/src/com/cloud/agent/SimulatorCmd.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/SimulatorCmd.java @@ -20,17 +20,17 @@ import java.io.Serializable; public class SimulatorCmd implements Serializable { private static final long serialVersionUID = 1L; - + private String testCase = "DEFAULT"; - + public SimulatorCmd(String testCase) { - this.testCase = testCase; + this.testCase = testCase; } - + public String getTestCase() { return testCase; } - + public void setTestCase(String testCase) { this.testCase = testCase; } diff --git a/agent-simulator/src/com/cloud/agent/SimulatorMigrateVmCmd.java b/plugins/hypervisors/simulator/src/com/cloud/agent/SimulatorMigrateVmCmd.java similarity index 99% rename from agent-simulator/src/com/cloud/agent/SimulatorMigrateVmCmd.java rename to plugins/hypervisors/simulator/src/com/cloud/agent/SimulatorMigrateVmCmd.java index f86b16ee7d4..6a2190d696a 100644 --- a/agent-simulator/src/com/cloud/agent/SimulatorMigrateVmCmd.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/SimulatorMigrateVmCmd.java @@ -21,12 +21,12 @@ public class SimulatorMigrateVmCmd extends SimulatorCmd { private static final long serialVersionUID = 1L; private String destIp; - + private String vmName; private long ramSize; private int cpuCount; private int utilization; - + public SimulatorMigrateVmCmd(String testCase) { super(testCase); } @@ -38,7 +38,7 @@ public class SimulatorMigrateVmCmd extends SimulatorCmd { public void setDestIp(String destIp) { this.destIp = destIp; } - + public String getVmName() { return vmName; } @@ -70,14 +70,14 @@ public class SimulatorMigrateVmCmd extends SimulatorCmd { public void setUtilization(int utilization) { this.utilization = utilization; } - + public String toString() { StringBuffer sb = new StringBuffer(); sb.append("SimulatorMigrateVmCmd {").append("vm: ").append(getVmName()); sb.append(", destIp: ").append(getDestIp()).append(", ramSize: ").append(getRamSize()); sb.append(", cpuCount: ").append(getCpuCount()).append(", utilization: ").append(getUtilization()); sb.append("}"); - + return sb.toString(); } } diff --git a/agent-simulator/src/com/cloud/agent/manager/MockAgentManager.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManager.java similarity index 100% rename from agent-simulator/src/com/cloud/agent/manager/MockAgentManager.java rename to plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManager.java diff --git a/agent-simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java similarity index 100% rename from agent-simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java rename to plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java diff --git a/agent-simulator/src/com/cloud/agent/manager/MockStorageManager.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java similarity index 99% rename from agent-simulator/src/com/cloud/agent/manager/MockStorageManager.java rename to plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java index 3b7a286c5e1..fc8aacc6ec3 100644 --- a/agent-simulator/src/com/cloud/agent/manager/MockStorageManager.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java @@ -51,17 +51,17 @@ import com.cloud.utils.component.Manager; public interface MockStorageManager extends Manager { public static final long DEFAULT_HOST_STORAGE_SIZE = 1 * 1024 * 1024 * 1024 * 1024L; //1T public static final long DEFAULT_TEMPLATE_SIZE = 1 * 1000 * 1000 * 1000L; //1G - + public PrimaryStorageDownloadAnswer primaryStorageDownload(PrimaryStorageDownloadCommand cmd); - + public CreateAnswer createVolume(CreateCommand cmd); public AttachVolumeAnswer AttachVolume(AttachVolumeCommand cmd); public Answer AttachIso(AttachIsoCommand cmd); - + public Answer DeleteStoragePool(DeleteStoragePoolCommand cmd); public Answer ModifyStoragePool(ModifyStoragePoolCommand cmd); public Answer CreateStoragePool(CreateStoragePoolCommand cmd); - + public Answer SecStorageSetup(SecStorageSetupCommand cmd); public Answer ListTemplates(ListTemplateCommand cmd); public Answer Destroy(DestroyCommand cmd); @@ -74,7 +74,7 @@ public interface MockStorageManager extends Manager { public Answer CreateVolumeFromSnapshot(CreateVolumeFromSnapshotCommand cmd); public Answer DeleteTemplate(DeleteTemplateCommand cmd); public Answer SecStorageVMSetup(SecStorageVMSetupCommand cmd); - + public void preinstallTemplates(String url, long zoneId); StoragePoolInfo getLocalStorage(String hostGuid); diff --git a/agent-simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java similarity index 99% rename from agent-simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java rename to plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java index cc15b206738..9bf4192c4bd 100644 --- a/agent-simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java @@ -703,7 +703,7 @@ public class MockStorageManagerImpl implements MockStorageManager { txn = Transaction.open(Transaction.CLOUD_DB); txn.close(); } - + MockVolumeVO newsnapshot = new MockVolumeVO(); String name = UUID.randomUUID().toString(); newsnapshot.setName(name); @@ -953,7 +953,7 @@ public class MockStorageManagerImpl implements MockStorageManager { @Override public StoragePoolInfo getLocalStorage(String hostGuid) { Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); - MockHost host = null; + MockHost host = null; MockStoragePoolVO storagePool = null; try { txn.start(); @@ -968,7 +968,7 @@ public class MockStorageManagerImpl implements MockStorageManager { txn = Transaction.open(Transaction.CLOUD_DB); txn.close(); } - + if (storagePool == null) { String uuid = UUID.randomUUID().toString(); storagePool = new MockStoragePoolVO(); @@ -998,7 +998,7 @@ public class MockStorageManagerImpl implements MockStorageManager { @Override public StoragePoolInfo getLocalStorage(String hostGuid, Long storageSize) { Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); - MockHost host = null; + MockHost host = null; try { txn.start(); host = _mockHostDao.findByGuid(hostGuid); diff --git a/agent-simulator/src/com/cloud/agent/manager/MockVmManager.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManager.java similarity index 98% rename from agent-simulator/src/com/cloud/agent/manager/MockVmManager.java rename to plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManager.java index 07cf584883e..82f600d04b3 100644 --- a/agent-simulator/src/com/cloud/agent/manager/MockVmManager.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManager.java @@ -40,7 +40,7 @@ import com.cloud.vm.VirtualMachine.State; public interface MockVmManager extends Manager { public Answer stopVM(StopCommand cmd); public Answer rebootVM(RebootCommand cmd); - + public Answer checkVmState(CheckVirtualMachineCommand cmd); public Map getVmStates(String hostGuid); public Answer getVncPort(GetVncPortCommand cmd); @@ -49,27 +49,27 @@ public interface MockVmManager extends Manager { Answer getVmStats(GetVmStatsCommand cmd); public CheckSshAnswer checkSshCommand(CheckSshCommand cmd); - + Answer SetStaticNatRules(SetStaticNatRulesCommand cmd); - + Answer SetPortForwardingRules(SetPortForwardingRulesCommand cmd); Answer SetFirewallRules(SetFirewallRulesCommand cmd); - + Answer getNetworkUsage(NetworkUsageCommand cmd); - + Answer IpAssoc(IpAssocCommand cmd); Answer LoadBalancerConfig(LoadBalancerConfigCommand cmd); - + Answer AddDhcpEntry(DhcpEntryCommand cmd); - + Answer setVmData(VmDataCommand cmd); Answer CleanupNetworkRules(CleanupNetworkRulesCmd cmd, SimulatorInfo info); - + Answer CheckConsoleProxyLoad(CheckConsoleProxyLoadCommand cmd); Answer WatchConsoleProxyLoad(WatchConsoleProxyLoadCommand cmd); - + Answer SavePassword(SavePasswordCommand cmd); HashMap> syncNetworkGroups(SimulatorInfo info); SecurityGroupRuleAnswer AddSecurityGroupRules(SecurityGroupRulesCmd cmd, SimulatorInfo info); diff --git a/agent-simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java similarity index 94% rename from agent-simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java rename to plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java index 78881f2fc3a..8177cda6b64 100644 --- a/agent-simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java @@ -60,20 +60,20 @@ public class MockVmManagerImpl implements MockVmManager { @Inject MockHostDao _mockHostDao = null; @Inject MockSecurityRulesDao _mockSecurityDao = null; private Map>> _securityRules = new ConcurrentHashMap>>(); - + public MockVmManagerImpl() { } - + @Override public boolean configure(String name, Map params) throws ConfigurationException { - + return true; } - + public String startVM(String vmName, NicTO[] nics, - int cpuHz, long ramSize, - String bootArgs, String hostGuid) { + int cpuHz, long ramSize, + String bootArgs, String hostGuid) { Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); MockHost host = null; @@ -95,7 +95,7 @@ public class MockVmManagerImpl implements MockVmManager { txn = Transaction.open(Transaction.CLOUD_DB); txn.close(); } - + if(vm == null) { int vncPort = 0; if(vncPort < 0) @@ -108,13 +108,13 @@ public class MockVmManagerImpl implements MockVmManager { vm.setVncPort(vncPort); vm.setHostId(host.getId()); if(vmName.startsWith("s-")) { - vm.setType("SecondaryStorageVm"); + vm.setType("SecondaryStorageVm"); } else if (vmName.startsWith("v-")) { - vm.setType("ConsoleProxy"); + vm.setType("ConsoleProxy"); } else if (vmName.startsWith("r-")) { - vm.setType("DomainRouter"); + vm.setType("DomainRouter"); } else if (vmName.startsWith("i-")) { - vm.setType("User"); + vm.setType("User"); } txn = Transaction.open(Transaction.SIMULATOR_DB); try { @@ -133,18 +133,18 @@ public class MockVmManagerImpl implements MockVmManager { if(vm.getState() == State.Stopped) { vm.setState(State.Running); txn = Transaction.open(Transaction.SIMULATOR_DB); - try { - txn.start(); - _mockVmDao.update(vm.getId(), (MockVMVO)vm); - txn.commit(); - } catch (Exception ex) { - txn.rollback(); - throw new CloudRuntimeException("unable to update vm " + vm.getName(), ex); - } finally { - txn.close(); + try { + txn.start(); + _mockVmDao.update(vm.getId(), (MockVMVO)vm); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("unable to update vm " + vm.getName(), ex); + } finally { + txn.close(); txn = Transaction.open(Transaction.CLOUD_DB); txn.close(); - } + } } } @@ -212,7 +212,7 @@ public class MockVmManagerImpl implements MockVmManager { } return true; } - + @Override public Map getVms(String hostGuid) { Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); @@ -303,8 +303,8 @@ public class MockVmManagerImpl implements MockVmManager { @Override public String getName() { return this.getClass().getSimpleName(); - } - + } + @Override public Answer getVmStats(GetVmStatsCommand cmd) { HashMap vmStatsNameMap = new HashMap(); @@ -370,9 +370,9 @@ public class MockVmManagerImpl implements MockVmManager { @Override public Answer SetFirewallRules(SetFirewallRulesCommand cmd) { - return new Answer(cmd); + return new Answer(cmd); } - + @Override public NetworkUsageAnswer getNetworkUsage(NetworkUsageCommand cmd) { @@ -516,20 +516,20 @@ public class MockVmManagerImpl implements MockVmManager { public Answer WatchConsoleProxyLoad(WatchConsoleProxyLoadCommand cmd) { return Answer.createUnsupportedCommandAnswer(cmd); } - + @Override public GetDomRVersionAnswer getDomRVersion(GetDomRVersionCmd cmd) { - return new GetDomRVersionAnswer(cmd, null, null, null); + return new GetDomRVersionAnswer(cmd, null, null, null); } @Override public SecurityGroupRuleAnswer AddSecurityGroupRules(SecurityGroupRulesCmd cmd, SimulatorInfo info) { if (!info.isEnabled()) { - return new SecurityGroupRuleAnswer(cmd, false, "Disabled", SecurityGroupRuleAnswer.FailureReason.CANNOT_BRIDGE_FIREWALL); + return new SecurityGroupRuleAnswer(cmd, false, "Disabled", SecurityGroupRuleAnswer.FailureReason.CANNOT_BRIDGE_FIREWALL); } - + Map> rules = _securityRules.get(info.getHostUuid()); - + if (rules == null) { logSecurityGroupAction(cmd, null); rules = new ConcurrentHashMap>(); @@ -539,10 +539,10 @@ public class MockVmManagerImpl implements MockVmManager { logSecurityGroupAction(cmd, rules.get(cmd.getVmName())); rules.put(cmd.getVmName(), new Ternary(cmd.getSignature(), cmd.getVmId(), cmd.getSeqNum())); } - + return new SecurityGroupRuleAnswer(cmd); } - + private boolean logSecurityGroupAction(SecurityGroupRulesCmd cmd, Ternary rule) { String action = ", do nothing"; String reason = ", reason="; @@ -554,13 +554,13 @@ public class MockVmManagerImpl implements MockVmManager { s_logger.info("New seqno received: " + cmd.getSeqNum() + " curr=" + currSeqnum); updateSeqnoAndSig = true; if (!cmd.getSignature().equals(currSig)) { - s_logger.info("New seqno received: " + cmd.getSeqNum() + " curr=" + currSeqnum + s_logger.info("New seqno received: " + cmd.getSeqNum() + " curr=" + currSeqnum + " new signature received:" + cmd.getSignature() + " curr=" + currSig + ", updated iptables"); action = ", updated iptables"; reason = reason + "seqno_increased_sig_changed"; } else { - s_logger.info("New seqno received: " + cmd.getSeqNum() + " curr=" + currSeqnum - + " no change in signature:" + cmd.getSignature() + ", do nothing"); + s_logger.info("New seqno received: " + cmd.getSeqNum() + " curr=" + currSeqnum + + " no change in signature:" + cmd.getSignature() + ", do nothing"); reason = reason + "seqno_increased_sig_same"; } } else if (cmd.getSeqNum() < currSeqnum) { @@ -568,14 +568,14 @@ public class MockVmManagerImpl implements MockVmManager { reason = reason + "seqno_decreased"; } else { if (!cmd.getSignature().equals(currSig)) { - s_logger.info("Identical seqno received: " + cmd.getSeqNum() + s_logger.info("Identical seqno received: " + cmd.getSeqNum() + " new signature received:" + cmd.getSignature() + " curr=" + currSig + ", updated iptables"); action = ", updated iptables"; reason = reason + "seqno_same_sig_changed"; updateSeqnoAndSig = true; } else { - s_logger.info("Identical seqno received: " + cmd.getSeqNum() + " curr=" + currSeqnum - + " no change in signature:" + cmd.getSignature() + ", do nothing"); + s_logger.info("Identical seqno received: " + cmd.getSeqNum() + " curr=" + currSeqnum + + " no change in signature:" + cmd.getSignature() + ", do nothing"); reason = reason + "seqno_same_sig_same"; } } @@ -585,8 +585,8 @@ public class MockVmManagerImpl implements MockVmManager { action = ", updated iptables"; reason = ", seqno_new"; } - s_logger.info("Programmed network rules for vm " + cmd.getVmName() + " seqno=" + cmd.getSeqNum() - + " signature=" + cmd.getSignature() + s_logger.info("Programmed network rules for vm " + cmd.getVmName() + " seqno=" + cmd.getSeqNum() + + " signature=" + cmd.getSignature() + " guestIp=" + cmd.getGuestIp() + ", numIngressRules=" + cmd.getIngressRuleSet().length + ", numEgressRules=" + cmd.getEgressRuleSet().length + " total cidrs=" + cmd.getTotalNumCidrs() + action + reason); @@ -595,13 +595,13 @@ public class MockVmManagerImpl implements MockVmManager { @Override public Answer SavePassword(SavePasswordCommand cmd) { - return new Answer(cmd); + return new Answer(cmd); } - + @Override public HashMap> syncNetworkGroups(SimulatorInfo info) { HashMap> maps = new HashMap>(); - + Map> rules = _securityRules.get(info.getHostUuid()); if (rules == null) { return maps; diff --git a/agent-simulator/src/com/cloud/agent/manager/SimulatorInfo.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorInfo.java similarity index 98% rename from agent-simulator/src/com/cloud/agent/manager/SimulatorInfo.java rename to plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorInfo.java index dafd33abb51..c084730c6bb 100644 --- a/agent-simulator/src/com/cloud/agent/manager/SimulatorInfo.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorInfo.java @@ -20,39 +20,39 @@ public class SimulatorInfo { private boolean enabled; private int timeout; private String hostUuid; - + public SimulatorInfo(boolean enabled, int timeout, String hostUuid) { this.enabled = enabled; this.timeout = timeout; this.hostUuid = hostUuid; } - + public SimulatorInfo() { this.enabled = true; this.timeout = -1; this.hostUuid = null; } - + public boolean isEnabled() { return this.enabled; } - + public int getTimeout() { return this.timeout; } - + public String getHostUuid() { return this.hostUuid; } - + public void setEnabled(boolean enabled) { this.enabled = enabled; } - + public void setTimeout(int timeout) { this.timeout = timeout; } - + public void setHostUuid(String hostUuid) { this.hostUuid = hostUuid; } diff --git a/agent-simulator/src/com/cloud/agent/manager/SimulatorManager.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManager.java similarity index 97% rename from agent-simulator/src/com/cloud/agent/manager/SimulatorManager.java rename to plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManager.java index 2b31b14d32f..ff8c32ce185 100755 --- a/agent-simulator/src/com/cloud/agent/manager/SimulatorManager.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManager.java @@ -23,7 +23,6 @@ import java.util.Map; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.StoragePoolInfo; -import com.cloud.agent.mockvm.MockVm; import com.cloud.simulator.MockVMVO; import com.cloud.utils.Pair; import com.cloud.utils.component.Manager; @@ -31,10 +30,10 @@ import com.cloud.vm.VirtualMachine.State; public interface SimulatorManager extends Manager { public static final String Name = "simulator manager"; - + public enum AgentType { Computing(0), // not used anymore - Routing(1), + Routing(1), Storage(2); int value; @@ -56,7 +55,7 @@ public interface SimulatorManager extends Manager { Answer simulate(Command cmd, String hostGuid); StoragePoolInfo getLocalStorage(String hostGuid); - + boolean configureSimulator(Long zoneId, Long podId, Long clusterId, Long hostId, String command, String values); public HashMap> syncNetworkGroups(String hostGuid); diff --git a/agent-simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java similarity index 88% rename from agent-simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java rename to plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java index 9a81ea6edaa..a32da34f0a9 100644 --- a/agent-simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java @@ -121,43 +121,43 @@ public class SimulatorManagerImpl implements SimulatorManager { public Answer simulate(Command cmd, String hostGuid) { Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); // txn.transitToUserManagedConnection(_concierge.conn()); - + try { MockHost host = _mockHost.findByGuid(hostGuid); String cmdName = cmd.toString(); int index = cmdName.lastIndexOf("."); if (index != -1) { - cmdName = cmdName.substring(index + 1); + cmdName = cmdName.substring(index + 1); } MockConfigurationVO config = _mockConfigDao.findByNameBottomUP(host.getDataCenterId(), host.getPodId(), host.getClusterId(), host.getId(), cmdName); - + SimulatorInfo info = new SimulatorInfo(); info.setHostUuid(hostGuid); - + if (config != null) { Map configParameters = config.getParameters(); for (Map.Entry entry : configParameters.entrySet()) { - if (entry.getKey().equalsIgnoreCase("enabled")) { - info.setEnabled(Boolean.parseBoolean(entry.getValue())); - } else if (entry.getKey().equalsIgnoreCase("timeout")) { - try { - info.setTimeout(Integer.valueOf(entry.getValue())); - } catch (NumberFormatException e) { - s_logger.debug("invalid timeout parameter: " + e.toString()); - } - } else if (entry.getKey().equalsIgnoreCase("wait")) { - try { - int wait = Integer.valueOf(entry.getValue()); - Thread.sleep(wait * 1000); - } catch (NumberFormatException e) { - s_logger.debug("invalid timeout parameter: " + e.toString()); - } catch (InterruptedException e) { - s_logger.debug("thread is interrupted: " + e.toString()); - } - } + if (entry.getKey().equalsIgnoreCase("enabled")) { + info.setEnabled(Boolean.parseBoolean(entry.getValue())); + } else if (entry.getKey().equalsIgnoreCase("timeout")) { + try { + info.setTimeout(Integer.valueOf(entry.getValue())); + } catch (NumberFormatException e) { + s_logger.debug("invalid timeout parameter: " + e.toString()); + } + } else if (entry.getKey().equalsIgnoreCase("wait")) { + try { + int wait = Integer.valueOf(entry.getValue()); + Thread.sleep(wait * 1000); + } catch (NumberFormatException e) { + s_logger.debug("invalid timeout parameter: " + e.toString()); + } catch (InterruptedException e) { + s_logger.debug("thread is interrupted: " + e.toString()); + } + } } } - + if (cmd instanceof GetHostStatsCommand) { return _mockAgentMgr.getHostStatistic((GetHostStatsCommand)cmd); } else if (cmd instanceof CheckHealthCommand) { @@ -165,7 +165,7 @@ public class SimulatorManagerImpl implements SimulatorManager { } else if (cmd instanceof PingTestCommand) { return _mockAgentMgr.pingTest((PingTestCommand)cmd); } else if (cmd instanceof PrepareForMigrationCommand) { - return _mockAgentMgr.prepareForMigrate((PrepareForMigrationCommand)cmd); + return _mockAgentMgr.prepareForMigrate((PrepareForMigrationCommand)cmd); } else if (cmd instanceof MigrateCommand) { return _mockVmMgr.Migrate((MigrateCommand)cmd, info); } else if (cmd instanceof StartCommand) { @@ -173,11 +173,11 @@ public class SimulatorManagerImpl implements SimulatorManager { } else if (cmd instanceof CheckSshCommand) { return _mockVmMgr.checkSshCommand((CheckSshCommand)cmd); } else if (cmd instanceof CheckVirtualMachineCommand) { - return _mockVmMgr.checkVmState((CheckVirtualMachineCommand)cmd); + return _mockVmMgr.checkVmState((CheckVirtualMachineCommand)cmd); } else if (cmd instanceof SetStaticNatRulesCommand) { return _mockVmMgr.SetStaticNatRules((SetStaticNatRulesCommand)cmd); } else if (cmd instanceof SetFirewallRulesCommand) { - return _mockVmMgr.SetFirewallRules((SetFirewallRulesCommand)cmd); + return _mockVmMgr.SetFirewallRules((SetFirewallRulesCommand)cmd); } else if (cmd instanceof SetPortForwardingRulesCommand) { return _mockVmMgr.SetPortForwardingRules((SetPortForwardingRulesCommand)cmd); } else if (cmd instanceof NetworkUsageCommand) { @@ -193,7 +193,7 @@ public class SimulatorManagerImpl implements SimulatorManager { } else if (cmd instanceof CleanupNetworkRulesCmd) { return _mockVmMgr.CleanupNetworkRules((CleanupNetworkRulesCmd)cmd, info); } else if (cmd instanceof CheckNetworkCommand) { - return _mockAgentMgr.checkNetworkCommand((CheckNetworkCommand) cmd); + return _mockAgentMgr.checkNetworkCommand((CheckNetworkCommand) cmd); }else if (cmd instanceof StopCommand) { return _mockVmMgr.stopVM((StopCommand)cmd); } else if (cmd instanceof RebootCommand) { @@ -261,12 +261,12 @@ public class SimulatorManagerImpl implements SimulatorManager { } else if (cmd instanceof BumpUpPriorityCommand) { return _mockVmMgr.bumpPriority((BumpUpPriorityCommand) cmd); } else if (cmd instanceof GetDomRVersionCmd) { - return _mockVmMgr.getDomRVersion((GetDomRVersionCmd) cmd); + return _mockVmMgr.getDomRVersion((GetDomRVersionCmd) cmd); } else if (cmd instanceof ClusterSyncCommand) { - return new Answer(cmd); - //return new ClusterSyncAnswer(((ClusterSyncCommand) cmd).getClusterId(), this.getVmStates(hostGuid)); + return new Answer(cmd); + //return new ClusterSyncAnswer(((ClusterSyncCommand) cmd).getClusterId(), this.getVmStates(hostGuid)); } else if (cmd instanceof CopyVolumeCommand) { - return _mockStorageMgr.CopyVolume((CopyVolumeCommand) cmd); + return _mockStorageMgr.CopyVolume((CopyVolumeCommand) cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); } @@ -288,19 +288,19 @@ public class SimulatorManagerImpl implements SimulatorManager { @Override public Map getVmStates(String hostGuid) { - return _mockVmMgr.getVmStates(hostGuid); + return _mockVmMgr.getVmStates(hostGuid); } - + @Override public Map getVms(String hostGuid) { - return _mockVmMgr.getVms(hostGuid); + return _mockVmMgr.getVms(hostGuid); } - + @Override public HashMap> syncNetworkGroups(String hostGuid) { - SimulatorInfo info = new SimulatorInfo(); - info.setHostUuid(hostGuid); - return _mockVmMgr.syncNetworkGroups(info); + SimulatorInfo info = new SimulatorInfo(); + info.setHostUuid(hostGuid); + return _mockVmMgr.syncNetworkGroups(info); } @Override diff --git a/agent-simulator/src/com/cloud/api/commands/ConfigureSimulator.java b/plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulator.java similarity index 98% rename from agent-simulator/src/com/cloud/api/commands/ConfigureSimulator.java rename to plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulator.java index 4147e3aae1f..60ce82e2c05 100755 --- a/agent-simulator/src/com/cloud/api/commands/ConfigureSimulator.java +++ b/plugins/hypervisors/simulator/src/com/cloud/api/commands/ConfigureSimulator.java @@ -37,25 +37,25 @@ import com.cloud.utils.component.ComponentLocator; public class ConfigureSimulator extends BaseCmd { public static final Logger s_logger = Logger.getLogger(ConfigureSimulator.class.getName()); private static final String s_name = "configuresimulatorresponse"; - + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, description="configure range: in a zone") private Long zoneId; - + @Parameter(name=ApiConstants.POD_ID, type=CommandType.LONG, description="configure range: in a pod") private Long podId; - + @Parameter(name=ApiConstants.CLUSTER_ID, type=CommandType.LONG, description="configure range: in a cluster") private Long clusterId; - + @Parameter(name=ApiConstants.HOST_ID, type=CommandType.LONG, description="configure range: in a host") private Long hostId; - + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="which command needs to be configured") private String command; - + @Parameter(name=ApiConstants.VALUE, type=CommandType.STRING, required=true, description="configuration options for this command, which is seperated by ;") private String values; - + @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { ComponentLocator locator = ComponentLocator.getLocator(ManagementService.Name); @@ -64,7 +64,7 @@ public class ConfigureSimulator extends BaseCmd { if (!result) { throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to configure simulator"); } - + SuccessResponse response = new SuccessResponse(getCommandName()); this.setResponseObject(response); } diff --git a/agent-simulator/src/com/cloud/configuration/SimulatorComponentLibrary.java b/plugins/hypervisors/simulator/src/com/cloud/configuration/SimulatorComponentLibrary.java similarity index 100% rename from agent-simulator/src/com/cloud/configuration/SimulatorComponentLibrary.java rename to plugins/hypervisors/simulator/src/com/cloud/configuration/SimulatorComponentLibrary.java diff --git a/agent-simulator/src/com/cloud/resource/AgentResourceBase.java b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentResourceBase.java similarity index 98% rename from agent-simulator/src/com/cloud/resource/AgentResourceBase.java rename to plugins/hypervisors/simulator/src/com/cloud/resource/AgentResourceBase.java index 6261158ee11..808ca070d4d 100644 --- a/agent-simulator/src/com/cloud/resource/AgentResourceBase.java +++ b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentResourceBase.java @@ -52,7 +52,7 @@ public class AgentResourceBase implements ServerResource { protected String _name; private List _warnings = new LinkedList(); private List _errors = new LinkedList(); - + private transient IAgentControl _agentControl; protected long _instanceId; @@ -64,36 +64,36 @@ public class AgentResourceBase implements ServerResource { protected MockHost agentHost = null; protected boolean stopped = false; protected String hostGuid = null; - + public AgentResourceBase(long instanceId, AgentType agentType, SimulatorManager simMgr, String hostGuid) { - _instanceId = instanceId; - + _instanceId = instanceId; + if(s_logger.isDebugEnabled()) { s_logger.info("New Routing host instantiated with guid:" + hostGuid); } - + if (agentType == AgentType.Routing) { _type = Host.Type.Routing; } else { _type = Host.Type.Storage; } - + this.hostGuid = hostGuid; } - + protected MockVmManager getVmMgr() { return _simMgr.getVmMgr(); } - + protected MockStorageManager getStorageMgr() { return _simMgr.getStorageMgr(); } - + protected MockAgentManager getAgentMgr() { return _simMgr.getAgentMgr(); } - + protected long getInstanceId() { return _instanceId; } @@ -102,7 +102,7 @@ public class AgentResourceBase implements ServerResource { if(s_logger.isDebugEnabled()) { s_logger.debug("Deserializing simulated agent on reconnect"); } - + } @Override @@ -113,18 +113,18 @@ public class AgentResourceBase implements ServerResource { public void setName(String name) { _name = name; } - + @Override public boolean configure(String name, Map params) throws ConfigurationException { hostGuid = (String)params.get("guid"); _locator = ComponentLocator.getLocator("management-server"); _simMgr = _locator.getManager(SimulatorManager.class); - + agentHost = getAgentMgr().getHost(hostGuid); return true; } - + private void reconnect(MockHost host) { if(s_logger.isDebugEnabled()) { @@ -244,7 +244,7 @@ public class AgentResourceBase implements ServerResource { } return file.getAbsolutePath(); } - + @Override public Answer executeRequest(Command cmd) { @@ -264,20 +264,20 @@ public class AgentResourceBase implements ServerResource { public void setType(Host.Type _type) { this._type = _type; } - + @Override public StartupCommand[] initialize() { return null; } - + public SimulatorManager getSimulatorManager() { return _simMgr; - } - - public void setSimulatorManager(SimulatorManager simMgr) { - _simMgr = simMgr; } - + + public void setSimulatorManager(SimulatorManager simMgr) { + _simMgr = simMgr; + } + public boolean isStopped() { return this.stopped; } diff --git a/agent-simulator/src/com/cloud/resource/AgentRoutingResource.java b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java similarity index 96% rename from agent-simulator/src/com/cloud/resource/AgentRoutingResource.java rename to plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java index f10713d126c..f35e4325b38 100644 --- a/agent-simulator/src/com/cloud/resource/AgentRoutingResource.java +++ b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java @@ -91,7 +91,7 @@ public class AgentRoutingResource extends AgentStorageResource { } else if (cmd instanceof ReadyCommand) { return new ReadyAnswer((ReadyCommand)cmd); } else if (cmd instanceof ShutdownCommand) { - return execute((ShutdownCommand)cmd); + return execute((ShutdownCommand)cmd); } else { return _simMgr.simulate(cmd, hostGuid); } @@ -99,7 +99,7 @@ public class AgentRoutingResource extends AgentStorageResource { return new Answer(cmd, false, e.getMessage()); } } - + @Override public Type getType() { return Host.Type.Routing; @@ -111,10 +111,10 @@ public class AgentRoutingResource extends AgentStorageResource { return null; } synchronized (_vms) { - if (_vms.size() == 0) { - //load vms state from database - _vms.putAll(_simMgr.getVmStates(hostGuid)); - } + if (_vms.size() == 0) { + //load vms state from database + _vms.putAll(_simMgr.getVmStates(hostGuid)); + } } final HashMap newStates = sync(); HashMap> nwGrpStates = _simMgr.syncNetworkGroups(hostGuid); @@ -131,18 +131,18 @@ public class AgentRoutingResource extends AgentStorageResource { totalCpu = agentHost.getCpuCount() * agentHost.getCpuSpeed(); totalMem = agentHost.getMemorySize(); for (Map.Entry entry : vmsMaps.entrySet()) { - MockVMVO vm = entry.getValue(); - usedCpu += vm.getCpu(); - usedMem += vm.getMemory(); - _runningVms.put(entry.getKey(), new Pair(Long.valueOf(vm.getCpu()), vm.getMemory())); + MockVMVO vm = entry.getValue(); + usedCpu += vm.getCpu(); + usedMem += vm.getMemory(); + _runningVms.put(entry.getKey(), new Pair(Long.valueOf(vm.getCpu()), vm.getMemory())); } - + List info = getHostInfo(); StartupRoutingCommand cmd = new StartupRoutingCommand((Integer) info.get(0), (Long) info.get(1), (Long) info.get(2), (Long) info.get(4), (String) info.get(3), HypervisorType.Simulator, RouterPrivateIpStrategy.HostLocal); cmd.setStateChanges(changes); - + Map hostDetails = new HashMap(); hostDetails.put(RouterPrivateIpStrategy.class.getCanonicalName(), RouterPrivateIpStrategy.DcGlobal.toString()); @@ -167,13 +167,13 @@ public class AgentRoutingResource extends AgentStorageResource { cmd.setCluster(String.valueOf(agentHost.getClusterId())); StartupStorageCommand ssCmd = initializeLocalSR(); - + return new StartupCommand[] { cmd, ssCmd }; } private StartupStorageCommand initializeLocalSR() { Map tInfo = new HashMap(); - + StoragePoolInfo poolInfo = _simMgr.getLocalStorage(hostGuid); StartupStorageCommand cmd = new StartupStorageCommand(poolInfo.getHostPath(), poolInfo.getPoolType(), poolInfo.getCapacityBytes(), tInfo); @@ -183,14 +183,14 @@ public class AgentRoutingResource extends AgentStorageResource { cmd.setResourceType(StorageResourceType.STORAGE_POOL); return cmd; } - + protected synchronized Answer execute(StartCommand cmd) throws IllegalArgumentException { VirtualMachineTO vmSpec = cmd.getVirtualMachine(); String vmName = vmSpec.getName(); if (this.totalCpu < (vmSpec.getCpus() * vmSpec.getSpeed() + this.usedCpu) || this.totalMem < (vmSpec.getMaxRam() + this.usedMem)) { - return new StartAnswer(cmd, "Not enough resource to start the vm"); + return new StartAnswer(cmd, "Not enough resource to start the vm"); } State state = State.Stopped; synchronized (_vms) { @@ -202,7 +202,7 @@ public class AgentRoutingResource extends AgentStorageResource { if (!result.getResult()) { return new StartAnswer(cmd, result.getDetails()); } - + this.usedCpu += vmSpec.getCpus() * vmSpec.getSpeed(); this.usedMem += vmSpec.getMaxRam(); _runningVms.put(vmName, new Pair(Long.valueOf(vmSpec.getCpus() * vmSpec.getSpeed()), vmSpec.getMaxRam())); @@ -217,7 +217,7 @@ public class AgentRoutingResource extends AgentStorageResource { return new StartAnswer(cmd); } - + protected synchronized StopAnswer execute(StopCommand cmd) { StopAnswer answer = null; @@ -230,11 +230,11 @@ public class AgentRoutingResource extends AgentStorageResource { } try { Answer result = _simMgr.simulate(cmd, hostGuid); - + if (!result.getResult()) { return new StopAnswer(cmd, result.getDetails(), false); } - + answer = new StopAnswer(cmd, null, 0, true); Pair data = _runningVms.get(vmName); if (data != null) { @@ -242,16 +242,16 @@ public class AgentRoutingResource extends AgentStorageResource { this.usedMem -= data.second(); } state = State.Stopped; - + } finally { synchronized (_vms) { _vms.put(vmName, state); } } - + return answer; } - + protected CheckVirtualMachineAnswer execute(final CheckVirtualMachineCommand cmd) { final String vmName = cmd.getVmName(); CheckVirtualMachineAnswer result = (CheckVirtualMachineAnswer)_simMgr.simulate(cmd, hostGuid); @@ -346,7 +346,7 @@ public class AgentRoutingResource extends AgentStorageResource { return changes; } - + private Answer execute(ShutdownCommand cmd) { this.stopped = true; return new Answer(cmd); diff --git a/agent-simulator/src/com/cloud/resource/AgentStorageResource.java b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java similarity index 93% rename from agent-simulator/src/com/cloud/resource/AgentStorageResource.java rename to plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java index 2751b875eb6..1125eeb7847 100644 --- a/agent-simulator/src/com/cloud/resource/AgentStorageResource.java +++ b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java @@ -62,7 +62,7 @@ public class AgentStorageResource extends AgentResourceBase implements Secondary return _simMgr.simulate(cmd, hostGuid); } } - + @Override public PingCommand getCurrentStatus(long id) { if (isStopped()) { @@ -73,14 +73,14 @@ public class AgentStorageResource extends AgentResourceBase implements Secondary @Override public Type getType() { - if(SecondaryStorageVm.Role.templateProcessor.toString().equals(_role)) - return Host.Type.SecondaryStorage; - return Host.Type.SecondaryStorageCmdExecutor; + if(SecondaryStorageVm.Role.templateProcessor.toString().equals(_role)) + return Host.Type.SecondaryStorage; + return Host.Type.SecondaryStorageCmdExecutor; } @Override public StartupCommand[] initialize() { - StartupSecondaryStorageCommand cmd = new StartupSecondaryStorageCommand(); + StartupSecondaryStorageCommand cmd = new StartupSecondaryStorageCommand(); cmd.setPrivateIpAddress(agentHost.getPrivateIpAddress()); cmd.setPrivateNetmask(agentHost.getPrivateNetMask()); @@ -97,15 +97,15 @@ public class AgentStorageResource extends AgentResourceBase implements Secondary cmd.setPod(String.valueOf(agentHost.getPodId())); cmd.setGuid(agentHost.getGuid()); return new StartupCommand[] { cmd }; - } - + } + @Override public boolean configure(String name, Map params) throws ConfigurationException { if (!super.configure(name, params)) { s_logger.warn("Base class was unable to configure"); return false; } - + return true; } diff --git a/agent-simulator/src/com/cloud/resource/SimulatorDiscoverer.java b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java similarity index 94% rename from agent-simulator/src/com/cloud/resource/SimulatorDiscoverer.java rename to plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java index 729d4b0fd23..b6d40d49589 100755 --- a/agent-simulator/src/com/cloud/resource/SimulatorDiscoverer.java +++ b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java @@ -60,7 +60,7 @@ import com.cloud.utils.component.Inject; public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, Listener, ResourceStateAdapter { private static final Logger s_logger = Logger .getLogger(SimulatorDiscoverer.class); - + @Inject HostDao _hostDao; @Inject VMTemplateDao _vmTemplateDao; @Inject VMTemplateHostDao _vmTemplateHostDao; @@ -70,10 +70,10 @@ public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, L @Inject MockAgentManager _mockAgentMgr = null; @Inject MockStorageManager _mockStorageMgr = null; @Inject ResourceManager _resourceMgr; - + /** * Finds ServerResources of an in-process simulator - * + * * @see com.cloud.resource.Discoverer#find(long, java.lang.Long, * java.lang.Long, java.net.URI, java.lang.String, java.lang.String) */ @@ -88,7 +88,7 @@ public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, L String scheme = uri.getScheme(); String host = uri.getAuthority(); String commands = URLDecoder.decode(uri.getPath()); - + long cpuSpeed = _mockAgentMgr.DEFAULT_HOST_SPEED_MHZ; long cpuCores = _mockAgentMgr.DEFAULT_HOST_CPU_CORES; long memory = _mockAgentMgr.DEFAULT_HOST_MEM_SIZE; @@ -145,7 +145,7 @@ public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, L if (s_logger.isInfoEnabled()) s_logger.info("invalid cluster id or cluster is not for Simulator hypervisors"); return null; - } + } cluster = Long.toString(clusterId); if(clu.getGuid() == null) { clu.setGuid(UUID.randomUUID().toString()); @@ -205,23 +205,23 @@ public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, L for (HostVO h : hosts) { associateTemplatesToZone(h.getId(), h.getDataCenterId()); } - } + } private void associateTemplatesToZone(long hostId, long dcId){ - VMTemplateZoneVO tmpltZone; + VMTemplateZoneVO tmpltZone; - List allTemplates = _vmTemplateDao.listAll(); - for (VMTemplateVO vt: allTemplates){ - if (vt.isCrossZones()) { - tmpltZone = _vmTemplateZoneDao.findByZoneTemplate(dcId, vt.getId()); - if (tmpltZone == null) { - VMTemplateZoneVO vmTemplateZone = new VMTemplateZoneVO(dcId, vt.getId(), new Date()); - _vmTemplateZoneDao.persist(vmTemplateZone); - } - } - } + List allTemplates = _vmTemplateDao.listAll(); + for (VMTemplateVO vt: allTemplates){ + if (vt.isCrossZones()) { + tmpltZone = _vmTemplateZoneDao.findByZoneTemplate(dcId, vt.getId()); + if (tmpltZone == null) { + VMTemplateZoneVO vmTemplateZone = new VMTemplateZoneVO(dcId, vt.getId(), new Date()); + _vmTemplateZoneDao.persist(vmTemplateZone); + } + } + } } - + @Override public HypervisorType getHypervisorType() { return HypervisorType.Simulator; @@ -231,7 +231,7 @@ public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, L public boolean matchHypervisor(String hypervisor) { return hypervisor.equalsIgnoreCase(HypervisorType.Simulator.toString()); } - + @Override public boolean configure(String name, Map params) throws ConfigurationException { super.configure(name, params); @@ -257,9 +257,9 @@ public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, L @Override public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { - + /*if(forRebalance) - return; + return; if ( Host.Type.SecondaryStorage == host.getType() ) { List tmplts = _vmTemplateDao.listAll(); for( VMTemplateVO tmplt : tmplts ) { @@ -275,7 +275,7 @@ public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, L } } }*/ - + } @Override @@ -312,12 +312,12 @@ public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, L if (!(firstCmd instanceof StartupRoutingCommand)) { return null; } - + StartupRoutingCommand ssCmd = ((StartupRoutingCommand) firstCmd); if (ssCmd.getHypervisorType() != HypervisorType.Simulator) { return null; } - + return _resourceMgr.fillRoutingHostVO(host, ssCmd, HypervisorType.Simulator, details, hostTags); } @@ -326,11 +326,11 @@ public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, L boolean isForceDeleteStorage) throws UnableDeleteHostException { return null; } - + @Override public boolean stop() { - _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName()); + _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName()); return super.stop(); } - + } diff --git a/agent-simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java similarity index 96% rename from agent-simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java rename to plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java index f828bc822ca..5d4d5b97c40 100644 --- a/agent-simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java +++ b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java @@ -45,14 +45,14 @@ public class SimulatorSecondaryDiscoverer extends SecondaryStorageDiscoverer imp @Inject AgentManager _agentMgr; @Inject ResourceManager _resourceMgr; @Inject SnapshotDao _snapshotDao; - + @Override public boolean configure(String name, Map params) throws ConfigurationException { - _agentMgr.registerForHostEvents(this, true, false, false); + _agentMgr.registerForHostEvents(this, true, false, false); _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this); return super.configure(name, params); } - + @Override public void postDiscovery(List hosts, long msId) { super.postDiscovery(hosts, msId); @@ -74,9 +74,9 @@ public class SimulatorSecondaryDiscoverer extends SecondaryStorageDiscoverer imp //for detecting SSVM dispatch StartupCommand firstCmd = startup[0]; if (!(firstCmd instanceof StartupSecondaryStorageCommand)) { - return null; + return null; } - + host.setType(com.cloud.host.Host.Type.SecondaryStorageVM); return host; } @@ -103,7 +103,7 @@ public class SimulatorSecondaryDiscoverer extends SecondaryStorageDiscoverer imp @Override public boolean stop() { - _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName()); + _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName()); return true; } @@ -130,7 +130,7 @@ public class SimulatorSecondaryDiscoverer extends SecondaryStorageDiscoverer imp @Override public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { - + } @Override diff --git a/agent-simulator/src/com/cloud/server/ManagementServerSimulatorImpl.java b/plugins/hypervisors/simulator/src/com/cloud/server/ManagementServerSimulatorImpl.java similarity index 99% rename from agent-simulator/src/com/cloud/server/ManagementServerSimulatorImpl.java rename to plugins/hypervisors/simulator/src/com/cloud/server/ManagementServerSimulatorImpl.java index 1c69b543aa8..35aa3010005 100644 --- a/agent-simulator/src/com/cloud/server/ManagementServerSimulatorImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/server/ManagementServerSimulatorImpl.java @@ -25,7 +25,7 @@ public class ManagementServerSimulatorImpl extends ManagementServerExtImpl { for (int i = 0; i < apis.length; i++) { newapis[i] = apis[i]; } - + newapis[apis.length] = "commands-simulator.properties"; return newapis; } diff --git a/agent-simulator/src/com/cloud/simulator/MockConfigurationVO.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockConfigurationVO.java similarity index 96% rename from agent-simulator/src/com/cloud/simulator/MockConfigurationVO.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/MockConfigurationVO.java index dfea2279e9e..3ed862bb69f 100644 --- a/agent-simulator/src/com/cloud/simulator/MockConfigurationVO.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockConfigurationVO.java @@ -33,79 +33,79 @@ public class MockConfigurationVO { @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") private long id; - + @Column(name="data_center_id", nullable=false) private Long dataCenterId; - + @Column(name="pod_id") private Long podId; - + @Column(name="cluster_id") private Long clusterId; - + @Column(name="host_id") private Long hostId; - + @Column(name="name") private String name; - + @Column(name="values") private String values; - + public long getId() { return this.id; } - + public Long getDataCenterId() { return this.dataCenterId; } - + public void setDataCenterId(Long dcId) { this.dataCenterId = dcId; } - + public Long getPodId() { return this.podId; } - + public void setPodId(Long podId) { this.podId = podId; } - + public Long getClusterId() { return this.clusterId; } - + public void setClusterId(Long clusterId) { this.clusterId = clusterId; } - + public Long getHostId() { return this.hostId; } - + public void setHostId(Long hostId) { this.hostId = hostId; } - + public String getName() { return this.name; } - + public void setName(String name) { this.name = name; } - + public String getValues() { return this.values; } - + public Map getParameters() { Map maps = new HashMap(); if (this.values == null) { return maps; } - + String[] vals = this.values.split("\\|"); for (String val : vals) { String[] paras = val.split(":"); @@ -113,9 +113,8 @@ public class MockConfigurationVO { } return maps; } - + public void setValues(String values) { this.values = values; } } - diff --git a/agent-simulator/src/com/cloud/simulator/MockHost.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockHost.java similarity index 93% rename from agent-simulator/src/com/cloud/simulator/MockHost.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/MockHost.java index d20e8259267..5ca90177189 100644 --- a/agent-simulator/src/com/cloud/simulator/MockHost.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockHost.java @@ -19,44 +19,44 @@ package com.cloud.simulator; public interface MockHost { public long getCpuSpeed(); public long getCpuCount(); - - + + public long getMemorySize(); - + public String getCapabilities(); - + public long getId(); - + public String getName(); - + public String getGuid(); - - + + public String getVersion(); - + public Long getDataCenterId(); - + public Long getPodId(); - + public Long getClusterId(); - + public String getPrivateIpAddress(); - + public String getPrivateNetMask(); - + public String getPrivateMacAddress(); - - + + public String getPublicIpAddress(); - + public String getPublicNetMask(); - + public String getPublicMacAddress(); - + public String getStorageIpAddress(); - + public String getStorageNetMask(); - + public String getStorageMacAddress(); - + } diff --git a/agent-simulator/src/com/cloud/simulator/MockHostVO.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockHostVO.java similarity index 94% rename from agent-simulator/src/com/cloud/simulator/MockHostVO.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/MockHostVO.java index 59b7e8d0788..c86dfa6a2bf 100644 --- a/agent-simulator/src/com/cloud/simulator/MockHostVO.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockHostVO.java @@ -31,245 +31,245 @@ public class MockHostVO implements MockHost { @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") private long id; - + @Column(name="name", nullable=false) private String name = null; - + @Column(name="private_ip_address", nullable=false) private String privateIpAddress; - + @Column(name="private_mac_address", nullable=false) private String privateMacAddress; - + @Column(name="private_netmask", nullable=false) private String privateNetmask; - + @Column(name="public_netmask") private String publicNetmask; - + @Column(name="public_ip_address") private String publicIpAddress; - + @Column(name="public_mac_address") private String publicMacAddress; - + @Column(name="storage_ip_address") private String storageIpAddress; - + @Column(name="storage_mac_address") private String storageMacAddress; - + @Column(name="storage_netmask") private String storageNetMask; - + @Column(name="guid") private String guid; - + @Column(name="version") private String version; - + @Column(name="data_center_id", nullable=false) private long dataCenterId; - + @Column(name="pod_id") private Long podId; - + @Column(name="cluster_id") private Long clusterId; - + @Column(name="speed") private long cpuSpeed; - + @Column(name="cpus") private long cpuCount; - + @Column(name="ram") private long memorySize; - + @Column(name="capabilities") private String capabilities; - + @Column(name="vm_id") private long vmId; - + @Column(name="resource") private String resource; - - - + + + public MockHostVO() { - + } - - + + public long getVmId() { return vmId; } - + public void setVmId(long vmId) { this.vmId = vmId; } - + public String getResource() { return this.resource; } - + public void setResource(String resource) { this.resource = resource; } - + public long getCpuSpeed() { return this.cpuSpeed; } - + public void setCpuSpeed(long cpuSpeed) { this.cpuSpeed = cpuSpeed; } - + public long getCpuCount() { return this.cpuCount; } - + public void setCpuCount(long cpuCount) { this.cpuCount = cpuCount; } - + public long getMemorySize() { return this.memorySize; } - + public void setMemorySize(long memorySize) { this.memorySize = memorySize; } - + public String getCapabilities() { return this.capabilities; } - + public void setCapabilities(String capabilities) { this.capabilities = capabilities; } - + public long getId() { return id; } - + public String getName() { return name; } - + public void setName(String name) { this.name = name; } - + public String getGuid() { return this.guid; } - + public void setGuid(String guid) { this.guid = guid; } - + public String getVersion() { return this.version; } - + public void setVersion(String version) { this.version = version; } - + public Long getDataCenterId() { return this.dataCenterId; } - + public void setDataCenterId(Long dataCenterId) { this.dataCenterId = dataCenterId; } - + public Long getPodId() { return this.podId; } - + public void setPodId(long podId) { this.podId = podId; } - + public Long getClusterId() { return this.clusterId; } - + public void setClusterId(Long clusterId) { this.clusterId = clusterId; } - + public String getPrivateIpAddress() { return privateIpAddress; } - + public void setPrivateIpAddress(String privateIpAddress) { this.privateIpAddress = privateIpAddress; } - + public String getPrivateNetMask() { return this.privateNetmask; } - + public void setPrivateNetMask(String privateNetmask) { this.privateNetmask = privateNetmask; } - + public String getPrivateMacAddress() { return this.privateMacAddress; } - + public void setPrivateMacAddress(String privateMacAddress) { this.privateMacAddress = privateMacAddress; } - + public String getPublicIpAddress() { return this.publicIpAddress; } - + public void setPublicIpAddress(String publicIpAddress) { this.publicIpAddress = publicIpAddress; } - + public String getPublicNetMask() { return this.publicNetmask; } - + public void setPublicNetMask(String publicNetMask) { this.publicNetmask = publicNetMask; } - + public String getPublicMacAddress() { return this.publicMacAddress; } - + public void setPublicMacAddress(String publicMacAddress) { this.publicMacAddress = publicMacAddress; } - + public String getStorageIpAddress() { return this.storageIpAddress; } - + public void setStorageIpAddress(String storageIpAddress) { this.storageIpAddress = storageIpAddress; } - + public String getStorageNetMask() { return this.storageNetMask; } - + public void setStorageNetMask(String storageNetMask) { this.storageNetMask = storageNetMask; } - + public String getStorageMacAddress() { return this.storageMacAddress; } - + public void setStorageMacAddress(String storageMacAddress) { this.storageMacAddress = storageMacAddress; } diff --git a/agent-simulator/src/com/cloud/simulator/MockSecStorageVO.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockSecStorageVO.java similarity index 96% rename from agent-simulator/src/com/cloud/simulator/MockSecStorageVO.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/MockSecStorageVO.java index c503cc260be..59a81c79abe 100644 --- a/agent-simulator/src/com/cloud/simulator/MockSecStorageVO.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockSecStorageVO.java @@ -31,45 +31,45 @@ public class MockSecStorageVO { @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") private long id; - + @Column(name="url") private String url; - + @Column(name="capacity") private long capacity; - + @Column(name="mount_point") private String mountPoint; - - + + public MockSecStorageVO() { - + } - + public long getId() { return this.id; } - + public String getMountPoint() { return this.mountPoint; } - + public void setMountPoint(String mountPoint) { this.mountPoint = mountPoint; } - + public String getUrl() { return url; } - + public void setUrl(String url) { this.url = url; } - + public long getCapacity() { return this.capacity; } - + public void setCapacity(long capacity) { this.capacity = capacity; } diff --git a/agent-simulator/src/com/cloud/simulator/MockSecurityRulesVO.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockSecurityRulesVO.java similarity index 96% rename from agent-simulator/src/com/cloud/simulator/MockSecurityRulesVO.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/MockSecurityRulesVO.java index 3036ea98db2..df31fbf277b 100644 --- a/agent-simulator/src/com/cloud/simulator/MockSecurityRulesVO.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockSecurityRulesVO.java @@ -31,73 +31,73 @@ public class MockSecurityRulesVO { @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") private long id; - + @Column(name="vmid") private Long vmId; - + @Column(name="signature") private String signature; - + @Column(name="seqnum") private Long seqNum; - + @Column(name="ruleset") private String ruleSet; - + @Column(name="hostid") private String hostId; - + @Column(name="vmname") public String vmName; - + public String getVmName() { return this.vmName; } - + public void setVmName(String vmName) { this.vmName = vmName; } - + public String getHostId() { return this.hostId; } - + public void setHostId(String hostId) { this.hostId = hostId; } - + public long getId() { return this.id; } - + public Long getVmId() { return this.vmId; } - + public void setVmId(Long vmId) { this.vmId = vmId; } - + public String getSignature() { return this.signature; } - + public void setSignature(String sig) { this.signature = sig; } - + public Long getSeqNum() { return this.seqNum; } - + public void setSeqNum(Long seqNum) { this.seqNum = seqNum; } - + public String getRuleSet() { return this.ruleSet; } - + public void setRuleSet(String ruleset) { this.ruleSet = ruleset; } diff --git a/agent-simulator/src/com/cloud/simulator/MockStoragePoolVO.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockStoragePoolVO.java similarity index 96% rename from agent-simulator/src/com/cloud/simulator/MockStoragePoolVO.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/MockStoragePoolVO.java index 81f0432247d..9c6e84d2714 100644 --- a/agent-simulator/src/com/cloud/simulator/MockStoragePoolVO.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockStoragePoolVO.java @@ -35,67 +35,67 @@ public class MockStoragePoolVO { @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") private long id; - + @Column(name="guid") private String uuid; - + @Column(name="mount_point") private String mountPoint; - + @Column(name="capacity") private long capacity; - + @Column(name="hostguid") private String hostGuid; - + @Column(name="pool_type") @Enumerated(value=EnumType.STRING) private StoragePoolType poolType; - + public MockStoragePoolVO() { - + } - + public String getHostGuid() { return this.hostGuid; } - + public void setHostGuid(String hostGuid) { this.hostGuid = hostGuid; } - + public long getId() { return this.id; } - + public StoragePoolType getPoolType() { return this.poolType; } - + public void setStorageType(StoragePoolType poolType) { this.poolType = poolType; } - + public String getUuid() { return this.uuid; } - + public void setUuid(String uuid) { this.uuid = uuid; } - + public String getMountPoint() { return this.mountPoint; } - + public void setMountPoint(String mountPoint) { this.mountPoint = mountPoint; } - + public long getCapacity() { return this.capacity; } - + public void setCapacity(long capacity) { this.capacity = capacity; } diff --git a/agent-simulator/src/com/cloud/simulator/MockVMVO.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVMVO.java similarity index 93% rename from agent-simulator/src/com/cloud/simulator/MockVMVO.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/MockVMVO.java index c1b391e37f6..4fb30850b63 100644 --- a/agent-simulator/src/com/cloud/simulator/MockVMVO.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVMVO.java @@ -33,98 +33,98 @@ public class MockVMVO implements MockVm{ @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") private long id; - + @Column(name="name") private String name; - + @Column(name="host_id") private long hostId; - + @Column(name="type") private String vmType; - + @Column(name="state") private State state; - + @Column(name="vnc_port") private int vncPort; - + @Column(name="memory") private long memory; - + @Column(name="cpu") private int cpu; - + public MockVMVO() { - + } - + public long getId() { return this.id; } - + public String getName() { return this.name; } - + public void setName(String name) { this.name = name; } - + public long getHostId() { return this.hostId; } - + public void setHostId(long hostId) { this.hostId = hostId; } - + public String getVmType() { return this.vmType; } - + public void setVmType(String vmType) { this.vmType = vmType; } - + public State getState() { return this.state; } - + public String getType() { - return this.vmType; + return this.vmType; } - + public void setState(State state) { this.state = state; } - + public int getVncPort() { return this.vncPort; } - + public void setVncPort(int vncPort) { this.vncPort = vncPort; } - + public long getMemory() { return this.memory; } - + public void setMemory(long memory) { this.memory = memory; } - + public int getCpu() { return this.cpu; } - + public void setCpu(int cpu) { this.cpu = cpu; } - + public void setType(String type) { - this.vmType = type; + this.vmType = type; } } diff --git a/agent-simulator/src/com/cloud/simulator/MockVm.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVm.java similarity index 99% rename from agent-simulator/src/com/cloud/simulator/MockVm.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/MockVm.java index 250ca7bedf4..2e1ba27c71c 100644 --- a/agent-simulator/src/com/cloud/simulator/MockVm.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVm.java @@ -20,21 +20,21 @@ import com.cloud.vm.VirtualMachine.State; // As storage is mapped from storage device, can virtually treat that VM here does public interface MockVm { - - + + public String getName(); - + public State getState(); - + public void setState(State state); - + public void setHostId(long hostId); public long getMemory(); - + public int getCpu(); public String getType(); public int getVncPort(); - + public void setName(String name); public void setMemory(long memory); public void setCpu(int cpu); @@ -42,4 +42,3 @@ public interface MockVm { public void setVncPort(int vncPort); public long getId(); } - diff --git a/agent-simulator/src/com/cloud/simulator/MockVolumeVO.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVolumeVO.java similarity index 96% rename from agent-simulator/src/com/cloud/simulator/MockVolumeVO.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/MockVolumeVO.java index 94908d7efd4..48a12f8ee93 100644 --- a/agent-simulator/src/com/cloud/simulator/MockVolumeVO.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVolumeVO.java @@ -43,76 +43,76 @@ public class MockVolumeVO { @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") private long id; - + @Column(name="name") private String name; - + @Column(name="size") private long size; - + @Column(name="path") private String path; - + @Column(name="pool_id") private long poolId; - + @Column(name="type") @Enumerated(value=EnumType.STRING) private MockVolumeType type; - + @Column(name="status") @Enumerated(value=EnumType.STRING) private VMTemplateStorageResourceAssoc.Status status; - + public long getId() { return id; } public String getName() { return this.name; } - + public void setName(String name) { this.name = name; } - + public long getSize() { return this.size; } - + public void setSize(long size) { this.size = size; } - + public String getPath() { return this.path; } - + public void setPath(String path) { this.path = path; } - + public long getPoolId() { return this.poolId; } - + public void setPoolId(long poolId) { this.poolId = poolId; } - + public MockVolumeType getType() { return this.type; } - + public void setType(MockVolumeType type) { this.type = type; } - + public Status getStatus() { return this.status; } - + public void setStatus(Status status) { this.status = status; } - + } diff --git a/agent-simulator/src/com/cloud/simulator/SimulatorGuru.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/SimulatorGuru.java similarity index 98% rename from agent-simulator/src/com/cloud/simulator/SimulatorGuru.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/SimulatorGuru.java index 20457e4db56..b9c404b66a1 100644 --- a/agent-simulator/src/com/cloud/simulator/SimulatorGuru.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/SimulatorGuru.java @@ -35,7 +35,7 @@ public class SimulatorGuru extends HypervisorGuruBase implements HypervisorGuru protected SimulatorGuru() { super(); } - + @Override public HypervisorType getHypervisorType() { return HypervisorType.Simulator; @@ -44,11 +44,11 @@ public class SimulatorGuru extends HypervisorGuruBase implements HypervisorGuru @Override public VirtualMachineTO implement(VirtualMachineProfile vm) { VirtualMachineTO to = toVirtualMachineTO(vm); - + // Determine the VM's OS description GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId()); to.setOs(guestOS.getDisplayName()); - + return to; } diff --git a/agent-simulator/src/com/cloud/simulator/SimulatorRuntimeException.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/SimulatorRuntimeException.java similarity index 98% rename from agent-simulator/src/com/cloud/simulator/SimulatorRuntimeException.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/SimulatorRuntimeException.java index ce962a2d296..9891bc82556 100644 --- a/agent-simulator/src/com/cloud/simulator/SimulatorRuntimeException.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/SimulatorRuntimeException.java @@ -26,15 +26,15 @@ import com.cloud.utils.exception.RuntimeCloudException; public class SimulatorRuntimeException extends RuntimeCloudException { private static final long serialVersionUID = SerialVersionUID.CloudRuntimeException; - + public SimulatorRuntimeException(String message) { super(message); } - + public SimulatorRuntimeException(String message, Throwable th) { super(message, th); } - + protected SimulatorRuntimeException() { super(); } diff --git a/agent-simulator/src/com/cloud/simulator/dao/MockConfigurationDao.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockConfigurationDao.java similarity index 100% rename from agent-simulator/src/com/cloud/simulator/dao/MockConfigurationDao.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockConfigurationDao.java diff --git a/agent-simulator/src/com/cloud/simulator/dao/MockConfigurationDaoImpl.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockConfigurationDaoImpl.java similarity index 88% rename from agent-simulator/src/com/cloud/simulator/dao/MockConfigurationDaoImpl.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockConfigurationDaoImpl.java index a65a4a77c55..bd1b48dfde8 100644 --- a/agent-simulator/src/com/cloud/simulator/dao/MockConfigurationDaoImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockConfigurationDaoImpl.java @@ -35,8 +35,8 @@ public class MockConfigurationDaoImpl extends GenericDaoBase _searchByDcIDPodIdClusterIdName; private SearchBuilder _searchByDcIDPodIdClusterIdHostIdName; private SearchBuilder _searchByGlobalName; - - + + public MockConfigurationDaoImpl() { _searchByGlobalName = createSearchBuilder(); _searchByGlobalName.and("dcId", _searchByGlobalName.entity().getDataCenterId(), SearchCriteria.Op.NULL); @@ -45,7 +45,7 @@ public class MockConfigurationDaoImpl extends GenericDaoBase sc = _searchByGlobalName.create(); sc.setParameters("name", name); @@ -113,19 +113,19 @@ public class MockConfigurationDaoImpl extends GenericDaoBase implements MockHostDao { - protected final SearchBuilder GuidSearch; + protected final SearchBuilder GuidSearch; public MockHostDaoImpl() { GuidSearch = createSearchBuilder(); GuidSearch.and("guid", GuidSearch.entity().getGuid(), SearchCriteria.Op.EQ); diff --git a/agent-simulator/src/com/cloud/simulator/dao/MockSecStorageDao.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockSecStorageDao.java similarity index 100% rename from agent-simulator/src/com/cloud/simulator/dao/MockSecStorageDao.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockSecStorageDao.java diff --git a/agent-simulator/src/com/cloud/simulator/dao/MockSecStorageDaoImpl.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockSecStorageDaoImpl.java similarity index 95% rename from agent-simulator/src/com/cloud/simulator/dao/MockSecStorageDaoImpl.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockSecStorageDaoImpl.java index fd8d1d3a90b..65a375f5843 100644 --- a/agent-simulator/src/com/cloud/simulator/dao/MockSecStorageDaoImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockSecStorageDaoImpl.java @@ -25,14 +25,14 @@ import com.cloud.utils.db.SearchCriteria; @Local(value={MockSecStorageDao.class}) public class MockSecStorageDaoImpl extends GenericDaoBase implements MockSecStorageDao { - protected final SearchBuilder urlSearch; + protected final SearchBuilder urlSearch; @Override public MockSecStorageVO findByUrl(String url) { SearchCriteria sc = urlSearch.create(); sc.setParameters("url", url); return findOneBy(sc); } - + public MockSecStorageDaoImpl() { urlSearch = createSearchBuilder(); urlSearch.and("url", urlSearch.entity().getUrl(), SearchCriteria.Op.EQ); diff --git a/agent-simulator/src/com/cloud/simulator/dao/MockSecurityRulesDao.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockSecurityRulesDao.java similarity index 100% rename from agent-simulator/src/com/cloud/simulator/dao/MockSecurityRulesDao.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockSecurityRulesDao.java diff --git a/agent-simulator/src/com/cloud/simulator/dao/MockSecurityRulesDaoImpl.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockSecurityRulesDaoImpl.java similarity index 96% rename from agent-simulator/src/com/cloud/simulator/dao/MockSecurityRulesDaoImpl.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockSecurityRulesDaoImpl.java index 43a1da6c8fb..8831efef2ec 100644 --- a/agent-simulator/src/com/cloud/simulator/dao/MockSecurityRulesDaoImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockSecurityRulesDaoImpl.java @@ -29,7 +29,7 @@ import com.cloud.utils.db.SearchCriteria; @Local(value={MockSecurityRulesDao.class}) public class MockSecurityRulesDaoImpl extends GenericDaoBase implements MockSecurityRulesDao { protected SearchBuilder vmIdSearch; - protected SearchBuilder hostSearch; + protected SearchBuilder hostSearch; @Override public MockSecurityRulesVO findByVmId(Long vmId) { SearchCriteria sc = vmIdSearch.create(); @@ -43,18 +43,18 @@ public class MockSecurityRulesDaoImpl extends GenericDaoBase params) throws ConfigurationException { vmIdSearch = createSearchBuilder(); vmIdSearch.and("vmId", vmIdSearch.entity().getVmId(), SearchCriteria.Op.EQ); vmIdSearch.done(); - + hostSearch = createSearchBuilder(); hostSearch.and("host", hostSearch.entity().getHostId(), SearchCriteria.Op.EQ); hostSearch.done(); - + return true; } - + } diff --git a/agent-simulator/src/com/cloud/simulator/dao/MockStoragePoolDao.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockStoragePoolDao.java similarity index 100% rename from agent-simulator/src/com/cloud/simulator/dao/MockStoragePoolDao.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockStoragePoolDao.java diff --git a/agent-simulator/src/com/cloud/simulator/dao/MockStoragePoolDaoImpl.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockStoragePoolDaoImpl.java similarity index 99% rename from agent-simulator/src/com/cloud/simulator/dao/MockStoragePoolDaoImpl.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockStoragePoolDaoImpl.java index e35b5372946..3a64d27e30d 100644 --- a/agent-simulator/src/com/cloud/simulator/dao/MockStoragePoolDaoImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockStoragePoolDaoImpl.java @@ -34,12 +34,12 @@ public class MockStoragePoolDaoImpl extends GenericDaoBase implements MockVMDao { - protected SearchBuilder GuidSearch; + protected SearchBuilder GuidSearch; protected SearchBuilder vmNameSearch; protected SearchBuilder vmhostSearch; @Inject MockHostDao _mockHostDao; @@ -57,7 +57,7 @@ public class MockVMDaoImpl extends GenericDaoBase implements Moc sc.setParameters("state", VirtualMachine.State.Running); return listBy(sc); } - + @Override public MockVMVO findByVmNameAndHost(String vmName, String hostGuid) { SearchCriteria sc = vmhostSearch.create(); @@ -65,28 +65,28 @@ public class MockVMDaoImpl extends GenericDaoBase implements Moc sc.setParameters("name", vmName); return findOneBy(sc); } - + @Override public boolean configure(String name, Map params) throws ConfigurationException { SearchBuilder host = _mockHostDao.createSearchBuilder(); host.and("guid", host.entity().getGuid(), SearchCriteria.Op.EQ); - + GuidSearch = createSearchBuilder(); GuidSearch.join("host", host, host.entity().getId(), GuidSearch.entity().getHostId(), JoinBuilder.JoinType.INNER); GuidSearch.and("state", GuidSearch.entity().getState(), SearchCriteria.Op.EQ); GuidSearch.done(); - + vmNameSearch = createSearchBuilder(); vmNameSearch.and("name", vmNameSearch.entity().getName(), SearchCriteria.Op.EQ); vmNameSearch.done(); - + SearchBuilder newhost = _mockHostDao.createSearchBuilder(); newhost.and("guid", newhost.entity().getGuid(), SearchCriteria.Op.EQ); vmhostSearch = createSearchBuilder(); vmhostSearch.and("name", vmhostSearch.entity().getName(), SearchCriteria.Op.EQ); vmhostSearch.join("host", newhost, newhost.entity().getId(), vmhostSearch.entity().getHostId(), JoinBuilder.JoinType.INNER); vmhostSearch.done(); - + return true; } } diff --git a/agent-simulator/src/com/cloud/simulator/dao/MockVolumeDao.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockVolumeDao.java similarity index 100% rename from agent-simulator/src/com/cloud/simulator/dao/MockVolumeDao.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockVolumeDao.java diff --git a/agent-simulator/src/com/cloud/simulator/dao/MockVolumeDaoImpl.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockVolumeDaoImpl.java similarity index 96% rename from agent-simulator/src/com/cloud/simulator/dao/MockVolumeDaoImpl.java rename to plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockVolumeDaoImpl.java index 87b54f196c1..a3a35179337 100644 --- a/agent-simulator/src/com/cloud/simulator/dao/MockVolumeDaoImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/dao/MockVolumeDaoImpl.java @@ -42,11 +42,11 @@ public class MockVolumeDaoImpl extends GenericDaoBase implem sc.setParameters("type", type); return listBy(sc); } - + @Override public Long findTotalStorageId(long id) { SearchCriteria sc = totalSearch.create(); - + sc.setParameters("poolId", id); return customSearch(sc, null).get(0); } @@ -57,20 +57,20 @@ public class MockVolumeDaoImpl extends GenericDaoBase implem sc.setParameters("path", "%" + path + "%"); return findOneBy(sc); } - + @Override public MockVolumeVO findByNameAndPool(String volumeName, String poolUUID) { SearchCriteria sc = namePoolSearch.create(); sc.setParameters("name", volumeName); sc.setParameters("poolUuid", poolUUID); - return findOneBy(sc); + return findOneBy(sc); } @Override public MockVolumeVO findByName(String volumeName) { SearchCriteria sc = nameSearch.create(); sc.setParameters("name", volumeName); - return findOneBy(sc); + return findOneBy(sc); } public MockVolumeDaoImpl() { @@ -78,24 +78,24 @@ public class MockVolumeDaoImpl extends GenericDaoBase implem idTypeSearch.and("storageId", idTypeSearch.entity().getPoolId(), SearchCriteria.Op.EQ); idTypeSearch.and("type", idTypeSearch.entity().getType(), SearchCriteria.Op.EQ); idTypeSearch.done(); - + pathTypeSearch = createSearchBuilder(); pathTypeSearch.and("path", pathTypeSearch.entity().getPath(), SearchCriteria.Op.LIKE); pathTypeSearch.done(); - + namePoolSearch = createSearchBuilder(); namePoolSearch.and("name", namePoolSearch.entity().getName(), SearchCriteria.Op.EQ); namePoolSearch.and("poolUuid", namePoolSearch.entity().getPoolId(), SearchCriteria.Op.EQ); namePoolSearch.done(); - + nameSearch = createSearchBuilder(); nameSearch.and("name", nameSearch.entity().getName(), SearchCriteria.Op.EQ); nameSearch.done(); - + totalSearch = createSearchBuilder(Long.class); totalSearch.select(null, Func.SUM, totalSearch.entity().getSize()); totalSearch.and("poolId", totalSearch.entity().getPoolId(), SearchCriteria.Op.EQ); totalSearch.done(); - - } + + } } diff --git a/plugins/pom.xml b/plugins/pom.xml index d71bd45aa29..65b5971a0e7 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -38,6 +38,7 @@ hypervisors/ovm hypervisors/xen hypervisors/kvm + hypervisors/simulator network-elements/elastic-loadbalancer network-elements/ovs network-elements/nicira-nvp @@ -124,6 +125,17 @@ hypervisors/vmware + + kvm + + + nonoss + + + + hypervisors/simulator + + From 39fea6f6fcc357c5eb8a2ece3be480323864234a Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Sat, 22 Dec 2012 13:07:48 -0800 Subject: [PATCH 09/23] simulator: fixing pom.xml for build --- plugins/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/pom.xml b/plugins/pom.xml index 65b5971a0e7..af8621028db 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -126,7 +126,7 @@ - kvm + simulator nonoss From beff1f45b15bff4540af62e851e7ce0acfde130e Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Sat, 22 Dec 2012 13:55:32 -0800 Subject: [PATCH 10/23] Simulator: components-simulator.xml resource The extended simulator component including the Simulator Managers and Discoverers --- .../resources/components-simulator.xml | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 plugins/hypervisors/simulator/resources/components-simulator.xml diff --git a/plugins/hypervisors/simulator/resources/components-simulator.xml b/plugins/hypervisors/simulator/resources/components-simulator.xml new file mode 100644 index 00000000000..4629acc866a --- /dev/null +++ b/plugins/hypervisors/simulator/resources/components-simulator.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From ed25ec050080867246b2af52a21328fb640699a5 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Sat, 22 Dec 2012 13:57:13 -0800 Subject: [PATCH 11/23] simulator: simulator maintenance mode and simulator latency per command Detail: To induce latency for a command you have to use an API call like so http://localhost:8096/client/api?command=configureSimulator&zoneid=1&podid=1&name=CheckRouterCommand&value=wait:80|timeout:0 (This is a hidden API command just for the simulator) You will see the configuration effected in the mockconfiguration table of simulator db. You can introduce the latency at runtime without restarting management server. mysql> select * from mockconfiguration; +----+----------------+--------+------------+---------+--------------------+-------------------+ | id | data_center_id | pod_id | cluster_id | host_id | name | values | +----+----------------+--------+------------+---------+--------------------+-------------------+ | 1 | 1 | 1 | NULL | NULL | CheckRouterCommand | wait:80|timeout:0 | +----+----------------+--------+------------+---------+--------------------+-------------------+ 1 row in set (0.00 sec) By providing the optional zoneid, podid, clusterid, hostid you can induce the latency at various levels. This delay will happen before the command is processed and post-execution return Command's Answer back to management server. Signed-off-by: Prasanna Santhanam --- .../cloud/agent/manager/MockAgentManager.java | 2 -- .../agent/manager/MockAgentManagerImpl.java | 9 ------ .../cloud/agent/manager/MockVmManager.java | 1 + .../agent/manager/MockVmManagerImpl.java | 29 +++++++++++++++++-- .../agent/manager/SimulatorManagerImpl.java | 18 +++++------- 5 files changed, 36 insertions(+), 23 deletions(-) diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManager.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManager.java index 7db5b20f55c..2bb1205b115 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManager.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManager.java @@ -56,8 +56,6 @@ public interface MockAgentManager extends Manager { Answer pingTest(PingTestCommand cmd); - Answer prepareForMigrate(PrepareForMigrationCommand cmd); - MockHost getHost(String guid); Answer maintain(MaintainCommand cmd); diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java index cb992979e07..f6bc8fc7fee 100755 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java @@ -429,15 +429,6 @@ public class MockAgentManagerImpl implements MockAgentManager { return new Answer(cmd); } - @Override - public PrepareForMigrationAnswer prepareForMigrate(PrepareForMigrationCommand cmd) { - VirtualMachineTO vm = cmd.getVirtualMachine(); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Preparing host for migrating " + vm); - } - return new PrepareForMigrationAnswer(cmd); - } - @Override public boolean start() { return true; diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManager.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManager.java index 82f600d04b3..117e2f6374f 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManager.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManager.java @@ -74,6 +74,7 @@ public interface MockVmManager extends Manager { HashMap> syncNetworkGroups(SimulatorInfo info); SecurityGroupRuleAnswer AddSecurityGroupRules(SecurityGroupRulesCmd cmd, SimulatorInfo info); MigrateAnswer Migrate(MigrateCommand cmd, SimulatorInfo info); + PrepareForMigrationAnswer prepareForMigrate(PrepareForMigrationCommand cmd); GetDomRVersionAnswer getDomRVersion(GetDomRVersionCmd cmd); Map getVms(String hostGuid); diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java index 8177cda6b64..d04e166309f 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java @@ -388,8 +388,12 @@ public class MockVmManagerImpl implements MockVmManager { String destGuid = cmd.getHostGuid(); MockVMVO vm = _mockVmDao.findByVmNameAndHost(vmName, info.getHostUuid()); if (vm == null) { - return new MigrateAnswer(cmd, false, "can;t find vm:" + vmName + " on host:" + info.getHostUuid(), null); - } + return new MigrateAnswer(cmd, false, "can't find vm:" + vmName + " on host:" + info.getHostUuid(), null); + } else { + if (vm.getState() == State.Migrating) { + vm.setState(State.Running); + } + } MockHost destHost = _mockHostDao.findByGuid(destGuid); if (destHost == null) { @@ -409,6 +413,27 @@ public class MockVmManagerImpl implements MockVmManager { } } + @Override + public PrepareForMigrationAnswer prepareForMigrate(PrepareForMigrationCommand cmd) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + VirtualMachineTO vmTo = cmd.getVirtualMachine(); + try { + txn.start(); + MockVMVO vm = _mockVmDao.findById(vmTo.getId()); + vm.setState(State.Migrating); + _mockVmDao.update(vm.getId(), vm); + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("unable to find vm " + vmTo.getName(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + return new PrepareForMigrationAnswer(cmd); + } + } + @Override public Answer IpAssoc(IpAssocCommand cmd) { return new Answer(cmd); diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java index a32da34f0a9..3d572ff83a3 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java @@ -16,8 +16,6 @@ // under the License. package com.cloud.agent.manager; -import java.sql.Connection; -import java.sql.SQLException; import java.util.HashMap; import java.util.Map; @@ -58,6 +56,7 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine.State; + @Local(value = { SimulatorManager.class }) public class SimulatorManagerImpl implements SimulatorManager { private static final Logger s_logger = Logger.getLogger(SimulatorManagerImpl.class); @@ -165,7 +164,7 @@ public class SimulatorManagerImpl implements SimulatorManager { } else if (cmd instanceof PingTestCommand) { return _mockAgentMgr.pingTest((PingTestCommand)cmd); } else if (cmd instanceof PrepareForMigrationCommand) { - return _mockAgentMgr.prepareForMigrate((PrepareForMigrationCommand)cmd); + return _mockVmMgr.prepareForMigrate((PrepareForMigrationCommand)cmd); } else if (cmd instanceof MigrateCommand) { return _mockVmMgr.Migrate((MigrateCommand)cmd, info); } else if (cmd instanceof StartCommand) { @@ -173,11 +172,11 @@ public class SimulatorManagerImpl implements SimulatorManager { } else if (cmd instanceof CheckSshCommand) { return _mockVmMgr.checkSshCommand((CheckSshCommand)cmd); } else if (cmd instanceof CheckVirtualMachineCommand) { - return _mockVmMgr.checkVmState((CheckVirtualMachineCommand)cmd); + return _mockVmMgr.checkVmState((CheckVirtualMachineCommand)cmd); } else if (cmd instanceof SetStaticNatRulesCommand) { return _mockVmMgr.SetStaticNatRules((SetStaticNatRulesCommand)cmd); } else if (cmd instanceof SetFirewallRulesCommand) { - return _mockVmMgr.SetFirewallRules((SetFirewallRulesCommand)cmd); + return _mockVmMgr.SetFirewallRules((SetFirewallRulesCommand)cmd); } else if (cmd instanceof SetPortForwardingRulesCommand) { return _mockVmMgr.SetPortForwardingRules((SetPortForwardingRulesCommand)cmd); } else if (cmd instanceof NetworkUsageCommand) { @@ -193,7 +192,7 @@ public class SimulatorManagerImpl implements SimulatorManager { } else if (cmd instanceof CleanupNetworkRulesCmd) { return _mockVmMgr.CleanupNetworkRules((CleanupNetworkRulesCmd)cmd, info); } else if (cmd instanceof CheckNetworkCommand) { - return _mockAgentMgr.checkNetworkCommand((CheckNetworkCommand) cmd); + return _mockAgentMgr.checkNetworkCommand((CheckNetworkCommand) cmd); }else if (cmd instanceof StopCommand) { return _mockVmMgr.stopVM((StopCommand)cmd); } else if (cmd instanceof RebootCommand) { @@ -261,12 +260,11 @@ public class SimulatorManagerImpl implements SimulatorManager { } else if (cmd instanceof BumpUpPriorityCommand) { return _mockVmMgr.bumpPriority((BumpUpPriorityCommand) cmd); } else if (cmd instanceof GetDomRVersionCmd) { - return _mockVmMgr.getDomRVersion((GetDomRVersionCmd) cmd); + return _mockVmMgr.getDomRVersion((GetDomRVersionCmd) cmd); } else if (cmd instanceof ClusterSyncCommand) { - return new Answer(cmd); - //return new ClusterSyncAnswer(((ClusterSyncCommand) cmd).getClusterId(), this.getVmStates(hostGuid)); + return new Answer(cmd); } else if (cmd instanceof CopyVolumeCommand) { - return _mockStorageMgr.CopyVolume((CopyVolumeCommand) cmd); + return _mockStorageMgr.CopyVolume((CopyVolumeCommand) cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); } From f0c3b4c62a7a1a440d723696d61b42dad58f6faf Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Sat, 22 Dec 2012 14:09:59 -0800 Subject: [PATCH 12/23] simulator:Using the priority to decide b/w MASTER/BACKUP BootArgs carry router priority for master and backup and simulator will reuse the priority to decide RvR status. Deprecating the odd/even logic. Signed-off-by: Prasanna Santhanam --- .../agent/manager/MockVmManagerImpl.java | 22 ++++++++++--------- .../src/com/cloud/simulator/MockVMVO.java | 10 +++++++++ .../src/com/cloud/simulator/MockVm.java | 3 +++ setup/db/create-schema-simulator.sql | 1 + 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java index d04e166309f..40cd80acf8e 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java @@ -107,6 +107,7 @@ public class MockVmManagerImpl implements MockVmManager { vm.setName(vmName); vm.setVncPort(vncPort); vm.setHostId(host.getId()); + vm.setBootargs(bootArgs); if(vmName.startsWith("s-")) { vm.setType("SecondaryStorageVm"); } else if (vmName.startsWith("v-")) { @@ -238,15 +239,16 @@ public class MockVmManagerImpl implements MockVmManager { @Override public CheckRouterAnswer checkRouter(CheckRouterCommand cmd) { String router_name = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - int router_id = Integer.parseInt(router_name.split("-")[1]); - if (router_id % 2 == 0) { - s_logger.debug("Found even routerId, making it MASTER in RvR"); + MockVm vm = _mockVmDao.findByVmName(router_name); + String args = vm.getBootargs(); + if (args.indexOf("router_pr=100") > 0) { + s_logger.debug("Router priority is for MASTER"); CheckRouterAnswer ans = new CheckRouterAnswer(cmd, "Status: MASTER & Bumped: NO", true); ans.setState(VirtualRouter.RedundantState.MASTER); return ans; } else { - s_logger.debug("Found odd routerId, making it BACKUP in RvR"); - CheckRouterAnswer ans = new CheckRouterAnswer(cmd, "Status: MASTER & Bumped: NO", true); + s_logger.debug("Router priority is for BACKUP"); + CheckRouterAnswer ans = new CheckRouterAnswer(cmd, "Status: BACKUP & Bumped: NO", true); ans.setState(VirtualRouter.RedundantState.BACKUP); return ans; } @@ -255,13 +257,13 @@ public class MockVmManagerImpl implements MockVmManager { @Override public Answer bumpPriority(BumpUpPriorityCommand cmd) { String router_name = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - int router_id = Integer.parseInt(router_name.split("-")[1]); - if (router_id % 2 == 0) { - return new Answer(cmd, true, "Status: MASTER & Bumped: YES"); - } else { + MockVm vm = _mockVmDao.findByVmName(router_name); + String args = vm.getBootargs(); + if (args.indexOf("router_pr=100") > 0) { return new Answer(cmd, true, "Status: BACKUP & Bumped: YES"); + } else { + return new Answer(cmd, true, "Status: MASTER & Bumped: YES"); } - } @Override diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVMVO.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVMVO.java index 4fb30850b63..3a5aa3d4c10 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVMVO.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVMVO.java @@ -55,6 +55,9 @@ public class MockVMVO implements MockVm{ @Column(name="cpu") private int cpu; + @Column(name="bootargs") + private String bootargs; + public MockVMVO() { } @@ -127,4 +130,11 @@ public class MockVMVO implements MockVm{ this.vmType = type; } + public String getBootargs() { + return bootargs; + } + + public void setBootargs(String bootargs) { + this.bootargs = bootargs; + } } diff --git a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVm.java b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVm.java index 2e1ba27c71c..e46b6a0cf99 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVm.java +++ b/plugins/hypervisors/simulator/src/com/cloud/simulator/MockVm.java @@ -41,4 +41,7 @@ public interface MockVm { public void setType(String type); public void setVncPort(int vncPort); public long getId(); + + public String getBootargs(); + public void setBootargs(String bootargs); } diff --git a/setup/db/create-schema-simulator.sql b/setup/db/create-schema-simulator.sql index 1ab838b1e73..6d4a130e2ba 100644 --- a/setup/db/create-schema-simulator.sql +++ b/setup/db/create-schema-simulator.sql @@ -76,6 +76,7 @@ CREATE TABLE `simulator`.`mockvm` ( `vnc_port` bigint unsigned, `memory` bigint unsigned, `cpu` bigint unsigned, + `bootargs` varchar(255), PRIMARY KEY (`id`), INDEX `i_mockvm__host_id`(`host_id`), INDEX `i_mockvm__state`(`state`), From 8f6fdc3efc37a2e97d1b745e9109e1fc85a990f4 Mon Sep 17 00:00:00 2001 From: Devdeep Singh Date: Sun, 23 Dec 2012 19:03:03 -0800 Subject: [PATCH 13/23] CLOUDSTACK-227: Fix NPE and throw an exception if the network is not found in Xen Signed-off-by: Rohit Yadav --- .../hypervisor/xen/resource/CitrixResourceBase.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 313703c0a82..36a12b1b4fa 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -4333,8 +4333,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } XsLocalNetwork storageNic1 = null; storageNic1 = getNetworkByName(conn, _storageNetworkName1); - _host.storageNetwork1 = storageNic1.getNetworkRecord(conn).uuid; - _host.storagePif1 = storageNic1.getPifRecord(conn).uuid; + if (storageNic1 == null) { + s_logger.warn("Unable to find storage network " + _storageNetworkName1 + " for host " + _host.ip); + throw new IllegalArgumentException("Unable to find storage network " + _storageNetworkName1 + " for host " + _host.ip); + } else { + _host.storageNetwork1 = storageNic1.getNetworkRecord(conn).uuid; + _host.storagePif1 = storageNic1.getPifRecord(conn).uuid; + } XsLocalNetwork storageNic2 = null; if (_storageNetworkName2 != null) { From 1f1a13448f2a5fcdf45e44a5a8ba8f5af66e37d5 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Sun, 23 Dec 2012 19:22:54 -0800 Subject: [PATCH 14/23] simulator: resurrect simulator hypervisor as plugin Multiple fixes: 1. changes to the mvn configuration a. include simulator to client.war b. activate simulator by profile 2. templates for simulator 3. developer prefill for simulator a. Use deplydb-simulator to setup simulator db 4. Inherit components-simulator.xml from components.xml 5. ListVolumesCommand missed for MockStorageManager 6. Include simulator properties into utils/db.properties TODO: Secondary storage VMs don't come up because ComponentLocator doesn't retain a unique set of adapaters by name. Fix this in subsequent checkin. --- client/pom.xml | 25 +- ...es.in => simulator_commands.properties.in} | 20 +- developer/developer-prefill.sql | 2 + developer/pom.xml | 134 +++++- .../resources/components-simulator.xml | 38 +- .../agent/manager/MockStorageManager.java | 13 +- .../agent/manager/MockStorageManagerImpl.java | 66 ++- .../agent/manager/SimulatorManagerImpl.java | 47 +- .../SimulatorSecondaryDiscoverer.java | 27 ++ plugins/pom.xml | 2 +- pom.xml | 2 - setup/db/create-schema-simulator.sql | 1 + setup/db/templates.simulator.sql | 437 +----------------- utils/conf/db.properties | 11 + 14 files changed, 271 insertions(+), 554 deletions(-) rename client/tomcatconf/{simulator.properties.in => simulator_commands.properties.in} (71%) diff --git a/client/pom.xml b/client/pom.xml index 1673429f3d9..77077066f9a 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -44,7 +44,7 @@ org.apache.cloudstack cloud-plugin-user-authenticator-sha256salted ${project.version} - + org.apache.cloudstack cloud-plugin-network-nvp @@ -66,9 +66,9 @@ ${project.version} - org.apache.cloudstack - cloud-plugin-hypervisor-ovm - ${project.version} + org.apache.cloudstack + cloud-plugin-hypervisor-ovm + ${project.version} org.apache.cloudstack @@ -290,7 +290,7 @@ - org.eclipse.m2e @@ -324,6 +324,21 @@ + + simulator + + + simulator + + + + + org.apache.cloudstack + cloud-plugin-hypervisor-simulator + ${project.version} + + + netapp diff --git a/client/tomcatconf/simulator.properties.in b/client/tomcatconf/simulator_commands.properties.in similarity index 71% rename from client/tomcatconf/simulator.properties.in rename to client/tomcatconf/simulator_commands.properties.in index 24e5e627c71..d2a46997e6f 100644 --- a/client/tomcatconf/simulator.properties.in +++ b/client/tomcatconf/simulator_commands.properties.in @@ -5,9 +5,9 @@ # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -15,17 +15,5 @@ # specific language governing permissions and limitations # under the License. -host=127.0.0.1 -port=8250 -workers=3 -zone=1 -pod=1 -run=13 -sequence=r -agent.save.path=/tmp/agents -latency=2 -latency.start.range=2 -latency.end.range=2 -delay.distribution={(5,10); (5,10); (5,10); (5,10); (5,10); (5,10); (5,10); (5,10); (5,10); (10,120)} -property.scan.enabled=1 -property.scan.interval=300 + +configureSimulator=com.cloud.api.commands.ConfigureSimulator;1 \ No newline at end of file diff --git a/developer/developer-prefill.sql b/developer/developer-prefill.sql index 8e215ba77d9..e14ac375e98 100644 --- a/developer/developer-prefill.sql +++ b/developer/developer-prefill.sql @@ -16,6 +16,8 @@ -- under the License. -- Add a default ROOT domain +use cloud; + INSERT INTO `cloud`.`domain` (id, name, parent, path, owner) VALUES (1, 'ROOT', NULL, '/', 2); diff --git a/developer/pom.xml b/developer/pom.xml index 61cb1108d3a..b782a595f3a 100644 --- a/developer/pom.xml +++ b/developer/pom.xml @@ -1,4 +1,4 @@ - 4.0.0 cloud-developer @@ -101,6 +102,7 @@ + org.gjt.mm.mysql.Driver jdbc:mysql://${db.cloud.host}:${db.cloud.port}/cloud ${db.cloud.username} @@ -109,7 +111,6 @@ ${maven.test.skip} true - drop-database @@ -310,9 +311,9 @@ true - - ${basedir}/developer-prefill.sql - + + ${basedir}/developer-prefill.sql + @@ -320,5 +321,128 @@ + + + + simulator + + deploydb-simulator + + + + + org.codehaus.mojo + properties-maven-plugin + 1.0-alpha-2 + + + initialize + + read-project-properties + + + + ${project.parent.basedir}/utils/conf/db.properties + ${project.parent.basedir}/utils/conf/db.properties.override + + true + + + + + + org.codehaus.mojo + sql-maven-plugin + 1.5 + + + mysql + mysql-connector-java + ${cs.mysql.version} + + + + org.gjt.mm.mysql.Driver + jdbc:mysql://${db.simulator.host}:3306/simulator + ${db.simulator.username} + ${db.simulator.password} + ${maven.test.skip} + true + + + + drop-database + process-test-resources + + execute + + + root + ${db.root.password} + jdbc:mysql://${db.simulator.host}:3306 + drop database if exists `simulator` + + + + create-database + process-test-resources + + execute + + + root + ${db.root.password} + jdbc:mysql://${db.simulator.host}:3306 + create database `simulator` + + + + grant-user-cloud + process-test-resources + + execute + + + root + ${db.root.password} + jdbc:mysql://${db.simulator.host}:3306 + GRANT ALL ON simulator.* to + ${db.simulator.username}@`localhost` identified by + '${db.simulator.password}'; + + + + grant-user-cloud-all + process-test-resources + + execute + + + root + ${db.root.password} + jdbc:mysql://${db.simulator.host}:3306 + GRANT ALL ON simulator.* to + ${db.simulator.username}@`%` identified by + '${db.simulator.password}'; + + + + create-schema + process-test-resources + + execute + + + + ${basedir}/target/db/create-schema-simulator.sql + ${basedir}/target/db/templates.simulator.sql + + + + + + + + diff --git a/plugins/hypervisors/simulator/resources/components-simulator.xml b/plugins/hypervisors/simulator/resources/components-simulator.xml index 4629acc866a..2658e4db3ee 100644 --- a/plugins/hypervisors/simulator/resources/components-simulator.xml +++ b/plugins/hypervisors/simulator/resources/components-simulator.xml @@ -18,7 +18,7 @@ specific language governing permissions and limitations under the License. --> - + @@ -30,44 +30,12 @@ under the License. true - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - @@ -95,4 +63,4 @@ under the License. - \ No newline at end of file + diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java index fc8aacc6ec3..ff26d185d76 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java @@ -35,17 +35,7 @@ import com.cloud.agent.api.ModifyStoragePoolCommand; import com.cloud.agent.api.SecStorageSetupCommand; import com.cloud.agent.api.SecStorageVMSetupCommand; import com.cloud.agent.api.StoragePoolInfo; -import com.cloud.agent.api.storage.CopyVolumeAnswer; -import com.cloud.agent.api.storage.CopyVolumeCommand; -import com.cloud.agent.api.storage.CreateAnswer; -import com.cloud.agent.api.storage.CreateCommand; -import com.cloud.agent.api.storage.DeleteTemplateCommand; -import com.cloud.agent.api.storage.DestroyCommand; -import com.cloud.agent.api.storage.DownloadCommand; -import com.cloud.agent.api.storage.DownloadProgressCommand; -import com.cloud.agent.api.storage.ListTemplateCommand; -import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; -import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; +import com.cloud.agent.api.storage.*; import com.cloud.utils.component.Manager; public interface MockStorageManager extends Manager { @@ -64,6 +54,7 @@ public interface MockStorageManager extends Manager { public Answer SecStorageSetup(SecStorageSetupCommand cmd); public Answer ListTemplates(ListTemplateCommand cmd); + public Answer ListVolumes(ListVolumeCommand cmd); public Answer Destroy(DestroyCommand cmd); public Answer Download(DownloadCommand cmd); public Answer DownloadProcess(DownloadProgressCommand cmd); diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java index 9bf4192c4bd..a950926a515 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java @@ -30,6 +30,7 @@ import java.util.UUID; import javax.ejb.Local; import javax.naming.ConfigurationException; +import com.cloud.agent.api.storage.*; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; @@ -56,20 +57,6 @@ import com.cloud.agent.api.SecStorageSetupAnswer; import com.cloud.agent.api.SecStorageSetupCommand; import com.cloud.agent.api.SecStorageVMSetupCommand; import com.cloud.agent.api.StoragePoolInfo; -import com.cloud.agent.api.storage.CopyVolumeAnswer; -import com.cloud.agent.api.storage.CopyVolumeCommand; -import com.cloud.agent.api.storage.CreateAnswer; -import com.cloud.agent.api.storage.CreateCommand; -import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; -import com.cloud.agent.api.storage.DeleteTemplateCommand; -import com.cloud.agent.api.storage.DestroyCommand; -import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.agent.api.storage.DownloadCommand; -import com.cloud.agent.api.storage.DownloadProgressCommand; -import com.cloud.agent.api.storage.ListTemplateAnswer; -import com.cloud.agent.api.storage.ListTemplateCommand; -import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; -import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VolumeTO; import com.cloud.simulator.MockHost; @@ -139,8 +126,8 @@ public class MockStorageManagerImpl implements MockStorageManager { @Override public PrimaryStorageDownloadAnswer primaryStorageDownload(PrimaryStorageDownloadCommand cmd) { - MockVolumeVO template = findVolumeFromSecondary(cmd.getUrl(), cmd.getSecondaryStorageUrl(), - MockVolumeType.TEMPLATE); + MockVolumeVO template = findVolumeFromSecondary(cmd.getUrl(), cmd.getSecondaryStorageUrl(), + MockVolumeType.TEMPLATE); if (template == null) { return new PrimaryStorageDownloadAnswer("Can't find primary storage"); } @@ -421,6 +408,49 @@ public class MockStorageManagerImpl implements MockStorageManager { return new SecStorageSetupAnswer(storage.getMountPoint()); } + @Override + public Answer ListVolumes(ListVolumeCommand cmd) { + Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); + MockSecStorageVO storage = null; + try { + txn.start(); + storage = _mockSecStorageDao.findByUrl(cmd.getSecUrl()); + if (storage == null) { + return new Answer(cmd, false, "Failed to get secondary storage"); + } + txn.commit(); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when finding sec storage " + cmd.getSecUrl(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + + txn = Transaction.open(Transaction.SIMULATOR_DB); + try { + txn.start(); + List volumes = _mockVolumeDao.findByStorageIdAndType(storage.getId(), + MockVolumeType.VOLUME); + + Map templateInfos = new HashMap(); + for (MockVolumeVO volume : volumes) { + templateInfos.put(volume.getName(), new TemplateInfo(volume.getName(), volume.getPath() + .replaceAll(storage.getMountPoint(), ""), volume.getSize(), volume.getSize(), true, false)); + } + txn.commit(); + return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos); + } catch (Exception ex) { + txn.rollback(); + throw new CloudRuntimeException("Error when finding template on sec storage " + storage.getId(), ex); + } finally { + txn.close(); + txn = Transaction.open(Transaction.CLOUD_DB); + txn.close(); + } + } + @Override public Answer ListTemplates(ListTemplateCommand cmd) { Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); @@ -907,7 +937,7 @@ public class MockStorageManagerImpl implements MockStorageManager { long defaultTemplateSize = 2 * 1024 * 1024 * 1024L; MockVolumeVO template = new MockVolumeVO(); template.setName("simulator-domR"); - template.setPath(storage.getMountPoint() + "template/tmpl/1/9/" + UUID.randomUUID().toString()); + template.setPath(storage.getMountPoint() + "template/tmpl/1/10/" + UUID.randomUUID().toString()); template.setPoolId(storage.getId()); template.setSize(defaultTemplateSize); template.setType(MockVolumeType.TEMPLATE); @@ -928,7 +958,7 @@ public class MockStorageManagerImpl implements MockStorageManager { template = new MockVolumeVO(); template.setName("simulator-Centos"); - template.setPath(storage.getMountPoint() + "template/tmpl/1/10/" + UUID.randomUUID().toString()); + template.setPath(storage.getMountPoint() + "template/tmpl/1/11/" + UUID.randomUUID().toString()); template.setPoolId(storage.getId()); template.setSize(defaultTemplateSize); template.setType(MockVolumeType.TEMPLATE); diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java index 3d572ff83a3..4f70ee5bae7 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java @@ -23,6 +23,7 @@ import javax.ejb.Local; import javax.naming.ConfigurationException; import com.cloud.agent.api.*; +import com.cloud.agent.api.storage.*; import org.apache.log4j.Logger; import com.cloud.agent.api.check.CheckSshCommand; @@ -36,14 +37,6 @@ import com.cloud.agent.api.routing.SetFirewallRulesCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; import com.cloud.agent.api.routing.VmDataCommand; -import com.cloud.agent.api.storage.CopyVolumeCommand; -import com.cloud.agent.api.storage.CreateCommand; -import com.cloud.agent.api.storage.DeleteTemplateCommand; -import com.cloud.agent.api.storage.DestroyCommand; -import com.cloud.agent.api.storage.DownloadCommand; -import com.cloud.agent.api.storage.DownloadProgressCommand; -import com.cloud.agent.api.storage.ListTemplateCommand; -import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.simulator.MockConfigurationVO; import com.cloud.simulator.MockHost; import com.cloud.simulator.MockVMVO; @@ -158,45 +151,45 @@ public class SimulatorManagerImpl implements SimulatorManager { } if (cmd instanceof GetHostStatsCommand) { - return _mockAgentMgr.getHostStatistic((GetHostStatsCommand)cmd); + return _mockAgentMgr.getHostStatistic((GetHostStatsCommand) cmd); } else if (cmd instanceof CheckHealthCommand) { - return _mockAgentMgr.checkHealth((CheckHealthCommand)cmd); + return _mockAgentMgr.checkHealth((CheckHealthCommand) cmd); } else if (cmd instanceof PingTestCommand) { - return _mockAgentMgr.pingTest((PingTestCommand)cmd); + return _mockAgentMgr.pingTest((PingTestCommand) cmd); } else if (cmd instanceof PrepareForMigrationCommand) { - return _mockVmMgr.prepareForMigrate((PrepareForMigrationCommand)cmd); + return _mockVmMgr.prepareForMigrate((PrepareForMigrationCommand) cmd); } else if (cmd instanceof MigrateCommand) { - return _mockVmMgr.Migrate((MigrateCommand)cmd, info); + return _mockVmMgr.Migrate((MigrateCommand) cmd, info); } else if (cmd instanceof StartCommand) { - return _mockVmMgr.startVM((StartCommand)cmd, info); + return _mockVmMgr.startVM((StartCommand) cmd, info); } else if (cmd instanceof CheckSshCommand) { - return _mockVmMgr.checkSshCommand((CheckSshCommand)cmd); + return _mockVmMgr.checkSshCommand((CheckSshCommand) cmd); } else if (cmd instanceof CheckVirtualMachineCommand) { - return _mockVmMgr.checkVmState((CheckVirtualMachineCommand)cmd); + return _mockVmMgr.checkVmState((CheckVirtualMachineCommand) cmd); } else if (cmd instanceof SetStaticNatRulesCommand) { - return _mockVmMgr.SetStaticNatRules((SetStaticNatRulesCommand)cmd); + return _mockVmMgr.SetStaticNatRules((SetStaticNatRulesCommand) cmd); } else if (cmd instanceof SetFirewallRulesCommand) { - return _mockVmMgr.SetFirewallRules((SetFirewallRulesCommand)cmd); + return _mockVmMgr.SetFirewallRules((SetFirewallRulesCommand) cmd); } else if (cmd instanceof SetPortForwardingRulesCommand) { - return _mockVmMgr.SetPortForwardingRules((SetPortForwardingRulesCommand)cmd); + return _mockVmMgr.SetPortForwardingRules((SetPortForwardingRulesCommand) cmd); } else if (cmd instanceof NetworkUsageCommand) { - return _mockVmMgr.getNetworkUsage((NetworkUsageCommand)cmd); + return _mockVmMgr.getNetworkUsage((NetworkUsageCommand) cmd); } else if (cmd instanceof IpAssocCommand) { - return _mockVmMgr.IpAssoc((IpAssocCommand)cmd); + return _mockVmMgr.IpAssoc((IpAssocCommand) cmd); } else if (cmd instanceof LoadBalancerConfigCommand) { - return _mockVmMgr.LoadBalancerConfig((LoadBalancerConfigCommand)cmd); + return _mockVmMgr.LoadBalancerConfig((LoadBalancerConfigCommand) cmd); } else if (cmd instanceof DhcpEntryCommand) { - return _mockVmMgr.AddDhcpEntry((DhcpEntryCommand)cmd); + return _mockVmMgr.AddDhcpEntry((DhcpEntryCommand) cmd); } else if (cmd instanceof VmDataCommand) { - return _mockVmMgr.setVmData((VmDataCommand)cmd); + return _mockVmMgr.setVmData((VmDataCommand) cmd); } else if (cmd instanceof CleanupNetworkRulesCmd) { - return _mockVmMgr.CleanupNetworkRules((CleanupNetworkRulesCmd)cmd, info); + return _mockVmMgr.CleanupNetworkRules((CleanupNetworkRulesCmd) cmd, info); } else if (cmd instanceof CheckNetworkCommand) { return _mockAgentMgr.checkNetworkCommand((CheckNetworkCommand) cmd); }else if (cmd instanceof StopCommand) { return _mockVmMgr.stopVM((StopCommand)cmd); } else if (cmd instanceof RebootCommand) { - return _mockVmMgr.rebootVM((RebootCommand)cmd); + return _mockVmMgr.rebootVM((RebootCommand) cmd); } else if (cmd instanceof GetVncPortCommand) { return _mockVmMgr.getVncPort((GetVncPortCommand)cmd); } else if (cmd instanceof CheckConsoleProxyLoadCommand) { @@ -225,6 +218,8 @@ public class SimulatorManagerImpl implements SimulatorManager { return _mockStorageMgr.SecStorageSetup((SecStorageSetupCommand)cmd); } else if (cmd instanceof ListTemplateCommand) { return _mockStorageMgr.ListTemplates((ListTemplateCommand)cmd); + } else if (cmd instanceof ListVolumeCommand) { + return _mockStorageMgr.ListVolumes((ListVolumeCommand)cmd); } else if (cmd instanceof DestroyCommand) { return _mockStorageMgr.Destroy((DestroyCommand)cmd); } else if (cmd instanceof DownloadProgressCommand) { diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java index 5d4d5b97c40..3f7cea5b6b1 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java +++ b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.resource; +import java.net.URI; import java.util.List; import java.util.Map; @@ -39,8 +40,11 @@ import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.secondary.SecondaryStorageDiscoverer; import com.cloud.utils.component.Inject; import com.cloud.utils.exception.CloudRuntimeException; +import org.apache.log4j.Logger; + @Local(value=Discoverer.class) public class SimulatorSecondaryDiscoverer extends SecondaryStorageDiscoverer implements ResourceStateAdapter, Listener { + private static final Logger s_logger = Logger.getLogger(SimulatorSecondaryDiscoverer.class); @Inject MockStorageManager _mockStorageMgr = null; @Inject AgentManager _agentMgr; @Inject ResourceManager _resourceMgr; @@ -53,10 +57,33 @@ public class SimulatorSecondaryDiscoverer extends SecondaryStorageDiscoverer imp return super.configure(name, params); } + @Override + public Map> find(long dcId, Long podId, Long clusterId, URI uri, String username, String password, List hostTags) { + if (!uri.getScheme().equalsIgnoreCase("nfs") && !uri.getScheme().equalsIgnoreCase("file") + && !uri.getScheme().equalsIgnoreCase("iso") && !uri.getScheme().equalsIgnoreCase("dummy")) { + s_logger.debug("It's not NFS or file or ISO, so not a secondary storage server: " + uri.toString()); + return null; + } + + if (uri.getScheme().equalsIgnoreCase("nfs") || uri.getScheme().equalsIgnoreCase("iso")) { + return createNfsSecondaryStorageResource(dcId, podId, uri); + } else if (uri.getScheme().equalsIgnoreCase("file")) { + return createLocalSecondaryStorageResource(dcId, podId, uri); + } else if (uri.getScheme().equalsIgnoreCase("dummy")) { + return createDummySecondaryStorageResource(dcId, podId, uri); + } else { + return null; + } + } + + @Override public void postDiscovery(List hosts, long msId) { super.postDiscovery(hosts, msId); for (HostVO host: hosts) { + if(s_logger.isDebugEnabled()) { + s_logger.debug("Preinstalling simulator templates"); + } _mockStorageMgr.preinstallTemplates(host.getStorageUrl(), host.getDataCenterId()); } } diff --git a/plugins/pom.xml b/plugins/pom.xml index af8621028db..820e76fc0e9 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -129,7 +129,7 @@ simulator - nonoss + simulator diff --git a/pom.xml b/pom.xml index 4d31cded68c..f3740326024 100644 --- a/pom.xml +++ b/pom.xml @@ -384,7 +384,5 @@ vmware-base - - diff --git a/setup/db/create-schema-simulator.sql b/setup/db/create-schema-simulator.sql index 6d4a130e2ba..facfefc5e75 100644 --- a/setup/db/create-schema-simulator.sql +++ b/setup/db/create-schema-simulator.sql @@ -14,6 +14,7 @@ -- KIND, either express or implied. See the License for the -- specific language governing permissions and limitations -- under the License. +use simulator; DROP TABLE IF EXISTS `simulator`.`mockhost`; DROP TABLE IF EXISTS `simulator`.`mocksecstorage`; diff --git a/setup/db/templates.simulator.sql b/setup/db/templates.simulator.sql index 2a140a4b21f..7e712f54177 100755 --- a/setup/db/templates.simulator.sql +++ b/setup/db/templates.simulator.sql @@ -17,439 +17,6 @@ INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type) - VALUES (1, 'routing-1', 'SystemVM Template (XenServer)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/routing/debian/latest/systemvm.vhd.bz2', 'c33dfaf0937b35c25ef6a0fdd98f24d3', 0, 'SystemVM Template (XenServer)', 'VHD', 15, 0, 1, 'XenServer'); + VALUES (10, 'simulator-domR', 'SystemVM Template (simulator)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/routing/debian/latest/systemvm.vhd.bz2', '', 0, 'SystemVM Template (simulator)', 'VHD', 15, 0, 1, 'Simulator'); INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type) - VALUES (2, 'centos53-x86_64', 'CentOS 5.3(64-bit) no GUI (XenServer)', 1, now(), 'BUILTIN', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/centos53-x86_64/latest/f59f18fb-ae94-4f97-afd2-f84755767aca.vhd.bz2', 'b63d854a9560c013142567bbae8d98cf', 0, 'CentOS 5.3(64-bit) no GUI (XenServer)', 'VHD', 11, 1, 1, 'XenServer'); - -INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type) - VALUES (3, 'routing-3', 'SystemVM Template (KVM)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/kvm/eec2209b-9875-3c8d-92be-c001bd8a0faf.qcow2.bz2', 'fe80a229e3bf38a702e836236ed07f57', 0, 'SystemVM Template (KVM)', 'QCOW2', 15, 0, 1, 'KVM'); - -INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, display_text, enable_password, format, guest_os_id, featured, cross_zones, hypervisor_type) - VALUES (4, 'centos55-x86_64', 'CentOS 5.5(64-bit) no GUI (KVM)', 1, now(), 'BUILTIN', 0, 64, 1, 'http://download.cloud.com/templates/builtin/eec2209b-9875-3c8d-92be-c001bd8a0faf.qcow2.bz2', '1da20ae69b54f761f3f733dce97adcc0', 'CentOS 5.5(64-bit) no GUI (KVM)', 0, 'QCOW2', 112, 1, 1, 'KVM'); - -INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type) - VALUES (7, 'centos53-x64', 'CentOS 5.3(64-bit) no GUI (vSphere)', 1, now(), 'BUILTIN', 0, 64, 1, 'http://download.cloud.com/releases/2.2.0/CentOS5.3-x86_64.ova', 'f6f881b7f2292948d8494db837fe0f47', 0, 'CentOS 5.3(64-bit) no GUI (vSphere)', 'OVA', 12, 1, 1, 'VMware'); - -INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type) - VALUES (8, 'routing-8', 'SystemVM Template (vSphere)', 0, now(), 'SYSTEM', 0, 32, 1, 'http://download.cloud.com/releases/2.2.0/systemvm.ova', 'ee3dc55e94e23a0490310bb78cf8cc76', 0, 'SystemVM Template (vSphere)', 'OVA', 15, 0, 1, 'VMware'); - -INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type) - VALUES (9, 'simulator-domR', 'SystemVM Template (simulator)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/routing/debian/latest/systemvm.vhd.bz2', '', 0, 'SystemVM Template (simulator)', 'VHD', 15, 0, 1, 'Simulator'); -INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type) - VALUES (10, 'simulator-Centos', 'CentOS 5.3(64-bit) no GUI (Simulator)', 1, now(), 'BUILTIN', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/centos53-x86_64/latest/f59f18fb-ae94-4f97-afd2-f84755767aca.vhd.bz2', '', 0, 'CentOS 5.3(64-bit) no GUI (Simulator)', 'VHD', 11, 1, 1, 'Simulator'); - -INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (1, 'CentOS'); -INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (2, 'Debian'); -INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (3, 'Oracle'); -INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (4, 'RedHat'); -INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (5, 'SUSE'); -INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (6, 'Windows'); -INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (7, 'Other'); -INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (8, 'Novel'); -INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (9, 'Unix'); -INSERT INTO `cloud`.`guest_os_category` (id, name) VALUES (10, 'Ubuntu'); - - -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (1, 1, 'CentOS 4.5 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (2, 1, 'CentOS 4.6 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (3, 1, 'CentOS 4.7 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (4, 1, 'CentOS 4.8 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (5, 1, 'CentOS 5.0 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (6, 1, 'CentOS 5.0 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (7, 1, 'CentOS 5.1 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (8, 1, 'CentOS 5.1 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (9, 1, 'CentOS 5.2 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (10, 1, 'CentOS 5.2 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (11, 1, 'CentOS 5.3 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (12, 1, 'CentOS 5.3 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (13, 1, 'CentOS 5.4 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (14, 1, 'CentOS 5.4 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (15, 2, 'Debian GNU/Linux 5.0 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (16, 3, 'Oracle Enterprise Linux 5.0 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (17, 3, 'Oracle Enterprise Linux 5.0 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (18, 3, 'Oracle Enterprise Linux 5.1 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (19, 3, 'Oracle Enterprise Linux 5.1 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (20, 3, 'Oracle Enterprise Linux 5.2 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (21, 3, 'Oracle Enterprise Linux 5.2 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (22, 3, 'Oracle Enterprise Linux 5.3 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (23, 3, 'Oracle Enterprise Linux 5.3 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (24, 3, 'Oracle Enterprise Linux 5.4 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (25, 3, 'Oracle Enterprise Linux 5.4 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (26, 4, 'Red Hat Enterprise Linux 4.5 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (27, 4, 'Red Hat Enterprise Linux 4.6 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (28, 4, 'Red Hat Enterprise Linux 4.7 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (29, 4, 'Red Hat Enterprise Linux 4.8 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (30, 4, 'Red Hat Enterprise Linux 5.0 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (31, 4, 'Red Hat Enterprise Linux 5.0 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (32, 4, 'Red Hat Enterprise Linux 5.1 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (33, 4, 'Red Hat Enterprise Linux 5.1 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (34, 4, 'Red Hat Enterprise Linux 5.2 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (35, 4, 'Red Hat Enterprise Linux 5.2 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (36, 4, 'Red Hat Enterprise Linux 5.3 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (37, 4, 'Red Hat Enterprise Linux 5.3 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (38, 4, 'Red Hat Enterprise Linux 5.4 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (39, 4, 'Red Hat Enterprise Linux 5.4 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (40, 5, 'SUSE Linux Enterprise Server 9 SP4 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (41, 5, 'SUSE Linux Enterprise Server 10 SP1 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (42, 5, 'SUSE Linux Enterprise Server 10 SP1 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (43, 5, 'SUSE Linux Enterprise Server 10 SP2 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (44, 5, 'SUSE Linux Enterprise Server 10 SP2 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (45, 5, 'SUSE Linux Enterprise Server 10 SP3 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (46, 5, 'SUSE Linux Enterprise Server 11 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (47, 5, 'SUSE Linux Enterprise Server 11 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (48, 6, 'Windows 7 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (49, 6, 'Windows 7 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (50, 6, 'Windows Server 2003 Enterprise Edition(32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (51, 6, 'Windows Server 2003 Enterprise Edition(64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (52, 6, 'Windows Server 2008 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (53, 6, 'Windows Server 2008 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (54, 6, 'Windows Server 2008 R2 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (55, 6, 'Windows 2000 Server SP4 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (56, 6, 'Windows Vista (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (57, 6, 'Windows XP SP2 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (58, 6, 'Windows XP SP3 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (59, 10, 'Other Ubuntu (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (60, 7, 'Other (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (61, 6, 'Windows 2000 Server'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (62, 6, 'Windows 98'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (63, 6, 'Windows 95'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (64, 6, 'Windows NT 4'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (65, 6, 'Windows 3.1'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (66, 4, 'Red Hat Enterprise Linux 3(32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (67, 4, 'Red Hat Enterprise Linux 3(64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (68, 7, 'Open Enterprise Server'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (69, 7, 'Asianux 3(32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (70, 7, 'Asianux 3(64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (72, 2, 'Debian GNU/Linux 5(64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (73, 2, 'Debian GNU/Linux 4(32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (74, 2, 'Debian GNU/Linux 4(64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (75, 7, 'Other 2.6x Linux (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (76, 7, 'Other 2.6x Linux (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (77, 8, 'Novell Netware 6.x'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (78, 8, 'Novell Netware 5.1'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (79, 9, 'Sun Solaris 10(32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (80, 9, 'Sun Solaris 10(64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (81, 9, 'Sun Solaris 9(Experimental)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (82, 9, 'Sun Solaris 8(Experimental)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (83, 9, 'FreeBSD (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (84, 9, 'FreeBSD (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (85, 9, 'SCO OpenServer 5'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (86, 9, 'SCO UnixWare 7'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (87, 6, 'Windows Server 2003 DataCenter Edition(32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (88, 6, 'Windows Server 2003 DataCenter Edition(64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (89, 6, 'Windows Server 2003 Standard Edition(32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (90, 6, 'Windows Server 2003 Standard Edition(64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (91, 6, 'Windows Server 2003 Web Edition'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (92, 6, 'Microsoft Small Bussiness Server 2003'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (93, 6, 'Windows XP (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (94, 6, 'Windows XP (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (95, 6, 'Windows 2000 Advanced Server'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (96, 5, 'SUSE Linux Enterprise 8(32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (97, 5, 'SUSE Linux Enterprise 8(64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (98, 7, 'Other Linux (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (99, 7, 'Other Linux (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (100, 10, 'Other Ubuntu (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (101, 6, 'Windows Vista (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (102, 6, 'DOS'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (103, 7, 'Other (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (104, 7, 'OS/2'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (105, 6, 'Windows 2000 Professional'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (106, 4, 'Red Hat Enterprise Linux 4(64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (107, 5, 'SUSE Linux Enterprise 9(32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (108, 5, 'SUSE Linux Enterprise 9(64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (109, 5, 'SUSE Linux Enterprise 10(32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (110, 5, 'SUSE Linux Enterprise 10(64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (111, 1, 'CentOS 5.5 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (112, 1, 'CentOS 5.5 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (113, 4, 'Red Hat Enterprise Linux 5.5 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (114, 4, 'Red Hat Enterprise Linux 5.5 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (115, 4, 'Fedora 13'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (116, 4, 'Fedora 12'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (117, 4, 'Fedora 11'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (118, 4, 'Fedora 10'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (119, 4, 'Fedora 9'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (120, 4, 'Fedora 8'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (121, 10, 'Ubuntu 10.04 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (122, 10, 'Ubuntu 9.10 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (123, 10, 'Ubuntu 9.04 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (124, 10, 'Ubuntu 8.10 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (125, 10, 'Ubuntu 8.04 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (126, 10, 'Ubuntu 10.04 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (127, 10, 'Ubuntu 9.10 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (128, 10, 'Ubuntu 9.04 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (129, 10, 'Ubuntu 8.10 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (130, 10, 'Ubuntu 8.04 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (131, 4, 'Red Hat Enterprise Linux 2'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (132, 2, 'Debian GNU/Linux 6(32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (133, 2, 'Debian GNU/Linux 6(64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (134, 3, 'Oracle Enterprise Linux 5.5 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (135, 3, 'Oracle Enterprise Linux 5.5 (64-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (136, 4, 'Red Hat Enterprise Linux 6.0 (32-bit)'); -INSERT INTO `cloud`.`guest_os` (id, category_id, display_name) VALUES (137, 4, 'Red Hat Enterprise Linux 6.0 (64-bit)'); - - -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'CentOS 4.5 (32-bit)', 1); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'CentOS 4.6 (32-bit)', 2); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'CentOS 4.7 (32-bit)', 3); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'CentOS 4.8 (32-bit)', 4); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'CentOS 5.0 (32-bit)', 5); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'CentOS 5.0 (64-bit)', 6); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'CentOS 5.1 (32-bit)', 7); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'CentOS 5.1 (32-bit)', 8); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'CentOS 5.2 (32-bit)', 9); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'CentOS 5.2 (64-bit)', 10); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'CentOS 5.3 (32-bit)', 11); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'CentOS 5.3 (64-bit)', 12); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'CentOS 5.4 (32-bit)', 13); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'CentOS 5.4 (64-bit)', 14); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Debian Lenny 5.0 (32-bit)', 15); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Oracle Enterprise Linux 5.0 (32-bit)', 16); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Oracle Enterprise Linux 5.0 (64-bit)', 17); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Oracle Enterprise Linux 5.1 (32-bit)', 18); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Oracle Enterprise Linux 5.1 (64-bit)', 19); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Oracle Enterprise Linux 5.2 (32-bit)', 20); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Oracle Enterprise Linux 5.2 (64-bit)', 21); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Oracle Enterprise Linux 5.3 (32-bit)', 22); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Oracle Enterprise Linux 5.3 (64-bit)', 23); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Oracle Enterprise Linux 5.4 (32-bit)', 24); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Oracle Enterprise Linux 5.4 (64-bit)', 25); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Red Hat Enterprise Linux 4.5 (32-bit)', 26); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Red Hat Enterprise Linux 4.6 (32-bit)', 27); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Red Hat Enterprise Linux 4.7 (32-bit)', 28); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Red Hat Enterprise Linux 4.8 (32-bit)', 29); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Red Hat Enterprise Linux 5.0 (32-bit)', 30); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Red Hat Enterprise Linux 5.0 (64-bit)', 31); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Red Hat Enterprise Linux 5.1 (32-bit)', 32); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Red Hat Enterprise Linux 5.1 (64-bit)', 33); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Red Hat Enterprise Linux 5.2 (32-bit)', 34); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Red Hat Enterprise Linux 5.2 (64-bit)', 35); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Red Hat Enterprise Linux 5.3 (32-bit)', 36); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Red Hat Enterprise Linux 5.3 (64-bit)', 37); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Red Hat Enterprise Linux 5.4 (32-bit)', 38); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Red Hat Enterprise Linux 5.4 (64-bit)', 39); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'SUSE Linux Enterprise Server 9 SP4 (32-bit)', 40); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'SUSE Linux Enterprise Server 10 SP1 (32-bit)', 41); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'SUSE Linux Enterprise Server 10 SP1 (64-bit)', 42); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'SUSE Linux Enterprise Server 10 SP2 (32-bit)', 43); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'SUSE Linux Enterprise Server 10 SP2 (64-bit)', 44); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'SUSE Linux Enterprise Server 10 SP3 (64-bit)', 45); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'SUSE Linux Enterprise Server 11 (32-bit)', 46); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'SUSE Linux Enterprise Server 11 (64-bit)', 47); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Windows 7 (32-bit)', 48); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Windows 7 (64-bit)', 49); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Windows Server 2003 (32-bit)', 50); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Windows Server 2003 (64-bit)', 51); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Windows Server 2008 (32-bit)', 52); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Windows Server 2008 (64-bit)', 53); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Windows Server 2008 R2 (64-bit)', 54); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Windows 2000 SP4 (32-bit)', 55); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Windows Vista (32-bit)', 56); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Windows XP SP2 (32-bit)', 57); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Windows XP SP3 (32-bit)', 58); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Other install media', 59); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Other install media', 100); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Other install media', 60); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("XenServer", 'Other install media', 103); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('XenServer', 'Other install media', 121); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('XenServer', 'Other install media', 126); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('XenServer', 'Other install media', 122); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('XenServer', 'Other install media', 127); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('XenServer', 'Other install media', 123); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('XenServer', 'Other install media', 128); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('XenServer', 'Other install media', 124); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('XenServer', 'Other install media', 129); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('XenServer', 'Other install media', 125); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('XenServer', 'Other install media', 130); - - -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows 7(32-bit)', 48); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows 7(64-bit)', 49); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows Server 2008 R2(64-bit)', 54); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows Server 2008(32-bit)', 52); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows Server 2008(64-bit)', 53); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows Server 2003, Enterprise Edition (32-bit)', 50); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows Server 2003, Enterprise Edition (64-bit)', 51); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows Server 2003, Datacenter Edition (32-bit)', 87); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows Server 2003, Datacenter Edition (64-bit)', 88); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows Server 2003, Standard Edition (32-bit)', 89); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows Server 2003, Standard Edition (64-bit)', 90); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows Server 2003, Web Edition', 91); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Small Bussiness Server 2003', 92); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows Vista (32-bit)', 56); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows Vista (64-bit)', 101); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows XP Professional (32-bit)', 93); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows XP Professional (32-bit)', 57); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows XP Professional (32-bit)', 58); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows XP Professional (64-bit)', 94); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows 2000 Advanced Server', 95); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows 2000 Server', 61); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows 2000 Professional', 105); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows 2000 Server', 55); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows 98', 62); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows 95', 63); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows NT 4', 64); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Microsoft Windows 3.1', 65); - -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Red Hat Enterprise Linux 5(32-bit)', 30); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Red Hat Enterprise Linux 5(32-bit)', 32); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Red Hat Enterprise Linux 5(32-bit)', 34); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Red Hat Enterprise Linux 5(32-bit)', 36); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Red Hat Enterprise Linux 5(32-bit)', 38); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Red Hat Enterprise Linux 5(64-bit)', 31); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Red Hat Enterprise Linux 5(64-bit)', 33); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Red Hat Enterprise Linux 5(64-bit)', 35); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Red Hat Enterprise Linux 5(64-bit)', 37); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Red Hat Enterprise Linux 5(64-bit)', 39); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Red Hat Enterprise Linux 4(32-bit)', 26); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Red Hat Enterprise Linux 4(32-bit)', 27); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Red Hat Enterprise Linux 4(32-bit)', 28); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Red Hat Enterprise Linux 4(32-bit)', 29); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Red Hat Enterprise Linux 4(64-bit)', 106); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Red Hat Enterprise Linux 3(32-bit)', 66); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Red Hat Enterprise Linux 3(64-bit)', 67); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Red Hat Enterprise Linux 2', 131); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Suse Linux Enterprise 11(32-bit)', 46); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Suse Linux Enterprise 11(64-bit)', 47); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Suse Linux Enterprise 10(32-bit)', 41); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Suse Linux Enterprise 10(32-bit)', 43); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Suse Linux Enterprise 10(64-bit)', 42); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Suse Linux Enterprise 10(64-bit)', 44); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Suse Linux Enterprise 10(64-bit)', 45); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Suse Linux Enterprise 10(32-bit)', 109); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Suse Linux Enterprise 10(64-bit)', 110); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Suse Linux Enterprise 8/9(32-bit)', 40); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Suse Linux Enterprise 8/9(32-bit)', 96); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Suse Linux Enterprise 8/9(64-bit)', 97); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Suse Linux Enterprise 8/9(32-bit)', 107); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Suse Linux Enterprise 8/9(64-bit)', 108); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Open Enterprise Server', 68); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Asianux 3(32-bit)', 69); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Asianux 3(64-bit)', 70); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Debian GNU/Linux 5(32-bit)', 15); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Debian GNU/Linux 5(64-bit)', 72); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Debian GNU/Linux 4(32-bit)', 73); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Debian GNU/Linux 4(64-bit)', 74); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Ubuntu Linux (32-bit)', 59); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Ubuntu Linux (32-bit)', 121); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Ubuntu Linux (32-bit)', 122); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Ubuntu Linux (32-bit)', 123); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Ubuntu Linux (32-bit)', 124); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Ubuntu Linux (32-bit)', 125); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Ubuntu Linux (64-bit)', 100); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Ubuntu Linux (64-bit)', 126); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Ubuntu Linux (64-bit)', 127); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Ubuntu Linux (64-bit)', 128); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Ubuntu Linux (64-bit)', 129); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Ubuntu Linux (64-bit)', 130); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Other 2.6x Linux (32-bit)', 75); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Other 2.6x Linux (64-bit)', 76); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Other Linux (32-bit)', 98); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Other Linux (64-bit)', 99); - -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Novell Netware 6.x', 77); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Novell Netware 5.1', 78); - -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Sun Solaris 10(32-bit)', 79); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Sun Solaris 10(64-bit)', 80); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Sun Solaris 9(Experimental)', 81); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Sun Solaris 8(Experimental)', 82); - -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'FreeBSD (32-bit)', 83); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'FreeBSD (64-bit)', 84); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'OS/2', 104); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'SCO OpenServer 5', 85); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'SCO UnixWare 7', 86); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'DOS', 102); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Other (32-bit)', 60); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ("VmWare", 'Other (64-bit)', 103); - - - -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'CentOS 4.5', 1); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'CentOS 4.6', 2); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'CentOS 4.7', 3); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'CentOS 4.8', 4); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'CentOS 5.0', 5); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'CentOS 5.0', 6); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'CentOS 5.1', 7); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'CentOS 5.1', 8); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'CentOS 5.2', 9); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'CentOS 5.2', 10); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'CentOS 5.3', 11); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'CentOS 5.3', 12); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'CentOS 5.4', 13); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'CentOS 5.4', 14); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'CentOS 5.5', 111); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'CentOS 5.5', 112); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 4.5', 26); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 4.6', 27); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 4.7', 28); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 4.8', 29); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 5.0', 30); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 5.0', 31); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 5.1', 32); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 5.1', 33); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 5.2', 34); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 5.2', 35); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 5.3', 36); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 5.3', 37); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 5.4', 38); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 5.4', 39); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 5.5', 113); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 5.5', 114); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 4', 106); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 3', 66); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 3', 67); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Red Hat Enterprise Linux 2', 131); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Fedora 13', 115); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Fedora 12', 116); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Fedora 11', 117); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Fedora 10', 118); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Fedora 9', 119); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Fedora 8', 120); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Ubuntu 10.04', 121); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Ubuntu 10.04', 126); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Ubuntu 9.10', 122); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Ubuntu 9.10', 127); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Ubuntu 9.04', 123); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Ubuntu 9.04', 128); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Ubuntu 8.10', 124); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Ubuntu 8.10', 129); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Ubuntu 8.04', 125); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Ubuntu 8.04', 130); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Debian GNU/Linux 5', 15); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Debian GNU/Linux 5', 72); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Debian GNU/Linux 4', 73); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Debian GNU/Linux 4', 74); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Other Linux 2.6x', 75); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Other Linux 2.6x', 76); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Other Ubuntu', 59); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Other Ubuntu', 100); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Other Linux', 98); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Other Linux', 99); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows 7', 48); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows 7', 49); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows Server 2003', 50); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows Server 2003', 51); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows Server 2003', 87); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows Server 2003', 88); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows Server 2003', 89); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows Server 2003', 90); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows Server 2003', 91); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows Server 2003', 92); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows Server 2008', 52); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows Server 2008', 53); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows 2000', 55); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows 2000', 61); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows 2000', 95); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows 98', 62); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows Vista', 56); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows Vista', 101); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows XP SP2', 57); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows XP SP3', 58); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows XP ', 93); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Windows XP ', 94); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'DOS', 102); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Other', 60); -INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES ('KVM', 'Other', 103); - + VALUES (11, 'simulator-Centos', 'CentOS 5.3(64-bit) no GUI (Simulator)', 1, now(), 'BUILTIN', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/centos53-x86_64/latest/f59f18fb-ae94-4f97-afd2-f84755767aca.vhd.bz2', '', 0, 'CentOS 5.3(64-bit) no GUI (Simulator)', 'VHD', 11, 1, 1, 'Simulator'); diff --git a/utils/conf/db.properties b/utils/conf/db.properties index 8c8833f7e94..18bf54c2b61 100644 --- a/utils/conf/db.properties +++ b/utils/conf/db.properties @@ -57,3 +57,14 @@ db.usage.autoReconnect=true # awsapi database settings db.awsapi.name=cloudbridge + +# Simulator database settings +db.simulator.username=cloud +db.simulator.password=cloud +db.simulator.host=localhost +db.simulator.port=3306 +db.simulator.name=simulator +db.simulator.maxActive=250 +db.simulator.maxIdle=30 +db.simulator.maxWait=10000 +db.simulator.autoReconnect=true From 7410de9cca9fe780739f1a811d338239b109149a Mon Sep 17 00:00:00 2001 From: Pranav Saxena Date: Mon, 24 Dec 2012 16:05:57 +0530 Subject: [PATCH 15/23] CLOUDSTACK-771:Instance Table misalignment : when instance is created with long display name:Solved by using the concept of Ellipses in CSS --- ui/css/cloudstack3.css | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index a1a68cb774a..72c98e62e02 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -441,13 +441,16 @@ body.login { div.list-view table tbody td span { display: block; float: left; - max-width: 210px; + max-width: 100px; word-wrap: break-word; text-indent: 0; margin-left: 12px; line-height: 15px; - overflow: auto; + overflow: hidden; overflow-x: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } div.list-view div.toolbar div.section-switcher div.section-select label { From 5b751b2a13a0b7c49fc03770a05573af7ca6feb9 Mon Sep 17 00:00:00 2001 From: Pranav Saxena Date: Mon, 24 Dec 2012 17:57:46 +0530 Subject: [PATCH 16/23] CLOUDSTACK-771:Instance Table misalignment : Adding the hover view in order to display the full text --- ui/css/cloudstack3.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 72c98e62e02..68817e40a29 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -453,6 +453,12 @@ div.list-view table tbody td span { } +div.list-view table tbody td span:hover { + +overflow:auto; + +} + div.list-view div.toolbar div.section-switcher div.section-select label { margin: 0 9px 0 0; } From 5aefd77f774723dd5729324043e62a413f580da8 Mon Sep 17 00:00:00 2001 From: Isaac Chiang Date: Tue, 18 Dec 2012 09:38:08 +0800 Subject: [PATCH 17/23] Fix for CloudStack-648 Signed-off-by: Gavin Lee --- .../com/cloud/api/response/UserResponse.java | 10 ++++++ client/tomcatconf/commands.properties.in | 2 +- server/src/com/cloud/api/ApiDBUtils.java | 4 +++ .../src/com/cloud/api/ApiResponseHelper.java | 3 +- ui/scripts/accounts.js | 32 ++++++++++--------- ui/scripts/sharedFunctions.js | 16 ++++++++++ 6 files changed, 50 insertions(+), 17 deletions(-) diff --git a/api/src/com/cloud/api/response/UserResponse.java b/api/src/com/cloud/api/response/UserResponse.java index 920eb598f5a..b1382e98b8a 100644 --- a/api/src/com/cloud/api/response/UserResponse.java +++ b/api/src/com/cloud/api/response/UserResponse.java @@ -69,6 +69,8 @@ public class UserResponse extends BaseResponse { @SerializedName("accountid") @Param(description="the account ID of the user") private IdentityProxy accountId = new IdentityProxy("account"); + @SerializedName("iscallerchilddomain") @Param(description="the boolean value representing if the updating target is in caller's child domain") + private boolean isCallerChildDomain; public Long getId() { return id.getValue(); @@ -188,4 +190,12 @@ public class UserResponse extends BaseResponse { public void setAccountId(Long accountId) { this.accountId.setValue(accountId); } + + public boolean getIsCallerSubdomain() { + return this.isCallerChildDomain; + } + + public void setIsCallerChildDomain(boolean isCallerChildDomain) { + this.isCallerChildDomain = isCallerChildDomain; + } } diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 437c8d458f5..e55017ce5ea 100755 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -31,7 +31,7 @@ markDefaultZoneForAccount=com.cloud.api.commands.MarkDefaultZoneForAccountCmd;1 #### User commands createUser=com.cloud.api.commands.CreateUserCmd;3 deleteUser=com.cloud.api.commands.DeleteUserCmd;3 -updateUser=com.cloud.api.commands.UpdateUserCmd;3 +updateUser=com.cloud.api.commands.UpdateUserCmd;15 listUsers=com.cloud.api.commands.ListUsersCmd;7 ####lockUser=com.cloud.api.commands.LockUserCmd;7 disableUser=com.cloud.api.commands.DisableUserCmd;7 diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index cdd5339665c..012075c2e49 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -469,6 +469,10 @@ public class ApiDBUtils { public static DomainVO findDomainByIdIncludingRemoved(Long domainId) { return _domainDao.findByIdIncludingRemoved(domainId); } + + public static boolean isChildDomain(long parentId, long childId) { + return _domainDao.isChildDomain(parentId, childId); + } public static DomainRouterVO findDomainRouterById(Long routerId) { return _domainRouterDao.findByIdIncludingRemoved(routerId); diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index a5747101215..8f9837f54a5 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -423,6 +423,7 @@ public class ApiResponseHelper implements ResponseGenerator { @Override public UserResponse createUserResponse(UserAccount user) { + Account account = UserContext.current().getCaller(); UserResponse userResponse = new UserResponse(); userResponse.setAccountName(user.getAccountName()); userResponse.setAccountType(user.getType()); @@ -439,8 +440,8 @@ public class ApiResponseHelper implements ResponseGenerator { userResponse.setApiKey(user.getApiKey()); userResponse.setSecretKey(user.getSecretKey()); userResponse.setAccountId((user.getAccountId())); + userResponse.setIsCallerChildDomain(ApiDBUtils.isChildDomain(account.getDomainId(), user.getDomainId())); userResponse.setObjectName("user"); - return userResponse; } diff --git a/ui/scripts/accounts.js b/ui/scripts/accounts.js index 324c5f56988..ba741a4f063 100644 --- a/ui/scripts/accounts.js +++ b/ui/scripts/accounts.js @@ -1248,22 +1248,20 @@ if (jsonObj.state == 'Destroyed') return []; if(isAdmin()) { - allowedActions.push("edit"); //updating networkdomain is allowed on any account, including system-generated default admin account - if(!(jsonObj.domain == "ROOT" && jsonObj.name == "admin" && jsonObj.accounttype == 1)) { //if not system-generated default admin account - if(jsonObj.state == "enabled") { - allowedActions.push("disable"); - allowedActions.push("lock"); + allowedActions.push("edit"); //updating networkdomain is allowed on any account, including system-generated default admin account + if(!(jsonObj.domain == "ROOT" && jsonObj.name == "admin" && jsonObj.accounttype == 1)) { //if not system-generated default admin account + if(jsonObj.state == "enabled") { + allowedActions.push("disable"); + allowedActions.push("lock"); + } else if(jsonObj.state == "disabled" || jsonObj.state == "locked") { + allowedActions.push("enable"); + } + allowedActions.push("remove"); } - else if(jsonObj.state == "disabled" || jsonObj.state == "locked") { - allowedActions.push("enable"); - } - allowedActions.push("remove"); - } - allowedActions.push("updateResourceCount"); - } - else if(isDomainAdmin()) { - allowedActions.push("updateResourceCount"); - } + allowedActions.push("updateResourceCount"); + } else if(isDomainAdmin()) { + allowedActions.push("updateResourceCount"); + } return allowedActions; } @@ -1281,6 +1279,10 @@ allowedActions.push("enable"); allowedActions.push("remove"); } + } else { + if(isSelfOrChildDomainUser(jsonObj.username, jsonObj.accounttype, jsonObj.domainid, jsonObj.iscallerchilddomain)) { + allowedActions.push("changePassword"); + } } return allowedActions; } diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js index 961c97387a4..eb78ad15da0 100644 --- a/ui/scripts/sharedFunctions.js +++ b/ui/scripts/sharedFunctions.js @@ -158,6 +158,22 @@ function isUser() { return (g_role == 0); } +function isSelfOrChildDomainUser(username, useraccounttype, userdomainid, iscallerchilddomain) { + if(username == g_username) { //is self + return true; + } else if(isDomainAdmin() + && iscallerchilddomain + && (useraccounttype == 0)) { //domain admin to user + return true; + } else if(isDomainAdmin() + && iscallerchilddomain + && (userdomainid != g_domainid) ) { //domain admin to subdomain admin and user + return true; + } else { + return false; + } +} + // FUNCTION: Handles AJAX error callbacks. You can pass in an optional function to // handle errors that are not already handled by this method. function handleError(XMLHttpResponse, handleErrorCallback) { From bab974c3bcd9f3f0b9a5812a59c70ace81716c0f Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Wed, 26 Dec 2012 13:36:58 -0800 Subject: [PATCH 18/23] marvin : cloudstack-version is not reqd for json load To build back cloudstack response we don't need to load the 'cloudstack-version' string, only the response --- tools/marvin/marvin/jsonHelper.py | 2 +- tools/marvin/marvin/sandbox/demo/simulator/simulator.cfg | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/marvin/marvin/jsonHelper.py b/tools/marvin/marvin/jsonHelper.py index b2e7d2ff7dc..652cce0bf9e 100644 --- a/tools/marvin/marvin/jsonHelper.py +++ b/tools/marvin/marvin/jsonHelper.py @@ -121,7 +121,7 @@ def getResultObj(returnObj, responsecls=None): if len(returnObj) == 0: return None - responseName = returnObj.keys()[0] + responseName = filter(lambda a: a!=u'cloudstack-version', returnObj.keys())[0] response = returnObj[responseName] if len(response) == 0: diff --git a/tools/marvin/marvin/sandbox/demo/simulator/simulator.cfg b/tools/marvin/marvin/sandbox/demo/simulator/simulator.cfg index 219c4dbbff5..7c733ade256 100644 --- a/tools/marvin/marvin/sandbox/demo/simulator/simulator.cfg +++ b/tools/marvin/marvin/sandbox/demo/simulator/simulator.cfg @@ -148,10 +148,6 @@ "name": "workers", "value": "10" }, - { - "name": "use.user.concentrated.pod.allocation", - "value": "false" - }, { "name": "account.cleanup.interval", "value": "600" From 539fca35209bdbf26eecfb22f7a63d2f21488cc1 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Wed, 26 Dec 2012 19:20:32 -0800 Subject: [PATCH 19/23] Simulator: Fixing the listTemplatesCommand Should return the ListTemplatesAnswer and ListVolumes returns ListVolumesAnswer Signed-off-by: Prasanna Santhanam --- .../src/com/cloud/agent/manager/MockStorageManagerImpl.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java index a950926a515..1076089dcd6 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java @@ -434,13 +434,13 @@ public class MockStorageManagerImpl implements MockStorageManager { List volumes = _mockVolumeDao.findByStorageIdAndType(storage.getId(), MockVolumeType.VOLUME); - Map templateInfos = new HashMap(); + Map templateInfos = new HashMap(); for (MockVolumeVO volume : volumes) { - templateInfos.put(volume.getName(), new TemplateInfo(volume.getName(), volume.getPath() + templateInfos.put(volume.getId(), new TemplateInfo(volume.getName(), volume.getPath() .replaceAll(storage.getMountPoint(), ""), volume.getSize(), volume.getSize(), true, false)); } txn.commit(); - return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos); + return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos); } catch (Exception ex) { txn.rollback(); throw new CloudRuntimeException("Error when finding template on sec storage " + storage.getId(), ex); From 1b533f2354fbc6c36ddae3fd17134fc37a7d954b Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Thu, 27 Dec 2012 11:58:50 -0800 Subject: [PATCH 20/23] List view UI: Add alt tag to table cells --- ui/scripts/ui/widgets/listView.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/scripts/ui/widgets/listView.js b/ui/scripts/ui/widgets/listView.js index 60f8e02c041..85523ea5e7a 100644 --- a/ui/scripts/ui/widgets/listView.js +++ b/ui/scripts/ui/widgets/listView.js @@ -914,6 +914,8 @@ $('').html(_s(content)) ); } + + $td.attr('title', _s(content)); }); $tr.find('td:first').addClass('first'); From 23e75eb788fdc5a1077ed7fe3451e7b8dcc9c020 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Thu, 27 Dec 2012 11:59:13 -0800 Subject: [PATCH 21/23] Increase max-width of list view table cells to 160px --- ui/css/cloudstack3.css | 45 +++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 68817e40a29..0478f4c65fb 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -441,7 +441,7 @@ body.login { div.list-view table tbody td span { display: block; float: left; - max-width: 100px; + max-width: 160px; word-wrap: break-word; text-indent: 0; margin-left: 12px; @@ -450,13 +450,10 @@ div.list-view table tbody td span { overflow-x: hidden; text-overflow: ellipsis; white-space: nowrap; - } div.list-view table tbody td span:hover { - -overflow:auto; - + overflow: auto; } div.list-view div.toolbar div.section-switcher div.section-select label { @@ -7221,19 +7218,18 @@ div.container div.panel div#details-tab-addloadBalancer.detail-group div.loadBal min-width: 100px; } -div.ui-dialog div.multi-edit-add-list div.view div.data-table table.body tbody tr.even td - { - border-right: 1px solid #BFBFBF; - clear: none; - color: #495A76; - font-size: 10px; - margin-right: 25px; - min-width: -moz-available; - max-width:90px; - overflow: hidden; - padding: 9px 5px 8px 0; - position: relative; - vertical-align: middle; +div.ui-dialog div.multi-edit-add-list div.view div.data-table table.body tbody tr.even td { + border-right: 1px solid #BFBFBF; + clear: none; + color: #495A76; + font-size: 10px; + margin-right: 25px; + min-width: -moz-available; + max-width: 90px; + overflow: hidden; + padding: 9px 5px 8px 0; + position: relative; + vertical-align: middle; } .multi-edit { @@ -10689,10 +10685,9 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it } div.container div.panel div#details-tab-network.detail-group div div.multi-edit table.multi-edit tbody tr td, - div.container div.panel div#details-tab-network.detail-group div div.multi-edit table.multi-edit thead tr th - { - min-width:72px; - font-size:10px; +div.container div.panel div#details-tab-network.detail-group div div.multi-edit table.multi-edit thead tr th { + min-width: 72px; + font-size: 10px; } .ui-dialog div.autoscaler .detail-actions { @@ -11178,8 +11173,8 @@ div.ui-dialog div.autoscaler div.field-group div.form-container form div.form-it background-position: -168px -31px; } -.reset .icon{ -background-position: -168px -31px; +.reset .icon { + background-position: -168px -31px; } .restoreVM:hover .icon, @@ -11187,7 +11182,6 @@ background-position: -168px -31px; background-position: -168px -613px; } - .reset:hover .icon { background-position: -168px -613px; } @@ -11316,3 +11310,4 @@ background-position: -168px -31px; cursor: pointer; color: #0000FF !important; } + From d3ca6a8a5749599b16c0a055a2748e08ab2f8395 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Thu, 27 Dec 2012 12:02:38 -0800 Subject: [PATCH 22/23] List view UI: Keep overflow row content in-line with mouse on hover --- ui/css/cloudstack3.css | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 0478f4c65fb..c3f4892d903 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -454,6 +454,7 @@ div.list-view table tbody td span { div.list-view table tbody td span:hover { overflow: auto; + margin-top: 4px; } div.list-view div.toolbar div.section-switcher div.section-select label { From eff0716426dd7fbfa5dbc9415b3fbaa6aafa6bc8 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Thu, 27 Dec 2012 13:46:52 -0800 Subject: [PATCH 23/23] UI: Minor cosmetic fixes -Fix missing icons on some dialog headers -multiEdit: Fix overflow for long text strings -Projects UI: Fix project selector margins, overflow on 'Events' box on project dashboard --- ui/css/cloudstack3.css | 34 ++++++++++++++++++++-------------- ui/images/icons.png | Bin 49385 -> 50745 bytes 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index c3f4892d903..6156f47be3a 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -3430,7 +3430,6 @@ Dialogs*/ display: inline; padding: 0; float: right; - text-decoration: underline; color: #516374; /*+text-shadow:0px -1px 1px #FFFFFF;*/ -moz-text-shadow: 0px -1px 1px #FFFFFF; @@ -3527,6 +3526,11 @@ Dialogs*/ -webkit-text-shadow: 0px -1px 1px #495968; -o-text-shadow: 0px -1px 1px #495968; text-shadow: 0px -1px 1px #495968; + background: url(../images/icons.png) no-repeat 0px -255px; +} + +.notice .ui-dialog-title { + background-position: 0px -288px; } .ui-dialog.confirm .ui-dialog-title { @@ -7469,11 +7473,12 @@ div.ui-dialog div.multi-edit-add-list div.view div.data-table table.body tbody t } .multi-edit .data .data-body .data-item > table tbody tr td span { - overflow-x: auto; - overflow-y: hidden; - max-width: 88px; + overflow: hidden; + max-width: 78px; display: block; float: left; + text-overflow: ellipsis; + white-space: nowrap; } .multi-edit .data .data-body .data-item table tbody tr td.blank { @@ -8793,6 +8798,7 @@ div.ui-dialog div.multi-edit-add-list div.view div.data-table table.body tbody t .project-selector .listing .data ul li { padding: 10px 0 10px 7px; cursor: pointer; + font-size: 12px; } .project-selector .listing .data ul li.odd { @@ -8816,8 +8822,8 @@ div.ui-dialog div.multi-edit-add-list div.view div.data-table table.body tbody t text-shadow: 0px 1px 1px #FFFFFF; text-align: left; color: #4F6171; - font-size: 12px; - padding: 2px 2px 3px 7px; + font-size: 11px; + padding: 3px 2px 3px 7px; border-bottom: 1px solid #FFFFFF; position: absolute; left: 0; @@ -8830,17 +8836,14 @@ div.ui-dialog div.multi-edit-add-list div.view div.data-table table.body tbody t border-radius: 4px 4px 4px 4px; font-size: 13px; font-weight: bold; + padding: 8px 20px; float: none; cursor: pointer; color: #838181; - /*+placement:shift 488px 9px;*/ - position: relative; - left: 488px; - top: 9px; left: 170px; top: -8px; - margin: 19px 0 0 0px; width: 54px; + margin: auto auto 17px; } .project-selector .button.cancel:hover { @@ -9205,9 +9208,9 @@ div.ui-dialog div.multi-edit-add-list div.view div.data-table table.body tbody t } .info-boxes .info-box ul li .date { - font-size: 13px; + font-size: 11px; text-align: center; - margin: 0; + margin: 1px 0 0; } .info-boxes .info-box ul li .date span { @@ -9226,7 +9229,10 @@ div.ui-dialog div.multi-edit-add-list div.view div.data-table table.body tbody t top: 8px; display: inline-block; padding-bottom: 13px; - max-width: 171px; + max-width: 153px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } .info-boxes .info-box ul li .total span { diff --git a/ui/images/icons.png b/ui/images/icons.png index 63c10b026313f21f985060c7452f5470154f8dfb..ea1a39cdf7f0a934d4041265470b4b0ade4a2b41 100644 GIT binary patch delta 47275 zcmW(+WmsG762#q#J5`FidyBQWy9X-}-0eW|qAl)Fio3g8@!}HPg1ZN~`R?E3Jb5L1 zW@mP1_XCleqmZjQv4B?duTq~hJeQ7EJTfvY+FxGg-IDhq9`TBNi&t3hbKkr2U?KhX zBp{aVj`_{t9Rn>2X9(ZBg;u*ri836h67(aHs-Q^y`A9(cnTavICjGc|`qbI5Q~YFc zj2;Dp^L_fASC2@Iu**a{_if#+Z$&{Ar-5TP>UFWk!AOME=4W8g$;OkSZZ2VD$LHey z5enRo7>ivHroRZEHLr}rs2!2du-8XlL1A59U6L4Yf(br{KMf#S+t{>N_5@=l^YQT! zM)s@79be=1aQx})e2D@>8pcrR+x`}~by)>0t&C@LZmzAc!;l;Yk4xWs2Cf^ zTIjN}SML`F42Wi&YCT6EZ`4djlza#Le?E;P{qhlb>6JkKhkvxMgxb{@Fw5>nr(J3E zls#RbC~SHQd-^Ad&uZA_=|sqY>?1cuse^R&S6vYUfFCK32|-I!Q!qjbDW6#HFu6V6 zoa-xnyjSsk!xXi$7Lw>n{wd>l)>18TrtEn~n<_{0Rax`9U3q!hVF&Kry-G0Q>zHYvN`P?m4*jqI_TK2OEVa#x zVW4vjY2bL{q9J*q^5LVsx|svtlwPL^8AAkWEZ{`} zVL9?}+&{33_vu3g8FJRb2!bb7l^s4L%G65z@(Vr@FA;MN4E3dJWS_V>Jt--P&z(<| zY=`mxSF8F8A(}JT^b2`tr8&amuGk6S{lW1t(m+fj^YEPw)AQuW!tD+_!Fyv4b2j6S z#~=5X&_egM^$eGB3Uy7*>$bRNx5K$P3T{i^ff|FOQdNjqE_zW!tk33;l$^|Ce)}Q}Lw23WRxk zhoHx`k)u8)LMKq08b7ZWve&CN8=SOkgi?KPc7cwsCX1^vCE6zzrvLu}gP!=X?p~uw zATJ|7PKX%+ypB*nK4kP5(g?hiJNO;;!#wT29~>N<{+(9*FV^$A9Z}D+i=U&vW3BUh z?st4=-{x=YlNuW!zpStHE8l>hN56_4c%3}5QkkIlL7D%*-9@3{NwAO}-dmvuE;OtF z1gElQbd`;`cSG{@3i&hqo%dt6%=tHr<^^iSFG+p}iuQ(prM>Oe`UqL9ZuP;oLxRGH?*545rZ@C9DRIe#NZYV>o;3n(#BP9+v%x%dFb`k6^qh)!ct|i`)&4)Et*pu5)|Ruf8fTI zhDPAf=BABuP=4PxVg&F<{XS>=jR(Mk;TkK4gS09@JT|1TPa&bvFyT@mWO9~w&v}nhldA! zG<0J)lYuhWDMox|;5Ve@U0=G(ZvbF5N%mzndrM%l-QGh3Ef22Cybk zBgNC$yo(2P$N@ZZsKiS*b7c!3@+eXP!gXS8YXIN6ZqA(=tm(O>bm!-PyACEFLp&QU ztx!ZFLxv(*MS*FlO3TYX{QQET!az(;O>Hha81vQ<|4e^936f;%5R0fn`~M&b_q+MQ zhU&4SIlt5e3$Wc~O<5E18*rsp%nAlWe3r#9kN`f1<-V5sLr=?oZg3aWLB9fMgSk(v z+@pGJ8@*Y(+r?$=60BU$-a|M+x$7HbPex`77ASjKhu-qog2oXG7^LGl%g`Hi<(@cc zV{sL-mldogUbjC98XaBUJvsP9Q!7*(x0{i4!4KGgdN}vyS)VU zoeyvNI_|TxANQvljt#a1lj3Rgo{oPd8jNEH1QLdy z-}nKEYFJ;ilx+H>QFE+~hJM78)BOJrH$+)>x+pH>p#wHCMQVKCY5P7|E?r;}D#nM$ z`jAXRqfJ-u$RTK-8*Y*o=OF#8BMpw1q8`=Oa-sOfcTD3VFqV>%5~J(A-dL9AixS&4 zj;l}1Myjks=D&!P1QB<1tO4=&;yMyxlpq{a^56BJ4&yjxtjjUo!fBrcA3XN9Tkx(y z2gMF$py>y`=jX;wUb3Cy-vm&UNO8}UCWAI5kDI3s6 zqYJtbnKD%}!bSg=XxtW~2nOHz6C)YSTO5p1T)Dad)jDj-SprTyuq8gbvx|GAr250V zb`Bg0aZ{w(dfq|%g{pITBK?p45N6Vsx_U5nlEo_&#CU!ERAF1v)6VTp?UTqME3r#6 zvTQU1vR#^V<74(dYI2?{dt(L6R}71_^gE;@R||JT5H?)AZxZi8mTQ*G#T!r z$NCVIC_zdqDJ`WEgDp;s3q9=R z6}DC!B3YOBevnTpdzx$Ps5fGqMRlbBq3w_WOW&d-mVD`Y(S$UcNInCv&Ji5 zM!vJ@l^!|?oIAWTgsSI&c1PB-CR{`lNDd1Iu0TUig~szHpN`hm+t@`cNW}O%o(1}c z#afaWE|jF6dI{#U#5N4PUwWwJ0jhEoYnL-=i4#dcj8WTNxQ6C#5xW1)*1PaRHu3iNm*c5Hp!FbPFt#H7-vL#*s+?|;#SZJplEPJ;;6FAy zYrDsORaqM8%R8q&GbdWV?Vlra6-FzF2KtM;thl(ibmA~v2MI=LZ7b;JY^fIOYTGxW z0dgpS&|!5%7I4ud0kGSKUDBhfm1j^XvQx$jVWRvw4jwB)g6Z-Bmto2qEM0e zv5vk>15NS6<2Ufa;TS35aDL8w$kOq6e;N2%@3)Q21bg-}P?5S?`URcwv<1 znc_dJPmr z6bh=({i@e|dQ=AT)dj-atpGmRP~y(mxrFW7q|C%i6tTlLN$r3PJ61evX-N+*9yFMoXWH@>8Z1V5?|q*UfpyIM8TMGiCW48} ze|qYM>b;mBGrxFflQkPugjg4ZOZL3niZ_ncv)Hy+EV|y{oDe=ET=a9rfVLL+ObI#$ zE{ErLFQk8y&P?tz8{cCMkbi$|;^-Ln@_hP|b#^}iJa3PPUFE(Ml~fq*`OpRh1trLR z=y}~$!?LUsm2zk%4B%DkuxM&)H{Ly7P8j4Z|Y-Q5X#dfIjX4=z}~s%v^WsG9t~Lj>A+&x+%UOAso|3`ll6+=-M= z_I^^yi=S6`GX&GnuJK#CUv-F<-IxY@7vMYi^|bBUdcy-u99W7`t|zW<$~Kj`vDL zb4%pMDi8X#-Za;2ki9@6^w$(zPSrC6KL+gxkv{>Ckc=YC`%B5g5_{dwpC-NWV-8^7 zm}1@)oFo#Dibk&j14A?;)2z$tRcH^#p;m=Le1<><;x$*CB88-xK z=WAeATe$14^|S-l{xQ>asxatv`03uB2}ing*v6S3#`l1d5~fWzx8P3_w_OOu8b36c zr0L^z9q)INU-nW!G55oVMz<~L0XGwVCoW;`=zoD71W!2K%bFDWHih~z!P zz3di;4^JMSGFhP==gau9zaT4V;e(U81#zrWxf6StelIdM(z9W>X07zI5y z0dOt&kq3lz;$Ot4W*6^Q&skX~yK07yX}R55D#fAHDp-R~XMTV{9Hc?f7%-;$MDR%c zmku5(GKWdI{%H@W1EP2S0cs{u#q*{ZVdHn<=dt3?cZHS{Sx+0Qt41xYt(eT+6E!S$ zBX8q};zo8Dd}#d%auVLA%1ur~M!MEtD=I2BRUBryPJPYRZ*l!LQawoPGnT8dk%-U~ z#*QXCF8rf`#_w@+LSFFD5TJYW3OT5!fkeON&GaEyuf(olmq)I9*Y0Y-LLW=MJJ=?j z#!K-H0z`|!LS=ZMG;`qA|5{r~k0bFNbPOabJ7^WiAAJGxSu9mD_^TRERTOQziMP;; z_>Ul1CEL+j=-B$iPsD!_o}0Ku;0ej!m3a9i$y4OK2Hi($qf+e&n5N`@D=pB#ZSbuc zjGnVE;eSSed)2g#$_CK*@G~{zHX$xdFY}HBya>nPt4-Bs6fi~VLEc(^8ql1f|9wJ? z$5Ae$O4R6NhpKh;VHC+#^GXmzAzhDMdq_;>(^W$f{WUTnFBG}odJ8>4_yOs&xSX$z zz(cAWs-n8Owz$_hfO#VRaPgc}v;phy$u{HAKUuA7zRi=X{_wC(e~{F3*tCaZQ zJ+v!?QMF(c&fVxG#+~uLzupUN#=WkF)0^S$7$?BbKm047)4&n^uVZAKI&fhg6$`GB zU_^st9UlHnCY9ujl|zwpV_jik;YG*qu+mDCDyHf0xQ2Yrz-~arxKcovjM#OcOp%CD z9xnnVkV42{ug>e zokR)p*#3WdTLO5zv$NaSs7p&r))eAdQg6FQDY#c*h2qanBZm`$(6D(UpJRW(VEVMh z^0t;#YxOo3Seiezk-8*#@!d|n&-Q&b=0-5`nysIhnpXakXL25@ zi#c~4Y)6fQ8MRq`6QHJp>476^tg)krqveVoOi4{;mbAIx#3t;V=Il+~ULCP~-nf%- zn|8kpOYY2YfrApCF|aaAlXv9FN5l&@T3X^dSspQ+Z`atGX2{zP_^p zkL_ws3t$tSJQh)V>rxOWaS@A#3)ZV=M5SG*p_0fm+Qf^EHv~fJF@fDC%$_b_6$66& z;R@Lz z=aME5h1cCc>O{8lWnQ?GHTfSG8lJ{I-+p?N-HCSBvxgfXG$Z6&9H*1YB_AfYmK45lDEEjlgzMvONub@Pxsxe?Od(S&I?yfQwzMC@Lg=`SI-F~e#~WUlekZZ)OT2~rGi4mFv^fRFceBq zJ_jJKw@T%CiQf^z7?EBOMQ|U3t=YPucmv2gAu?8xaonm1qshGeD!FAv&d&>4bjTX5 zd?CL-F@9n0H(|rVwWp@Fp9TzkrJ@eVmth$b1*>t+ENROBtYuc@Hge~ZPVdRVphc~n zRLg*(mTyc>RqSLZc26t1uYGCri91e-3m*kzv zo}1^WmUB_7P6m4kxZ7ZLiUiQ6S*df2d@P)t1o`UuWmzCY$c-zDJ^)IL`mZanCN8Thwb@Tn$alp9=I|2SXplJKaW-c)QA@KIe^D zeJ7|;tUsNYr|b7M@Y#9bQj@eIbwd8%ru8rtES!kWwfUg-?;wmPR z9^oKnLbtIp-} zjPV+pd$0dV2n~=`pcp}pbvpS^z1_o^woesP`dGDRR7nfduYHtzyTI{dLm%D+kojG0 zLbTzx(*~BvfofbHWpa5)D68wOD_s=UdYto4kmdFaGQZY1%zx(=|D@kPv|w^iOh>sb zxb!IPPe^Hb(NMou6W@E{1vI@9l0xOkS02Rv`DxH4VDgaFJ8JzV(c;8!JWmi*?P@Dw z8!bJmwl@i(`RbJwYs^NZJiu)He%28~L$#z=O_iMbK|-^nrvKjpDQbyxrp~CvQ%&Md z=cApd={e$f+g;u|O@{I&2To$KLj9lmH!}nYSfdKp9F2T3oZ0=CK^yD*%P3`GOo5cb zok8k{fDNW^tgkykK8uQEP!p1Tx^^3q=lP$Z_)nUa?nM;^Ed^*GoDMpIP()=mT{(DQ z%?G^5&Pa(Me?hdZpQD4T`01U@%uHip_l?i+Qdd!VX&CRXQ&DAw0fzoKw zw#cj^;Vo&Ts-`Bd$a$w`^Qk0BeXflOd8mfAcDzzySZOFPFYm_{$6nk@Ejc%GPz~&! zZ4_l3ef43vA%<~&<+0R|sk&vVosr2#sy}M4z3;OwX%hHV$kiSv<=>r;L}L$C1b4hZ ztGoJLGIoFqJmKnI&eZnV45-9wP;-vwu4#+RQk)qB>;d3cF2v3M{%zoDBIRvS+w^`D zf1tFt6)la0*Q4iQBJJFzA~slDa>cCsjfQM$g@t~ zhaGYj5<<#IifGW+LD!iV8wXkxY)W7X50p-shKA;H{GSY@3V0EKr(AFJJF$8mKHjMY z3!=hIN5aOnbKwHzOlkMmt=d7N2zDd1{*oL6{{-N94)CJ_+AeP&cW*nbR?@D~^N{Y; z{3T|BeO&Sh@3JPJd+LdY>${6*+7lu=6c|AN-bBemM3zYZ@eyz}44e4?;{>%`*xl7Q zm8qL*H#kfcOo2TnxFn-YvFtYtt~G*dskXsaagmtzjNj40kjZ4 zujVE^=oXY<4K@r})}nkmJMEf}4CzVAR~9)RiB}dyRhfWj)5jwUnAUZORX%U~Xd65w z(v>liUe;0%dKr;$VAY7_n<0Wm!Ad+<7e&05qba+W;tH?y}rHF2;s-DYHE+tUq%4n^w} z+Uoe6|8mn3%bq3-8uec?CQRul0KCFduk=^|1zjB$Z83rqMmTBeJ1xs95fDIqk%d?+%NNh<7E9 zGdq;{3vt*V{86}nG{)tyMDDrKyn>f75|bhr{q>ry-br#9k2~ z?y!`V4_R^>bR`4k;P4v+iOIFx*j2sLyK~xEOJ{oN$W|3Ox9jHqq^-og{%yF!GKc)v zbq>A7&#w&5A9}yW8;~l78*R3uD$-YwGr*ztcm9%Dl@5JH&QeJC_X0?0u*ItbRlR3W z5uJy!z*DNk>634DreO{*Ddy-+Ul+T1T zD2W|Gl}GC8VTi*u9^WWksl#G!+=Z4PfDR^L4A@xPwK=NAqRfiE5o?D`F0 zzzP;ab9Hkwxv(H%E00}Hq*qi~{vlH-e%zdaG;$$Ek~|c}G@K|D-nbutcb>Hv^Jn}G z`0PK+t3N?V$5X{Dfl4WUm(8Z7`{|F`?7C0OPEyEtFZD?4iQ0y?c^XIEvUFDZFg)v& z;q1Aj#b4736^*GXpxWGze>C{|K;vgXqr(UiM2&%lV+(5Bn>q7$X^Sn#ynhJ#xx&Bb zOF8m2r*zH5&R0RsEZy3yI?5ciV!;%pj2Q!2#m_%o-HS(an9J32(L^tLEzR$GO;U#g zBvCQZ2MTaCIVCM8sfAiw*gG$8J)YOwyd1>irX%YXlBA(?Y^yJU_>--9WNVke?YF8y zN0(^2i{%ooAr z6$+`>@G+Q1`g4iTrI47$meJ1I5hgA}dmUId%qlwZ{N^1Jm8^{RTb;Hf@t?PZYb_@V zoJLcMu*`89z|#$0+*0!NY-J@C9nRgHg9Nz5jJa++5_Y>sx_2GGVgpdFpN-hj>IZ2! z)c>eVi}$PI@Ye*?%VuAVoW`%q_@A4$k^6{M#nX7mCxVQ_rs@?*l9;VHIjf42QiqGs zT`}tX%~Su|){jj2C3SPekdgdZnzGA~3M z?EEQKkkE1h@?X^gdQ@2c6fBa@(?I_koTw&KY&4%E|EVQ{;MMVt@2agD(+vKK zkH#Oap6V`u4_m(`$&rXEEcgpp)xM^u(1?0WRm020#53=SSG*K&a|-yaJj+UNDgoh}hTNlq@^tn1%-Lg z2GO*SfiZMWeXodQmDUZlwb3P-4d5=379Ve&dUqO+wHE|^*rmbq&zJS^A=WaTH&Djd2F}(d83!!xQqCI?}6WtN@x!zo0C-;DOb! zui~vstqaw;nOo4Y+Owi-w2?&&%=ynid)|CZsMo~}360575kxpi^5Tvc7xZRQX#j(h%h@><+a>oievx{+H=?_{1%o=jply0j^>ikLH}>iNj8!q1AT zS%eGRbS5f-IA!AXnQ|ShvkFzokg$O)Ja=>4_79QL<)MMUb2|wXVZUOSg=*8D&1MW* z{9bQQD$=s@@}-g={k2Ks{t<(yxcof|`3Y5VP-2D`RHr2SQ|TiE46y^cHGnf@p5e@h z<)SA$me(3Af~`T$8pv;et0BzHA@|K4k4TFgymxrgER6HLlR64k=vMT5XciYR{bKR^ zy6Auez_U-#OA+aYyVzN{!4{=K$%seO}|ex^)dyBgRH$>v$AT<@4a%sga?Q z&N-HAjNThrMm!^S+>eQg!Q2{%6&L=gK&a6YhY+ZCAPTRRzs6Xo@#4NWIC;Ci=w>_5 zR$5W~hScTj`*`Au`v{3fXkrA=zeNsOI9qlhz$Is-#iFYs(kt|qx(x2HPR`d=AFOS! zjrGlqqVQvv5YAMx3f;YMp|(mc@GIw~$;=da*q#koa|C0v&!Ft% zL@IglF8-RBBAHM#)Kt_I;uVQ|k0a^3HrN0rjF1X_f*|YKmh)fXn8yNkW##_5*ldR? z)AjZ7waS8N6pBuSF%>vm$mKNjyiulhE0_@r#0 zt~rtnyOK)j@tc~mQMuJZF^DmH%uc7=D|H?Z8iio`=i^2NYq{wLZ)_R|UskeFu=!^Y z)_nE;2uwk5t-msP=NuU3RsFySkv?p?5AH_{FTh)%`f371GYEbB8UAvm`H{tJsfj6V zN)^@A>P|gaLZui9O-B07nHNddUhiM6$$HiWL5){I`8Zb801Az0kainXz7cQvaj}uE zh=N`p#AyY`J{){%i9Fs(4U$$(yyyu3Mle-*Z-FW`0-`8Pc0au`7fgTY5klNYnj9Rn#Etk0left4}5 z-SbX{wq%%rqFz3}s=G+e;-8dXJa#iubKp_*a1EZEPsW_yK1bB<)$}CU7fAItNLxg< zFSNAG==}YV0)RH+j^TEdG+FJ({NyLK zb31ktXI0vqy^7B5fTbmF4xN(9@iuD&o~3`adFiVaVhM=iID)_PQx`!*e=%rAAmz!IW=FEnE*7ZriC^@s`%sR%V+{|t%4scf_-V9|1RPV5PJcZKydrKb;=4_Gy zQN72a75RKI<5{*F~2c0$yNJFLnM6$hN$CSqrydK<*mX=T>8{9eE6$`hc_^(37 z&-$`jQQBT5cI0kc38TjzwUrT4r{f3C4<0A3d(fU?uicvWS-)BsRCQ63v-bPz_2Iu^3JyqE~vH+h$b% zr^o$IJOJv|iO>?DYtN$f?JZ7003U}Ix5?p!muQ##PySc&DC)^*aT&zJ!8&_MO zm+m|!uo=OF58ktqglNry?Lo7<<#tOA(brV`wO|-tk}J$Llx@W?2qp2}GEvQZ>RXAe zO_75&+-14Rd}h&_=fQCb?B~uu(<*g9Yafbd zanIDtBRcKWnk)$z4EiV21z+#})17kYMC}qr_x33&9(TMtB6UvB8c=Go7M4*~t$jzA z=`BymOz}}E>*#pxcRtfll9kqZEQc~zrrAI4UWhvhj|B^1G0LzSK-^fl8SE7w(ZA&i zUZX?;mPa5BooQI4yfgEe+>u2Cr&KWR8z6`H7!>^Fn(w9f-3czMFV45TseB z=f>@&|9r#o5cBf~_V@}cj@VD;-SXsHug+s}>Mi`5~ z-ss1aR0n-f^k7R9X{yZGXQ%u=eE%dJO-K2o1D>^?gl*&l>Gi~Uf7VrJ3Vf2V=xEEF z5T%jn4D*IsU*}%d@%09><9LWo^h&5Rd6~mtFWR~XIoAXHfZnMc(wu5ygUXfQMN|CU z=seI>*NhF11?#vjItUb@s{ zs*QoOpO#4lbwB0ph7dw3@|gi(9o=tcotMhtC2~nd`}Hs(q80DPGw^4}yWVU* zN%o>l`TqP;u2C^(`ofMIsey*5ZZ-6LBpu`onVApkSVpTnpFLtQ0>zPx3ibM@u3p`8vAsY~NuuN{tlgcq09g zrCh{<1Y%lIxe7dZ@mL(yt;Og8;>@bUPhr86SF|(yJSLEv7X1j zIuq&s!I61?jRl-D#=c^u^H^*;-(vKkg)fJKn6DOLR@@gnrxmVcLaEsSi*H>mOsMBd zl*@EFYWsGDzr9cAyHSmk-so0qa$-Kf%io~a@Z`7-n`hN;=4=4VvIDh+^&D1hczV+tB(yedF<9kfzHKU7mA_+yjv*( zwrn$v7q`$0oZXAPswg$S2&rFcxf0bXIgK@yEUOH6{-N13FQ1$w*@$iUBUxJ3m`{LcJ*!@m<^1j=C9-A39O`k?z=-^0j)6uylp4aaNdjAWv z!C`H9VadD2NBC=gyw0%y>K9|f`>LtdGGxITOaW?Ii775qYU8Kj>$ZDb=#X#&MN_o`g(BTc>^Y_iK#DxYy|43Z~*FGqv`y zV7+wT#ec?AlYb^{=8tEJj3QrSal$(_QZ+&c)7CN?rLvE9GFmV0!Xb%2aw-%owtZBq z{@&a^88FVeIG$#!YA~Isdc^JdOCLgI)Vomv>3ChJ7y#HCrMJ?(cUl?2l7=qWv)9pA z*RHBei5_@z+~}?r$!^UCcoUbuJA4z@cfDvok#l_;CT6P46DxOX^Ml>oR_HZf#3V9n zJ$hXZL}y?7byi<|IHVfeN?YUQnP2|rA1V`>B=;epTUGrU*4b*c0!P*7-KG;o+0ir& zm%cL0IsklX>SMJQ$=8Z+iEU?nXs#g1iyf0<)>^$_6^)mCw09(Up8KH`jtbaN#jU@K z<>)ZB8;6yKbxxI**}ee z5`6g7FKUC05czRZc?!h5#lqg?&Y_roDK@Y?1RB7%m%}WmjqRllRga&?Is@ql9}wO4 ztudE!CrrShKLit#M38reJH@anom2C3md;aVx1IaylITZji~t56)YHcQSAJfqOZ^~p z{FR3Ns8($6f3EcypZI(a{*FlziK$8Yl}gJk%+&(kuIWt2OkVB^zV(mIF=dOb^RfoO z0IOZtzA+0WHc7irjW68LFsEUFC zVf>!UcP4>rtn5y`YnLqG$lbU@Myb58r`IJjw`9E1z!jfS(=bQ98;+3$79hgSbry2u zD~T_Q*1a-LXa5kwF>~ktrC5a_K|Y_3_G%oGSjEqiIPT`weXfJgK}K$yoZRP+0rgZ%`}-p@@kyOJ(h%~R`?nMI$2kDU z#P9p*)McR)28cT?9`XxxM9V(KZLN1Aj-C2Su(H*@c_+!37%LlLTYjFtw;{v+TB`Jg^Cc<>UE%f-|IN_$bYx zG2!*o@+o3ftwRoVXzpVEtb{F^_k(V$Imy67N~d0msQY+-YFAnrXx@p!A~ao$Yjlj_w|s+#on zl*&%u6e20lqxp%V4s&RChwg|_nKZd_%jN6&2eaUT*0Um0lShXo`cmhKP8 zZDRL0Q{3Nd?8YP8-5gs+Ht(AFNA3w?(hn`<>Y`DdN+t)O&C)ueJX14y&$;$;%{miV zVq<~y>7J{z4H}^2zH}hOrWYpi)Q1&g?8?QQZE)R|C>j;PMBGc)0e=lR-xWqulvI)D z?Vr+x%bW}1L6#b2-z?S8)8xS1<|2b@aa3zh@ZoOZ$bfxzM_rsIgu4SopADH2b(uur zen-uvicz3+Cyb+FfPUB78#`@IDBWq6w8(nDTSGxwk!s0A#sJ`vpP$)RpqF&AC5r*! zCyRKDpO(3^p%*fhTEd-pMQhe4ioA~xy%H=Zn~B4KBWQ>h-RDE7_4_{+EU`n5o~6r= z@URV4g?iy8Z8?t%i}!hmzc`6`ZBU?m>Ke@>1DwWN*?O@*BY~^zq`|y@ex0z56t{o3 zKVGWd(uX@e$;*d!owr>Csps=^tADB$!{=rcQpGY2_+W|89UYaPJ4N*q?$kE6w#602 zi1`e}Sbb)kHOR=@&Vp0>#1ZB{%%@C8=E~78+RyJvI2Q_Ecm5um@j zz>l((g>jRHyBgVZZ=~?_Sic6Rqp8vbE(HKDgvJ@~iXdx`IeaoZ0MR^l9lB{Z{*-hm7AF}lN7<|0JaGtJD z?xpg%C3xqsp#!#^M?b9-Pg$`PVhI%qkbJu9k>jXSbfq-%$st7Q9iC|6Vqfp$tarV} zt8tb82>6-dhM3)R^8+`>jnv_Qu%+1xNG;RF8k?odM2xUs{*>ZE|;Ax@Rur9PK8AKij=1UHML24H8Kq!)bN%< zeJ1~R1qG(n)%Z)}r6gBIz5mGTYN;qP>SDF~0*g=xf6wrd+@zylzPk~isY_}^;JC*A zvUYq-mA#sO4@;->I_d)ce&;d`=POXtT=1fk{}9VbROmc=3rKI>X<_wSm#?5!deh85 zZpVt;9&u6gk1vCiUmF@mYTtZ$PdrNzrYEe&c7h<fx zt~Ec0r+vK{A+YsPfjkQ!UP~!Dbu2cZ$C0ESe3Lyk)!_&82+*$$3X;|A2ye&tWOh95 z_N4W{ELbyKUl_klADn|z+4m1<7iB9=na_bppPEjCwCnkB%(1tzEo^Mn>Uie4tz@tb zMT4x$b?WcS%&O1C)@Oq52#+3b8atnYY%7{AtJQ22z+l$uVGIB~ahU@55jgnn;j%y$ zhJKWlKvjPdnh6i|iwN=beI4y*sw}{aBD4q%Fe}#2ite zmEp>oM1)&}Bahl#UGV4=Ks6zLs(6S$LsRMiWP14l4ik$&6BKcPkGG>Hf8c9; z3Xj)Rpx(xI{)2MG;>c6kqB3leeeRe6KOtz(uWV0plK;Jdv|xa<$sT*?t+;~53qrLvbkB*61xvOT25boP{Ggpd7~mWPZ;Jp@id253pJ+{i=0rF32# zIC#Lb(22}p(WaGdB74M*qct{eA2%aTjD5?4VrWdhth&mxpE zF;QCC(c*htKQ9IwF@C<-asXfupsYS-c5aR^c94-6ix>;lMh$aZ(4WtW+Ujqz->{Ly zvKu*n0qwjR9DwEW2|G^J*^=Q8!fletFBi$3zLveAxTR5?mD?z5`mma2HCw=C`m9dG zsH1O2u-x1r8t?bVS;y?h4PD_-ra+sfb+Se_kvqR zo1g1IUp^2SI4^c~9z9*#8)FAp2+zc13i&>B4$_9jf0?DtX}yje2D!~)qdY*2Wa1t< zRe^lbkWM<X*mhx_quv~m34XT;sR03(l--;wr$Hte3Qcx(r|&C zZNMjQY)o2dK&iUumpfxEqeV~+mZk?25feY@DprPO{gGdjAO%HHMfT%qfnG58UA;Xu z91~nvH>-!s+~ zkmX3eF?^h>S~tK)SjHCKjr(N$wC$1&GZ-Z6yz56FjG=)IsVfWayxeCcm%%LyuVU4i z5*bJ$@3P<~m_C{?spX#P+&G#jG;U3;M>rMRzVw0*~J zudfb^@(tQu8fgKMuAfpODJdn0DBayivouJ*ASIGYNtbjZ-Hm{Bv!pajcXM7)zwexX z&UNkOKeGGOJTvpm+;fl4^Nf<{7KY$-wJaN3+dea3z*QVE)mUTm^J)E>hLXw;mt!S4 z?b6i^de#K@U+G7Fj3eJpS4VV@YLj492S@)6l(H=<` zc&RULT+kp?7qi=}aJOJNcP@F24B)6#FzIx?rTXPA#F{pK(DkQhv%8BcL6}#R8TO{s z2h14@vU9a<%rdhAAfsD-;V)hQq=X z<{Y1$$Vy4|w(SD9z~w+i6sc**-05kJVARK@AY|XEnLH4{f8t9Bd6w}}2ShEFrMrs1 ztb`&}qfZL4vF)`vs*Je@R@#xH^;QN7c`s$G*j=;&4Y!9|RgF5ud{0vH!8-ii@rlNh zic{gEK{1=#$u6OjB9NjXn7LQ7wkUXs_xp&#?Y@1DKz%)+XZ)SD!?5%&ngFwIx<0vu z!{J_Cs-l2Z!>>5;?r;9p)n~i%EYGvA#V2`OZi&XmT%vT&%D8mGKueK|>8S z6c?f>?|MWDl6VV6D_HW%mq%o1$*$Hg9&%XYA$S6FP7^vNo9^>kW#p!TIBhBhc!Zz% z>ogzbG6Fa!+{eyPDoYLLin0P1F)`nboy`LfFpg?4XpGo2z!0t0iN(+h;<@J>z)(S7 z0uSriQM6vf-f2%abY{5!`n2KTI?r?2c<9-k#i_3yP$d7)v+&0{+=q z<8Ajt*e8YGHpF|jtrIB63vp;)q_WbET@W}@H$ zurA|jsiSFxd z(#pc^R*S_0=JQSGwu`)-ksODf5f%&hQsV@rE8roAf^{Xkkhurah4pA2Ks&dT$NcSN zfD@eMKh4rL)dhO;1q4;Y-Q(k96!>@{tk!HOJn6*Sm&B(~O z3t+-ObuFQE*`Xesdt|fI5o1?14Oh*h?c^oiWafyOFB;OkUY41ka-n3k5q=u!S$Y!| zE_<>_`_4;=aTtT zUHC7L!W#e|a!<6-ZXgO4&TVw@%x{HI@$9^%2sjyZ{ri77di^pyvq#f;(yKBl7o*v9 z5RC7L40q%WcGZe{*PCix*}wPw55on9Jx$IJIDM*-MeYe3+SIOmE_a39JIl@c6XQ5@ z``>r!+3$A*L$v13ugv&t)nCq^8G`*`MO7JlwOyd!bo ztuL>rc=`hg=`dWkq}kHi+Sw}et%^z<-mm$crdxI6kS`fe?q@?hWT1{MjY22Caf(K) zk2lGHAb-ab@_P@{o1I$e0RYkj(8xzX{!IN0rTKA#HgIuIbs|b`lI-$3=uG^vj$;~} zS4DFBPJl#cbfYl)^l zln=b`mWvmdg14T;51o!T|6y{xdf@uwEQE6$5h|h^?|pw(IC93R*S~%YcyUmM%f$&9 zbuy(sMmNU$bVr!cZeY^>f(=I=?Yp;EdQfWUzoX!RAWlXrsq@kN-4eYJEX2FbjeKaq z3i4_2M2@MmMCvFA0=!r2Y~(`MXR8TG`%9e^xov}#{Br-!tG8w&D?wK)y1RZu36un6 z5g+A0;)A2MnGZ_BnX*8m?add7+5u)gFFL%~e_Q=o*!K3?bl@9zUmT|c-B{eOGbxrv zmxuaN5W@QdzM7;uYeoy}|E>rub@K2iscH2_jjLX`xyja^uO^U@^9lXgnApn7%J$-xSfbr zE3$`#jO$~WJ(rNa7y7|99Z(bnT#=554$s|SWem~1s84xb2?)jb7*l*3DdV@w1SNk(@C|6zC2lrVWZM$c_Dno(Q%Jj?{k^+lzDN=B zd0khLGR>kx9E*9rv4S0(4J9Uty|{4CwiMFpA%OTa8e;0)5dr|)&(CV7X|a? zt7b_vf=O6CTa%-?!>JtLR`a>TYROeO$$7f)crB&L1NU+RW#{jg>^>nkhwIqB%I&EH zBFmTqVlbVfem7ayWSTDw0Lg36`Nm1vY_*9L;O23Y+mLwv)x+!SqWWW1zR&lY8wlWG zrlxYe^hgO^;UHtm2LDZQg=^KtvosuCq>pb`*tm^UHSJYa6;87mCSb3Wk-xg%KQVU5 zPLK`OwZSLYq|0qNSk*k87b$z;TD7~>`-f=fQyV7)$G^FEKv*~=l6+g(M?c9c#Z5-#O7aY(0If=fQ^;`A>1!3Geyf)&o3|k`$c(w}Ck9POxco&HArP z;*WwK9v>f%pdhYZUPr;S2NlCREk;EZ6@I@x8*l)G|Hne`BJfi1Qs$8GlTBjGJo`6M zOmFklIJ3d7pDY07;D7(4B##j86cpgc`%BbN)k}Dh%teT_jz|GayUr2w=5+eddvGD1PQ%_mQ z67P#p3N4{avqXnv6t{o-?IoJ}VYA%aGOI6sEaA`nQ^zbva5YCHx|1PZfoPu-&H zTKnbN9qO2wlA1|4{q4I?x}c#>jiAQa)(?BfKbMDQE%T$^+ZR^t3Y+CEY>7zk^P!hR zEo=p!wZ=zwq>%5W65S3RSphldfoZ^1|rYLrZ7})O={i?*ZmD6lU8MN(M4x zEe2~{UU)T`&(>CrPM%1t*xsvP@{b551;>*Xu*S)vyjtbQ7=_MszB)?2(cRvPs*@8E z9-UZ;wY8d;1wRH?4#=`+-HTnVyT6ulRbH#|eZSiy052oq+9xY(QLmicPAm6RC6vP5 zoR^oE9e$}Q&mba)+j+{Ki5~+u>@jZjK^P>>u8jGWo1N#P1$!v?(z#tHa|gxj{HMh7 z`u%i5MC+uHlsH!X;x{+Lc|$`-Y6S+mE&4==zv@;;=y&1N%Oo%q>PVR%TYRK=iC$Zq zo&wa>nY&EXnOR$1<#4Z>@fF-3Tm~;hHFKn`={qxgCa)uyKEXb2jykn~tB})V@F)#; z=&S`-k({`BcfHx%>ifyn;X4X6u|t*ueRqQsuvYg|br{da&Ri>0L)nM0Y5Ql$Jo zFA*NGFDm8L_3p;icojpTF1EAa3I z)Kyf@wzrXIXZ?_nz>jaU=D&^MfzbKn!D?$`F1EMR7^8DE>%Wzh;n?;~nJS&eROt(Z z-^^c!_3wHF{ytcNywGtbQDx!+2(JP@>eKJ#{96VY1UsVIbO!SUB1~R`5?4rLZv76@1gNez4qmX7=|w&YRUavnUkLwRgM(cWUv5h zTTj{v3Rt4ou@E6qio~hzhbEPeFc_!}G`?%|=rIu8>MwvKGa4EgvUf_{@Ca2zkPxvB z@J+of^|@UbDLwm&IB-OdSre z%Gu*nZR;@}8s5UnaVc|(AJG`gwtwg#Jun|rs*Oyk@zTc?Ns<`t^`38VF|H9bOQAM{ zh&&(~yAAU8I;(g9DF)HQqnF4jLoso1a^3jQ^`9Rq;^~=``Sth}ty1tfjhBIlY2t$G z^TzSuEh7fx7=+jyjY$*+b0~O?mxgw%^M=j;eXqHCmEF}?W76(6>+jysDb{Z^qV`NRwklo^nfo4R} zCKtV$Vv*EPu>X-*iY>DQq)4hE1+ZZad2LLDv76YO0L3eK_xlvWGGfx-gUl4R)Cuul z;;k-yJ^J2K1B5r*8rh}OP%OmuwnwQg{Y<+j8svSUQ3*HUaH=jnqh$RsqyCiqO;09m z?c}cHUlaRUhIpb}yM~dRCje0tIAt2*O4Wi+VwqnYP`$HBaVq0>VjTV8e|}W^N=jo9SB$xO^3Tz6 zVxv7wqy$yLA66$+HrF>SN-gU4Irq*T4sK}0SSeWF3CX~2T+;yID(1V5Nq<}%KVE5u zUXIF40V#ly3X>dml1_5%43qu$;v_R)Fr-#G_e8VB#QVFVv&X9t^277Z$1oEFTN+zb zwuZ0N6G*3!DgoENg&+3Bf1auoJ;aBi2(}2e8e&GP!{(gv-`GmSHm9GwX=@hw0@b=u zZ*oTSZ15-ZCQGh2u?;1c1)VMM9VNyC(cR=7Kb7NkCH=9+ZNzrArH$L4rO5xH#JTjG%^px%yAJ0QGPRgW#FGiJMT?VTfAI^ zgJbMb{!Al7w;H>h=(cN@ zN8<(U-{AsfA@x@MN2nm0uK)0-+ng;r`JMo(K=`YH3?t8Ewd}c`V&Mx0rQU2{sPwr+ z_hB4o1HyNVKR)44M z@yF^QyIE) z%SQB`J~p}@1Z&~0^hvnK4vq#7Q~0i#hWE{!zRyLwt2HZ@N7Si^>BwTC5=g;FHWMt%cafKEoT2XIwga%?hDf>um_BE zCbrHeHxh`%1pc|)&8t+mc>&WG0RzT)@VTViyi)ui7e=hM_bfavUhJ_l&)vo}PDjUh z$b~r|LXByMeDV1#*}B)h+G)YUg%^|!{wz1wlf}3;?l_rLtzYXq(91e0oeP{n%^}(J_ZOX!EA>2=m?r=$T;3v&Kgg z?@A3W|NE}c?nC%_qr!pLsQ+@k5Bs2s>lDdDiW2eOJwwXRb)8{6K9tDCFEo~yr}bw9~dpQ!OO<)<_d8~73B z_@eSZbNX+p!m+MPa>kNN0&a(b9xDTSS@iRVi}b}LQ5g5^%teEgfI`nK3&In0 zOk0#qU!VPeJpP1qQU)(;Lh*v@?4Q+0akJFOPcft7NB14lEqmF>-)>FqF5fEh6=UrA zaEPIZ-JJ)zoyZHWaH`-HAY{KMbHl4%r;Qy6a@LvVRfdL`RkApr`pCsnMA~;um3%h4XE2fnfR# z<=TrxX{T#I)+(udyYSX|RqhQp0-A{3DddcUBwa=1$<>29|67z?WGS9BIf>oKO|MkF zpV`%|qxGbyzj%~~3pZ7n|BG~Z3cu54eAO*XLs-ae@gt1FJEORWLry0F+q>l&5ArYU ziDWrmK0e=go;V>;=C!oS4tvQj^w^?-T1Q3A28MH7F$T@1Y+86s&!WADl&aTlrUQ=s zpXjHyR+m&?vtOP0J{ryPmb*9$Uiz5ce~m4`{=Y25cmVG=a_@_Ln66a^_4+s za0^bShKp?=*0#_JRQ;|s`W}UQEy+8INNsEWYxQzhozQe&`mqs~mp+3V$nEi9f_9Y& zkpJwidO1`1T{_h@!7?BA&u6vnr|f^p`bcTMX^V?pbCbEY2f-j`g9K}8Zu_ByS1VO@Kt7f!1sw9vKpHy28W3GJzT06`O_vldWQc`6z)mhUSLC+g zEyMAa!HrcP+x@a<6_r_H73`SQ;m5vN4{jdIW<%vM(O>Hl_y$s6;FV}#Db&mw7t3^d1Q2Tk?0gR_87}K@Rbi^J)-T; z+F;E3=QS^N_BT0azdfr<>xrLq{gGW|O?C24&G zI|-TuBSen!&As+*$WF)V$m&awUEhJb7nW_Wmg||6Xtz3(Tfth&o--S#F^lK&qzWg% zTy>1lD^Rhfy|cM|*sW%2{mr#1U&vTM8v@O^ssJ6tg&!|3#QKvX7h~aW)T39Yk=u9{ z(y4rz{Osfq8_zOdvI(aQkldE2r;-Mp&t3boL~H=0Od#<-5+Q`{TVmeY{-9{7_JNiL zai*;iJ2{MIRQ|-{sw{AO(ogf@8G@uazFh(su=%}@oQ7j(h30FJT1+L3^;P6}aGn?- zfl$qlQXDk0Gv3UN%Sns}%8TVF7*xY;A7Vz0<1w*8K95U>xT?JKdMQ8o&%|yexX?b- zXB1B8)6U@SWa&D;52_w zGcx2mhq;9X94l4gbxo3w5*g5Vw6N(d$3iSs0ZkLd*7QYK$xG70xhA(zHZu#+xat}* za@DWEwapN4yw~5Con|s1F~lnorfAwE$uGUDIhJPn`}tvuXRbzZGh1v~boy4akR`Gz zHfSrxYX4+^!GGB!!s`0nOLsVq!A_9ENfWMf(+PU6Ue`BcH-M>J;@5>>dbtIdT=}84 z4W&0=Mb+N8<74&=MN&gw-&*W*I5|wZG3Ts{pK3wtVDPTbf#_C3+1f)@(NvW3swz&e z*4L}QlEsNFW|kkkA0`Q5KYR75B}4w#@K{q^%sxR7{ich_`3SS;?+0N*C+hMFIppT2 zc8v`y%~xF?r~n26HSUQ-{x9JaJjq7!BkfTC)>O796v0cK#%Ig>1l0%aM6J!g>wsqu z&4gy$q4`*l`}gpqM374&8~TH`2#S}^@;IWTWSbkiyV+Gu;fCF9haOkd)aarD!qf@9 z1mB1~kz5UndY8>dT7pV9r=o{`v9Ky2AfH`?z0x@ZqU)s8fQ4mZFpu;5Y+prRdUO_7 z9uob9$&z2x>*!OLez!+w#aO7=f9fIZ2k7_Vk9ui^NT~V)ozLQ!j}^5DLg&Hic}ISk z(ui!~gr|d~JVf+y(u&!HPY2pq(UeU&q?7o9!3x9d+&VN)<4sJo=0;Xo#b}QY*eRaY zhrn%}1hD=ssK1qfZt9nLrR}y^ojoLjd!<@Bfjt=H-HqDT520C|e8K%f zUTH!E7Q;>ST)TP=GI`qZj%WeVt{K?594?mFV}hS6cF)+%c37GP8`NKiZw} z-4-URUMz1?c2+<+6Nxj63i=b5{S?cH#T5o023apb`s{a4@cpJcN}-h>wibrEDF0JR zGU$oQb#!tnGiZCmZ9UV>SnT#30*(6Iv4#dTORliuj4GNh zQgG~T6YL`FxPF1f&1|0vL`44y;qM>Rg!xjTf`~KnuC!&>b++#Xg!$t|Eul3b<`y8q zd+q>nWB@aAkPp}tKA_Uaaco4)c7~|2I|De z7`A+InemDe&|GpC^1)$@?m5C;Es09=bbpE3wmD`ArqM$vI8if^$h97Zca%i6o??eV z4X|92Pp=^Ar!{?9yTOr&`nJNzB7Z~uhVvkY33o!rp#T_@e>&fFiqvC_t4D@0g#doa z$B7Hg&2s1?WeI{i-qHWA4kPeq&uB3NNeU$b7Y~v2L1S-Q_+^3aZgzGND-N!oJ81nq zl10mwwdxC{1nMoT1 z6&C)Jsr)qbN`pw#62o6$s)bpT3q{ zPcKT*&xbap7p#CO`J3zvv5qk|U<_`Yv;J(1J8-)1i^nFN!r{M@Y;Bd1D@kXTW20|x z`K%I3fQnG#L7Bl-svZLJ>lj80`TR4ejD=j*%x{>IOiHQ(p<1x@^{rN1#P}}mNNGB= zg5qqtNE#qg_KR#gqbsFsroB2dA(&zWNdd~u|Kl3t@^df6zt2ef@xBE)N(>f|*otc6 zT8d;*QOiJ_8+li!lQy9|Q#2bt^$~&o3%d!FOc(np4iMDjx}FwzM=7l%Q=R=cZDHv6 zsl(7u6P#*cB)yWFQs0H}ocP#xMnKs#?`^hHb&=GJ)7xqs=S(M_B-xSKF>x&|GT`=d zeqS*BT_l|W8*%QRZ4J@&*(C@dEfnkNz#k)^w{K6JvYM?-%1+UggnA+wCB)|x=ccow z=j7(4rgh9CvcHDv{E&XN%J)NbvLq-K+KIZtjYg(UOG~_fB_b!}i7*t;!@|HK*~4x@YGb?WF=H9&$!hOc#P$ZQ3A=& zmE?M2G%juz=vq|RpD(MCSL<~(O+BAX$*}%3lo7tzuYG1E*DpXF9((V12zMkpPn(B= z$Qw>HRMdROrx36Sf=?l=l07ZcKPHBV((TLugduRcpIG&Pl-@8Nqa_1ZeGI`IZ64Ri z)+hNb#2%TGl}?sW003@(fdH{=g}f4XNIAq^yO8VYh9>>X%JUMV+$DUFI=buu{mA!i z>BCZ0C(J$-qfV6V-gyl*(zCYB=M9gKR{JDY?CxU>lOI5~;Q|&y4DH7T-4O9odBN4O;=Qy?(Ta)Dh>HuxP_SBgOF*0!mW3*IhZEdXu zHNqA?85o7skV95g!xEC9a@vk|2GMPmw(%T|L zOM!L~IePYV8gTC`4E z75t1v!Z;TQdjC@H@%5 zevCda7*YxCmY; zm%=X-Eh$cjk*ORtjfIh!9+5=|LJv*W0k+O>X8)D5SBJH=2NBqd&`ZXBK^R0d4Ep9K zR&QX^tAA>8@Km0tx=4HuA1FW>^AStOp$Vw_Y!P?48?t5Ke}MeE1L zP`cec-v(=fi0E}WfW>ts1jP9mJoAB(Mf9q|(SDbc3G_VE6A-}z`M+M0qX*6`F;lT688M@L-F#wJ8@J(%SdKXW z18NY)Pb``$iBougzZtN-2b`mnq+pWHPOVI-f>!izoD{be&&htr{#d?z`K*bNnI}w< zC@uCsW?aJ_@ca7X4CDVBmaI3$4=;FLyJV3_KkyA!ysc@RnV+!UEB;DOL!XJW*-_x~ zLwzeX9uv<-PwZUC+5}O>N6V_yYRrqu z6#G+v_AKU|98bDxivcQ;|lo;IF>y6M4ld_6G7N|Dfs2uLLzWA}_QH zPfE-we5aAk>!j4;ypJ&()nHciZNpR>=nS&CBv%S^7wjxFux)GO<(F#-tj>5_gBOs- z=@sL|+81Q>>2j zQ70={A)r;i`)W>qXL7t)@L$|F^12OIdIZqbK)=RQiY~c`wK)bdtpGOCd-{sw36$C=jd(3$;^JLzyJMtl@x8E#bZi)YOZ(!iQH~A@PE?dM9n-b zRv6x`0W8AbglSH)$#$vg-!Jt%MWJuk(vWIJ}*q^EjU*c4|mHZWIBS_PlaDi)GX(}X1!o0$ctN+x zvzzQNrud!kpBI#x07P><7i_ta2`2-{8aF0o`^ySKpi_*!mBW&`QN|kYP#BFh9%L$$ z+dfm{>LkWxFfR=5{FcsMn_AIrS%_(Xw<=1J1$F}v9-e@G$onr)^ZroEpNI$)$}E!I zu6r6WzIUTrj0ls+mR^}xo}t;8Zr353P-MtNuV}&KG8X>6;7?fZt<6ZS2jKjS&H$bh z9Q4Q0q4oSlEwO77Lo&26xy*mNY;r!p4-;>#c*{$~F7dGHxwh7#I!5p3Y3~Xjc``(7 z-JE?yF~-56?r_=sahul$QLWT}kVl52@(jjtB9@4S4@A+K#qdZyR7lQzXkIL+qgtBD zqo-ET45I3h)w2N?e1poesCsaQ8&?9`LJ%)`EazjK zyNHp>9w6^qjO}H%C%V_lfOj#yfQD+!_J;A_xBWSWp7a^(kqNW8vGFPqIqJ|yC?c@d(q=_E z3~!6qkSBSN06Gf}93~{OE0HCXcGT1n``t^Vqhkyi9(N~DvR<68sH*XTjh5E4zAB7D+&ye$9%Zr9n< z6~Ty}M4LN_CbA2aGp~TCi)rgWz*R<|qBn=GnIj!BY|sxl~YR-j3X6rrM6|)b@+22v)trl~7acE6q61P5JvI zBn?ggScM3cvVsW_Wr&C)y-qjRYX<_fwiq=2F48^>iaW5I zeb<2wyr`<%eL~-H|Dv=B4hNsY%q=izJH9hh)_e; zTnU43h22jnC?#BTfLpIDsG63!THn_h%pLA(*rdLdQC>?qgdPE3REn2oB~eWF?OU2q za(sOBG(Tifd`xw!PrO?imWpaEw6XNeQ1D<9(9*RNk6fsH+FABo#N68Fi=OL{Cb zQkL*BbL%QGok5;Z9Ake-;^8tn^}~k`hfG6SW4$Bw8yF)an&|-?{FDVD6o?n{0>nE7 z@u$ZqMP`(Tc+jU$pM|m&L^6}bgHapr;DmAYx^Nj zXlZFTUzLZ~znVBicmiUSsFE&L;KdTOU)UUViiaIN>Aj<%8aR4F;NPVuOYljaJuzG%OY(qNSDa((P!y6l4xj>ntxXUuX%W0lSSD z2O<^2+)^>2b9z*yQ@83sk9WV$r+(h)=(|@^EDc^a#%kL0Rkz+PmGIUwE8Zd`Mg%oU z22r0y_JuL0t=S5PrAWZ*w@=s2S>Pp*8MV3?nq^j7Bpd%?Be3aeg*9Wyj4)0*>rwNV z=qF4BW>u9jSm~Zl-3NMzfEjToGo%UCdqhr{V!r9HKN!IyEFTn=PdV-?%F0+?3uzL% z4aW($o^l3H_^TO-#I!8QhI0w6dIOetZ7I+yjcKDlWmHr=8tT#YZMtl$+i?XBHcWL3 z^YZvt_STdS4i6Z7l%+>!67^!#a7DQ{Zb5K z+wn+kA&boBid*gO6o&Q*M9J;J!&9QW-e8q$l ziglkuKwf!4gR8UEqAGvUG#d(D+XXR5_3~G#3x|rk@twjC4h~wHTo+oJh+<<@Ooq*g z<8jcNovo@BR}bVw(Gg@+4Aw~~dtvysI^H$1E}ygk>n4bo{COn$cR z!&I@?H5@?WlEFmu<}f*0w}(ttSWZ|&>TqunvD(hayx$3>?BYYV1LrAm0#l$+s1u?O zWP%7>s{&8;dU|lv3)ktRcVKkL8xId}5Sv1`_%R}45!`uBZQ_Ls7E(Y_+uA<$`XSB2 z@hcUTw-f%*Ix{P?_7Kj2c-yI!STLayWoDiWpg}-(pvJZT8d1@jB_ZzN&PK+@E2{yW zZzA(QgMzi*ZXU1d(lMqsA0eGZ?YAxvkdl`JZs49vNWX$GtkM9+tt{>{zbnqR5IC^r zpT`uT*jfht7K74TIW#>UkS`4M#d66!Q%3Y^!h~RlhIVoJWpB87)i)$10C!3bsBQWF zF46>-_(ioIQ_@c2+64QO+{g>RkFP`!-A{MK(i^bD;=0>mu)(=$44o0M*&Rsu-dU!v zsmhH{fwsNRdx1?n_@O6?(V-md@ral@3g17PaGW*OQr%Q<{K=@4C5;={#;^AHPC|oT zdUl5J;bA;^Qnm)^4nyQ0_Q?WrBJja$ zuP*X4o+^Q&RXXg^`hVOoP2`g(l|Iyg@E(_s97st?u?mi}mg&tmPQ0OgxX6n$L3}^d zevFDTj#)Upz81H(ny93RsEA~or^~KXUAlB^_rU z(6#i+!NCD@g5+-4{SmH0YHe+N_UD+DOXOuF6Vdp&ArBC$zx>{-%T<>2Sj5yjy99$1 zz`YNEuU35vPMs`2ElFC?yc|163QIxGi#s^i9l)yY5 z9rX$f;(?r?FQ;#=)`VHPWPV&vnWpH(zkM=&2w)y?D%LvFetAu2M4Qx44UM1jcGQ93 z$7hjYcxR=jr^6_^>;kYzK3?uNflPey@jNedQi?ZfZy6RJ4>?}LKw@H-n>FD}ji7-w zG1@P@ctNil2gcrj_tNo-ysK1Zq^CLzbHa%RIn{!+KETI&An@yNTI4IQhRn<{0(9h$ zK&-CY#`?#Ph)ZCP6w28uoB0TX^*04I;-HoI`HfDSk>&|CawwD{{9zv{|TAHa3tQ;sVGxgaR zBD>#Pf_C|UOQvlc3LBWKv;-pxWs1CEm}%&sJ;C#i@*Y_0`dk&$n6VPGhIppBvt)xs z!twfQWdP_zqw-+0TFFys+qAGu+u*-A+3@X-q|ZoCM}+8Ws0J6o^+p{%5dgJ&!Fdoo zu>-5}JSboI_MR4@Z7|i69}84tgNs~_$dVa3`T20Pv|sPChj$5yh*qnrs@zHAd)R|?!BsAoN(d0m@Z z(-HYL^Ys&ap8>c}*WUX9WLlk{ECWf8v3?(_>F%#&pio0zBm6>U!vt#`&LLKiP{f-Zu3?|TKIq-L3`46wSmYTUl^b*~8nkcthO*Y=x@)*~PsSwW7Szmiwl z$|L&UM@VKa_V{K89+IMBg(HYF)Ib~;56?@XhgpJa$%3Y3Sr*enF?whV`!g#>>=$=7 zxHcRLtD|y1It{IhlGaWu3btyz5JXf|&>`S`(?$bH-D_FCV=g~lHtHrTE_A=h&E7$Rv^*5Jb5P{a zXkM>%t*oq=GHcc^ZwPr_61{lAMFW6$&d7x4nm-IvP4ef=J|YbQqt0X{c9$KspLZI3 zkn2v0c}r|;4m%#}vfVcOAlX2s+M4k0u6y>co9oN@>gC_THgmO3mig8$5z^UT*q?uk zNus#^vAuQfnfZ%yO%B~G4@10rHEEj{ePzYqc24lQUhPSI!pq;`2yb5lcaHN(%QWuI zi?xCuLRHJ56Fkc+D`Gj4EH^mGaGtu@K!~3=9%5czEBrV;rv$GzhFRmo)K#!>mDlwJ zeXS5H4*~%=8Ba;aS>&1Myu53cx~+qRqN}UNEX6r_VYT>EHNdccUf!TGc3z(7gi3W~ z=(bkX==I`h_|^FaJ&;nbhWIi}9S14m&f1Moc=LTWAQsC8RV&z1J6o=BU1f}3TU&ei z*v$!6S(w!sFqw?|VMn{%Y-o7JrlF#_yuj&a@)i=7$lWFk<1vsk&?VD+FL?HGNtX*-xzB4XtQ;33daf{K9`8Z+9s~(no45T(riCX(S7Ks= zS;<}7R-7<*x#Fd;OQPEOv7F-mmMO>?P2-y;3N56i`AWXA2{MkbC+Cg$6vr))_u6y# zBa>Bm7lHa&xTl!~m#^fE2W^eHT3ikE^dT^Cs*vCvJp*-%ed~yz4%wRNx|__=tqAqH zpu^rm*&(T>j2|{i1tVHG)T}KJmB4Pqzsp`fi^Fz=vHU%U%XI_jmsI?0UW}ff)T6qc zeuzL!{6T6hx_#4KoaO2YA__r-@SEVpL+~Nf2u~0uee9}!g8x^edUt(gX#tgo6I@l< z4+k62A3SQ((+FR=eD3EV#1K)!$-Q-g^`6#W-3W8s-OA&ptn{r$wa3t*Wg}+lb_7I# z`9=VOq4_)RE7`6mdR(=K>`aQs_<6|-^dn=#{8H@LIyvF>s-N`rQ&i6+=-Hy$>_Z74l_UT#X^w-;#8< z_Hbwg-gtQa?peevyWjoUA*Kxccs4~;ta;N}N6cmjIS4+8_@p&iUqiX^9yK0=*MwA- z4#gn5)L`t=%u<%Ri7g&yy|ce9MQ&sA>azW7QdRAs2Lym1L_Kn0PiOKrFvgg9|KIoM zU!kZb@6ue8)yoc5A-ayUs?v7?IV(BRFz|R8ZLqqS=-gj7M4$qdfbO(&tHxJBVMk0$ z=lR#tH|jy$ym7qRYU$1(e>;`6Zs|?txdDp)PHUPF)nCpJn{sY92Tm zwWmECWC@*W@Jps=JutMBoogjMw!N!Cg^ZUeT1X4L|EI3E0E+7W;)XBXCEcacA<~_q z2ujEgr4^7a>AZ_{gCGbxxmsauq@9-|L-&N&O0x|49wjx%ieQO zpU*j`ag2+Vh;zK=|0isQ#YqJJo&rewPx09 zx&f;ZM7(}-+k-xgmtJ-8I}x{T$BJ6TNzWSw^Za~$40Y%^ zZRA5OtOL^lLmrK8d zNRa5x{EoSA!t@gs8wd|s{!Dpr5cwIg--S5-+z6RonXbAWP2jgDJ_mr_C~m2ZwD7-b zNzHgCBF~h^`%bce{#QcGLVGijlCMJ#=RUzii1^B0^ly^W;KKqCzv^0m3wBoz&lD~6 z_4T(~g`sfWW(G0yL-~%bI4RqL;c=H9Y6e zqFhp^do@3PKG`B1W_0KE)AmlP*a<1tlcM`wwM&`q9IOwG?j0ckx902UGO9Iw0qH}l zp(5|BHhBYNy2&yV=7>tZ|8#GIxWbdEtUvOJmZ|}s>1f!BtZo==jfms9tS$%D0jvK! zIUaxw5g3WyWM)37KQa`1mhNq!lk^h%*Bz{huL&rb+l3jhEQiWe=BFm+QnzyE~E>bUW!Ge9K|s z+%tf7=1rejI`)HH&ZXl>%CVEB-)NnvGOrO*BI)CPRV7F5v2MBK;zzLff>sv zaj^t?dkOXkZ73IcqlSfyFDyy&t|%!5w!@7GZ4U0&0|OkNlb46?HWBg3L}@}daAbej zugT`uURSmis7Xwqi)+gKt0CV`_U049%`Pt;!hD<1x+9hX=0LHoTEw48-2TAUnsVM#($-EvsUs(Mi7M4)bhGkl{N zZ^}y2R!KzM@aOvX?3uG!7Od-Z=Xu3y(81RY> z*u}p#k4JZMT9;!u0e;{JQ;(Zx=j6bM1BqWDB{o^Dr2N@3bF=j>sj1J{E#E)G!v*;= zSaYJXNUNzKOMuH~Y5uSK85yxa3v^QR^D}Lb;Vx2ya{$VE03T-&dIJFzB3`zYGgl+0 zYp|FAFypH=G1)?Xf0#Ebft=!OXn#&Hn??I8#j1`#w&1JZ*!4W0Mlb6Q0oLK=rvJ`M z9%oRl@ZW|gB6}0#Qo6lx)tQ;ht(Te}c~oYoiw-W;&~Qt6ApPTqZlGf6lBhL5o*Z51 z^0BIraD;Zrb14ZGU-=O(ssU~MM^@aH3?l`4;Qi6C(Gg%nw*Hs?{h0^@BLX|7`ntO9 z<8yyy!~D1DI0-myRpk1F+p6B=dCpTWQ+6h^JYFnUs_^Z&BDVqB~s)rt~h<{ZHL#Wj7^BVIRV~si@X^}3{H!&f zVU!W{HZzk1uq^-V8R-A2#gr7a5Ph`9*4GNG@#9IW2xdpR&bov5(a(yb8yo5Bn;M*0 z?!MXx9mwH%cdhWq5383Sd&a|`ZV#Xg#?)3GM}_WBO!}&$A584TDXs6J%Bv&mD?+h+ zR~w`TEoP6i``_$0wn6CRk?~(~+Ol{vbx^{aWhNryD+iUUrbh);ZC?aVCYNyQcERBr z(}rsa(L9X?SE{WFkt@s9RtXlG=+!lpSG-b3!Sdp90t&%EB(AezXh?t~N*}Tt1V=6H zc;EIjw^G{)={q<6lF2l3!%_922X!VB;-{_;Q29gW@hV=s8e(fp(%f(7hx`!f#l_s37)4X-PERlDl;jhJ zc;`|i7jThAsZ*Af0;-(N`zWgY^}ZLB<|6fWM@cAXzdGA{pCpN^KvBl+!z4 z*P>J!5H$NI!CO|wRgISBbTBAb~Wl57{`FS3lxTi&ztHYHB>vB7<=4`dFJD1ekJA#GMrfx0ZD7L3e2n_^~73T5Yd{{j&>R218l~&>U8U7_{3T4rx>}Jcu_733d0{h9VuU*v$QGGs! z%!uV$D?J8cmH7T8DN>Y!L(Ot!Q_^fFtLkW;k)et)-FN31%F+RN0{<>miq%uWyL(%6}cSUw|^CEtcry)@~lJ7rbXJr&U?f6m2IUr`RG-nR1p z@-?)SC%`3fDYeEXobd2HCj5GJ>|h|EFpLuWk;fsVHfKpoS{U!aga4(5QZ|!3F1+KF z0AoKHTo}w5rz-ZgPUz!_=g27>kA8BRIQB%eC8aS}hF~Y62fT#g zdADy6+A{?PUA&mea^-5VA_!YqRGWz)?i#SBOuFIVzTb_4CZa|wmE?!~V+=8`KFGLq zqdrw^&o?)c(a?Q{oS0GjQvDZZYB*s9UD3T9qxN<`c`KfhN`&I)-(>iL#knX!dPEet zziZ;UGm4 z{Wci-_R)vl6_wi=>W9+}umbDTlLqHWFRy{^$&fc64fNjSQWSNt`jrtEl|i!w$-9u! zd+%6Q}gJ^nDKsN>2HKLIjkPsw4j1Kvd6on`#iVm4_@6LeBIz9 zq9q_u`>~eFeCFO$!~OX(Lk4gueB=r3qyEj=vhwGWk}tZVsG>4%OZKkp@e>mhlPom| zvWSvyfU0?Ug}9qSCggnwL4E{o0be)Ga8}kJ zY-+4>(G4=Y)CQCUd3n)k{VQh)R&w;(nexX6tAq3CJ$3Ug_Z6OV37xEB#Cf3M=shA% z`Cnc$PBZ2&pN*3=T2=c8jD7q5)ifHKjm>`-l+Vc`HG}_fpEJzRUVAxHchcVB56#w? zq1d)x;n`qI^fA84bomj=%HG&-R(!tvC%4kHcDoCHA%X~dkfO=l>K9JIg+}1L zxZhS-LBZbRnAnHKf9PpAOrJbC-I=*UED8H0y9${EPj?1gL<}jcqqBw-FSZ-!+D?B< z^}bjkOLSL&T`7i0{h9YWJ5wUZ4^77fLpf1sOnm`wg7b_&w5K)w{uft!SI0IG{pG=e zS;Gsz!LL!AYEri&dU~7IY5xq9;=it8wGDLiI2_&CKdDS9(Y`3Rc?OzwID}s!4-PYP z)0G5GP0>GIzy7QeQ+BQ&{biM{y6HJO?7`JF>m0!m$jwyy(c$QO1@I$+*Fj*rxd_0K z@>Sd3(NV$mTm7a{dxIx5iE}UL`+J#Bhbt520XtT%SG<}5vzm+&4!`9&zX(E6QpQES zvUld!mwc|5D*-DN!UoV^MGKEecw?a9f(l9*CpL$T}R$K&f+dr+T|W4*Ypf z@jkSFP2$Io+GZ-sb!Ft19!B&)6{NfFD^8>SFRx^Lrquv6gXWE$hr*r<0pV9 zu)=(7Um@K-(>tV~tjDZ>%5rLarQE2>PLXI|>Lyb(M%YweKaKudXfYz=CwC;ACH@|> zx$k}v<4lwD1vTs-XOCdLVZs~{CGWiUJ);AdrN|?Mf#i#P0JOL~_`AWo{yKR+o0im9 z9I!8X*fqGytT5YGA@|jfGWH=)cv=#YBeq*qkniExlSCY!g8GN{&dHcT>TiSP`@Rag5<6lV ziwb}ea_Ftk>U!0EXtKGpYa-7>(w>oU%3t8fasBW*b-v|57X3F8-;VieNePMZ_$<-= z-7$g3PB-1Q>Njnnu8p~M64XUjv5e&SZ)+TsBtSz$GyB%!sc&r6=KU`->{-y#-5pmU zGqkDCRTl)xXmY;1`~aE~FP5tkN+*m4Zr(byfFHd%`b~Hhx5>fMj?yE62m2(ZV(C@KZTbTlfB*fohVm^QBK= zbigiVY9YZYSps;3GeX}rU>XP714FKJ{lJVKYa+Z~T(2ClSH_QTXvk@5MrO|dv&RggJZ5GRg#a%@gB#$!ud|_Hb-*id zq*6G4jV%0tjY+{ju7A(>hMae>?*rt#1oMzgz|alAl?53KaW^8@DCw&Aa{-s*A`DZV z3(m_Z;nz?B#X3qK+Dl6}5`NVk7{tcJSU+%g&$f~)Qe9MPl>@3f)<_()vP^!>iNaJ7_CezpqxDycj^ivOs$pEo8uS&Dk%!Klf*M*DO|!nh)o3+#`}XfJ?z zmxWq|U1{&B|c3w`u+){sP%@VJpS9@&cYhqRgsnl0H(7wfDnxBYL)XXs&8C7~X^> zjbOmmWutpDfLD@bl0dR352yg}H4{khr+Gr&7*sgn`yWy=QtM+5vKfU|H}o>eI**giN$+*^eeEjx|hY2PXc=qt&e-)+*x5j71`d0RVf+zd_ z?F;yMv@~>Fl!U5U(MvrMRSZ5`lk{yX%tvRJqu9Y$6CLJA3urNB>pdz}W?9ckn5F2S zKjZNAxQtKtZc!8IjER@Dw=a|IK%=rV_NjR;hs$UOS9n;!6`ryX%e_|U4z6;%#=nPi zM^Kp5+91Xw%gf71cG2^!O7JrQ3!*0RCi0;D@bzE=12cs|#C{xN2zak_^gGo0xzx6x$1@M|g+A z!r=untf!S#TZZ|F^BrhZxkmrN>uwIGnUPdv_&s` zg^o1hUTG`2p&>abyP}f}p#5IHK^}6D+}s~nd+X^@f%p_G&8PxDdbDNlx3@%dBO;^X zmCH9P)tI|3Y;*2h(nsX?H#*I20jRy-wN`833 z52JTlT*t$v zC;_}zK#Xh6pW?3ScUD$V22E*BB#ewr#}8F89Q8z92KOTlpWXY!$)lZ#ZhJeJUa1s< z8pZBj)PP)>g{&}Qt~5as7^P?> zyE5#hq=$acAHp2l9p9gSx=U96k?2u?+$@w~=m_X>aUC9F-1dJD|L`SuOaimKAG+_u z)sH2QDozEhZZauo>NWIwc^w-;!vw1@mK!XZ1x%lKe%>blLM*#-?+6v@+cPUWK>nZ2 zk{ikrO~%x`@%nJMLx6Hm1l$3~CN3UwvT&+5RW(ClOB!#C7$G+P&66tATBpO`d?}!u z*S9~)yTY}7#l@2S?)hc>q}-OCJug;lY>Gs*v&5!O(Ih0n?`tb!w(sY`Qg4_i+78Qj ztfR%5;sv)8q<+s!NF1U=EJ3)^A`St>{=hAmI%5 znr~SbhFXw~+wDi!2tJ2v)ItcY&iQP_+4oN`a}5keFOHzS5VD4&N7}Lmh4xIZyDh!j zic>{NFMC$}b_a#qz$gw;nmVmeT~z(yOL zmKJ_+z>&KBz@!jSP}Ny=RDN~VaEIUoY0(@wmBrIuA=h~b7ZG}j`quTd!bUwuP=V@JDPpDQyt2&_0#Ry9NsAst2G`V1#?X^b4%5;k<`q2@p z{pXzz_b_X({pekZ!Vjw0y}yl=Tm$o6=~U&t*D`DcnS8cBo-SbEKIqbVabwS=@bxQy zbn|GdGjbgY?%vV!Mavu0kT-=NsLEwBSy`#O+!YN23d1H4b4t7QwTUbfhmW)C=IWgo zK}UOP2bWJ(h*pLXIJBAYfF2C$?oHo8G`lvJ?%m=1^0sk>BjX!>Ug`}9Ck*_#UXCBVp3mu?bfz=NbO+n$padMcj)9VD5-+R z?*U5J`DeKm3fBGf`z#We1nDNEdmM;viN>vYCE#XIVvzky~4a@$t3w8Fw6GxNnh=&hZKnNA7Tj;tMHU zwYMmd+pY}fi2FI@S->$yYZsSVBkUXFIJ8&&hDKu@4S_ZfxiSPF-%jC{X9I_O3`%sa zGHgstJav$)(dzKqG&Xq!Wul}Vogf@D_{cM3h364J|A0ud+SqZmT`M^!ZXF{ul?+zw zz?L|1;S67>j>{F@G%Ej3*i|}t^>}Ay{rK74;V0>x4cl9gYaq<(GyPExE6Qf@zoQ`g zrE(uWRo)m%ITtiU>DhgJ5EH4S80^9;^4oj9#RECq@s<4wy!maA*h;9f?_gD+(cJ%Q zpwC4@HuHj?>yK^i+X~*(^&ba^6l`}pq~-$$o49}4jjdNTqkUHTvrok94kuf=F~SMz z1r&xxhP~Xqw`NXur=;p@@)ni7yvDo-8_8xGkK1*5B?D1>4+$ukz@w5CQ|+DKU#YKZ zyyqf@*-Og_fK;0F7r&#PCt^*W&W?hc{tLf_n&!Q&DrCHKb4*UtY`VSX*cSqZ=Uj6) zKy|EC&bDVLHEXHE+kn$h5X+ZtoreA|jm~(m7c(aw1G~zz7<+FxKW2f2cQijtXQYaCd>U!ML~TzO9rv3l*4?uND$?k-!Jw6>iUV zLKDyrMZLCC10o@p-5fB%YG?gMVxFb7>a%_3vyAoB;P9mLvf-+tvOJeXLTfOrU;yj# zLKt%VjX?UT2iqs8=#-ck;#e2TGXJ+#n_|XH&*riPcER@^Yc3H5=;Ix*{h|S;lvIs4 z{}|DKXn8x^MNB@&Em%b**xX!^hI2av=K?MrF#esEr}ev=9%}7#!Jd(pme%5-KWCA; zP4ze0M(2Rj9VOAe^;2&B8-_rjiB#MRYYO^TTw*x*N1y~#ym*!0RVW44HUVs6;i+e_ z{Yx6NQIN{fz7eba_dX2b70Gxei8@L88$5-@t^P(8t2oZXISK}FaNQ@}b*^ZngBtRk z|116T99w@$TK< z-`{;IO7*_UB-4vL^qGl;M$gzEXI3r1_r@m5e|_|PYcunre<*ux)?-M-+0|8!LY0P& zHbMl_5w>(RG+n1kghy82hjKJAKzR_QU3&!VB#SXWSolP%ubW>l!7jj)^ygQ5S z_k7!-Rt4u!d@^6>HO5io@x^5=wb@#|{b)sT@fuyv3LlJ;S0Ek&i;m@9n9F9LTw*8^ zgGxH{?X@`=)J3X)ioZhb?aGoqlvPp!$Lc>Cq=x=1$g13N*(I3tYK5kEfThXEf-G`E z1>2#DF^#1?gJJmIvd~@IA5+KE0wPLNa1efqY`bdGfM4z)I~j%f*aG)8=oRlkf}q)Y zmm{X9m*RAHuC21L(6>LQBcMM${cTm2y!&S)SMnQMEbAv@GwxBTyC@1Be)_-#%uS!p z)0{Q~fK8#>##{S4VloT7iIb-UYXi`V^smjWDTq9X>O4*p9Cxc$q*)_F7_pR7^c|qm ztl^kGV2f=x+-pOi#7NRymK4(uOumc5w;aT2O5eg#iI1EX`dPq< zwI&9}y*#XQ8;bNF=Sr?_Ha4DQLQ^NgJk2z;_-=8~YUtH5^MIU(s(#4G*dBq_eXmdb zacsx0GwzfdbzUY4Ff%g|e91If4?8$qL!pE1S|cn)!#=GyKovCJn&L!)mAgA*ZRL&L$_kD0ErkXMVESx_{$ zWY+Pjmni(F6bN^p`6SX_pEr>y!EOpAa+|F%8uar;_S1-NOWhXV`SA0U#|i-fChZ-8 zeVYbsxpyv)`djyByyRZk9{e8V8GABeYHa-9t|}qaaK-;}DAPm7#00VM%64g^@l(hX zBO_#aX=$^G7T?v$>;m$A(1}dC8rSCO#f9Nf+5I6n3M}X^ew2geg+=U|HYNWmg)C6x z&QzO^)-(Ifi-q$(=LNhP8Um?Mww+0Dg$IVhC}KCa^*BAkI1`ui_a*|h8;ZgQpiLAdW-zOMWLTDCjCGA^v(9a$EgZ=f95U2}{2 zKcDB?yeZ;%Qv9k`cr(jn{LcJzpfu{lFqE)NX)PAIcbZ$Q-P8Sv`w139{5Ge=(d>F= z(%g)@$LN_3tHAXGyy|wbzVGk)7F9yMAH5e1K89gk zT5Rv4a9}1^hlmDUs543Yy!&kZ$7L^c1ha=clCp)eo(n_q+g>bDE#(O#DP}Incgr9r zAP8QsKitoFEUwc=-WA9qKNu;!twhKA;p2t#OlLHb5OQGme$yIR4|SZq?3rtq32=fZ z#=>Wp%o8BY#7j-=Hcm`?PvlCGk-1DUfWFE~V{Rx_@vdvl3|Mi%ufgd`V^cIfv|pKP z0>_t#46<|msnKNs7cwjBKQEcMkyaSaD5?XAB zF{_IzIDRp8)OlrFj4f9+(k%-;2|pFv9tQFQC(;Rra-A>Kj~I!%;76xxl08kw8q9iCsr(%%I(E%>o@$t=mFKWjlXTzO7u(k^WPM@h(n`dC1SIl3$&N)sU7=Z{^sRf?GoDLOmW~lRx{BxIHk0NDcR^|vY5%zKqC9- zLz&6}fj5BY>%WE3-=Q*%F>x9AdBNz*qzJ2W!0BI!-oNV9%B!FcVWjjk+sca^Xs2)^ zzwT(!dwhI=$tHI)2(bduy^^%s3!6YoPZ#t@AoQR7i)~MlHMLi2r`$fkX7l#dNH2y} zGD$&z@b7~xjdU0&T%AJvS5)g7Nj4+agszv2^YAUBxdV;AN+H~I8rL4b=o4c*4aGi5!{!I>< zrSZ&{qy@*7|MVXZ;cmxn6IuATf|DGAn`Sxv+NfUNurLyJ>5!Rn|wIgIA zS-|P?S0i&3`L{7>E;iT2M;w3If3!V6nGl}||4(1MG6WoZ26MI*Ny8JDRCSq+3W*4T zUQEj78Tbbs@h_DL1;xp>0Vi3&ZUyDdtx)e`} zo07w>MS85`v&r{lUFrWL=LGo4(SXlM>n8c`*#%X)PBiX#vA*(21;;-rVk_fZYPE$^ zCRzoF5&5O=r8LGLf4ylQ)t~G(_y1-YDVd?|66)yi9&KtIiApP1i)|k>r$*oYkeYmFLa)oH*x0!v9)a?5ZfRt;s>CxA(I7qv8Z_a81mVO9{XX)y_JC+zre7Da;# z0LMbnnb}^I^iFf^7tUfgzr|X#p3`fH66^bcd#_!@-2-wwat_&ts}(YC$6<_!{fyDJRXUq#D3Ul!l0`crSeuo**k~h zUyIYRy6WOK)~ZISBSDyMUb!ZmFh38hVr9@Z$K`aB?E2Taqc9eA;6`a;18@FRQhf6yCH-{j0~*WuLNF7nc?-7hBl@m5k}n=VEL>SGZ2|j#+&)~0Jpjl21RK%?7p7lb z4Jh7X_$3e*vpwHAIYHAOp`i2h(+8}SbNbo6uJuR-qC8qy&p*2n;^1NuMuE(E4)FSJ zUY>V@&l;}UcgVgH2@#cx05rHqJ3$Z80wT;781yVvay(!RowpA5Jtf`6yGFPE4t)j~ zuO&oPWXo~Y5p*fD0}L%Q+JHMC)B;u}5Zw7ET&0;abPs^FNS|Rlyd>N_?lyY{;JxY5 zGl?dlSFMT(S$|PtidMc13@IwjYX7sEWGQ0J)J$9Z7&sO%)!>VtRCD7!0DV2sc%)vX IYWe#A079gAw*UYD delta 45801 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