From a804b1283fdd29fc528a3b90d6ea04bb88045228 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 6 Jan 2011 10:33:06 -0800 Subject: [PATCH 001/142] Add Zone Wizard - basic mode - move Add Guest IP Range section from step3(createPod) to step4(AddIPRange). --- ui/jsp/resource.jsp | 69 ++++++++--------- ui/scripts/cloud.core.resource.js | 124 ++++++++++++++---------------- 2 files changed, 93 insertions(+), 100 deletions(-) diff --git a/ui/jsp/resource.jsp b/ui/jsp/resource.jsp index 9c4b8c8651c..ac3b31f1ae9 100644 --- a/ui/jsp/resource.jsp +++ b/ui/jsp/resource.jsp @@ -361,31 +361,7 @@ - -
  • - - - - - - -
  • -
  • - - - -
  • -
  • - - - -
  • + @@ -394,11 +370,8 @@
    Back
    - -
    - Submit -
    +
    + Go to Step 4
    @@ -427,14 +400,40 @@

    - Step 4: Add an IP range to public network in zone

    + Step 4: Add an IP range

    -
      +
        +
      1. + + - + + + +
      2. +
      3. + + + +
      4. +
      5. + + + +
      6. +
      +
    diff --git a/ui/scripts/cloud.core.resource.js b/ui/scripts/cloud.core.resource.js index 4f1d9efb91d..ec1591c94f2 100644 --- a/ui/scripts/cloud.core.resource.js +++ b/ui/scripts/cloud.core.resource.js @@ -1065,18 +1065,20 @@ function initAddZoneWizard() { case "Basic": //create VLAN in pod-level //hide Zone VLAN Range in Add Zone(step 2), show Guest IP Range in Add Pod(step3) $thisWizard.find("#step2").find("#add_zone_vlan_container, #add_zone_guestcidraddress_container").hide(); - $thisWizard.find("#step3").find("#guestip_container, #guestnetmask_container, #guestgateway_container, #submit_in_step3").show(); - $thisWizard.find("#step3").find("#go_to_step_4").hide(); + + //$thisWizard.find("#step3").find("#guestip_container, #guestnetmask_container, #guestgateway_container").show(); + $thisWizard.find("#step4").find("#guestip_list").show(); + $thisWizard.find("#step4").find("#publicip_list").hide(); return true; break; case "Advanced": //create VLAN in zone-level //show Zone VLAN Range in Add Zone(step 2), hide Guest IP Range in Add Pod(step3) $thisWizard.find("#step2").find("#add_zone_vlan_container, #add_zone_guestcidraddress_container").show(); - $thisWizard.find("#step3").find("#guestip_container, #guestnetmask_container, #guestgateway_container, #submit_in_step3").hide(); - $thisWizard.find("#step3").find("#go_to_step_4").show(); - - // default value of "#add_publicip_vlan_scope" is "zone-wide". Calling change() will hide "#add_publicip_vlan_domain_container", "#add_publicip_vlan_account_container". + + //$thisWizard.find("#step3").find("#guestip_container, #guestnetmask_container, #guestgateway_container").hide(); + $thisWizard.find("#step4").find("#guestip_list").hide(); + $thisWizard.find("#step4").find("#publicip_list").show(); $addZoneWizard.find("#step4").find("#add_publicip_vlan_scope").change(); return true; @@ -1135,9 +1137,7 @@ function initAddZoneWizard() { break; case "go_to_step_4": //step 3 => step 4 - var isValid = addZoneWizardValidatePod($thisWizard); - if($thisWizard.find("#step3").find("#guestip_container").css("display") != "none") - isValid &= addZoneWizardValidateGuestIPRange($thisWizard); + var isValid = addZoneWizardValidatePod($thisWizard); if (!isValid) return; @@ -1159,28 +1159,20 @@ function initAddZoneWizard() { $thisWizard.find("#step2").hide(); $thisWizard.find("#step1").show(); break; - - case "submit_in_step3": //step 3 => make API call - var isValid = addZoneWizardValidatePod($thisWizard); - if($thisWizard.find("#step3").find("#guestip_container").css("display") != "none") - isValid &= addZoneWizardValidateGuestIPRange($thisWizard); - if (!isValid) - return; - - $thisWizard.find("#step3").hide(); - $thisWizard.find("#after_submit_screen").show(); - addZoneWizardSubmit($thisWizard); - break; - - case "submit_in_step4": //step 4 => make API call - var isValid = addZoneWizardValidatePublicIPRange($thisWizard); + + case "submit": //step 4 => make API call + var isValid = true; + if($thisWizard.find("#step4").find("#guestip_list").css("display") != "none") + isValid = addZoneWizardValidateGuestIPRange($thisWizard); + if($thisWizard.find("#step4").find("#publicip_list").css("display") != "none") + isValid &= addZoneWizardValidatePublicIPRange($thisWizard); if (!isValid) return; $thisWizard.find("#step4").hide(); $thisWizard.find("#after_submit_screen").show(); addZoneWizardSubmit($thisWizard); - break; + break; } return false; }); @@ -1368,8 +1360,47 @@ function addZoneWizardSubmit($thisWizard) { }); // create pod (end) - // add IP range to public network in zone (begin) - if(networktype == "Advanced") { + // add guest IP range to basic zone (begin) + if($thisWizard.find("#step4").find("#guestip_list").css("display") != "none") { + var netmask = $thisWizard.find("#step4").find("#guestip_list").find("#guestnetmask").val(); + var startip = $thisWizard.find("#step4").find("#guestip_list").find("#startguestip").val(); + var endip = $thisWizard.find("#step4").find("#guestip_list").find("#endguestip").val(); + var guestgateway = $thisWizard.find("#step4").find("#guestip_list").find("#guestgateway").val(); + + var array1 = []; + array1.push("&vlan=untagged"); + array1.push("&zoneid=" + zoneId); + array1.push("&podId=" + podId); + array1.push("&forVirtualNetwork=false"); //direct VLAN + array1.push("&gateway="+todb(guestgateway)); + array1.push("&netmask="+todb(netmask)); + array1.push("&startip="+todb(startip)); + if(endip != null && endip.length > 0) + array1.push("&endip="+todb(endip)); + + $.ajax({ + data: createURL("command=createVlanIpRange" + array1.join("")), + dataType: "json", + async: false, + success: function(json) { + $thisWizard.find("#after_submit_screen").find("#add_iprange_tick_cross").removeClass().addClass("zonepopup_reviewtick"); + $thisWizard.find("#after_submit_screen").find("#add_iprange_message").removeClass().text("Guest IP range was created successfully"); + + var item = json.createvlaniprangeresponse.vlan; + vlanId = item.id; + }, + error: function(XMLHttpResponse) { + handleError(XMLHttpResponse, function() { + $thisWizard.find("#after_submit_screen").find("#add_iprange_tick_cross").removeClass().addClass("zonepopup_reviewcross"); + $thisWizard.find("#after_submit_screen").find("#add_iprange_message").removeClass().addClass("error").text(("Failed to create Guest IP range: " + parseXMLHttpResponse(XMLHttpResponse))); + }); + } + }); + } + // add guest IP range to basic zone (end) + + // add public IP range to basic zone (begin) + if($thisWizard.find("#step4").find("#publicip_list").css("display") != "none") { var isDirect = false; var isTagged = $thisWizard.find("#step4").find("#add_publicip_vlan_tagged").val() == "tagged"; @@ -1419,46 +1450,9 @@ function addZoneWizardSubmit($thisWizard) { } }); } - // add IP range to public network in zone (end) + // add public IP range to basic zone (end) } - - if(podId != null && $thisWizard.find("#step3").find("#guestip_container").css("display") != "none") { - var netmask = $thisWizard.find("#step3").find("#guestnetmask").val(); - var startip = $thisWizard.find("#step3").find("#startguestip").val(); - var endip = $thisWizard.find("#step3").find("#endguestip").val(); - var guestgateway = $thisWizard.find("#step3").find("#guestgateway").val(); - - var array1 = []; - array1.push("&vlan=untagged"); - array1.push("&zoneid=" + zoneId); - array1.push("&podId=" + podId); - array1.push("&forVirtualNetwork=false"); //direct VLAN - array1.push("&gateway="+todb(guestgateway)); - array1.push("&netmask="+todb(netmask)); - array1.push("&startip="+todb(startip)); - if(endip != null && endip.length > 0) - array1.push("&endip="+todb(endip)); - $.ajax({ - data: createURL("command=createVlanIpRange" + array1.join("")), - dataType: "json", - async: false, - success: function(json) { - $thisWizard.find("#after_submit_screen").find("#add_iprange_tick_cross").removeClass().addClass("zonepopup_reviewtick"); - $thisWizard.find("#after_submit_screen").find("#add_iprange_message").removeClass().text("Guest IP range was created successfully"); - - var item = json.createvlaniprangeresponse.vlan; - vlanId = item.id; - }, - error: function(XMLHttpResponse) { - handleError(XMLHttpResponse, function() { - $thisWizard.find("#after_submit_screen").find("#add_iprange_tick_cross").removeClass().addClass("zonepopup_reviewcross"); - $thisWizard.find("#after_submit_screen").find("#add_iprange_message").removeClass().addClass("error").text(("Failed to create Guest IP range: " + parseXMLHttpResponse(XMLHttpResponse))); - }); - } - }); - } - $thisWizard.find("#after_submit_screen").find("#spinning_wheel").hide(); } From 2caa6f4247bf9e93d37e1aab6d0921bad0ed55f6 Mon Sep 17 00:00:00 2001 From: NIKITA Date: Thu, 6 Jan 2011 10:36:19 -0800 Subject: [PATCH 002/142] Class change for close button in zone wizard popup --- ui/css/main.css | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/ui/css/main.css b/ui/css/main.css index 3dd641830ca..36c97b229bf 100644 --- a/ui/css/main.css +++ b/ui/css/main.css @@ -299,9 +299,9 @@ a:hover { .vmpopup_container_closebutton { width:13px; height:13px; - float:right; + float:left; background:url(../images/vm_closebutton.gif) no-repeat top left; - margin:8px 10px 0 0; + margin:8px 0 0 0; padding:0; cursor:pointer; cursor:hand; @@ -312,6 +312,23 @@ a:hover { } + +.zonepopup_container_closebutton { + width:13px; + height:13px; + float:left; + background:url(../images/vm_closebutton.gif) no-repeat top left; + margin:8px 0 0 0; + padding:0; + cursor:pointer; + cursor:hand; +} + +.zonepopup_container_closebutton:hover { + background:url(../images/vm_closebutton_hover.gif) no-repeat top left; +} + + .vmpopup_container_top { width:737px; height:30px; From 0fcfd876a57b44266dcc47940149568d0a02684e Mon Sep 17 00:00:00 2001 From: NIKITA Date: Thu, 6 Jan 2011 10:40:03 -0800 Subject: [PATCH 003/142] close buttons class name changed for zone wizard --- ui/jsp/resource.jsp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ui/jsp/resource.jsp b/ui/jsp/resource.jsp index ac3b31f1ae9..1152f1b1678 100644 --- a/ui/jsp/resource.jsp +++ b/ui/jsp/resource.jsp @@ -146,7 +146,7 @@ Step 4
    -
    +
    @@ -215,7 +215,7 @@ Step 4
    -
    +
    @@ -315,7 +315,7 @@ Step 4
    -
    +
    @@ -393,7 +393,7 @@ Step 4
    -
    +
    @@ -538,7 +538,7 @@ Step 3
    -
    +
    From 30f6f1088c39c8213844ce89c9dbd4b9f2e5a767 Mon Sep 17 00:00:00 2001 From: will Date: Thu, 6 Jan 2011 10:46:48 -0800 Subject: [PATCH 004/142] Removed check for type== virtual or direct when processing network offerings. --- ui/scripts/cloud.core.instance.js | 2 +- ui/scripts/cloud.core.zone.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/scripts/cloud.core.instance.js b/ui/scripts/cloud.core.instance.js index c0d71ce7661..da0e02e4ab7 100644 --- a/ui/scripts/cloud.core.instance.js +++ b/ui/scripts/cloud.core.instance.js @@ -849,7 +849,7 @@ function initVMWizard() { var networkOfferings = json.listnetworkofferingsresponse.networkoffering; if (networkOfferings != null && networkOfferings.length > 0) { for (var i = 0; i < networkOfferings.length; i++) { - if (networkOfferings[i].type == "Virtual" && networkOfferings[i].isdefault) { + if (networkOfferings[i].isdefault) { // Create a network from this. $.ajax({ data: createURL("command=createNetwork&networkOfferingId="+networkOfferings[i].id+"&name="+todb(networkName)+"&displayText="+todb(networkDesc)+"&zoneId="+$thisPopup.find("#wizard_zone").val()), diff --git a/ui/scripts/cloud.core.zone.js b/ui/scripts/cloud.core.zone.js index 05dff7e4329..49e45c2058f 100644 --- a/ui/scripts/cloud.core.zone.js +++ b/ui/scripts/cloud.core.zone.js @@ -541,7 +541,7 @@ function bindAddVLANButton($button, $leftmenuItem1) { var networkOfferings = json.listnetworkofferingsresponse.networkoffering; if (networkOfferings != null && networkOfferings.length > 0) { for (var i = 0; i < networkOfferings.length; i++) { - if (networkOfferings[i].type == "Direct" && networkOfferings[i].isdefault) { + if (networkOfferings[i].isdefault) { // Create a network from this. $.ajax({ data: createURL("command=createNetwork&name="+name+"&displayText="+desc+"&networkOfferingId="+networkOfferings[i].id+"&zoneId="+zoneObj.id+vlan+scopeParams+"&gateway="+todb(gateway)+"&netmask="+todb(netmask)+"&startip="+todb(startip)+"&endip="+todb(endip)), From b97c6a6ed2fc04b4dcfa66a5438de707408b515d Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 6 Jan 2011 10:55:40 -0800 Subject: [PATCH 005/142] bug 7654 - resource page - add primary storage - skip calling listPods when zone field is empty. --- ui/scripts/cloud.core.resource.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/scripts/cloud.core.resource.js b/ui/scripts/cloud.core.resource.js index ec1591c94f2..b3bde703c7f 100644 --- a/ui/scripts/cloud.core.resource.js +++ b/ui/scripts/cloud.core.resource.js @@ -1542,6 +1542,8 @@ function initAddPrimaryStorageShortcut($midmenuAddLink2, currentPageInRightPanel $dialogAddPool.find("#zone_dropdown").bind("change", function(event) { var zoneId = $(this).val(); + if(zoneId == null) + return; $.ajax({ data: createURL("command=listPods&zoneId="+zoneId), dataType: "json", From 977773701a5a478d368260565a1778b4405e7666 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 6 Jan 2011 11:01:39 -0800 Subject: [PATCH 006/142] physical resource page - add cluster - validate zone field and pod field. --- ui/scripts/cloud.core.resource.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ui/scripts/cloud.core.resource.js b/ui/scripts/cloud.core.resource.js index b3bde703c7f..bb0e58c7604 100644 --- a/ui/scripts/cloud.core.resource.js +++ b/ui/scripts/cloud.core.resource.js @@ -673,7 +673,9 @@ function initAddClusterShortcut() { if(hypervisor == "VmWare") clusterType = $thisDialog.find("#type_dropdown").val(); - var isValid = true; + var isValid = true; + isValid &= validateDropDownBox("Zone", $thisDialog.find("#zone_dropdown"), $thisDialog.find("#zone_dropdown_errormsg")); + isValid &= validateDropDownBox("Pod", $thisDialog.find("#pod_dropdown"), $thisDialog.find("#pod_dropdown_errormsg")); if(hypervisor == "VmWare" && clusterType != "CloudManaged") { isValid &= validateString("vCenter Server", $thisDialog.find("#cluster_hostname"), $thisDialog.find("#cluster_hostname_errormsg")); isValid &= validateString("vCenter user", $thisDialog.find("#cluster_username"), $thisDialog.find("#cluster_username_errormsg")); From 468ea1a970141c92f97ba439fab89d5ad2ff6a6c Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 6 Jan 2011 11:38:52 -0800 Subject: [PATCH 007/142] Add Zone Wizard - review screen (last screen) - add step4 on the top. --- ui/jsp/resource.jsp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ui/jsp/resource.jsp b/ui/jsp/resource.jsp index 1152f1b1678..ef3fd5417cf 100644 --- a/ui/jsp/resource.jsp +++ b/ui/jsp/resource.jsp @@ -536,6 +536,8 @@ Step 2
    Step 3
    +
    + Step 4
    @@ -547,7 +549,7 @@
    From 4a409200dc2092a2d4ffe7c9e9f41c7792e3d292 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 7 Jan 2011 08:02:08 -0500 Subject: [PATCH 008/142] fix build for rhel6 and fix router default gw --- .../computing/LibvirtCapXMLParser.java | 8 ++- .../config/etc/init.d/cloud-early-config | 9 ++- python/lib/cloud_utils.py | 55 ++++++++++--------- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/agent/src/com/cloud/agent/resource/computing/LibvirtCapXMLParser.java b/agent/src/com/cloud/agent/resource/computing/LibvirtCapXMLParser.java index f99adcb063d..d9a063b920b 100644 --- a/agent/src/com/cloud/agent/resource/computing/LibvirtCapXMLParser.java +++ b/agent/src/com/cloud/agent/resource/computing/LibvirtCapXMLParser.java @@ -36,7 +36,7 @@ public class LibvirtCapXMLParser extends LibvirtXMLParser { private boolean _osType = false; private boolean _domainTypeKVM = false; private boolean _emulatorFlag = false; - private String _emulator ; + private final StringBuffer _emulator = new StringBuffer() ; private final StringBuffer _capXML = new StringBuffer(); private static final Logger s_logger = Logger.getLogger(LibvirtCapXMLParser.class); private final ArrayList guestOsTypes = new ArrayList(); @@ -53,6 +53,7 @@ public class LibvirtCapXMLParser extends LibvirtXMLParser { _domainTypeKVM = false; } else if (qName.equalsIgnoreCase("emulator")) { _emulatorFlag = false; + } else if (_host) { _capXML.append("<").append("/").append(qName).append(">"); } @@ -65,7 +66,7 @@ public class LibvirtCapXMLParser extends LibvirtXMLParser { } else if (_osType) { guestOsTypes.add(new String(ch, start, length)); } else if (_emulatorFlag) { - _emulator = new String(ch, start, length); + _emulator.append(ch, start, length); } } @@ -90,6 +91,7 @@ public class LibvirtCapXMLParser extends LibvirtXMLParser { } } else if (qName.equalsIgnoreCase("emulator") && _domainTypeKVM) { _emulatorFlag = true; + _emulator.delete(0, _emulator.length()); } else if (_host) { _capXML.append("<").append(qName); for (int i=0; i < attributes.getLength(); i++) { @@ -120,7 +122,7 @@ public class LibvirtCapXMLParser extends LibvirtXMLParser { } public String getEmulator() { - return _emulator; + return _emulator.toString(); } public static void main(String [] args) { 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 2cd6aaeb86f..34d54edcf59 100755 --- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config +++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config @@ -180,8 +180,13 @@ setup_common() { ip route add $MGMTNET via $LOCAL_GW dev eth1 fi - ip route delete default - ip route add default via $GW dev eth2 + ip route delete default + if [ -n $3 ] + then + ip route add default via $GW dev $3 + else + ip route add default via $GW dev eth1 + fi } setup_dnsmasq() { diff --git a/python/lib/cloud_utils.py b/python/lib/cloud_utils.py index 3bfc62976a9..87d1d64856d 100644 --- a/python/lib/cloud_utils.py +++ b/python/lib/cloud_utils.py @@ -34,6 +34,7 @@ Unknown = 0 Fedora = 1 CentOS = 2 Ubuntu = 3 +RHEL6 = 4 IPV4 = 4 IPV6 = 6 @@ -42,10 +43,14 @@ IPV6 = 6 if os.path.exists("/etc/fedora-release"): distro = Fedora elif os.path.exists("/etc/centos-release"): distro = CentOS -elif os.path.exists("/etc/redhat-release") and not os.path.exists("/etc/fedora-release"): distro = CentOS +elif os.path.exists("/etc/redhat-release"): + version = file("/etc/redhat-release").readline() + if version.find("Red Hat Enterprise Linux Server release 6") != -1: + distro = RHEL6 + elif version.find("Centos release") != -1: + distro = CentOS elif os.path.exists("/etc/legal") and "Ubuntu" in file("/etc/legal").read(-1): distro = Ubuntu else: distro = Unknown - logFileName=None # ================== LIBRARY UTILITY CODE============= def setLogFile(logFile): @@ -264,7 +269,7 @@ def check_hostname(): #check function def check_kvm(): - if distro in (Fedora,CentOS): + if distro in (Fedora,CentOS,RHEL6): if os.path.exists("/dev/kvm"): return True raise CheckFailed("KVM is not correctly installed on this system, or support for it is not enabled in the BIOS") else: @@ -284,7 +289,7 @@ def check_cgroups(): #check function def check_selinux(): - if distro not in [Fedora,CentOS]: return # no selinux outside of those + if distro not in [Fedora,CentOS,RHEL6]: return # no selinux outside of those enforcing = False try: output = getenforce().stdout.strip() @@ -365,7 +370,7 @@ class SetupNetworking(ConfigTask): self.runtime_state_changed = False self.was_nm_service_running = None self.was_net_service_running = None - if distro in (Fedora, CentOS): + if distro in (Fedora, CentOS, RHEL6): self.nmservice = 'NetworkManager' self.netservice = 'network' else: @@ -376,7 +381,7 @@ class SetupNetworking(ConfigTask): def done(self): try: alreadysetup = False - if distro in (Fedora,CentOS): + if distro in (Fedora,CentOS, RHEL6): if self.pubNic != None: alreadysetup = alreadysetup or augtool._print("/files/etc/sysconfig/network-scripts/ifcfg-%s"%self.pubNic).stdout.strip() if self.prvNic != None: @@ -463,12 +468,12 @@ class SetupNetworking(ConfigTask): self.old_net_device = dev - if distro in (Fedora, CentOS): + if distro in (Fedora, CentOS, RHEL6): inconfigfile = "/".join(augtool.match("/files/etc/sysconfig/network-scripts/*/DEVICE",dev).stdout.strip().split("/")[:-1]) if not inconfigfile: raise TaskFailed("Device %s has not been set up in /etc/sysconfig/network-scripts"%dev) pathtoconfigfile = inconfigfile[6:] - if distro in (Fedora, CentOS): + if distro in (Fedora, CentOS, RHEL6): automatic = augtool.match("%s/ONBOOT"%inconfigfile,"yes").stdout.strip() else: automatic = augtool.match("/files/etc/network/interfaces/auto/*/",dev).stdout.strip() @@ -476,17 +481,17 @@ class SetupNetworking(ConfigTask): if distro is Fedora: raise TaskFailed("Device %s has not been set up in %s as automatic on boot"%dev,pathtoconfigfile) else: raise TaskFailed("Device %s has not been set up in /etc/network/interfaces as automatic on boot"%dev) - if distro not in (Fedora , CentOS): + if distro not in (Fedora , CentOS, RHEL6): inconfigfile = augtool.match("/files/etc/network/interfaces/iface",dev).stdout.strip() if not inconfigfile: raise TaskFailed("Device %s has not been set up in /etc/network/interfaces"%dev) - if distro in (Fedora, CentOS): + if distro in (Fedora, CentOS, RHEL6): isstatic = augtool.match(inconfigfile + "/BOOTPROTO","none").stdout.strip() if not isstatic: isstatic = augtool.match(inconfigfile + "/BOOTPROTO","static").stdout.strip() else: isstatic = augtool.match(inconfigfile + "/method","static").stdout.strip() if not isstatic: - if distro in (Fedora, CentOS): raise TaskFailed("Device %s has not been set up as a static device in %s"%(dev,pathtoconfigfile)) + if distro in (Fedora, CentOS, RHEL6): raise TaskFailed("Device %s has not been set up as a static device in %s"%(dev,pathtoconfigfile)) else: raise TaskFailed("Device %s has not been set up as a static device in /etc/network/interfaces"%dev) if is_service_running(self.nmservice): @@ -503,7 +508,7 @@ class SetupNetworking(ConfigTask): yield "Creating Cloud bridging device and making device %s member of this bridge"%dev - if distro in (Fedora, CentOS): + if distro in (Fedora, CentOS, RHEL6): ifcfgtext = file(pathtoconfigfile).read() newf = "/etc/sysconfig/network-scripts/ifcfg-%s"%self.brname #def restore(): @@ -687,7 +692,7 @@ class SetupLibvirt(ConfigTask): cfgline = "export CGROUP_DAEMON='cpu:/virt'" def done(self): try: - if distro in (Fedora,CentOS): libvirtfile = "/etc/sysconfig/libvirtd" + if distro in (Fedora,CentOS, RHEL6): libvirtfile = "/etc/sysconfig/libvirtd" elif distro is Ubuntu: libvirtfile = "/etc/default/libvirt-bin" else: raise AssertionError, "We should not reach this" return self.cfgline in file(libvirtfile,"r").read(-1) @@ -696,14 +701,14 @@ class SetupLibvirt(ConfigTask): raise def execute(self): - if distro in (Fedora,CentOS): libvirtfile = "/etc/sysconfig/libvirtd" + if distro in (Fedora,CentOS, RHEL6): libvirtfile = "/etc/sysconfig/libvirtd" elif distro is Ubuntu: libvirtfile = "/etc/default/libvirt-bin" else: raise AssertionError, "We should not reach this" libvirtbin = file(libvirtfile,"r").read(-1) libvirtbin = libvirtbin + "\n" + self.cfgline + "\n" file(libvirtfile,"w").write(libvirtbin) - if distro in (CentOS, Fedora): svc = "libvirtd" + if distro in (CentOS, Fedora, RHEL6): svc = "libvirtd" else: svc = "libvirt-bin" stop_service(svc) enable_service(svc) @@ -731,7 +736,7 @@ class SetupLiveMigration(ConfigTask): startswith = stanza.split("=")[0] + '=' replace_or_add_line("/etc/libvirt/libvirtd.conf",startswith,stanza) - if distro is Fedora: + if distro in (Fedora, RHEL6): replace_or_add_line("/etc/sysconfig/libvirtd","LIBVIRTD_ARGS=","LIBVIRTD_ARGS=-l") elif distro is Ubuntu: @@ -743,7 +748,7 @@ class SetupLiveMigration(ConfigTask): else: raise AssertionError("Unsupported distribution") - if distro in (CentOS, Fedora): svc = "libvirtd" + if distro in (CentOS, Fedora, RHEL6): svc = "libvirtd" else: svc = "libvirt-bin" stop_service(svc) enable_service(svc) @@ -753,14 +758,14 @@ class SetupRequiredServices(ConfigTask): name = "required services setup" def done(self): - if distro is Fedora: nfsrelated = "rpcbind nfslock" + if distro in (Fedora, RHEL6): nfsrelated = "rpcbind nfslock" elif distro is CentOS: nfsrelated = "portmap nfslock" else: return True return all( [ is_service_running(svc) for svc in nfsrelated.split() ] ) def execute(self): - if distro is Fedora: nfsrelated = "rpcbind nfslock" + if distro in (Fedora, RHEL6): nfsrelated = "rpcbind nfslock" elif distro is CentOS: nfsrelated = "portmap nfslock" else: raise AssertionError("Unsupported distribution") @@ -772,7 +777,7 @@ class SetupFirewall(ConfigTask): def done(self): - if distro in (Fedora, CentOS): + if distro in (Fedora, CentOS,RHEL6): if not os.path.exists("/etc/sysconfig/iptables"): return True if ":on" not in chkconfig("--list","iptables").stdout: return True else: @@ -784,7 +789,7 @@ class SetupFirewall(ConfigTask): def execute(self): ports = "22 1798 16509".split() - if distro in (Fedora , CentOS): + if distro in (Fedora , CentOS, RHEL6): for p in ports: iptables("-I","INPUT","1","-p","tcp","--dport",p,'-j','ACCEPT') o = service.iptables.save() ; print o.stdout + o.stderr else: @@ -800,7 +805,7 @@ class SetupFirewall2(ConfigTask): def done(self): - if distro in (Fedora, CentOS): + if distro in (Fedora, CentOS, RHEL6): if not os.path.exists("/etc/sysconfig/iptables"): return True if ":on" not in chkconfig("--list","iptables").stdout: return True rule = "FORWARD -i %s -o %s -j ACCEPT"%(self.brname,self.brname) @@ -817,7 +822,7 @@ class SetupFirewall2(ConfigTask): yield "Permitting traffic in the bridge interface, migration port and for VNC ports" - if distro in (Fedora , CentOS): + if distro in (Fedora , CentOS, RHEL6): for rule in ( "-I FORWARD -i %s -o %s -j ACCEPT"%(self.brname,self.brname), @@ -856,7 +861,7 @@ def config_tasks(brname, pubNic, prvNic): SetupFirewall(), SetupFirewall2(brname), ) - elif distro in (Ubuntu,Fedora): + elif distro in (Ubuntu,Fedora, RHEL6): config_tasks = ( SetupNetworking(brname, pubNic, prvNic), SetupCgConfig(), @@ -929,7 +934,7 @@ def prompt_for_hostpods(zonespods): def device_exist(devName): try: alreadysetup = False - if distro in (Fedora,CentOS): + if distro in (Fedora,CentOS, RHEL6): alreadysetup = augtool._print("/files/etc/sysconfig/network-scripts/ifcfg-%s"%devName).stdout.strip() else: alreadysetup = augtool.match("/files/etc/network/interfaces/iface",devName).stdout.strip() From a0ce28b769b2121ddea05348fb78ee381e2d572b Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 7 Jan 2011 08:27:24 -0500 Subject: [PATCH 009/142] one more fix for router gw, and rhel build --- cloud.spec | 2 ++ .../debian/config/etc/init.d/cloud-early-config | 2 +- wscript_configure | 15 +++++++++++++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/cloud.spec b/cloud.spec index 386e0beea41..17b4e841868 100644 --- a/cloud.spec +++ b/cloud.spec @@ -302,6 +302,8 @@ Obsoletes: %{name}-premium-vendor-zynga < %{version}-%{release} Requires: java >= 1.6.0 Requires: %{name}-utils = %{version}-%{release} Requires: %{name}-premium-deps +# there is a fsimage.so in the source code, which adds xen-libs as a dependence, needs to supress it, as rhel doesn't have this pacakge +AutoReqProv: no License: CSL 1.1 Group: System Environment/Libraries %description premium 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 34d54edcf59..e3f245e6c69 100755 --- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config +++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config @@ -185,7 +185,7 @@ setup_common() { then ip route add default via $GW dev $3 else - ip route add default via $GW dev eth1 + ip route add default via $GW dev eth0 fi } diff --git a/wscript_configure b/wscript_configure index 6bed5734ada..6a8f866034b 100644 --- a/wscript_configure +++ b/wscript_configure @@ -37,6 +37,12 @@ systemjars = { "tomcat6-jsp-2.1-api-6.0.26.jar", #"tomcat6/catalina.jar", # all supported distros put the file there ), + 'RHEL6': + ( + "tomcat6-servlet-2.5-api.jar", + "tomcat6-el-2.1-api-6.0.24.jar", + "tomcat6-jsp-2.1-api-6.0.24.jar", + ), 'CentOS': ( "tomcat6-servlet-2.5-api.jar", @@ -100,12 +106,17 @@ if Options.platform == 'win32': conf.env.DISTRO = "Windows" elif Options.platform == 'darwin': conf.env.DISTRO = "Mac" elif _exists("/etc/network"): conf.env.DISTRO = "Ubuntu" elif _exists("/etc/fedora-release"): conf.env.DISTRO = "Fedora" -elif _exists("/etc/centos-release") or _exists("/etc/redhat-release"): conf.env.DISTRO = "CentOS" +elif _exists("/etc/centos-release"): conf.env.DISTRO = "CentOS" +elif _exists("/etc/redhat-release"): + version = file("/etc/redhat-release").readline() + if version.find("Red Hat Enterprise Linux Server release 6") != -1: + conf.env.DISTRO = RHEL6 + elif version.find("Centos release") != -1: + conf.env.DISTRO = CentOS else: conf.env.DISTRO = "unknown" if conf.env.DISTRO == "unknown": c = "YELLOW" else: c = "GREEN" conf.check_message_2(conf.env.DISTRO,c) - conf.check_message_1('Detecting installation prefix') if Options.options.prefix == Options.default_prefix: if conf.env.DISTRO == 'Windows': From daea474baa4fab8a6b976b74c3a91b1c79b5d496 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 7 Jan 2011 08:31:26 -0500 Subject: [PATCH 010/142] fix build --- wscript_configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wscript_configure b/wscript_configure index 6a8f866034b..afc9526db35 100644 --- a/wscript_configure +++ b/wscript_configure @@ -110,9 +110,9 @@ elif _exists("/etc/centos-release"): conf.env.DISTRO = "CentOS" elif _exists("/etc/redhat-release"): version = file("/etc/redhat-release").readline() if version.find("Red Hat Enterprise Linux Server release 6") != -1: - conf.env.DISTRO = RHEL6 + conf.env.DISTRO = "RHEL6" elif version.find("Centos release") != -1: - conf.env.DISTRO = CentOS + conf.env.DISTRO = "CentOS" else: conf.env.DISTRO = "unknown" if conf.env.DISTRO == "unknown": c = "YELLOW" else: c = "GREEN" From d33d61b1b4885dff98e31840bcb385f4da33ffbb Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 7 Jan 2011 08:40:22 -0500 Subject: [PATCH 011/142] fix default gw one more time... --- patches/systemvm/debian/config/etc/init.d/cloud-early-config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 e3f245e6c69..1c4fbd6cde1 100755 --- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config +++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config @@ -181,7 +181,7 @@ setup_common() { fi ip route delete default - if [ -n $3 ] + if [ -n "$3" ] then ip route add default via $GW dev $3 else From 02dc187a0cb8be4f856a42faa10054f660c66acc Mon Sep 17 00:00:00 2001 From: alena Date: Wed, 5 Jan 2011 11:15:27 -0800 Subject: [PATCH 012/142] bug 7727: Don't create Public network with broadcast_domain_type=vlan for Basic zone status 7727: resolved fixed --- .../ConfigurationManagerImpl.java | 39 +++++++------------ .../cloud/network/guru/PublicNetworkGuru.java | 2 + .../cloud/server/ConfigurationServerImpl.java | 21 +++++----- 3 files changed, 27 insertions(+), 35 deletions(-) diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 67bc0fcd483..c0dcd4e7673 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -1207,36 +1207,23 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura Account systemAccount = _accountDao.findById(Account.ACCOUNT_ID_SYSTEM); BroadcastDomainType broadcastDomainType = null; - if (offering.getGuestIpType() != GuestIpType.DirectPodBased) { - if (offering.getTrafficType() == TrafficType.Management) { + if (offering.getTrafficType() == TrafficType.Management) { + broadcastDomainType = BroadcastDomainType.Native; + } else if (offering.getTrafficType() == TrafficType.Control) { + broadcastDomainType = BroadcastDomainType.LinkLocal; + } else if (offering.getTrafficType() == TrafficType.Public) { + if (zone.getNetworkType() == NetworkType.Basic && offering.getGuestIpType() == GuestIpType.DirectPodBased) { broadcastDomainType = BroadcastDomainType.Native; - } else if (offering.getTrafficType() == TrafficType.Public) { + } else if (zone.getNetworkType() == NetworkType.Advanced && offering.getGuestIpType() == null) { broadcastDomainType = BroadcastDomainType.Vlan; - } else if (offering.getTrafficType() == TrafficType.Control) { - broadcastDomainType = BroadcastDomainType.LinkLocal; - } - userNetwork.setBroadcastDomainType(broadcastDomainType); - _networkMgr.setupNetwork(systemAccount, offering, userNetwork, plan, null, null, true); - } + } else { + continue; + } + } + userNetwork.setBroadcastDomainType(broadcastDomainType); + _networkMgr.setupNetwork(systemAccount, offering, userNetwork, plan, null, null, true); } } - - //if zone is basic, create a untagged network - if (zone != null && zone.getNetworkType() == NetworkType.Basic) { - //Create network - DataCenterDeployment plan = new DataCenterDeployment(zone.getId(), null, null, null); - NetworkVO userNetwork = new NetworkVO(); - userNetwork.setBroadcastDomainType(BroadcastDomainType.Native); - - Account systemAccount = _accountDao.findById(Account.ACCOUNT_ID_SYSTEM); - - List networkOffering = _networkOfferingDao.findByType(GuestIpType.DirectPodBased); - if (networkOffering == null || networkOffering.isEmpty()) { - throw new CloudRuntimeException("No default DirectPodBased network offering is found"); - } - - _networkMgr.setupNetwork(systemAccount, networkOffering.get(0), userNetwork, plan, null, null, true); - } } @Override diff --git a/server/src/com/cloud/network/guru/PublicNetworkGuru.java b/server/src/com/cloud/network/guru/PublicNetworkGuru.java index 59dbce2b260..17bf1d50a0d 100644 --- a/server/src/com/cloud/network/guru/PublicNetworkGuru.java +++ b/server/src/com/cloud/network/guru/PublicNetworkGuru.java @@ -50,6 +50,8 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { @Inject VlanDao _vlanDao; @Inject NetworkManager _networkMgr; @Inject IPAddressDao _ipAddressDao; + + @Override public Network design(NetworkOffering offering, DeploymentPlan plan, Network network, Account owner) { diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index c9bff361a5f..d51d3459629 100644 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -748,17 +748,20 @@ public class ConfigurationServerImpl implements ConfigurationServer { BroadcastDomainType broadcastDomainType = null; TrafficType trafficType= offering.getTrafficType(); GuestIpType guestIpType = offering.getGuestIpType(); - if (offering.getGuestIpType() != GuestIpType.DirectPodBased) { - if (trafficType == TrafficType.Management || trafficType == TrafficType.Storage) { + + if (trafficType == TrafficType.Management || trafficType == TrafficType.Storage) { + broadcastDomainType = BroadcastDomainType.Native; + } else if (trafficType == TrafficType.Control) { + broadcastDomainType = BroadcastDomainType.LinkLocal; + } else if (offering.getTrafficType() == TrafficType.Public) { + if (zone.getNetworkType() == NetworkType.Basic && offering.getGuestIpType() == GuestIpType.DirectPodBased) { broadcastDomainType = BroadcastDomainType.Native; - } else if (trafficType == TrafficType.Public) { + } else if (zone.getNetworkType() == NetworkType.Advanced && offering.getGuestIpType() == null) { broadcastDomainType = BroadcastDomainType.Vlan; - } else if (trafficType == TrafficType.Control) { - broadcastDomainType = BroadcastDomainType.LinkLocal; - } - } else if (zone.getNetworkType() == NetworkType.Basic && offering.getGuestIpType() == GuestIpType.DirectPodBased){ - broadcastDomainType = BroadcastDomainType.Vlan; - } + } else { + continue; + } + } if (broadcastDomainType != null) { NetworkVO network = new NetworkVO(id, trafficType, guestIpType, mode, broadcastDomainType, networkOfferingId, zoneId, domainId, accountId, related, null, null, true); From 916b516d1370a3c69f2c888afd1875d2c2a9b46d Mon Sep 17 00:00:00 2001 From: alena Date: Thu, 6 Jan 2011 00:47:50 -0800 Subject: [PATCH 013/142] bug 7878: Fixed Basic zone functionality - uservm/systemvm/domR start status 7878: resolved fixed --- .../cloud/api/commands/CreateNetworkCmd.java | 4 +- .../commands/CreateNetworkOfferingCmd.java | 9 +- .../cloud/api/commands/RestartNetworkCmd.java | 46 +-- .../commands/UpdateNetworkOfferingCmd.java | 2 +- .../api/response/NetworkOfferingResponse.java | 11 - api/src/com/cloud/network/NetworkService.java | 2 + api/src/com/cloud/network/Networks.java | 6 - .../network/lb/LoadBalancingRulesService.java | 2 + .../com/cloud/offering/NetworkOffering.java | 26 +- api/src/com/cloud/user/AccountService.java | 11 +- client/tomcatconf/components.xml.in | 1 + .../xen/resource/CitrixResourceBase.java | 3 +- server/src/com/cloud/api/ApiDBUtils.java | 2 +- .../src/com/cloud/api/ApiResponseHelper.java | 9 +- .../configuration/ConfigurationManager.java | 2 +- .../ConfigurationManagerImpl.java | 59 ++-- .../consoleproxy/ConsoleProxyManagerImpl.java | 13 +- server/src/com/cloud/dc/dao/VlanDao.java | 4 - .../src/com/cloud/network/NetworkManager.java | 13 +- .../com/cloud/network/NetworkManagerImpl.java | 301 +++++++----------- server/src/com/cloud/network/NetworkVO.java | 11 +- .../cloud/network/element/DhcpElement.java | 18 +- .../network/element/VirtualRouterElement.java | 2 +- .../network/guru/ControlNetworkGuru.java | 34 +- .../cloud/network/guru/DirectNetworkGuru.java | 54 +++- .../guru/DirectPodBasedNetworkGuru.java | 123 +++++++ .../cloud/network/guru/GuestNetworkGuru.java | 39 ++- .../network/guru/PodBasedNetworkGuru.java | 2 +- .../cloud/network/guru/PublicNetworkGuru.java | 46 +-- .../lb/LoadBalancingRulesManagerImpl.java | 25 +- .../VirtualNetworkApplianceManagerImpl.java | 47 ++- .../cloud/offerings/NetworkOfferingVO.java | 29 +- .../offerings/dao/NetworkOfferingDao.java | 5 - .../offerings/dao/NetworkOfferingDaoImpl.java | 44 --- .../cloud/server/ConfigurationServerImpl.java | 60 ++-- .../SecondaryStorageManagerImpl.java | 16 +- server/src/com/cloud/user/AccountManager.java | 2 - .../com/cloud/user/AccountManagerImpl.java | 49 ++- .../src/com/cloud/vm/UserVmManagerImpl.java | 4 +- .../src/com/cloud/vm/dao/DomainRouterDao.java | 2 + .../com/cloud/vm/dao/DomainRouterDaoImpl.java | 9 + setup/db/create-schema.sql | 1 - utils/src/com/cloud/utils/net/NetUtils.java | 12 + 43 files changed, 636 insertions(+), 524 deletions(-) create mode 100644 server/src/com/cloud/network/guru/DirectPodBasedNetworkGuru.java diff --git a/api/src/com/cloud/api/commands/CreateNetworkCmd.java b/api/src/com/cloud/api/commands/CreateNetworkCmd.java index e1375abe297..c2ec0a7392b 100644 --- a/api/src/com/cloud/api/commands/CreateNetworkCmd.java +++ b/api/src/com/cloud/api/commands/CreateNetworkCmd.java @@ -65,10 +65,10 @@ public class CreateNetworkCmd extends BaseCmd { @Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description="the ID or VID of the VLAN. Default is an \"untagged\" VLAN.") private String vlan; - @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="account who will own the VLAN. If VLAN is Zone wide, this parameter should be ommited") + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="account who will own the network") private String accountName; - @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="domain ID of the account owning a VLAN") + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="domain ID of the account owning a network") private Long domainId; @Parameter(name=ApiConstants.IS_SHARED, type=CommandType.BOOLEAN, description="true is network offering supports vlans") diff --git a/api/src/com/cloud/api/commands/CreateNetworkOfferingCmd.java b/api/src/com/cloud/api/commands/CreateNetworkOfferingCmd.java index 2d3cfdb985d..2c6822254f5 100644 --- a/api/src/com/cloud/api/commands/CreateNetworkOfferingCmd.java +++ b/api/src/com/cloud/api/commands/CreateNetworkOfferingCmd.java @@ -26,8 +26,8 @@ import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; import com.cloud.api.response.NetworkOfferingResponse; -import com.cloud.network.Networks.Availability; import com.cloud.offering.NetworkOffering; +import com.cloud.offering.NetworkOffering.Availability; @Implementation(description="Creates a network offering.", responseObject=NetworkOfferingResponse.class) public class CreateNetworkOfferingCmd extends BaseCmd { @@ -44,9 +44,6 @@ public class CreateNetworkOfferingCmd extends BaseCmd { @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, required=true, description="the display text of the network offering") private String displayText; - @Parameter(name=ApiConstants.TYPE, type=CommandType.STRING, required=true, description="type of the network. Supported types Virtual, Direct") - private String type; - @Parameter(name=ApiConstants.TRAFFIC_TYPE, type=CommandType.STRING, required=true, description="the traffic type for the network offering, supported types are Public, Management, Control, Guest, Vlan or Storage.") private String traffictype; @@ -78,10 +75,6 @@ public class CreateNetworkOfferingCmd extends BaseCmd { return tags; } - public String getType() { - return type; - } - public String getTraffictype() { return traffictype; } diff --git a/api/src/com/cloud/api/commands/RestartNetworkCmd.java b/api/src/com/cloud/api/commands/RestartNetworkCmd.java index 72ba23414b5..b03c5d73ca9 100644 --- a/api/src/com/cloud/api/commands/RestartNetworkCmd.java +++ b/api/src/com/cloud/api/commands/RestartNetworkCmd.java @@ -17,8 +17,6 @@ */ package com.cloud.api.commands; -import java.util.List; - import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; @@ -32,10 +30,10 @@ import com.cloud.api.response.SuccessResponse; import com.cloud.event.EventTypes; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; -import com.cloud.user.UserContext; @Implementation(description="Reapplies all ip addresses for the particular network", responseObject=IPAddressResponse.class) public class RestartNetworkCmd extends BaseAsyncCmd { @@ -46,12 +44,6 @@ public class RestartNetworkCmd extends BaseAsyncCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="the account to associate with this IP address") - private String accountName; - - @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="the ID of the domain to associate with this IP address") - private Long domainId; - @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required=true, description="the ID of the availability zone you want to acquire an public IP address from") private Long zoneId; @@ -63,20 +55,6 @@ public class RestartNetworkCmd extends BaseAsyncCmd { /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// - public String getAccountName() { - if (accountName != null) { - return accountName; - } - return UserContext.current().getCaller().getAccountName(); - } - - public long getDomainId() { - if (domainId != null) { - return domainId; - } - return UserContext.current().getCaller().getDomainId(); - } - public long getZoneId() { return zoneId; } @@ -90,26 +68,16 @@ public class RestartNetworkCmd extends BaseAsyncCmd { } public long getEntityOwnerId() { - List networks = _networkService.getVirtualNetworksOwnedByAccountInZone(getAccountName(), getDomainId(), getZoneId()); - if (networks.size() == 0) { - assert (networks.size() <= 1) : "No virtual network is found"; - } - assert (networks.size() <= 1) : "Too many virtual networks. This logic should be obsolete"; - - return networks.get(0).getAccountId(); + return _networkService.getNetwork(networkId).getAccountId(); } public Long getNetworkId() { - if (networkId != null) { - return networkId; + Network network = _networkService.getNetwork(networkId); + if (network == null) { + throw new InvalidParameterValueException("Unable to find network by id " + networkId); + } else { + return network.getId(); } - - List networks = _networkService.getVirtualNetworksOwnedByAccountInZone(getAccountName(), getDomainId(), getZoneId()); - if (networks.size() == 0) { - return null; - } - assert (networks.size() <= 1) : "Too many virtual networks. This logic should be obsolete"; - return networks.get(0).getId(); } diff --git a/api/src/com/cloud/api/commands/UpdateNetworkOfferingCmd.java b/api/src/com/cloud/api/commands/UpdateNetworkOfferingCmd.java index 980010b7d95..901a841240d 100644 --- a/api/src/com/cloud/api/commands/UpdateNetworkOfferingCmd.java +++ b/api/src/com/cloud/api/commands/UpdateNetworkOfferingCmd.java @@ -26,8 +26,8 @@ import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; import com.cloud.api.response.NetworkOfferingResponse; -import com.cloud.network.Networks.Availability; import com.cloud.offering.NetworkOffering; +import com.cloud.offering.NetworkOffering.Availability; @Implementation(description="Updates a network offering.", responseObject=NetworkOfferingResponse.class) public class UpdateNetworkOfferingCmd extends BaseCmd { diff --git a/api/src/com/cloud/api/response/NetworkOfferingResponse.java b/api/src/com/cloud/api/response/NetworkOfferingResponse.java index 56d75410578..47bf6e98436 100644 --- a/api/src/com/cloud/api/response/NetworkOfferingResponse.java +++ b/api/src/com/cloud/api/response/NetworkOfferingResponse.java @@ -24,9 +24,6 @@ public class NetworkOfferingResponse extends BaseResponse{ @SerializedName("maxconnections") @Param(description="the max number of concurrent connection the network offering supports") private Integer maxConnections; - @SerializedName("type") @Param(description="type of the network. Supported types are Virtualized, DirectSingle, DirectDual") - private String type; - @SerializedName("traffictype") @Param(description="the traffic type for the network offering, supported types are Public, Management, Control, Guest, Vlan or Storage.") private String trafficType; @@ -87,14 +84,6 @@ public class NetworkOfferingResponse extends BaseResponse{ this.maxConnections = maxConnections; } - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - public String getTrafficType() { return trafficType; } diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java index fdcdae253d1..5b0a9da8860 100644 --- a/api/src/com/cloud/network/NetworkService.java +++ b/api/src/com/cloud/network/NetworkService.java @@ -55,4 +55,6 @@ public interface NetworkService { int getActiveNicsInNetwork(long networkId); + Network getNetwork(long networkId); + } diff --git a/api/src/com/cloud/network/Networks.java b/api/src/com/cloud/network/Networks.java index 9286ece6d51..889ca567047 100644 --- a/api/src/com/cloud/network/Networks.java +++ b/api/src/com/cloud/network/Networks.java @@ -36,12 +36,6 @@ public class Networks { Firewall } - public enum Availability { - Required, - Optional, - Unavailable; - } - /** * Different ways to assign ip address to this network. */ diff --git a/api/src/com/cloud/network/lb/LoadBalancingRulesService.java b/api/src/com/cloud/network/lb/LoadBalancingRulesService.java index 07863b7c6b2..5505f7d34fc 100644 --- a/api/src/com/cloud/network/lb/LoadBalancingRulesService.java +++ b/api/src/com/cloud/network/lb/LoadBalancingRulesService.java @@ -61,5 +61,7 @@ public interface LoadBalancingRulesService { * @return list of load balancers that match the criteria */ List searchForLoadBalancers(ListLoadBalancerRulesCmd cmd); + + List listByNetworkId(long networkId); } diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java index d4c09737b6e..6a36b071370 100644 --- a/api/src/com/cloud/offering/NetworkOffering.java +++ b/api/src/com/cloud/offering/NetworkOffering.java @@ -17,7 +17,6 @@ */ package com.cloud.offering; -import com.cloud.network.Networks.Availability; import com.cloud.network.Networks.TrafficType; /** @@ -29,13 +28,23 @@ public interface NetworkOffering { public enum GuestIpType { Virtual, Direct, - DirectPodBased, } - public final String DefaultVirtualizedNetworkOffering = "DefaultVirtualizedNetworkOffering"; - public final String DefaultDirectNetworkOffering = "DefaultDirectNetworkOffering"; - public final String DefaultDirectPodBasedNetworkOffering = "DefaultDirectPodBasedNetworkOffering"; - public final String DefaultDirectChooseVlanNetworkOffering = "DefaultDirectChooseVlanNetworkOffering"; + public enum Availability { + Required, + Optional, + Unavailable; + } + + public final static String SystemPublicNetwork = "System-Public-Network"; + public final static String SystemControlNetwork = "System-Control-Network"; + public final static String SystemManagementNetwork = "System-Management-Network"; + public final static String SystemStorageNetwork = "System-Storage-Network"; + public final static String SysteGuestNetwork = "System-Guest-Network"; + + public final static String DefaultVirtualizedNetworkOffering = "DefaultVirtualizedNetworkOffering"; + public final static String DefaultDirectNetworkOffering = "DefaultDirectNetworkOffering"; + public final static String DefaultDirectChooseVlanNetworkOffering = "DefaultDirectChooseVlanNetworkOffering"; long getId(); @@ -59,11 +68,6 @@ public interface NetworkOffering { */ Integer getMulticastRateMbps(); - /** - * @return the type of IP address to allocate as the primary ip address to a guest - */ - GuestIpType getGuestIpType(); - /** * @return concurrent connections to be supported. */ diff --git a/api/src/com/cloud/user/AccountService.java b/api/src/com/cloud/user/AccountService.java index 3a0baa6df74..4858a285797 100644 --- a/api/src/com/cloud/user/AccountService.java +++ b/api/src/com/cloud/user/AccountService.java @@ -104,7 +104,6 @@ public interface AccountService { * @param cmd - the LockAccount command defining the accountId to be locked. * @return account object */ - //Account lockAccount(LockAccountCmd cmd); Account lockAccount(DisableAccountCmd cmd); /** @@ -139,6 +138,14 @@ public interface AccountService { User createUser(CreateUserCmd cmd); boolean deleteUser(DeleteUserCmd deleteUserCmd); - + + boolean isAdmin(short accountType); + + Account finalizeOwner(Account caller, String accountName, Long domainId); + + Account getActiveAccount(String accountName, Long domainId); + + Account getAccount(Long accountId); + } diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index 61052977b66..f152f103fcd 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -45,6 +45,7 @@ + diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 2b9c9d6f911..011d5e8a605 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -151,6 +151,7 @@ import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VirtualMachineTO.Monitor; import com.cloud.agent.api.to.VirtualMachineTO.SshMonitor; import com.cloud.agent.api.to.VolumeTO; +import com.cloud.dc.Vlan; import com.cloud.exception.InternalErrorException; import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -2942,7 +2943,7 @@ public abstract class CitrixResourceBase implements ServerResource { Set routerVIFs = router.getVIFs(conn); for (VIF vif : routerVIFs) { Network vifNetwork = vif.getNetwork(conn); - if (vlanId.equals("untagged")) { + if (vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) { if (vifNetwork.getUuid(conn).equals(_host.publicNetwork)) { return vif; } diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 3fe4c16a3ef..b397cbd5adf 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -509,7 +509,7 @@ public class ApiDBUtils { } public static long getPublicNetworkIdByZone(long zoneId) { - return _networkMgr.getSystemNetworkIdByZoneAndTrafficTypeAndGuestType(zoneId, TrafficType.Public, null); + return _networkMgr.getSystemNetworkByZoneAndTrafficType(zoneId, TrafficType.Public).getId(); } public static Long getVlanNetworkId(long vlanId) { diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 1875b520dd3..da9c3d3d4bc 100644 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -113,7 +113,6 @@ import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityGroupRules; import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering; -import com.cloud.offering.NetworkOffering.GuestIpType; import com.cloud.offering.ServiceOffering; import com.cloud.org.Cluster; import com.cloud.server.Criteria; @@ -1090,10 +1089,7 @@ public class ApiResponseHelper implements ResponseGenerator { nicResponse.setTrafficType(network.getTrafficType().toString()); //Set type - NetworkOffering networkOffering = ApiDBUtils.findNetworkOfferingById(network.getNetworkOfferingId()); - if (networkOffering.getGuestIpType() != null) { - nicResponse.setType(networkOffering.getGuestIpType().toString()); - } + nicResponse.setType(network.getGuestType().toString()); nicResponse.setObjectName("nic"); @@ -2174,9 +2170,6 @@ public class ApiResponseHelper implements ResponseGenerator { response.setDisplayText(offering.getDisplayText()); response.setTags(offering.getTags()); response.setTrafficType(offering.getTrafficType().toString()); - if (offering.getGuestIpType() != null) { - response.setType(offering.getGuestIpType().toString()); - } response.setMaxconnections(offering.getConcurrentConnections()); response.setIsDefault(offering.isDefault()); response.setSpecifyVlan(offering.getSpecifyVlan()); diff --git a/server/src/com/cloud/configuration/ConfigurationManager.java b/server/src/com/cloud/configuration/ConfigurationManager.java index a9b254436d6..6716340941f 100644 --- a/server/src/com/cloud/configuration/ConfigurationManager.java +++ b/server/src/com/cloud/configuration/ConfigurationManager.java @@ -29,9 +29,9 @@ import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; -import com.cloud.network.Networks.Availability; import com.cloud.network.Networks.TrafficType; import com.cloud.offering.DiskOffering; +import com.cloud.offering.NetworkOffering.Availability; import com.cloud.offering.NetworkOffering.GuestIpType; import com.cloud.offering.ServiceOffering; import com.cloud.offerings.NetworkOfferingVO; diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index c0dcd4e7673..cf656f6744b 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -93,13 +93,13 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.IPAddressVO; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; -import com.cloud.network.Networks.Availability; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.TrafficType; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.NetworkDao; import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering; +import com.cloud.offering.NetworkOffering.Availability; import com.cloud.offering.NetworkOffering.GuestIpType; import com.cloud.offering.ServiceOffering; import com.cloud.offerings.NetworkOfferingVO; @@ -1212,14 +1212,18 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura } else if (offering.getTrafficType() == TrafficType.Control) { broadcastDomainType = BroadcastDomainType.LinkLocal; } else if (offering.getTrafficType() == TrafficType.Public) { - if (zone.getNetworkType() == NetworkType.Basic && offering.getGuestIpType() == GuestIpType.DirectPodBased) { - broadcastDomainType = BroadcastDomainType.Native; - } else if (zone.getNetworkType() == NetworkType.Advanced && offering.getGuestIpType() == null) { + if (zone.getNetworkType() == NetworkType.Advanced) { broadcastDomainType = BroadcastDomainType.Vlan; } else { continue; } - } + } else if (offering.getTrafficType() == TrafficType.Guest) { + if (zone.getNetworkType() == NetworkType.Basic) { + broadcastDomainType = BroadcastDomainType.Native; + } else { + continue; + } + } userNetwork.setBroadcastDomainType(broadcastDomainType); _networkMgr.setupNetwork(systemAccount, offering, userNetwork, plan, null, null, true); } @@ -1648,14 +1652,14 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura if (forVirtualNetwork){ if (network == null) { //find default public network in the zone - networkId = _networkMgr.getSystemNetworkIdByZoneAndTrafficTypeAndGuestType(zoneId, TrafficType.Public, null); + networkId = _networkMgr.getSystemNetworkByZoneAndTrafficType(zoneId, TrafficType.Public).getId(); } else if (network.getGuestType() != null || network.getTrafficType() != TrafficType.Public){ throw new InvalidParameterValueException("Can't find Public network by id=" + networkId); } } else { if (network == null) { if (zone.getNetworkType() == DataCenter.NetworkType.Basic) { - networkId = _networkMgr.getSystemNetworkIdByZoneAndTrafficTypeAndGuestType(zoneId, TrafficType.Public, GuestIpType.DirectPodBased); + networkId = _networkMgr.getSystemNetworkByZoneAndTrafficType(zoneId, TrafficType.Guest).getId(); } else { throw new InvalidParameterValueException("Nework id is required for Direct vlan creation "); } @@ -1677,11 +1681,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura //check if startIp and endIp belong to network Cidr String networkCidr = network.getCidr(); String networkGateway = network.getGateway(); - Long networkZoneId = network.getDataCenterId(); - String[] splitResult = networkCidr.split("\\/"); - long size = Long.valueOf(splitResult[1]); - String networkNetmask = NetUtils.getCidrNetmask(size); + String networkNetmask = NetUtils.getCidrNetmask(networkCidr); //Check if ip addresses are in network range if (!NetUtils.sameSubnet(startIP, networkGateway, networkNetmask)) { @@ -1719,7 +1720,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura throw new InvalidParameterValueException("Please specify a valid pod."); } - if (podId != null && _podDao.findById(podId).getDataCenterId() != zoneId) { throw new InvalidParameterValueException("Pod id=" + podId + " doesn't belong to zone id=" + zoneId); } @@ -1753,7 +1753,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura if(hypervisorType.equalsIgnoreCase("xenserver")) { //check for the vlan being added before going to db, to see if it is untagged - if(vlanType.toString().equalsIgnoreCase("VirtualNetwork") && vlanId.equalsIgnoreCase("untagged")) + if(vlanType.toString().equalsIgnoreCase("VirtualNetwork") && vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) { if(_configDao.getValue("xen.public.network.device") == null || _configDao.getValue("xen.public.network.device").equals("")) { @@ -1774,13 +1774,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura } } - - -// //check if the account's domain is a child of the zone's domain, for adding vlan ip ranges -// if(domainId != null && !_domainDao.isChildDomain(zone.getDomainId(), domainId)){ -// //this is for account specific case, as domainId != null -// throw new PermissionDeniedException("The account associated with specific domain id:"+domainId+" doesn't have permissions to add vlan ip ranges for the zone:"+zone.getId()); -// } //ACL check checkAccess(account, zone); @@ -1909,6 +1902,19 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura throw new InvalidParameterValueException("The VLAN tag " + vlanId + " is already being used for the guest network in zone " + zone.getName()); } + //For untagged vlan check if vlan per pod already exists. If yes, verify that new vlan range has the same netmask and gateway + if (zone.getNetworkType() == NetworkType.Basic && vlanId.equalsIgnoreCase(Vlan.UNTAGGED) && podId != null){ + List podVlans = _vlanDao.listVlansForPodByType(podId, VlanType.DirectAttached); + if (podVlans != null && !podVlans.isEmpty()) { + VlanVO podVlan = podVlans.get(0); + if (!podVlan.getVlanNetmask().equals(vlanNetmask)) { + throw new InvalidParameterValueException("Vlan netmask is different from the netmask of Untagged vlan id=" + podVlan.getId() + " existing in the pod " + podId); + } else if (!podVlan.getVlanGateway().equals(vlanGateway)) { + throw new InvalidParameterValueException("Vlan gateway is different from the gateway of Untagged vlan id=" + podVlan.getId() + " existing in the pod " + podId); + } + } + } + // Everything was fine, so persist the VLAN String ipRange = startIP; if (endIP != null) { @@ -2665,7 +2671,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura String name = cmd.getNetworkOfferingName(); String displayText = cmd.getDisplayText(); String tags = cmd.getTags(); - String typeString = cmd.getType(); String trafficTypeString = cmd.getTraffictype(); Boolean specifyVlan = cmd.getSpecifyVlan(); String availabilityStr = cmd.getAvailability(); @@ -2685,16 +2690,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura throw new InvalidParameterValueException("Invalid value for traffictype. Supported traffic types: Public, Management, Control, Guest, Vlan or Storage"); } - //Verify type - for (GuestIpType gType : GuestIpType.values()) { - if (gType.name().equalsIgnoreCase(typeString)) { - type = gType; - } - } - if (type == null || type == GuestIpType.DirectPodBased) { - throw new InvalidParameterValueException("Invalid value for type. Supported types: Virtual, Direct"); - } - //Verify availability for (Availability avlb : Availability.values()) { if (avlb.name().equalsIgnoreCase(availabilityStr)) { @@ -2717,7 +2712,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura int networkRate = ((networkRateStr == null) ? 200 : Integer.parseInt(networkRateStr)); int multicastRate = ((multicastRateStr == null) ? 10 : Integer.parseInt(multicastRateStr)); tags = cleanupTags(tags); - NetworkOfferingVO offering = new NetworkOfferingVO(name, displayText, trafficType, type, false, specifyVlan, networkRate, multicastRate, maxConnections, false, availability, false, false, false, false, false, false, false); + NetworkOfferingVO offering = new NetworkOfferingVO(name, displayText, trafficType, false, specifyVlan, networkRate, multicastRate, maxConnections, false, availability, false, false, false, false, false, false, false); if ((offering = _networkOfferingDao.persist(offering)) != null) { saveConfigurationEvent(userId, null, EventTypes.EVENT_NETWORK_OFFERING_CREATE, "Successfully created new network offering with name: " + name + ".", "noId=" + offering.getId(), "name=" + name, diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 0f248e55ae4..0b4819018b8 100644 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -72,6 +72,8 @@ import com.cloud.certificate.dao.CertificateDao; import com.cloud.cluster.ClusterManager; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; import com.cloud.dc.dao.DataCenterDao; @@ -697,8 +699,12 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx DataCenterDeployment plan = new DataCenterDeployment(dataCenterId); - List defaultOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmPublicNetwork); - List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmControlNetwork, NetworkOfferingVO.SystemVmManagementNetwork); + List defaultOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemPublicNetwork); + if (dc.getNetworkType() == NetworkType.Basic) { + defaultOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SysteGuestNetwork); + } + + List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork, NetworkOfferingVO.SystemManagementNetwork); List> networks = new ArrayList>(offerings.size() + 1); NicProfile defaultNic = new NicProfile(); defaultNic.setDefaultNic(true); @@ -2020,10 +2026,11 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx cmds.addCommand("checkSsh", check); ConsoleProxyVO proxy = profile.getVirtualMachine(); + DataCenter dc = dest.getDataCenter(); List nics = _nicDao.listBy(proxy.getId()); for (NicVO nic : nics) { NetworkVO network = _networkDao.findById(nic.getNetworkId()); - if (network.getTrafficType() == TrafficType.Public) { + if ((network.getTrafficType() == TrafficType.Public && dc.getNetworkType() == NetworkType.Advanced) || (network.getTrafficType() == TrafficType.Guest && dc.getNetworkType() == NetworkType.Basic)) { proxy.setPublicIpAddress(nic.getIp4Address()); proxy.setPublicNetmask(nic.getNetmask()); proxy.setPublicMacAddress(nic.getMacAddress()); diff --git a/server/src/com/cloud/dc/dao/VlanDao.java b/server/src/com/cloud/dc/dao/VlanDao.java index a0bf95e7067..c4c028b1f74 100644 --- a/server/src/com/cloud/dc/dao/VlanDao.java +++ b/server/src/com/cloud/dc/dao/VlanDao.java @@ -40,13 +40,9 @@ public interface VlanDao extends GenericDao { List listVlansForPodByType(long podId, Vlan.VlanType vlanType); void addToPod(long podId, long vlanDbId); - -// Pair assignIpAddress(long zoneId, long accountId, long domainId, VlanType vlanType, boolean sourceNat); List listVlansForAccountByType(Long zoneId, long accountId, VlanType vlanType); -// Pair assignPodDirectAttachIpAddress(long zoneId, long podId, long accountId, long domainId); - boolean zoneHasDirectAttachUntaggedVlans(long zoneId); List listZoneWideVlans(long zoneId, VlanType vlanType, String vlanId); diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index d4fa6f4b45d..a7f458e3208 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -33,9 +33,7 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; import com.cloud.network.rules.FirewallRule; import com.cloud.network.vpn.RemoteAccessVpnElement; -import com.cloud.offering.NetworkOffering.GuestIpType; import com.cloud.offerings.NetworkOfferingVO; -import com.cloud.service.ServiceOfferingVO; import com.cloud.user.Account; import com.cloud.user.AccountVO; import com.cloud.utils.Pair; @@ -59,13 +57,14 @@ public interface NetworkManager extends NetworkService { * Assigns a new public ip address. * * @param dcId + * @param podId TODO * @param owner * @param type * @param networkId * @return * @throws InsufficientAddressCapacityException */ - PublicIp assignPublicIpAddress(long dcId, Account owner, VlanType type, Long networkId) throws InsufficientAddressCapacityException; + PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId) throws InsufficientAddressCapacityException; /** * assigns a source nat ip address to an account within a network. @@ -125,21 +124,19 @@ public interface NetworkManager extends NetworkService { AccountVO getNetworkOwner(long configurationId); List getNetworksforOffering(long offeringId, long dataCenterId, long accountId); - - List setupNetwork(Account owner, ServiceOfferingVO offering, DeploymentPlan plan) throws ConcurrentOperationException; - Network getNetwork(long id); String getNextAvailableMacAddressInNetwork(long networkConfigurationId) throws InsufficientAddressCapacityException; boolean applyRules(List rules, boolean continueOnError) throws ResourceUnavailableException; Map> getZoneCapabilities(long zoneId); - long getSystemNetworkIdByZoneAndTrafficTypeAndGuestType(long zoneId, TrafficType trafficType, GuestIpType guestType); + Network getSystemNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType); List getRemoteAccessVpnElements(); PublicIpAddress getPublicIpAddress(Ip ipAddress); - Network getBasicZoneDefaultPublicNetwork(long zoneId); + String getPodVlanGateway(long podId); + } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 1af653a815b..e0674cc4b81 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -43,30 +43,30 @@ import com.cloud.agent.api.to.NicTO; import com.cloud.agent.manager.Commands; import com.cloud.alert.AlertManager; import com.cloud.api.BaseCmd; -import com.cloud.api.ServerApiException; import com.cloud.api.commands.AssociateIPAddrCmd; import com.cloud.api.commands.CreateNetworkCmd; import com.cloud.api.commands.DisassociateIPAddrCmd; import com.cloud.api.commands.ListNetworksCmd; import com.cloud.api.commands.RestartNetworkCmd; -import com.cloud.capacity.dao.CapacityDao; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.ResourceCount.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.configuration.dao.ResourceLimitDao; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.DataCenterVO; +import com.cloud.dc.PodVlanMapVO; import com.cloud.dc.Vlan; import com.cloud.dc.Vlan.VlanType; import com.cloud.dc.VlanVO; import com.cloud.dc.dao.AccountVlanMapDao; import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.PodVlanMapDao; import com.cloud.dc.dao.VlanDao; import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; +import com.cloud.domain.Domain; import com.cloud.domain.dao.DomainDao; import com.cloud.event.EventTypes; import com.cloud.event.EventUtils; @@ -87,20 +87,15 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Service; import com.cloud.network.Networks.AddressFormat; -import com.cloud.network.Networks.Availability; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; -import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.RemoteAccessVpnDao; -import com.cloud.network.dao.VpnUserDao; import com.cloud.network.element.NetworkElement; import com.cloud.network.guru.NetworkGuru; import com.cloud.network.lb.LoadBalancingRule; -import com.cloud.network.lb.LoadBalancingRule.LbDestination; import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.network.rules.FirewallRule; @@ -109,13 +104,12 @@ import com.cloud.network.rules.RulesManager; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.network.vpn.RemoteAccessVpnElement; import com.cloud.offering.NetworkOffering; +import com.cloud.offering.NetworkOffering.Availability; import com.cloud.offering.NetworkOffering.GuestIpType; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.resource.Resource; import com.cloud.resource.Resource.ReservationStrategy; -import com.cloud.service.ServiceOfferingVO; -import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; @@ -170,27 +164,21 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Inject EventDao _eventDao = null; @Inject ConfigurationDao _configDao; @Inject UserVmDao _vmDao = null; - @Inject ResourceLimitDao _limitDao = null; - @Inject CapacityDao _capacityDao = null; @Inject AgentManager _agentMgr; @Inject AlertManager _alertMgr; @Inject AccountManager _accountMgr; @Inject ConfigurationManager _configMgr; - @Inject ServiceOfferingDao _serviceOfferingDao = null; @Inject AccountVlanMapDao _accountVlanMapDao; - @Inject UserStatisticsDao _statsDao = null; @Inject NetworkOfferingDao _networkOfferingDao = null; @Inject NetworkDao _networksDao = null; @Inject NicDao _nicDao = null; @Inject RemoteAccessVpnDao _remoteAccessVpnDao = null; - @Inject VpnUserDao _vpnUsersDao = null; @Inject VirtualNetworkApplianceManager _routerMgr; @Inject RulesManager _rulesMgr; @Inject LoadBalancingRulesManager _lbMgr; - @Inject FirewallRulesDao _firewallRulesDao; - @Inject LoadBalancerDao _lbDao; @Inject PortForwardingRulesDao _pfRulesDao; @Inject UsageEventDao _usageEventDao; + @Inject PodVlanMapDao _podVlanMapDao; @Inject(adapter=NetworkGuru.class) Adapters _networkGurus; @@ -203,7 +191,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag SearchBuilder AccountsUsingNetworkSearch; SearchBuilder AssignIpAddressSearch; + SearchBuilder AssignIpAddressFromPodVlanSearch; SearchBuilder IpAddressSearch; + int _networkGcWait; int _networkGcInterval; @@ -212,15 +202,22 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag HashMap _lastNetworkIdsToFree = new HashMap(); @Override - public PublicIp assignPublicIpAddress(long dcId, Account owner, VlanType type, Long networkId) throws InsufficientAddressCapacityException { - return fetchNewPublicIp(dcId, owner, type, networkId, false, true); + public PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId) throws InsufficientAddressCapacityException { + return fetchNewPublicIp(dcId, podId, owner, type, networkId, false, true); } @DB - public PublicIp fetchNewPublicIp(long dcId, Account owner, VlanType vlanUse, Long networkId, boolean sourceNat, boolean assign) throws InsufficientAddressCapacityException { + public PublicIp fetchNewPublicIp(long dcId, Long podId, Account owner, VlanType vlanUse, Long networkId, boolean sourceNat, boolean assign) throws InsufficientAddressCapacityException { Transaction txn = Transaction.currentTxn(); txn.start(); - SearchCriteria sc = AssignIpAddressSearch.create(); + SearchCriteria sc = null; + if (podId != null) { + sc = AssignIpAddressFromPodVlanSearch.create(); + sc.setJoinParameters("podVlanMapSB", "podId", podId); + } else { + sc = AssignIpAddressSearch.create(); + } + sc.setParameters("dc", dcId); //for direct network take ip addresses only from the vlans belonging to the network @@ -303,7 +300,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag s_logger.debug("assigning a new ip address in " + dcId + " to " + owner); } - ip = fetchNewPublicIp(dcId, owner, VlanType.VirtualNetwork, network.getId(), true, false); + ip = fetchNewPublicIp(dcId, null, owner, VlanType.VirtualNetwork, network.getId(), true, false); sourceNat = ip.ip(); sourceNat.setState(IpAddress.State.Allocated); _ipAddressDao.update(sourceNat.getAddress(), sourceNat); @@ -441,26 +438,24 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag protected Account getAccountForApiCommand(String accountName, Long domainId) throws InvalidParameterValueException, PermissionDeniedException{ Account account = UserContext.current().getCaller(); - if ((account == null) || isAdmin(account.getType())) { + if (_accountMgr.isAdmin(account.getType())) { //The admin is making the call, determine if it is for someone else or for himself if (domainId != null) { if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId)) { throw new PermissionDeniedException("Invalid domain id (" + domainId + ") given, , permission denied"); } if (accountName != null) { - Account userAccount = _accountDao.findActiveAccount(accountName, domainId); + Account userAccount = _accountMgr.getActiveAccount(accountName, domainId); if (userAccount != null) { account = userAccount; } else { throw new PermissionDeniedException("Unable to find account " + accountName + " in domain " + domainId + ", permission denied"); } } - } else if (account != null) { + } else { // the admin is calling the api on his own behalf return account; - } else { - throw new InvalidParameterValueException("Account information is not specified."); - } + } } return account; } @@ -506,7 +501,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override public List getVirtualNetworksOwnedByAccountInZone(String accountName, long domainId, long zoneId) { - Account owner = _accountDao.findActiveAccount(accountName, domainId); + Account owner = _accountMgr.getActiveAccount(accountName, domainId); if (owner == null) { throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId + ", permission denied"); } @@ -522,7 +517,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag Account caller = UserContext.current().getCaller(); long userId = UserContext.current().getCallerUserId(); - Account owner = _accountDao.findActiveAccount(accountName, domainId); + Account owner = _accountMgr.getActiveAccount(accountName, domainId); if (owner == null) { throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId + ", permission denied"); } @@ -572,7 +567,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } txn.start(); - ip = fetchNewPublicIp(zoneId, owner, VlanType.VirtualNetwork, network.getId(), false, false); + ip = fetchNewPublicIp(zoneId, null, owner, VlanType.VirtualNetwork, network.getId(), false, false); if (ip == null) { throw new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zoneId); @@ -701,26 +696,27 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _networkGcWait = NumbersUtil.parseInt(_configs.get(Config.NetworkGcWait.key()), 600); _networkGcInterval = NumbersUtil.parseInt(_configs.get(Config.NetworkGcInterval.key()), 600); - NetworkOfferingVO publicNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemVmPublicNetwork, TrafficType.Public, null); + NetworkOfferingVO publicNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemPublicNetwork, TrafficType.Public, null); publicNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(publicNetworkOffering); - _systemNetworks.put(NetworkOfferingVO.SystemVmPublicNetwork, publicNetworkOffering); - NetworkOfferingVO managementNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemVmManagementNetwork, TrafficType.Management, null); + _systemNetworks.put(NetworkOfferingVO.SystemPublicNetwork, publicNetworkOffering); + NetworkOfferingVO managementNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemManagementNetwork, TrafficType.Management, null); managementNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(managementNetworkOffering); - _systemNetworks.put(NetworkOfferingVO.SystemVmManagementNetwork, managementNetworkOffering); - NetworkOfferingVO controlNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemVmControlNetwork, TrafficType.Control, null); + _systemNetworks.put(NetworkOfferingVO.SystemManagementNetwork, managementNetworkOffering); + NetworkOfferingVO controlNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemControlNetwork, TrafficType.Control, null); controlNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(controlNetworkOffering); - _systemNetworks.put(NetworkOfferingVO.SystemVmControlNetwork, controlNetworkOffering); - NetworkOfferingVO storageNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemVmStorageNetwork, TrafficType.Storage, null); + _systemNetworks.put(NetworkOfferingVO.SystemControlNetwork, controlNetworkOffering); + NetworkOfferingVO storageNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemStorageNetwork, TrafficType.Storage, null); storageNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(storageNetworkOffering); - _systemNetworks.put(NetworkOfferingVO.SystemVmStorageNetwork, storageNetworkOffering); - - NetworkOfferingVO defaultGuestNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultVirtualizedNetworkOffering, "Virtual Vlan", TrafficType.Guest, GuestIpType.Virtual, false, false, rateMbps, multicastRateMbps, null, true, Availability.Required, false, false, false, false, false, false, false); - defaultGuestNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultGuestNetworkOffering); - NetworkOfferingVO defaultGuestDirectNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultDirectNetworkOffering, "Direct", TrafficType.Public, GuestIpType.Direct, false, false, rateMbps, multicastRateMbps, null, true, Availability.Required, false, false, false, false, false, false, false); - defaultGuestNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultGuestDirectNetworkOffering); - NetworkOfferingVO defaultGuestDirectPodBasedNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultDirectPodBasedNetworkOffering, "DirectPodBased", TrafficType.Public, GuestIpType.DirectPodBased, true, false, rateMbps, multicastRateMbps, null, true, Availability.Required, false, false, false, false, false, false, false); - defaultGuestNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultGuestDirectPodBasedNetworkOffering); + _systemNetworks.put(NetworkOfferingVO.SystemStorageNetwork, storageNetworkOffering); + NetworkOfferingVO guestNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SysteGuestNetwork, TrafficType.Guest, null); + guestNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(guestNetworkOffering); + _systemNetworks.put(NetworkOfferingVO.SysteGuestNetwork, guestNetworkOffering); + NetworkOfferingVO defaultGuestNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultVirtualizedNetworkOffering, "Virtual Vlan", TrafficType.Guest, false, false, rateMbps, multicastRateMbps, null, true, Availability.Required, false, false, false, false, false, false, false); + defaultGuestNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultGuestNetworkOffering); + NetworkOfferingVO defaultGuestDirectNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultDirectNetworkOffering, "Direct", TrafficType.Public, false, false, rateMbps, multicastRateMbps, null, true, Availability.Required, false, false, false, false, false, false, false); + defaultGuestDirectNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultGuestDirectNetworkOffering); + AccountsUsingNetworkSearch = _accountDao.createSearchBuilder(); SearchBuilder networkAccountSearch = _networksDao.createSearchBuilderForAccount(); AccountsUsingNetworkSearch.join("nc", networkAccountSearch, AccountsUsingNetworkSearch.entity().getId(), networkAccountSearch.entity().getAccountId(), JoinType.INNER); @@ -729,14 +725,26 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag AccountsUsingNetworkSearch.done(); AssignIpAddressSearch = _ipAddressDao.createSearchBuilder(); - SearchBuilder vlanSearch = _vlanDao.createSearchBuilder(); AssignIpAddressSearch.and("dc", AssignIpAddressSearch.entity().getDataCenterId(), Op.EQ); AssignIpAddressSearch.and("allocated", AssignIpAddressSearch.entity().getAllocatedTime(), Op.NULL); - AssignIpAddressSearch.join("vlan", vlanSearch, vlanSearch.entity().getId(), AssignIpAddressSearch.entity().getVlanId(), JoinType.INNER); + SearchBuilder vlanSearch = _vlanDao.createSearchBuilder(); vlanSearch.and("type", vlanSearch.entity().getVlanType(), Op.EQ); vlanSearch.and("networkId", vlanSearch.entity().getNetworkId(), Op.EQ); + AssignIpAddressSearch.join("vlan", vlanSearch, vlanSearch.entity().getId(), AssignIpAddressSearch.entity().getVlanId(), JoinType.INNER); AssignIpAddressSearch.done(); + AssignIpAddressFromPodVlanSearch = _ipAddressDao.createSearchBuilder(); + AssignIpAddressFromPodVlanSearch.and("dc", AssignIpAddressFromPodVlanSearch.entity().getDataCenterId(), Op.EQ); + AssignIpAddressFromPodVlanSearch.and("allocated", AssignIpAddressFromPodVlanSearch.entity().getAllocatedTime(), Op.NULL); + SearchBuilder podVlanSearch = _vlanDao.createSearchBuilder(); + podVlanSearch.and("type", podVlanSearch.entity().getVlanType(), Op.EQ); + podVlanSearch.and("networkId", podVlanSearch.entity().getNetworkId(), Op.EQ); + SearchBuilder podVlanMapSB = _podVlanMapDao.createSearchBuilder(); + podVlanMapSB.and("podId", podVlanMapSB.entity().getPodId(), Op.EQ); + AssignIpAddressFromPodVlanSearch.join("podVlanMapSB", podVlanMapSB, podVlanMapSB.entity().getVlanDbId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(), JoinType.INNER); + AssignIpAddressFromPodVlanSearch.join("vlan", podVlanSearch, podVlanSearch.entity().getId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(), JoinType.INNER); + AssignIpAddressFromPodVlanSearch.done(); + IpAddressSearch = _ipAddressDao.createSearchBuilder(); IpAddressSearch.and("accountId", IpAddressSearch.entity().getAllocatedToAccountId(), Op.EQ); IpAddressSearch.and("dataCenterId", IpAddressSearch.entity().getDataCenterId(), Op.EQ); @@ -1114,16 +1122,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return _nicDao.listBy(vm.getId()); } - public static boolean isAdmin(short accountType) { - return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || - (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || - (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN)); - } - private Account findAccountByIpAddress(Ip ipAddress) { IPAddressVO address = _ipAddressDao.findById(ipAddress); if ((address != null) && (address.getAllocatedToAccountId() != null)) { - return _accountDao.findById(address.getAllocatedToAccountId()); + return _accountMgr.getAccount(address.getAllocatedToAccountId()); } return null; } @@ -1133,29 +1135,23 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag public boolean disassociateIpAddress(DisassociateIPAddrCmd cmd) throws PermissionDeniedException, IllegalArgumentException { Long userId = UserContext.current().getCallerUserId(); - Account account = UserContext.current().getCaller(); + Account caller = UserContext.current().getCaller(); Ip ipAddress = cmd.getIpAddress(); // Verify input parameters Account accountByIp = findAccountByIpAddress(ipAddress); if(accountByIp == null) { - throw new ServerApiException(BaseCmd.PARAM_ERROR, "Unable to find account owner for ip " + ipAddress); + throw new InvalidParameterValueException("Unable to find account owner for ip " + ipAddress); } Long accountId = accountByIp.getId(); - if (account != null) { - if (!isAdmin(account.getType())) { - if (account.getId() != accountId.longValue()) { - throw new ServerApiException(BaseCmd.PARAM_ERROR, "account " + account.getAccountName() + " doesn't own ip address " + ipAddress); - } - } else if (!_domainDao.isChildDomain(account.getDomainId(), accountByIp.getDomainId())) { - throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to disassociate IP address " + ipAddress + ", permission denied."); + if (!_accountMgr.isAdmin(caller.getType())) { + if (caller.getId() != accountId.longValue()) { + throw new PermissionDeniedException("account " + caller.getAccountName() + " doesn't own ip address " + ipAddress); } - } - - // If command is executed via 8096 port, set userId to the id of System account (1) - if (userId == null) { - userId = Long.valueOf(1); + } else { + Domain domain = _domainDao.findById(accountByIp.getDomainId()); + _accountMgr.checkAccess(caller, domain); } try { @@ -1168,7 +1164,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return true; } - Account Account = _accountDao.findById(accountId); + Account Account = _accountMgr.getAccount(accountId); if (Account == null) { return false; } @@ -1240,12 +1236,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return _networksDao.getNetworksForOffering(offeringId, dataCenterId, accountId); } - @Override - public List setupNetwork(Account owner, ServiceOfferingVO offering, DeploymentPlan plan) throws ConcurrentOperationException { - NetworkOfferingVO networkOffering = _networkOfferingDao.findByServiceOffering(offering); - return setupNetwork(owner, networkOffering, plan, null, null, false); - } - @Override public List listNetworkOfferings() { return _networkOfferingDao.listNonSystemNetworkOfferings(); @@ -1312,8 +1302,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag String name = cmd.getNetworkName(); String displayText = cmd.getDisplayText(); Boolean isShared = cmd.getIsShared(); - Account owner = null; - Long ownerId = null; //if end ip is not specified, default it to startIp if (endIP == null && startIP != null) { @@ -1329,65 +1317,24 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag //Check if zone exists if (zoneId == null || ((_dcDao.findById(zoneId)) == null)) { throw new InvalidParameterValueException("Please specify a valid zone."); + } + + DataCenter zone = _dcDao.findById(zoneId); + if (zone.getNetworkType() == NetworkType.Basic) { + throw new InvalidParameterValueException("Network creation is not allowed in zone with network type " + NetworkType.Basic); } - //Check permissions - if (isAdmin(ctxAccount.getType())) { - if (domainId != null) { - if ((ctxAccount != null) && !_domainDao.isChildDomain(ctxAccount.getDomainId(), domainId)) { - throw new PermissionDeniedException("Failed to create a newtwork, invalid domain id (" + domainId + ") given."); - } - if (accountName != null) { - owner = _accountDao.findActiveAccount(accountName, domainId); - if (owner == null) { - throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); - } - } - } else { - owner = ctxAccount; - } - } else { - //regular user can't create networks for anybody else but himself - owner = ctxAccount; - } - - ownerId = owner.getId(); + Account owner = _accountMgr.finalizeOwner(ctxAccount, accountName, domainId); //Don't allow to create network with vlan that already exists in the system - if (networkOffering.getGuestIpType() == GuestIpType.Direct && vlanId != null) { + if (vlanId != null) { String uri ="vlan://" + vlanId; List networks = _networksDao.listBy(zoneId, uri); if ((networks != null && !networks.isEmpty())) { throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists in zone " + zoneId); } } - - //if VlanId is Direct untagged, verify if there is already network of this type in the zone - if (networkOffering.getGuestIpType() == GuestIpType.DirectPodBased && vlanId != null && vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) { - SearchBuilder sb = _networksDao.createSearchBuilder(); - sb.and("broadcastDomainType", sb.entity().getBroadcastDomainType(), SearchCriteria.Op.EQ); - sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ); - - SearchBuilder networkSearch = _networkOfferingDao.createSearchBuilder(); - networkSearch.and("guestIpType", networkSearch.entity().getGuestIpType(), SearchCriteria.Op.EQ); - sb.join("networkSearch", networkSearch, sb.entity().getNetworkOfferingId(), networkSearch.entity().getId(), JoinBuilder.JoinType.INNER); - - SearchCriteria sc = sb.create(); - sc.setParameters("broadcastDomainType", BroadcastDomainType.Native); - sc.setParameters("dataCenterId", zoneId); - sc.setJoinParameters("networkSearch", "guestIpType", GuestIpType.DirectPodBased); - - List networks = _networksDao.search(sc, null); - if (networks!= null && !networks.isEmpty()) { - throw new InvalidParameterValueException("Network with untagged vlan already exists for the zone " + zoneId); - } - } - - //Regular user can create only network of Virtual type - if (ctxAccount.getType() == Account.ACCOUNT_TYPE_NORMAL && networkOffering.getGuestIpType() != GuestIpType.Virtual) { - throw new InvalidParameterValueException("Regular user can create only networ of type " + GuestIpType.Virtual); - } - + //VlanId can be specified only when network offering supports it if (ctxAccount.getType() == Account.ACCOUNT_TYPE_NORMAL && vlanId != null && !networkOffering.getSpecifyVlan()) { throw new InvalidParameterValueException("Can't specify vlan because network offering doesn't support it"); @@ -1420,14 +1367,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag List networks = setupNetwork(owner, networkOffering, userNetwork, plan, name, displayText, isShared); Long networkId = null; + Network network = null; if (networks == null || networks.isEmpty()) { txn.rollback(); throw new CloudRuntimeException("Fail to create a network"); } else { + network = networks.get(0); networkId = networks.get(0).getId(); - } - - for (Network network : networks) { if (network.getGuestType() == GuestIpType.Virtual) { s_logger.debug("Creating a source natp ip for " + network); PublicIp ip = assignSourceNatIpAddress(owner, network, userId); @@ -1437,12 +1383,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } + Long ownerId = owner.getId(); //Don't pass owner to create vlan when network offering is of type Direct - done to prevent accountVlanMap entry creation when vlan is mapped to network - if (networkOffering.getGuestIpType() == GuestIpType.Direct) { + if (network.getGuestType() == GuestIpType.Direct) { owner = null; } - if (ctxAccount.getType() == Account.ACCOUNT_TYPE_ADMIN && networkOffering.getGuestIpType() == GuestIpType.Direct && startIP != null && endIP != null && gateway != null) { + if (ctxAccount.getType() == Account.ACCOUNT_TYPE_ADMIN && network.getGuestType() == GuestIpType.Direct && startIP != null && endIP != null && gateway != null) { //Create vlan ip range Vlan vlan = _configMgr.createVlanAndPublicIpRange(userId, zoneId, null, startIP, endIP, gateway, netmask, false, vlanId, owner, networkId); if (vlan == null) { @@ -1493,14 +1440,14 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag isSystem = false; } - if (isAdmin(account.getType())) { + if (_accountMgr.isAdmin(account.getType())) { if (domainId != null) { if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId)) { throw new PermissionDeniedException("Invalid domain id (" + domainId + ") given, unable to list networks"); } if (accountName != null) { - account = _accountDao.findActiveAccount(accountName, domainId); + account = _accountMgr.getActiveAccount(accountName, domainId); if (account == null) { throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); } @@ -1567,7 +1514,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override @DB public boolean deleteNetwork(long networkId) throws InvalidParameterValueException, PermissionDeniedException{ Long userId = UserContext.current().getCallerUserId(); - Account account = UserContext.current().getCaller(); + Account caller = UserContext.current().getCaller(); //Verify network id NetworkVO network = _networksDao.findById(networkId); @@ -1580,14 +1527,14 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag String name = network.getName(); //Perform permission check - if (account != null) { - if (!isAdmin(account.getType())) { - if (network.getAccountId() != account.getId()) { - throw new PermissionDeniedException("Account " + account.getAccountName() + " does not own network id=" + networkId + ", permission denied"); - } - } else if (!(account.getType() == Account.ACCOUNT_TYPE_ADMIN) && !_domainDao.isChildDomain(account.getDomainId(), _accountDao.findById(network.getAccountId()).getId())) { - throw new PermissionDeniedException("Unable to delete network " + networkId + ", permission denied."); + if (!_accountMgr.isAdmin(caller.getType())) { + if (network.getAccountId() != caller.getId()) { + throw new PermissionDeniedException("Account " + caller.getAccountName() + " does not own network id=" + networkId + ", permission denied"); } + } else { + Account owner = _accountMgr.getAccount(network.getAccountId()); + Domain domain = _domainDao.findById(owner.getDomainId()); + _accountMgr.checkAccess(caller, domain); } //Don't allow to remove network if there are non-destroyed vms using it @@ -1757,16 +1704,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override public boolean restartNetwork(RestartNetworkCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException { //This method reapplies Ip addresses, LoadBalancer and PortForwarding rules - String accountName = cmd.getAccountName(); - long domainId = cmd.getDomainId(); Account caller = UserContext.current().getCaller(); - - Account owner = _accountDao.findActiveAccount(accountName, domainId); - if (owner == null) { - throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId + ", permission denied"); - } - - _accountMgr.checkAccess(caller, owner); Long networkId = cmd.getNetworkId(); Network network = null; @@ -1777,28 +1715,28 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } } + Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId()); + if (!_accountMgr.isAdmin(caller.getType())) { + _accountMgr.checkAccess(caller, network); + } else { + Domain domain = _domainDao.findById(owner.getDomainId()); + _accountMgr.checkAccess(caller, domain); + } + s_logger.debug("Restarting network " + networkId + "..."); - boolean success = true; if (!applyIpAssociations(network, false)) { s_logger.warn("Failed to apply ips as a part of network " + networkId + " restart"); - success = false; + return false; } else { s_logger.debug("Ip addresses are reapplied successfully as a part of network " + networkId + " restart"); } - //Reapply lb rules - List lbs = _lbDao.listByNetworkId(networkId); - List lbRules = new ArrayList(); - for (LoadBalancerVO lb : lbs) { - List dstList = _lbMgr.getExistingDestinations(lb.getId()); - LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList); - lbRules.add(loadBalancing); - } - + List lbRules = _lbMgr.listByNetworkId(networkId); + if (!applyRules(lbRules, true)) { s_logger.warn("Failed to apply load balancing rules as a part of network " + network.getId() + " restart"); - success = false; + return false; } else { s_logger.debug("Load balancing rules are reapplied successfully as a part of network " + networkId + " restart"); } @@ -1807,15 +1745,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag List pfRules = _pfRulesDao.listByNetworkId(networkId); if (!applyRules(pfRules, true)) { s_logger.warn("Failed to apply port forwarding rules as a part of network " + network.getId() + " restart"); - success = false; + return false; } else { s_logger.debug("Port forwarding rules are reapplied successfully as a part of network " + networkId + " restart"); } - if (success){ - s_logger.debug("Network " + networkId + " is restarted successfully."); - } - return success; + s_logger.debug("Network " + networkId + " is restarted successfully."); + return true; } @Override @@ -1874,26 +1810,26 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } @Override - public long getSystemNetworkIdByZoneAndTrafficTypeAndGuestType(long zoneId, TrafficType trafficType, GuestIpType guestType) { + public Network getSystemNetworkByZoneAndTrafficType(long zoneId, TrafficType trafficType) { //find system public network offering Long networkOfferingId = null; List offerings = _networkOfferingDao.listSystemNetworkOfferings(); for (NetworkOfferingVO offering: offerings) { - if (offering.getTrafficType() == trafficType && offering.getGuestIpType() == guestType) { + if (offering.getTrafficType() == trafficType) { networkOfferingId = offering.getId(); break; } } if (networkOfferingId == null) { - throw new InvalidParameterValueException("Unable to find system network offering with traffic type " + trafficType + " and guestIpType " + guestType); + throw new InvalidParameterValueException("Unable to find system network offering with traffic type " + trafficType); } List networks = _networksDao.listBy(Account.ACCOUNT_ID_SYSTEM, networkOfferingId, zoneId); if (networks == null) { throw new InvalidParameterValueException("Unable to find network with traffic type " + trafficType + " in zone " + zoneId); } - return networks.get(0).getId(); + return networks.get(0); } @Override @@ -1907,21 +1843,14 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } @Override - public Network getBasicZoneDefaultPublicNetwork(long zoneId) { - SearchBuilder sb = _networksDao.createSearchBuilder(); - sb.and("trafficType", sb.entity().getTrafficType(), SearchCriteria.Op.EQ); - sb.and("guestType", sb.entity().getGuestType(), SearchCriteria.Op.EQ); - sb.and("dataCenterId", sb.entity().getDataCenterId(), SearchCriteria.Op.EQ); - SearchCriteria sc = sb.create(); - sc.setParameters("trafficType", TrafficType.Public); - sc.setParameters("guestType", GuestIpType.DirectPodBased); - sc.setParameters("dataCenterId", zoneId); - - List networks = _networksDao.search(sc, null); - if (networks == null || networks.isEmpty()) { - return null; + public String getPodVlanGateway(long podId) { + List vlans = _vlanDao.listVlansForPodByType(podId, VlanType.DirectAttached); + //we don't allow vlans to have different gateways, so take the value from the first one + if (vlans == null || !vlans.isEmpty()) { + return vlans.get(0).getVlanGateway(); } else { - return networks.get(0); + return null; } } + } diff --git a/server/src/com/cloud/network/NetworkVO.java b/server/src/com/cloud/network/NetworkVO.java index e62655ceca8..955f6f6aac5 100644 --- a/server/src/com/cloud/network/NetworkVO.java +++ b/server/src/com/cloud/network/NetworkVO.java @@ -142,14 +142,19 @@ public class NetworkVO implements Network { * @param broadcastDomainType * @param networkOfferingId * @param dataCenterId + * @param state TODO */ - public NetworkVO(TrafficType trafficType, GuestIpType guestType, Mode mode, BroadcastDomainType broadcastDomainType, long networkOfferingId, long dataCenterId) { + public NetworkVO(TrafficType trafficType, GuestIpType guestType, Mode mode, BroadcastDomainType broadcastDomainType, long networkOfferingId, long dataCenterId, State state) { this.trafficType = trafficType; this.mode = mode; this.broadcastDomainType = broadcastDomainType; this.networkOfferingId = networkOfferingId; this.dataCenterId = dataCenterId; - this.state = State.Allocated; + if (state == null) { + state = State.Allocated; + } else { + this.state = state; + } this.id = -1; this.guestType = guestType; } @@ -183,7 +188,7 @@ public class NetworkVO implements Network { * @param isShared TODO */ public NetworkVO(long id, TrafficType trafficType, GuestIpType guestType, Mode mode, BroadcastDomainType broadcastDomainType, long networkOfferingId, long dataCenterId, long domainId, long accountId, long related, String name, String displayText, Boolean isShared) { - this(trafficType, guestType, mode, broadcastDomainType, networkOfferingId, dataCenterId); + this(trafficType, guestType, mode, broadcastDomainType, networkOfferingId, dataCenterId, State.Allocated); this.domainId = domainId; this.accountId = accountId; this.related = related; diff --git a/server/src/com/cloud/network/element/DhcpElement.java b/server/src/com/cloud/network/element/DhcpElement.java index 3f9767f32d9..2ef447d66e2 100644 --- a/server/src/com/cloud/network/element/DhcpElement.java +++ b/server/src/com/cloud/network/element/DhcpElement.java @@ -26,6 +26,7 @@ import javax.ejb.Local; import org.apache.log4j.Logger; import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; @@ -35,6 +36,7 @@ import com.cloud.network.Network.Capability; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.network.NetworkManager; +import com.cloud.network.Networks.TrafficType; import com.cloud.network.PublicIpAddress; import com.cloud.network.dao.NetworkDao; import com.cloud.network.router.VirtualNetworkApplianceManager; @@ -67,16 +69,24 @@ public class DhcpElement extends AdapterBase implements NetworkElement{ @Inject UserVmDao _userVmDao; @Inject DomainRouterDao _routerDao; - private boolean canHandle(GuestIpType ipType, DeployDestination dest) { + private boolean canHandle(GuestIpType ipType, DeployDestination dest, TrafficType trafficType) { DataCenter dc = dest.getDataCenter(); String provider = dc.getGatewayProvider(); - return ((ipType == GuestIpType.Virtual && !provider.equals(Provider.VirtualRouter.getName())) || (provider.equals(Provider.VirtualRouter.getName()) && (ipType == GuestIpType.Direct || ipType == GuestIpType.DirectPodBased))); + if (provider.equals(Provider.VirtualRouter.getName())) { + if (dc.getNetworkType() == NetworkType.Basic) { + return (ipType == GuestIpType.Direct && trafficType == TrafficType.Guest); + } else { + return (ipType == GuestIpType.Direct); + } + } else { + return (ipType == GuestIpType.Virtual); + } } @Override public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException { - if (!canHandle(offering.getGuestIpType(), dest)) { + if (!canHandle(network.getGuestType(), dest, offering.getTrafficType())) { return false; } _routerMgr.deployDhcp(network, dest, context.getAccount()); @@ -85,7 +95,7 @@ public class DhcpElement extends AdapterBase implements NetworkElement{ @Override public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { - if (canHandle(network.getGuestType(), dest)) { + if (canHandle(network.getGuestType(), dest, network.getTrafficType())) { if (vm.getType() != VirtualMachine.Type.User) { return false; diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index 8908a82b7b0..7a366601982 100644 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -93,7 +93,7 @@ public class VirtualRouterElement extends AdapterBase implements NetworkElement, @Override public boolean implement(Network guestConfig, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException { - if (!canHandle(offering.getGuestIpType(), dest.getDataCenter())) { + if (!canHandle(guestConfig.getGuestType(), dest.getDataCenter())) { return false; } _routerMgr.deployVirtualRouter(guestConfig, dest, context.getAccount()); diff --git a/server/src/com/cloud/network/guru/ControlNetworkGuru.java b/server/src/com/cloud/network/guru/ControlNetworkGuru.java index 43436adc626..5cc92d4802a 100644 --- a/server/src/com/cloud/network/guru/ControlNetworkGuru.java +++ b/server/src/com/cloud/network/guru/ControlNetworkGuru.java @@ -1,4 +1,18 @@ /** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . * */ package com.cloud.network.guru; @@ -25,6 +39,7 @@ import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.TrafficType; import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.resource.Resource.ReservationStrategy; import com.cloud.user.Account; import com.cloud.utils.component.ComponentLocator; @@ -40,16 +55,26 @@ import com.cloud.vm.VirtualMachineProfile; public class ControlNetworkGuru extends PodBasedNetworkGuru implements NetworkGuru { private static final Logger s_logger = Logger.getLogger(ControlNetworkGuru.class); @Inject DataCenterDao _dcDao; + @Inject NetworkOfferingDao _networkOfferingDao; String _cidr; String _gateway; + + protected boolean canHandle(NetworkOffering offering) { + if (offering.isSystemOnly() && offering.getTrafficType() == TrafficType.Control) { + return true; + } else { + s_logger.trace("We only care about System only Control network"); + return false; + } + } @Override public Network design(NetworkOffering offering, DeploymentPlan plan, Network specifiedConfig, Account owner) { - if (offering.getTrafficType() != TrafficType.Control) { + if (!canHandle(offering)) { return null; } - NetworkVO config = new NetworkVO(offering.getTrafficType(), offering.getGuestIpType(), Mode.Static, BroadcastDomainType.LinkLocal, offering.getId(), plan.getDataCenterId()); + NetworkVO config = new NetworkVO(offering.getTrafficType(), null, Mode.Static, BroadcastDomainType.LinkLocal, offering.getId(), plan.getDataCenterId(), Network.State.Setup); config.setCidr(_cidr); config.setGateway(_gateway); @@ -64,8 +89,9 @@ public class ControlNetworkGuru extends PodBasedNetworkGuru implements NetworkGu public NicProfile allocate(Network config, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { - if (config.getTrafficType() != TrafficType.Control) { - return null; + NetworkOffering offering = _networkOfferingDao.findByIdIncludingRemoved(config.getNetworkOfferingId()); + if (!canHandle(offering)) { + return null; } if(vm.getHypervisorType() == HypervisorType.VmWare && vm.getType() != VirtualMachine.Type.DomainRouter) { diff --git a/server/src/com/cloud/network/guru/DirectNetworkGuru.java b/server/src/com/cloud/network/guru/DirectNetworkGuru.java index ec4bcc1ed59..d26426d524d 100644 --- a/server/src/com/cloud/network/guru/DirectNetworkGuru.java +++ b/server/src/com/cloud/network/guru/DirectNetworkGuru.java @@ -1,4 +1,18 @@ /** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . * */ package com.cloud.network.guru; @@ -8,7 +22,7 @@ import javax.ejb.Local; import org.apache.log4j.Logger; import com.cloud.dc.DataCenter; -import com.cloud.dc.DataCenterVO; +import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.Vlan.VlanType; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.VlanDao; @@ -31,6 +45,7 @@ import com.cloud.network.addr.PublicIp; import com.cloud.network.dao.IPAddressDao; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.GuestIpType; +import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.resource.Resource.ReservationStrategy; import com.cloud.user.Account; import com.cloud.utils.component.AdapterBase; @@ -48,16 +63,32 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru { @Inject VlanDao _vlanDao; @Inject NetworkManager _networkMgr; @Inject IPAddressDao _ipAddressDao; - + @Inject NetworkOfferingDao _networkOfferingDao; + + protected boolean canHandle(NetworkOffering offering, DataCenter dc) { + //this guru handles only non-system Public network + if (dc.getNetworkType() == NetworkType.Advanced && offering.getTrafficType() == TrafficType.Public && !offering.isSystemOnly()) { + return true; + } else { + s_logger.trace("We only take care of Public Direct networks"); + return false; + } + } + @Override public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) { - if (!(offering.getTrafficType() == TrafficType.Public && (offering.getGuestIpType() == GuestIpType.Direct || offering.getGuestIpType() == GuestIpType.DirectPodBased))) { - s_logger.trace("We only take care of public direct network, so this is no ours"); + DataCenter dc = _dcDao.findById(plan.getDataCenterId()); + + if (!canHandle(offering, dc)) { return null; } - NetworkVO config = new NetworkVO(offering.getTrafficType(), offering.getGuestIpType(), Mode.Dhcp, BroadcastDomainType.Vlan, offering.getId(), plan.getDataCenterId()); - DataCenterVO dc = _dcDao.findById(plan.getDataCenterId()); + State state = State.Allocated; + if (offering.isSystemOnly()) { + state = State.Setup; + } + + NetworkVO config = new NetworkVO(offering.getTrafficType(), GuestIpType.Direct, Mode.Dhcp, BroadcastDomainType.Vlan, offering.getId(), plan.getDataCenterId(), state); if (userSpecified != null) { if ((userSpecified.getCidr() == null && userSpecified.getGateway() != null) || @@ -92,10 +123,10 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru { protected void getIp(NicProfile nic, DataCenter dc, VirtualMachineProfile vm, Network network) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException { if (nic.getIp4Address() == null) { - PublicIp ip = _networkMgr.assignPublicIpAddress(dc.getId(), vm.getOwner(), VlanType.DirectAttached, network.getId()); + PublicIp ip = _networkMgr.assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.DirectAttached, network.getId()); nic.setIp4Address(ip.getAddress().toString()); nic.setGateway(ip.getGateway()); - nic.setNetmask(ip.getNetmask()); + nic.setNetmask(ip.getNetmask()); nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); nic.setBroadcastType(BroadcastDomainType.Vlan); nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag())); @@ -110,6 +141,12 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru { @Override public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException { + + DataCenter dc = _dcDao.findById(network.getDataCenterId()); + NetworkOffering offering = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId()); + if (!canHandle(offering, dc)) { + return null; + } if (nic == null) { nic = new NicProfile(ReservationStrategy.Create, null, null, null, null); @@ -119,7 +156,6 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru { nic.setStrategy(ReservationStrategy.Create); } - DataCenter dc = _dcDao.findById(network.getDataCenterId()); getIp(nic, dc, vm, network); return nic; diff --git a/server/src/com/cloud/network/guru/DirectPodBasedNetworkGuru.java b/server/src/com/cloud/network/guru/DirectPodBasedNetworkGuru.java new file mode 100644 index 00000000000..520bedfd155 --- /dev/null +++ b/server/src/com/cloud/network/guru/DirectPodBasedNetworkGuru.java @@ -0,0 +1,123 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +package com.cloud.network.guru; + +import java.net.URI; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.dc.DataCenter; +import com.cloud.dc.Pod; +import com.cloud.dc.Vlan; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.Vlan.VlanType; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.VlanDao; +import com.cloud.deploy.DeployDestination; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapcityException; +import com.cloud.network.Network; +import com.cloud.network.NetworkManager; +import com.cloud.network.Networks.AddressFormat; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.addr.PublicIp; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.resource.Resource.ReservationStrategy; +import com.cloud.utils.component.Inject; +import com.cloud.vm.NicProfile; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineProfile; + +@Local(value=NetworkGuru.class) +public class DirectPodBasedNetworkGuru extends DirectNetworkGuru{ +private static final Logger s_logger = Logger.getLogger(DirectPodBasedNetworkGuru.class); + + @Inject DataCenterDao _dcDao; + @Inject VlanDao _vlanDao; + @Inject NetworkManager _networkMgr; + @Inject IPAddressDao _ipAddressDao; + @Inject NetworkOfferingDao _networkOfferingDao; + + + protected boolean canHandle(NetworkOffering offering, DataCenter dc) { + //this guru handles system Direct pod based network + if (dc.getNetworkType() == NetworkType.Basic && offering.getTrafficType() == TrafficType.Guest && offering.isSystemOnly()) { + return true; + } else { + s_logger.trace("We only take care of Guest Direct Pod based networks"); + return false; + } + } + + @Override + public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapcityException, + InsufficientAddressCapacityException, ConcurrentOperationException { + + DataCenter dc = _dcDao.findById(network.getDataCenterId()); + NetworkOffering offering = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId()); + + if (!canHandle(offering, dc)) { + return null; + } + + if (nic == null) { + nic = new NicProfile(ReservationStrategy.Start, null, null, null, null); + } else { + nic.setStrategy(ReservationStrategy.Start); + } + + return nic; + } + + @Override + public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException { + if (nic.getIp4Address() == null) { + getIp(nic, dest.getPod(), vm, network); + } + } + + protected void getIp(NicProfile nic, Pod pod, VirtualMachineProfile vm, Network network) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException { + DataCenter dc = _dcDao.findById(pod.getDataCenterId()); + if (nic.getIp4Address() == null) { + PublicIp ip = _networkMgr.assignPublicIpAddress(dc.getId(), pod.getId(), vm.getOwner(), VlanType.DirectAttached, network.getId()); + nic.setIp4Address(ip.getAddress().toString()); + nic.setGateway(ip.getGateway()); + nic.setNetmask(ip.getNetmask()); + if(ip.getVlanTag() != null && ip.getVlanTag().equalsIgnoreCase(Vlan.UNTAGGED)) { + nic.setIsolationUri(URI.create("vlan://" + Vlan.UNTAGGED)); + nic.setBroadcastUri(URI.create("vlan://" + Vlan.UNTAGGED)); + nic.setBroadcastType(BroadcastDomainType.Native); + } + nic.setFormat(AddressFormat.Ip4); + nic.setReservationId(String.valueOf(ip.getVlanTag())); + nic.setMacAddress(ip.getMacAddress()); + } + nic.setDns1(dc.getDns1()); + nic.setDns2(dc.getDns2()); + } + +} diff --git a/server/src/com/cloud/network/guru/GuestNetworkGuru.java b/server/src/com/cloud/network/guru/GuestNetworkGuru.java index a44b97763a6..ffdeb6abc86 100644 --- a/server/src/com/cloud/network/guru/GuestNetworkGuru.java +++ b/server/src/com/cloud/network/guru/GuestNetworkGuru.java @@ -24,7 +24,10 @@ import java.util.TreeSet; import javax.ejb.Local; -import com.cloud.dc.DataCenterVO; +import org.apache.log4j.Logger; + +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.VlanDao; import com.cloud.deploy.DeployDestination; @@ -56,6 +59,7 @@ import com.cloud.vm.dao.NicDao; @Local(value=NetworkGuru.class) public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { + private static final Logger s_logger = Logger.getLogger(GuestNetworkGuru.class); @Inject protected NetworkManager _networkMgr; @Inject protected DataCenterDao _dcDao; @Inject protected VlanDao _vlanDao; @@ -69,25 +73,24 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { super(); } + protected boolean canHandle(NetworkOffering offering, DataCenter dc) { + //This guru handles only non-system Guest network + if (dc.getNetworkType() == NetworkType.Advanced && offering.getTrafficType() == TrafficType.Guest && !offering.isSystemOnly()) { + return true; + } else { + s_logger.trace("We only take care of Guest networks in zone of type " + NetworkType.Advanced); + return false; + } + } + @Override public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) { - if (offering.getTrafficType() != TrafficType.Guest || offering.getGuestIpType() != GuestIpType.Virtual) { + DataCenter dc = _dcDao.findById(plan.getDataCenterId()); + if (!canHandle(offering, dc)) { return null; } - - BroadcastDomainType broadcastType = null; - Mode mode = null; - GuestIpType ipType = offering.getGuestIpType(); - if (ipType == GuestIpType.Virtual) { - mode = Mode.Dhcp; - broadcastType = BroadcastDomainType.Vlan; - } else { - broadcastType = BroadcastDomainType.Native; - mode = Mode.Dhcp; - } - DataCenterVO dc = _dcDao.findById(plan.getDataCenterId()); - - NetworkVO network = new NetworkVO(offering.getTrafficType(), offering.getGuestIpType(), mode, broadcastType, offering.getId(), plan.getDataCenterId()); + + NetworkVO network = new NetworkVO(offering.getTrafficType(), GuestIpType.Virtual, Mode.Dhcp, BroadcastDomainType.Vlan, offering.getId(), plan.getDataCenterId(), State.Allocated); if (userSpecified != null) { if ((userSpecified.getCidr() == null && userSpecified.getGateway() != null) || (userSpecified.getCidr() != null && userSpecified.getGateway() == null)) { @@ -135,7 +138,9 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { assert (network.getState() == State.Implementing) : "Why are we implementing " + network; long dcId = dest.getDataCenter().getId(); - NetworkVO implemented = new NetworkVO(network.getTrafficType(), network.getGuestType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), network.getDataCenterId()); + + + NetworkVO implemented = new NetworkVO(network.getTrafficType(), network.getGuestType(), network.getMode(), network.getBroadcastDomainType(), network.getNetworkOfferingId(), network.getDataCenterId(), State.Allocated); if (network.getBroadcastUri() == null) { String vnet = _dcDao.allocateVnet(dcId, network.getAccountId(), context.getReservationId()); diff --git a/server/src/com/cloud/network/guru/PodBasedNetworkGuru.java b/server/src/com/cloud/network/guru/PodBasedNetworkGuru.java index 126c5df3aab..2fb0229bd23 100644 --- a/server/src/com/cloud/network/guru/PodBasedNetworkGuru.java +++ b/server/src/com/cloud/network/guru/PodBasedNetworkGuru.java @@ -50,7 +50,7 @@ public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru { return null; } - NetworkVO config = new NetworkVO(type, offering.getGuestIpType(), Mode.Static, BroadcastDomainType.Native, offering.getId(), plan.getDataCenterId()); + NetworkVO config = new NetworkVO(type, null, Mode.Static, BroadcastDomainType.Native, offering.getId(), plan.getDataCenterId(), Network.State.Setup); DataCenterVO dc = _dcDao.findById(plan.getDataCenterId()); config.setDns1(dc.getDns1()); config.setDns2(dc.getDns2()); diff --git a/server/src/com/cloud/network/guru/PublicNetworkGuru.java b/server/src/com/cloud/network/guru/PublicNetworkGuru.java index 17bf1d50a0d..7c45f8b066b 100644 --- a/server/src/com/cloud/network/guru/PublicNetworkGuru.java +++ b/server/src/com/cloud/network/guru/PublicNetworkGuru.java @@ -3,15 +3,12 @@ */ package com.cloud.network.guru; -import java.net.URI; - import javax.ejb.Local; import org.apache.log4j.Logger; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; -import com.cloud.dc.DataCenterVO; import com.cloud.dc.Vlan.VlanType; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.VlanDao; @@ -23,6 +20,7 @@ import com.cloud.exception.InsufficientVirtualNetworkCapcityException; import com.cloud.network.Network; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; +import com.cloud.network.Network.State; import com.cloud.network.Networks.AddressFormat; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.IsolationType; @@ -31,7 +29,7 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; import com.cloud.network.dao.IPAddressDao; import com.cloud.offering.NetworkOffering; -import com.cloud.offering.NetworkOffering.GuestIpType; +import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.resource.Resource.ReservationStrategy; import com.cloud.user.Account; import com.cloud.utils.component.AdapterBase; @@ -50,19 +48,28 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { @Inject VlanDao _vlanDao; @Inject NetworkManager _networkMgr; @Inject IPAddressDao _ipAddressDao; + @Inject NetworkOfferingDao _networkOfferingDao; + protected boolean canHandle(NetworkOffering offering, DataCenter dc) { + if (dc.getNetworkType() == NetworkType.Advanced && offering.getTrafficType() == TrafficType.Public && offering.isSystemOnly()) { + return true; + } else { + s_logger.trace("We only take care of System only Public Virtual Network"); + return false; + } + } @Override public Network design(NetworkOffering offering, DeploymentPlan plan, Network network, Account owner) { - if (offering.getTrafficType() != TrafficType.Public || (offering.getGuestIpType() != null && offering.getGuestIpType() != GuestIpType.Virtual)) { - s_logger.trace("We only take care of Public Virtual Network"); + DataCenter dc = _dcDao.findById(plan.getDataCenterId()); + + if (!canHandle(offering, dc)) { return null; } if (offering.getTrafficType() == TrafficType.Public) { - NetworkVO ntwk = new NetworkVO(offering.getTrafficType(), offering.getGuestIpType(), Mode.Static, BroadcastDomainType.Vlan, offering.getId(), plan.getDataCenterId()); - DataCenterVO dc = _dcDao.findById(plan.getDataCenterId()); + NetworkVO ntwk = new NetworkVO(offering.getTrafficType(), null, Mode.Static, BroadcastDomainType.Vlan, offering.getId(), plan.getDataCenterId(), State.Setup); ntwk.setDns1(dc.getDns1()); ntwk.setDns2(dc.getDns2()); return ntwk; @@ -77,20 +84,13 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { protected void getIp(NicProfile nic, DataCenter dc, VirtualMachineProfile vm, Network network) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException { if (nic.getIp4Address() == null) { - PublicIp ip = _networkMgr.assignPublicIpAddress(dc.getId(), vm.getOwner(), dc.getNetworkType().equals(NetworkType.Basic) ? VlanType.DirectAttached : VlanType.VirtualNetwork, null); + PublicIp ip = _networkMgr.assignPublicIpAddress(dc.getId(), null, vm.getOwner(), VlanType.VirtualNetwork, null); nic.setIp4Address(ip.getAddress().toString()); nic.setGateway(ip.getGateway()); - nic.setNetmask(ip.getNetmask()); - if(ip.getVlanTag() != null && ip.getVlanTag().equalsIgnoreCase("untagged")) { - nic.setIsolationUri(URI.create("vlan://untagged")); - nic.setBroadcastUri(URI.create("vlan://untagged")); - nic.setBroadcastType(BroadcastDomainType.Native); - } else if (ip.getVlanTag() != null){ - nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); - nic.setBroadcastUri(IsolationType.Vlan.toUri(ip.getVlanTag())); - nic.setBroadcastType(BroadcastDomainType.Vlan); - } - + nic.setNetmask(ip.getNetmask()); + nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); + nic.setBroadcastUri(IsolationType.Vlan.toUri(ip.getVlanTag())); + nic.setBroadcastType(BroadcastDomainType.Vlan); nic.setFormat(AddressFormat.Ip4); nic.setReservationId(String.valueOf(ip.getVlanTag())); nic.setMacAddress(ip.getMacAddress()); @@ -102,7 +102,10 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { @Override public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException { - if (network.getTrafficType() != TrafficType.Public) { + + DataCenter dc = _dcDao.findById(network.getDataCenterId()); + NetworkOffering offering = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId()); + if (!canHandle(offering, dc)) { return null; } @@ -110,7 +113,6 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { nic = new NicProfile(ReservationStrategy.Create, null, null, null, null); } - DataCenter dc = _dcDao.findById(network.getDataCenterId()); getIp(nic, dc, vm, network); if (nic.getIp4Address() == null) { diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index 255d0fcd1eb..459f7710f07 100644 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -1329,18 +1329,17 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager, return _lbDao.search(sc, searchFilter); } - -// @Override -// public LoadBalancerVO findLoadBalancer(Long accountId, String name) { -// SearchCriteria sc = _loadBalancerDao.createSearchCriteria(); -// sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId); -// sc.addAnd("name", SearchCriteria.Op.EQ, name); -// List loadBalancers = _loadBalancerDao.search(sc, null); -// if ((loadBalancers != null) && !loadBalancers.isEmpty()) { -// return loadBalancers.get(0); -// } -// return null; -// } - + + @Override + public List listByNetworkId(long networkId) { + List lbs = _lbDao.listByNetworkId(networkId); + List lbRules = new ArrayList(); + for (LoadBalancerVO lb : lbs) { + List dstList = getExistingDestinations(lb.getId()); + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList); + lbRules.add(loadBalancing); + } + return lbRules; + } } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 615adc0bd56..f059f412a6a 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -72,8 +72,10 @@ import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ResourceLimitDao; import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; +import com.cloud.dc.Vlan; import com.cloud.dc.dao.AccountVlanMapDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.HostPodDao; @@ -1022,12 +1024,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian PublicIp sourceNatIp = _networkMgr.assignSourceNatIpAddress(owner, guestNetwork, _accountService.getSystemUser().getId()); - List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmControlNetwork); + List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork); NetworkOfferingVO controlOffering = offerings.get(0); NetworkVO controlConfig = _networkMgr.setupNetwork(_systemAcct, controlOffering, plan, null, null, false).get(0); List> networks = new ArrayList>(3); - NetworkOfferingVO publicOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmPublicNetwork).get(0); + NetworkOfferingVO publicOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemPublicNetwork).get(0); List publicConfigs = _networkMgr.setupNetwork(_systemAcct, publicOffering, plan, null, null, false); NicProfile defaultNic = new NicProfile(); defaultNic.setDefaultNic(true); @@ -1036,7 +1038,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian defaultNic.setNetmask(sourceNatIp.getNetmask()); defaultNic.setTrafficType(TrafficType.Public); defaultNic.setMacAddress(sourceNatIp.getMacAddress()); - if (sourceNatIp.getVlanTag().equals("untagged")) { + if (sourceNatIp.getVlanTag().equals(Vlan.UNTAGGED)) { defaultNic.setBroadcastType(BroadcastDomainType.Native); } else { defaultNic.setBroadcastType(BroadcastDomainType.Vlan); @@ -1053,9 +1055,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian gatewayNic.setMode(guestNetwork.getMode()); String gatewayCidr = guestNetwork.getCidr(); - String[] cidrPair = gatewayCidr.split("\\/"); - long guestCidrSize = Long.parseLong(cidrPair[1]); - gatewayNic.setNetmask(NetUtils.getCidrNetmask(guestCidrSize)); + gatewayNic.setNetmask(NetUtils.getCidrNetmask(gatewayCidr)); networks.add(new Pair((NetworkVO) guestNetwork, gatewayNic)); networks.add(new Pair(controlConfig, null)); @@ -1096,8 +1096,17 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian + guestNetwork; DataCenterDeployment plan = new DataCenterDeployment(dcId); - - DomainRouterVO router = _routerDao.findByNetworkConfiguration(guestNetwork.getId()); + DataCenter dc = _dcDao.findById(dcId); + DomainRouterVO router = null; + Long podId = dest.getPod().getId(); + + //In Basic zone and Guest network we have to start domR per pod, not per network + if (dc.getNetworkType() == NetworkType.Basic && guestNetwork.getTrafficType() == TrafficType.Guest) { + router = _routerDao.findByNetworkConfigurationAndPod(guestNetwork.getId(), podId); + } else { + router = _routerDao.findByNetworkConfiguration(guestNetwork.getId()); + } + if (router == null) { long startEventId = EventUtils.saveStartedEvent(User.UID_SYSTEM, owner.getId(), EventTypes.EVENT_ROUTER_CREATE, "Starting to create router for accountId : " +owner.getAccountId()); long id = _routerDao.getNextInSequence(Long.class, "id"); @@ -1105,7 +1114,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian s_logger.debug("Creating the router " + id); } - List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmControlNetwork); + List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork); NetworkOfferingVO controlOffering = offerings.get(0); NetworkVO controlConfig = _networkMgr.setupNetwork(_systemAcct, controlOffering, plan, null, null, false).get(0); @@ -1147,12 +1156,13 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian String type = null; String dhcpRange = null; - // get first ip address from network cidr - String cidr = network.getCidr(); - String[] splitResult = cidr.split("\\/"); - long size = Long.valueOf(splitResult[1]); - dhcpRange = NetUtils.getIpRangeStartIpFromCidr(splitResult[0], size); - + DataCenter dc = dest.getDataCenter(); + + if (dc.getNetworkType() == NetworkType.Advanced) { + String cidr = network.getCidr(); + dhcpRange = NetUtils.getDhcpRange(cidr); + } + String domain = network.getNetworkDomain(); if (router.getRole() == Role.DHCP_USERDATA) { type = "dhcpsrvr"; @@ -1176,6 +1186,13 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian if (nic.getDns2() != null) { buf.append(" dns2=").append(nic.getDns2()); } + if (dc.getNetworkType() == NetworkType.Basic) { + long cidrSize = NetUtils.getCidrSize(nic.getNetmask()); + String cidr = NetUtils.getCidrSubNet(nic.getGateway(), cidrSize); + if (cidr != null) { + dhcpRange = NetUtils.getIpRangeStartIpFromCidr(cidr, cidrSize); + } + } } if (nic.getTrafficType() == TrafficType.Management) { buf.append(" localgw=").append(dest.getPod().getGateway()); diff --git a/server/src/com/cloud/offerings/NetworkOfferingVO.java b/server/src/com/cloud/offerings/NetworkOfferingVO.java index b8e4872579d..a31decb0165 100644 --- a/server/src/com/cloud/offerings/NetworkOfferingVO.java +++ b/server/src/com/cloud/offerings/NetworkOfferingVO.java @@ -28,7 +28,6 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; -import com.cloud.network.Networks.Availability; import com.cloud.network.Networks.TrafficType; import com.cloud.offering.NetworkOffering; import com.cloud.service.ServiceOfferingVO; @@ -37,11 +36,7 @@ import com.cloud.utils.db.GenericDao; @Entity @Table(name="network_offerings") public class NetworkOfferingVO implements NetworkOffering { - public final static String SystemVmPublicNetwork = "System-Public-Network"; - public final static String SystemVmControlNetwork = "System-Control-Network"; - public final static String SystemVmManagementNetwork = "System-Management-Network"; - public final static String SystemVmStorageNetwork = "System-Storage-Network"; - + @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") @@ -62,10 +57,6 @@ public class NetworkOfferingVO implements NetworkOffering { @Column(name="concurrent_connections") Integer concurrentConnections; - @Column(name="type") - @Enumerated(value=EnumType.STRING) - GuestIpType guestIpType; - @Column(name="traffic_type") @Enumerated(value=EnumType.STRING) TrafficType trafficType; @@ -121,11 +112,6 @@ public class NetworkOfferingVO implements NetworkOffering { return displayText; } - @Override - public GuestIpType getGuestIpType() { - return guestIpType; - } - @Override public long getId() { return id; @@ -200,10 +186,6 @@ public class NetworkOfferingVO implements NetworkOffering { this.concurrentConnections = concurrentConnections; } - public void setGuestIpType(GuestIpType guestIpType) { - this.guestIpType = guestIpType; - } - public void setTrafficType(TrafficType trafficType) { this.trafficType = trafficType; } @@ -311,10 +293,9 @@ public class NetworkOfferingVO implements NetworkOffering { this.dhcpService = dhcpService; } - public NetworkOfferingVO(String name, String displayText, TrafficType trafficType, GuestIpType type, boolean systemOnly, boolean specifyVlan, Integer rateMbps, Integer multicastRateMbps, Integer concurrentConnections, boolean isDefault, Availability availability, boolean lbService, boolean gatewayService, boolean dhcpService, boolean firewallService, boolean dnsService, boolean userDataService, boolean vpnService) { + public NetworkOfferingVO(String name, String displayText, TrafficType trafficType, boolean systemOnly, boolean specifyVlan, Integer rateMbps, Integer multicastRateMbps, Integer concurrentConnections, boolean isDefault, Availability availability, boolean lbService, boolean gatewayService, boolean dhcpService, boolean firewallService, boolean dnsService, boolean userDataService, boolean vpnService) { this.name = name; this.displayText = displayText; - this.guestIpType = type; this.rateMbps = rateMbps; this.multicastRateMbps = multicastRateMbps; this.concurrentConnections = concurrentConnections; @@ -333,7 +314,7 @@ public class NetworkOfferingVO implements NetworkOffering { } public NetworkOfferingVO(ServiceOfferingVO offering) { - this("Network Offering for " + offering.getName(), "Network Offering for " + offering.getDisplayText(), TrafficType.Guest, offering.getGuestIpType(), false, false, offering.getRateMbps(), offering.getMulticastRateMbps(), null, false, Availability.Required, false, false, false, false, false, false, false); + this("Network Offering for " + offering.getName(), "Network Offering for " + offering.getDisplayText(), TrafficType.Guest, false, false, offering.getRateMbps(), offering.getMulticastRateMbps(), null, false, Availability.Required, false, false, false, false, false, false, false); this.serviceOfferingId = offering.getId(); } @@ -345,12 +326,12 @@ public class NetworkOfferingVO implements NetworkOffering { * @param type */ public NetworkOfferingVO(String name, TrafficType trafficType, GuestIpType type) { - this(name, "System Offering for " + name, trafficType, type, true, false, null, null, null, false, Availability.Required, false, false, false, false, false, false, false); + this(name, "System Offering for " + name, trafficType, true, false, null, null, null, false, Availability.Required, false, false, false, false, false, false, false); } @Override public String toString() { StringBuilder buf = new StringBuilder("[Network Offering ["); - return buf.append(id).append("-").append(trafficType).append("-").append(name).append("-").append(guestIpType).append("]").toString(); + return buf.append(id).append("-").append(trafficType).append("-").append(name).append("]").toString(); } } diff --git a/server/src/com/cloud/offerings/dao/NetworkOfferingDao.java b/server/src/com/cloud/offerings/dao/NetworkOfferingDao.java index c7bc7188910..245f6e41bac 100644 --- a/server/src/com/cloud/offerings/dao/NetworkOfferingDao.java +++ b/server/src/com/cloud/offerings/dao/NetworkOfferingDao.java @@ -5,9 +5,7 @@ package com.cloud.offerings.dao; import java.util.List; -import com.cloud.offering.NetworkOffering.GuestIpType; import com.cloud.offerings.NetworkOfferingVO; -import com.cloud.service.ServiceOfferingVO; import com.cloud.utils.db.GenericDao; /** @@ -33,11 +31,8 @@ public interface NetworkOfferingDao extends GenericDao */ NetworkOfferingVO persistDefaultNetworkOffering(NetworkOfferingVO offering); - NetworkOfferingVO findByServiceOffering(ServiceOfferingVO offering); - List listNonSystemNetworkOfferings(); List listSystemNetworkOfferings(); - List findByType(GuestIpType type); } diff --git a/server/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java b/server/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java index 505e2742b19..63bbaaa630c 100644 --- a/server/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java +++ b/server/src/com/cloud/offerings/dao/NetworkOfferingDaoImpl.java @@ -11,14 +11,11 @@ import javax.persistence.EntityExistsException; import org.apache.log4j.Logger; -import com.cloud.offering.NetworkOffering.GuestIpType; import com.cloud.offerings.NetworkOfferingVO; -import com.cloud.service.ServiceOfferingVO; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.exception.CloudRuntimeException; @Local(value=NetworkOfferingDao.class) @DB(txn=false) public class NetworkOfferingDaoImpl extends GenericDaoBase implements NetworkOfferingDao { @@ -26,9 +23,7 @@ public class NetworkOfferingDaoImpl extends GenericDaoBase NameSearch; - final SearchBuilder ServiceOfferingSearch; final SearchBuilder SystemOfferingSearch; - final SearchBuilder TypeSearch; protected NetworkOfferingDaoImpl() { super(); @@ -37,14 +32,6 @@ public class NetworkOfferingDaoImpl extends GenericDaoBase sc = ServiceOfferingSearch.create(); - sc.setParameters("serviceoffering", offering.getGuestIpType()); - - NetworkOfferingVO vo = findOneBy(sc); - if (vo != null) { - return vo; - } - - vo = new NetworkOfferingVO(offering); - try { - return persist(vo); - } catch (Exception e) { - s_logger.debug("Got a persistence exception. Assuming it's because service offering id is duplicate"); - vo = findOneBy(sc); - if (vo != null) { - return vo; - } - - throw new CloudRuntimeException("Unable to persist network offering", e); - } - } - @Override public List listNonSystemNetworkOfferings() { SearchCriteria sc = SystemOfferingSearch.create(); @@ -107,13 +70,6 @@ public class NetworkOfferingDaoImpl extends GenericDaoBase findByType(GuestIpType type) { - SearchCriteria sc = TypeSearch.create(); - sc.setParameters("guestIpType", type); - return listBy(sc); - } - @Override public List listSystemNetworkOfferings() { SearchCriteria sc = SystemOfferingSearch.create(); diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index d51d3459629..dcce0270332 100644 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -47,7 +47,6 @@ import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; -import com.cloud.dc.Vlan.VlanType; import com.cloud.dc.VlanVO; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.HostPodDao; @@ -59,13 +58,12 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Network.State; import com.cloud.network.NetworkVO; -import com.cloud.network.Networks.Availability; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.TrafficType; import com.cloud.network.dao.NetworkDao; import com.cloud.offering.NetworkOffering; -import com.cloud.offering.NetworkOffering.GuestIpType; +import com.cloud.offering.NetworkOffering.Availability; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.service.ServiceOfferingVO; @@ -694,20 +692,21 @@ public class ConfigurationServerImpl implements ConfigurationServer { Integer rateMbps = getIntegerConfigValue(Config.NetworkThrottlingRate.key(), null); Integer multicastRateMbps = getIntegerConfigValue(Config.MulticastThrottlingRate.key(), null); - NetworkOfferingVO publicNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemVmPublicNetwork, TrafficType.Public, null); + NetworkOfferingVO publicNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemPublicNetwork, TrafficType.Public, null); publicNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(publicNetworkOffering); - NetworkOfferingVO managementNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemVmManagementNetwork, TrafficType.Management, null); + NetworkOfferingVO managementNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemManagementNetwork, TrafficType.Management, null); managementNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(managementNetworkOffering); - NetworkOfferingVO controlNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemVmControlNetwork, TrafficType.Control, null); + NetworkOfferingVO controlNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemControlNetwork, TrafficType.Control, null); controlNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(controlNetworkOffering); - NetworkOfferingVO storageNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemVmStorageNetwork, TrafficType.Storage, null); + NetworkOfferingVO storageNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SystemStorageNetwork, TrafficType.Storage, null); storageNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(storageNetworkOffering); - NetworkOfferingVO defaultGuestNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultVirtualizedNetworkOffering, "Virtual Vlan", TrafficType.Guest, GuestIpType.Virtual, false, false, rateMbps, multicastRateMbps, null, true, Availability.Required, false, false, false, false, false, false, false); + NetworkOfferingVO guestNetworkOffering = new NetworkOfferingVO(NetworkOfferingVO.SysteGuestNetwork, TrafficType.Guest, null); + guestNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(guestNetworkOffering); + + NetworkOfferingVO defaultGuestNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultVirtualizedNetworkOffering, "Virtual Vlan", TrafficType.Guest, false, false, rateMbps, multicastRateMbps, null, true, Availability.Required, false, false, false, false, false, false, false); defaultGuestNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultGuestNetworkOffering); - NetworkOfferingVO defaultGuestDirectNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultDirectNetworkOffering, "Direct", TrafficType.Public, GuestIpType.Direct, false, false, rateMbps, multicastRateMbps, null, true, Availability.Required, false, false, false, false, false, false, false); + NetworkOfferingVO defaultGuestDirectNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultDirectNetworkOffering, "Direct", TrafficType.Public, false, false, rateMbps, multicastRateMbps, null, true, Availability.Required, false, false, false, false, false, false, false); defaultGuestNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultGuestDirectNetworkOffering); - NetworkOfferingVO defaultGuestDirectPodBasedNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultDirectPodBasedNetworkOffering, "DirectPodBased", TrafficType.Public, GuestIpType.DirectPodBased, true, false, rateMbps, multicastRateMbps, null, true, Availability.Required, false, false, false, false, false, false, false); - defaultGuestNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultGuestDirectPodBasedNetworkOffering); } private Integer getIntegerConfigValue(String configKey, Integer dflt) { @@ -727,6 +726,8 @@ public class ConfigurationServerImpl implements ConfigurationServer { guruNames.put(TrafficType.Management, "PodBasedNetworkGuru-com.cloud.network.guru.PodBasedNetworkGuru"); guruNames.put(TrafficType.Control, "ControlNetworkGuru-com.cloud.network.guru.ControlNetworkGuru"); guruNames.put(TrafficType.Storage, "PodBasedNetworkGuru-com.cloud.network.guru.PodBasedNetworkGuru"); + guruNames.put(TrafficType.Guest, "DirectPodBasedNetworkGuru-com.cloud.network.guru.DirectPodBasedNetworkGuru"); + for (DataCenterVO zone : zones) { long zoneId = zone.getId(); @@ -747,24 +748,27 @@ public class ConfigurationServerImpl implements ConfigurationServer { BroadcastDomainType broadcastDomainType = null; TrafficType trafficType= offering.getTrafficType(); - GuestIpType guestIpType = offering.getGuestIpType(); if (trafficType == TrafficType.Management || trafficType == TrafficType.Storage) { broadcastDomainType = BroadcastDomainType.Native; } else if (trafficType == TrafficType.Control) { broadcastDomainType = BroadcastDomainType.LinkLocal; - } else if (offering.getTrafficType() == TrafficType.Public) { - if (zone.getNetworkType() == NetworkType.Basic && offering.getGuestIpType() == GuestIpType.DirectPodBased) { - broadcastDomainType = BroadcastDomainType.Native; - } else if (zone.getNetworkType() == NetworkType.Advanced && offering.getGuestIpType() == null) { + } else if (offering.getTrafficType() == TrafficType.Public) { + if (zone.getNetworkType() == NetworkType.Advanced) { broadcastDomainType = BroadcastDomainType.Vlan; } else { continue; } - } + } else if (offering.getTrafficType() == TrafficType.Guest) { + if (zone.getNetworkType() == NetworkType.Basic) { + broadcastDomainType = BroadcastDomainType.Native; + } else { + continue; + } + } if (broadcastDomainType != null) { - NetworkVO network = new NetworkVO(id, trafficType, guestIpType, mode, broadcastDomainType, networkOfferingId, zoneId, domainId, accountId, related, null, null, true); + NetworkVO network = new NetworkVO(id, trafficType, null, mode, broadcastDomainType, networkOfferingId, zoneId, domainId, accountId, related, null, null, true); network.setGuruName(guruNames.get(network.getTrafficType())); network.setDns1(zone.getDns1()); network.setDns2(zone.getDns2()); @@ -781,33 +785,35 @@ public class ConfigurationServerImpl implements ConfigurationServer { private void updateVlanWithNetworkId(VlanVO vlan) { long zoneId = vlan.getDataCenterId(); long networkId = 0L; - if (vlan.getVlanType() == VlanType.VirtualNetwork) { - networkId = getSystemNetworkIdByZoneAndTrafficTypeAndGuestType(zoneId, TrafficType.Public, null); - } else if (vlan.getVlanType() == VlanType.DirectAttached) { - networkId = getSystemNetworkIdByZoneAndTrafficTypeAndGuestType(zoneId, TrafficType.Public, GuestIpType.DirectPodBased); + DataCenterVO zone = _zoneDao.findById(zoneId); + + if (zone.getNetworkType() == NetworkType.Advanced) { + networkId = getSystemNetworkIdByZoneAndTrafficType(zoneId, TrafficType.Public); + } else { + networkId = getSystemNetworkIdByZoneAndTrafficType(zoneId, TrafficType.Guest); } - + vlan.setNetworkId(networkId); _vlanDao.update(vlan.getId(), vlan); } - private long getSystemNetworkIdByZoneAndTrafficTypeAndGuestType(long zoneId, TrafficType trafficType, GuestIpType guestType) { + private long getSystemNetworkIdByZoneAndTrafficType(long zoneId, TrafficType trafficType) { //find system public network offering Long networkOfferingId = null; List offerings = _networkOfferingDao.listSystemNetworkOfferings(); for (NetworkOfferingVO offering: offerings) { - if (offering.getTrafficType() == trafficType && offering.getGuestIpType() == guestType) { + if (offering.getTrafficType() == trafficType) { networkOfferingId = offering.getId(); break; } } if (networkOfferingId == null) { - throw new InvalidParameterValueException("Unable to find system network offering with traffic type " + trafficType + " and guestIpType " + guestType); + throw new InvalidParameterValueException("Unable to find system network offering with traffic type " + trafficType); } List networks = _networkDao.listBy(Account.ACCOUNT_ID_SYSTEM, networkOfferingId, zoneId); - if (networks == null) { + if (networks == null || networks.isEmpty()) { throw new InvalidParameterValueException("Unable to find network with traffic type " + trafficType + " in zone " + zoneId); } return networks.get(0).getId(); diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index 6af5602f90d..4b47bb2df79 100644 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -56,6 +56,8 @@ import com.cloud.async.BaseAsyncJobExecutor; import com.cloud.cluster.ClusterManager; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; import com.cloud.dc.dao.DataCenterDao; @@ -440,9 +442,14 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V Account systemAcct = _accountMgr.getSystemAccount(); DataCenterDeployment plan = new DataCenterDeployment(dataCenterId); + DataCenter dc = _dcDao.findById(plan.getDataCenterId()); - List defaultOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmPublicNetwork); - List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmControlNetwork, NetworkOfferingVO.SystemVmManagementNetwork); + List defaultOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemPublicNetwork); + if (dc.getNetworkType() == NetworkType.Basic) { + defaultOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SysteGuestNetwork); + } + + List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork, NetworkOfferingVO.SystemManagementNetwork); List> networks = new ArrayList>(offerings.size() + 1); NicProfile defaultNic = new NicProfile(); defaultNic.setDefaultNic(true); @@ -1504,10 +1511,11 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V cmds.addCommand("checkSsh", check); SecondaryStorageVmVO secVm = profile.getVirtualMachine(); - List nics = _nicDao.listBy(secVm.getId()); + DataCenter dc = dest.getDataCenter(); + List nics = _nicDao.listBy(secVm.getId()); for (NicVO nic : nics) { NetworkVO network = _networkDao.findById(nic.getNetworkId()); - if (network.getTrafficType() == TrafficType.Public) { + if ((network.getTrafficType() == TrafficType.Public && dc.getNetworkType() == NetworkType.Advanced) || (network.getTrafficType() == TrafficType.Guest && dc.getNetworkType() == NetworkType.Basic)) { secVm.setPublicIpAddress(nic.getIp4Address()); secVm.setPublicNetmask(nic.getNetmask()); secVm.setPublicMacAddress(nic.getMacAddress()); diff --git a/server/src/com/cloud/user/AccountManager.java b/server/src/com/cloud/user/AccountManager.java index b24428a1f29..5b2b8da31c7 100755 --- a/server/src/com/cloud/user/AccountManager.java +++ b/server/src/com/cloud/user/AccountManager.java @@ -98,8 +98,6 @@ public interface AccountManager extends AccountService { List searchForLimits(Criteria c); - - /** * Disables an account by accountId * @param accountId diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index d952e9a1a49..f8dfe283141 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -74,7 +74,6 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.IPAddressVO; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; -import com.cloud.network.VirtualNetworkApplianceService; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.router.VirtualNetworkApplianceManager; @@ -674,7 +673,8 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag return _systemAccount; } - public static boolean isAdmin(short accountType) { + @Override + public boolean isAdmin(short accountType) { return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN)); @@ -1576,4 +1576,49 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } } } + + public Account finalizeOwner(Account caller, String accountName, Long domainId) { + if (isAdmin(caller.getType())) { + if (domainId != null) { + DomainVO domain = _domainDao.findById(domainId); + if (domain == null) { + throw new InvalidParameterValueException("Unable to find the domain by id=" + domainId); + } + + if (accountName != null) { + Account owner = _accountDao.findActiveAccount(accountName, domainId); + if (owner == null) { + throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); + } + checkAccess(caller, domain); + return owner; + } else { + throw new InvalidParameterValueException("Account have to be specified along with domainId"); + } + } else { + return caller; + } + } else { + //regular user can't create resources for other people + return caller; + } + } + + @Override + public Account getActiveAccount(String accountName, Long domainId) { + if (accountName == null || domainId == null) { + throw new InvalidParameterValueException("Both accountName and domainId are required for finding active account in the system"); + } else { + return _accountDao.findActiveAccount(accountName, domainId); + } + } + + @Override + public Account getAccount(Long accountId) { + if (accountId == null) { + throw new InvalidParameterValueException("AccountId is required by account search"); + } else { + return _accountDao.findById(accountId); + } + } } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 7afa42ecdb2..bc064d9269f 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -2239,9 +2239,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager s_logger.debug("Allocating in the DB for vm"); if (dc.getNetworkType() == NetworkType.Basic && networkList == null) { - Network defaultNetwork = _networkMgr.getBasicZoneDefaultPublicNetwork(dc.getId()); + Network defaultNetwork = _networkMgr.getSystemNetworkByZoneAndTrafficType(dc.getId(), TrafficType.Guest); if (defaultNetwork == null) { - throw new InvalidParameterValueException("Unable to find a default directPodBased network to start a vm"); + throw new InvalidParameterValueException("Unable to find a default Direct network to start a vm"); } else { networkList = new ArrayList(); networkList.add(defaultNetwork.getId()); diff --git a/server/src/com/cloud/vm/dao/DomainRouterDao.java b/server/src/com/cloud/vm/dao/DomainRouterDao.java index 3b0e1ff16c9..94ed2bce5f3 100755 --- a/server/src/com/cloud/vm/dao/DomainRouterDao.java +++ b/server/src/com/cloud/vm/dao/DomainRouterDao.java @@ -122,4 +122,6 @@ public interface DomainRouterDao extends GenericDao, State DomainRouterVO findByNetworkConfiguration(long networkConfigurationId); DomainRouterVO findByNetworkConfigurationIncludingRemoved(long networkConfigurationId); + + DomainRouterVO findByNetworkConfigurationAndPod(long networkConfigurationId, long podId); } diff --git a/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java b/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java index deac41ce05d..4dd2aa65f74 100755 --- a/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java +++ b/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java @@ -126,6 +126,8 @@ public class DomainRouterDaoImpl extends GenericDaoBase im NetworkConfigSearch = createSearchBuilder(); NetworkConfigSearch.and("network", NetworkConfigSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); + NetworkConfigSearch.and("podId", NetworkConfigSearch.entity().getPodId(), SearchCriteria.Op.EQ); + NetworkConfigSearch.done(); _updateTimeAttr = _allAttributes.get("updateTime"); assert _updateTimeAttr != null : "Couldn't get this updateTime attribute"; @@ -366,4 +368,11 @@ public class DomainRouterDaoImpl extends GenericDaoBase im sc.setParameters("state", State.Stopped); return listBy(sc); } + @Override + public DomainRouterVO findByNetworkConfigurationAndPod(long networkConfigurationId, long podId) { + SearchCriteria sc = NetworkConfigSearch.create(); + sc.setParameters("network", networkConfigurationId); + sc.setParameters("podId", podId); + return findOneBy(sc); + } } diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index c310221e626..253dee46224 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -200,7 +200,6 @@ CREATE TABLE `cloud`.`nics` ( CREATE TABLE `cloud`.`network_offerings` ( `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', `name` varchar(64) NOT NULL unique COMMENT 'network offering', - `type` varchar(32) COMMENT 'type of network', `display_text` varchar(255) NOT NULL COMMENT 'text to display to users', `nw_rate` smallint unsigned COMMENT 'network rate throttle mbits/s', `mc_rate` smallint unsigned COMMENT 'mcast rate throttle mbits/s', diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java index 4646f42cd36..45a60552291 100755 --- a/utils/src/com/cloud/utils/net/NetUtils.java +++ b/utils/src/com/cloud/utils/net/NetUtils.java @@ -691,6 +691,12 @@ public class NetUtils { return long2Ip(numericNetmask); } + public static String getCidrNetmask(String cidr) { + String[] cidrPair = cidr.split("\\/"); + long guestCidrSize = Long.parseLong(cidrPair[1]); + return getCidrNetmask(guestCidrSize); + } + public static String cidr2Netmask(String cidr) { String[] tokens = cidr.split("\\/"); return getCidrNetmask(Integer.parseInt(tokens[1])); @@ -879,6 +885,12 @@ public class NetUtils { return result; } + + public static String getDhcpRange(String cidr) { + String[] splitResult = cidr.split("\\/"); + long size = Long.valueOf(splitResult[1]); + return NetUtils.getIpRangeStartIpFromCidr(splitResult[0], size); + } } From 4ec3bc5865e94a2005bfbde7b9e44b02adf1236e Mon Sep 17 00:00:00 2001 From: alena Date: Thu, 6 Jan 2011 15:06:18 -0800 Subject: [PATCH 014/142] bug 7244: delete corresponding untagged pod vlan ranges when pod is deleted status 7244: resolved fixed --- .../configuration/ConfigurationManagerImpl.java | 10 +++++++++- server/src/com/cloud/network/NetworkManager.java | 3 ++- .../src/com/cloud/network/NetworkManagerImpl.java | 15 +++++---------- .../src/com/cloud/network/rules/RulesManager.java | 2 ++ .../com/cloud/network/rules/RulesManagerImpl.java | 6 +++++- 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index cf656f6744b..968f025a330 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -523,7 +523,15 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura if (!(_LinkLocalIpAllocDao.deleteIpAddressByPod(podId))) { throw new CloudRuntimeException("Failed to cleanup private ip addresses for pod " + podId); } - + + //Delete vlans associated with the pod + List vlans = _networkMgr.listPodVlans(podId); + if (vlans != null && !vlans.isEmpty()) { + for (Vlan vlan: vlans) { + _vlanDao.remove(vlan.getId()); + } + } + //Delete the pod if (!(_podDao.expunge(podId))) { throw new CloudRuntimeException("Failed to delete pod " + podId); diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index a7f458e3208..d8dd1982248 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -20,6 +20,7 @@ package com.cloud.network; import java.util.List; import java.util.Map; +import com.cloud.dc.Vlan; import com.cloud.dc.Vlan.VlanType; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; @@ -137,6 +138,6 @@ public interface NetworkManager extends NetworkService { PublicIpAddress getPublicIpAddress(Ip ipAddress); - String getPodVlanGateway(long podId); + List listPodVlans(long podId); } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index e0674cc4b81..3addb3b067e 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -99,6 +99,7 @@ import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.PortForwardingRuleVO; import com.cloud.network.rules.RulesManager; import com.cloud.network.rules.dao.PortForwardingRulesDao; @@ -176,7 +177,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Inject VirtualNetworkApplianceManager _routerMgr; @Inject RulesManager _rulesMgr; @Inject LoadBalancingRulesManager _lbMgr; - @Inject PortForwardingRulesDao _pfRulesDao; @Inject UsageEventDao _usageEventDao; @Inject PodVlanMapDao _podVlanMapDao; @@ -1636,7 +1636,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override public boolean applyRules(List rules, boolean continueOnError) throws ResourceUnavailableException { - if (rules.size() == 0) { + if (rules == null || rules.size() == 0) { s_logger.debug("There are no rules to forward to the network elements"); return true; } @@ -1742,7 +1742,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } //Reapply pf rules - List pfRules = _pfRulesDao.listByNetworkId(networkId); + List pfRules = _rulesMgr.listByNetworkId(networkId); if (!applyRules(pfRules, true)) { s_logger.warn("Failed to apply port forwarding rules as a part of network " + network.getId() + " restart"); return false; @@ -1843,14 +1843,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } @Override - public String getPodVlanGateway(long podId) { + public List listPodVlans(long podId) { List vlans = _vlanDao.listVlansForPodByType(podId, VlanType.DirectAttached); - //we don't allow vlans to have different gateways, so take the value from the first one - if (vlans == null || !vlans.isEmpty()) { - return vlans.get(0).getVlanGateway(); - } else { - return null; - } + return vlans; } } diff --git a/server/src/com/cloud/network/rules/RulesManager.java b/server/src/com/cloud/network/rules/RulesManager.java index 136464e509f..8d101623642 100644 --- a/server/src/com/cloud/network/rules/RulesManager.java +++ b/server/src/com/cloud/network/rules/RulesManager.java @@ -75,4 +75,6 @@ public interface RulesManager extends RulesService { FirewallRule[] reservePorts(IpAddress ip, String protocol, FirewallRule.Purpose purpose, int... ports) throws NetworkRuleConflictException; boolean releasePorts(Ip ip, String protocol, FirewallRule.Purpose purpose, int... ports); + + List listByNetworkId(long networkId); } diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index edd43b431c0..b420f1b0f85 100644 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -526,6 +526,10 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { return allRules; } - + + @Override + public List listByNetworkId(long networkId) { + return _forwardingDao.listByNetworkId(networkId); + } } From 6cbdf0481e6d268eeb8f1b35c836e05184170264 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 6 Jan 2011 16:24:35 -0800 Subject: [PATCH 015/142] bug 7744: multiple-selectable page - avoid binding event handler to middle menu items since middle menu items have already been controlled by JQuery Selectable Widget. --- ui/scripts/cloud.core.js | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/ui/scripts/cloud.core.js b/ui/scripts/cloud.core.js index 13e56ddcd51..25e0db146d7 100644 --- a/ui/scripts/cloud.core.js +++ b/ui/scripts/cloud.core.js @@ -956,10 +956,6 @@ function listMidMenuItems2(commandString, getSearchParamsFn, jsonResponse1, json (page > 1)? $("#midmenu_prevbutton").show(): $("#midmenu_prevbutton").hide(); - //var $container = $("#midmenu_container").empty(); - //if(isMultipleSelectionInMidMenu == true) - // $container = createMultipleSelectionSubContainer(); - var count = 0; $.ajax({ cache: false, @@ -967,8 +963,10 @@ function listMidMenuItems2(commandString, getSearchParamsFn, jsonResponse1, json dataType: "json", async: false, success: function(json) { - var $container = $("#midmenu_container").empty(); - if(isMultipleSelectionInMidMenu == true) + var $container; + if(isMultipleSelectionInMidMenu != true) + $container = $("#midmenu_container").empty(); + else $container = createMultipleSelectionSubContainer(); selectedItemsInMidMenu = {}; @@ -979,12 +977,23 @@ function listMidMenuItems2(commandString, getSearchParamsFn, jsonResponse1, json var $midmenuItem1 = $("#midmenu_item").clone(); $midmenuItem1.data("toRightPanelFn", toRightPanelFn); toMidmenuFn(items[i], $midmenuItem1); - bindClickToMidMenu($midmenuItem1, toRightPanelFn, getMidmenuIdFn); + if(isMultipleSelectionInMidMenu != true) + bindClickToMidMenu($midmenuItem1, toRightPanelFn, getMidmenuIdFn); $container.append($midmenuItem1.show()); if(i == 0) { //click the 1st item in middle menu as default - $midmenuItem1.click(); - if(isMultipleSelectionInMidMenu == true) { + if(isMultipleSelectionInMidMenu != true) { + $midmenuItem1.click(); + } + else { + if(selected_midmenu_id != null && selected_midmenu_id.length > 0) + $("#"+selected_midmenu_id).find("#content").removeClass("selected"); + selected_midmenu_id = getMidmenuIdFn($midmenuItem1.data("jsonObj")); + $midmenuItem1.find("#content").addClass("selected"); + clearRightPanel(); + toRightPanelFn($midmenuItem1); + //$midmenuItem1.click(); + $midmenuItem1.addClass("ui-selected"); //because instance page is using JQuery selectable widget to do multiple-selection selectedItemsInMidMenu[items[i].id] = $midmenuItem1; //because instance page is using JQuery selectable widget to do multiple-selection } From b331f7bb8d89e7c922dd90b6d84b22e323c60b66 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Thu, 6 Jan 2011 12:16:42 -0500 Subject: [PATCH 016/142] add missing config files --- wscript_configure | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wscript_configure b/wscript_configure index afc9526db35..a830352e265 100644 --- a/wscript_configure +++ b/wscript_configure @@ -37,7 +37,7 @@ systemjars = { "tomcat6-jsp-2.1-api-6.0.26.jar", #"tomcat6/catalina.jar", # all supported distros put the file there ), - 'RHEL6': + 'RHEL': ( "tomcat6-servlet-2.5-api.jar", "tomcat6-el-2.1-api-6.0.24.jar", @@ -110,7 +110,7 @@ elif _exists("/etc/centos-release"): conf.env.DISTRO = "CentOS" elif _exists("/etc/redhat-release"): version = file("/etc/redhat-release").readline() if version.find("Red Hat Enterprise Linux Server release 6") != -1: - conf.env.DISTRO = "RHEL6" + conf.env.DISTRO = "RHEL" elif version.find("Centos release") != -1: conf.env.DISTRO = "CentOS" else: conf.env.DISTRO = "unknown" From c12e96dcc32c542f646b36fcf8d5b435d66d47c2 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Thu, 6 Jan 2011 12:25:50 -0500 Subject: [PATCH 017/142] add missing files --- .../SYSCONFDIR/rc.d/init.d/cloud-agent.in | 81 ++++++++++++++++++ .../rc.d/init.d/cloud-management.in | 41 ++++++++++ .../SYSCONFDIR/sysconfig/cloud-management.in | 6 ++ .../rc.d/init.d/cloud-console-proxy.in | 81 ++++++++++++++++++ .../rc.d/init.d/cloud-ipallocator.in | 82 +++++++++++++++++++ 5 files changed, 291 insertions(+) create mode 100644 agent/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-agent.in create mode 100644 client/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-management.in create mode 100644 client/distro/rhel/SYSCONFDIR/sysconfig/cloud-management.in create mode 100644 console-proxy/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in create mode 100644 python/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in diff --git a/agent/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-agent.in b/agent/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-agent.in new file mode 100644 index 00000000000..e6fc5f8cca3 --- /dev/null +++ b/agent/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-agent.in @@ -0,0 +1,81 @@ +#!/bin/bash + +# chkconfig: 35 99 10 +# description: Cloud Agent + +# WARNING: if this script is changed, then all other initscripts MUST BE changed to match it as well + +. /etc/rc.d/init.d/functions + +whatami=cloud-agent + +# set environment variables + +SHORTNAME="$whatami" +PIDFILE=@PIDDIR@/"$whatami".pid +LOCKFILE=@LOCKDIR@/"$SHORTNAME" +LOGFILE=@AGENTLOG@ +PROGNAME="Cloud Agent" + +unset OPTIONS +[ -r @SYSCONFDIR@/sysconfig/"$SHORTNAME" ] && source @SYSCONFDIR@/sysconfig/"$SHORTNAME" +DAEMONIZE=@BINDIR@/@PACKAGE@-daemonize +PROG=@LIBEXECDIR@/agent-runner + +start() { + echo -n $"Starting $PROGNAME: " + if hostname --fqdn >/dev/null 2>&1 ; then + daemon --check=$SHORTNAME --pidfile=${PIDFILE} "$DAEMONIZE" \ + -n "$SHORTNAME" -p "$PIDFILE" -l "$LOGFILE" "$PROG" $OPTIONS + RETVAL=$? + echo + else + failure + echo + echo The host name does not resolve properly to an IP address. Cannot start "$PROGNAME". > /dev/stderr + RETVAL=9 + fi + [ $RETVAL = 0 ] && touch ${LOCKFILE} + return $RETVAL +} + +stop() { + echo -n $"Stopping $PROGNAME: " + killproc -p ${PIDFILE} $SHORTNAME # -d 10 $SHORTNAME + RETVAL=$? + echo + [ $RETVAL = 0 ] && rm -f ${LOCKFILE} ${PIDFILE} +} + + +# See how we were called. +case "$1" in + start) + start + ;; + stop) + stop + ;; + status) + status -p ${PIDFILE} $SHORTNAME + RETVAL=$? + ;; + restart) + stop + sleep 3 + start + ;; + condrestart) + if status -p ${PIDFILE} $SHORTNAME >&/dev/null; then + stop + sleep 3 + start + fi + ;; + *) + echo $"Usage: $whatami {start|stop|restart|condrestart|status|help}" + RETVAL=3 +esac + +exit $RETVAL + diff --git a/client/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-management.in b/client/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-management.in new file mode 100644 index 00000000000..d61cb7b8088 --- /dev/null +++ b/client/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-management.in @@ -0,0 +1,41 @@ +#!/bin/bash +# +# @PACKAGE@-management This shell script takes care of starting and stopping Tomcat +# +# chkconfig: - 80 20 +# +### BEGIN INIT INFO +# Provides: tomcat6 +# Required-Start: $network $syslog +# Required-Stop: $network $syslog +# Default-Start: +# Default-Stop: +# Description: Release implementation for Servlet 2.5 and JSP 2.1 +# Short-Description: start and stop tomcat +### END INIT INFO +# +# - originally written by Henri Gomez, Keith Irwin, and Nicolas Mailhot +# - heavily rewritten by Deepak Bhole and Jason Corley +# + +if [ -r /etc/rc.d/init.d/functions ]; then + . /etc/rc.d/init.d/functions +fi +if [ -r /lib/lsb/init-functions ]; then + . /lib/lsb/init-functions +fi + + +NAME="$(basename $0)" + +# See how we were called. +case "$1" in + status) + status ${NAME} + RETVAL=$? + ;; + *) + . /etc/rc.d/init.d/tomcat6 +esac + +exit $RETVAL diff --git a/client/distro/rhel/SYSCONFDIR/sysconfig/cloud-management.in b/client/distro/rhel/SYSCONFDIR/sysconfig/cloud-management.in new file mode 100644 index 00000000000..2d4b22f4bff --- /dev/null +++ b/client/distro/rhel/SYSCONFDIR/sysconfig/cloud-management.in @@ -0,0 +1,6 @@ +# This file is loaded in /etc/init.d/vmopsmanagement +# ATM we only do two things here: + +dummy=1 ; export TOMCAT_CFG=@MSCONF@/tomcat6.conf ; . @MSCONF@/tomcat6.conf +#-------------------------- + diff --git a/console-proxy/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in b/console-proxy/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in new file mode 100644 index 00000000000..488df568f02 --- /dev/null +++ b/console-proxy/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-console-proxy.in @@ -0,0 +1,81 @@ +#!/bin/bash + +# chkconfig: 35 99 10 +# description: Cloud Console Proxy + +# WARNING: if this script is changed, then all other initscripts MUST BE changed to match it as well + +. /etc/rc.d/init.d/functions + +whatami=cloud-console-proxy + +# set environment variables + +SHORTNAME="$whatami" +PIDFILE=@PIDDIR@/"$whatami".pid +LOCKFILE=@LOCKDIR@/"$SHORTNAME" +LOGFILE=@CPLOG@ +PROGNAME="Cloud Console Proxy" + +unset OPTIONS +[ -r @SYSCONFDIR@/sysconfig/"$SHORTNAME" ] && source @SYSCONFDIR@/sysconfig/"$SHORTNAME" +DAEMONIZE=@BINDIR@/@PACKAGE@-daemonize +PROG=@LIBEXECDIR@/console-proxy-runner + +start() { + echo -n $"Starting $PROGNAME: " + if hostname --fqdn >/dev/null 2>&1 ; then + daemon --check=$SHORTNAME --pidfile=${PIDFILE} "$DAEMONIZE" \ + -n "$SHORTNAME" -p "$PIDFILE" -l "$LOGFILE" "$PROG" $OPTIONS + RETVAL=$? + echo + else + failure + echo + echo The host name does not resolve properly to an IP address. Cannot start "$PROGNAME". > /dev/stderr + RETVAL=9 + fi + [ $RETVAL = 0 ] && touch ${LOCKFILE} + return $RETVAL +} + +stop() { + echo -n $"Stopping $PROGNAME: " + killproc -p ${PIDFILE} $SHORTNAME # -d 10 $SHORTNAME + RETVAL=$? + echo + [ $RETVAL = 0 ] && rm -f ${LOCKFILE} ${PIDFILE} +} + + +# See how we were called. +case "$1" in + start) + start + ;; + stop) + stop + ;; + status) + status -p ${PIDFILE} $SHORTNAME + RETVAL=$? + ;; + restart) + stop + sleep 3 + start + ;; + condrestart) + if status -p ${PIDFILE} $SHORTNAME >&/dev/null; then + stop + sleep 3 + start + fi + ;; + *) + echo $"Usage: $whatami {start|stop|restart|condrestart|status|help}" + RETVAL=3 +esac + +exit $RETVAL + diff --git a/python/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in b/python/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in new file mode 100644 index 00000000000..e0b6b613253 --- /dev/null +++ b/python/distro/rhel/SYSCONFDIR/rc.d/init.d/cloud-ipallocator.in @@ -0,0 +1,82 @@ +#!/bin/bash + +# chkconfig: 35 99 10 +# description: Cloud Agent + +# WARNING: if this script is changed, then all other initscripts MUST BE changed to match it as well + +. /etc/rc.d/init.d/functions + +whatami=cloud-external-ipallocator + +# set environment variables + +SHORTNAME="$whatami" +PIDFILE=@PIDDIR@/"$whatami".pid +LOCKFILE=@LOCKDIR@/"$SHORTNAME" +LOGFILE=@AGENTLOG@ +PROGNAME="Cloud Agent" + +unset OPTIONS +[ -r @SYSCONFDIR@/sysconfig/"$SHORTNAME" ] && source @SYSCONFDIR@/sysconfig/"$SHORTNAME" +DAEMONIZE=@BINDIR@/@PACKAGE@-daemonize +PROG=@BINDIR@/@PACKAGE@-external-ipallocator.py +OPTIONS=8083 + +start() { + echo -n $"Starting $PROGNAME: " + if hostname --fqdn >/dev/null 2>&1 ; then + daemon --check=$SHORTNAME --pidfile=${PIDFILE} "$DAEMONIZE" \ + -n "$SHORTNAME" -p "$PIDFILE" -l "$LOGFILE" "$PROG" $OPTIONS + RETVAL=$? + echo + else + failure + echo + echo The host name does not resolve properly to an IP address. Cannot start "$PROGNAME". > /dev/stderr + RETVAL=9 + fi + [ $RETVAL = 0 ] && touch ${LOCKFILE} + return $RETVAL +} + +stop() { + echo -n $"Stopping $PROGNAME: " + killproc -p ${PIDFILE} $SHORTNAME # -d 10 $SHORTNAME + RETVAL=$? + echo + [ $RETVAL = 0 ] && rm -f ${LOCKFILE} ${PIDFILE} +} + + +# See how we were called. +case "$1" in + start) + start + ;; + stop) + stop + ;; + status) + status -p ${PIDFILE} $SHORTNAME + RETVAL=$? + ;; + restart) + stop + sleep 3 + start + ;; + condrestart) + if status -p ${PIDFILE} $SHORTNAME >&/dev/null; then + stop + sleep 3 + start + fi + ;; + *) + echo $"Usage: $whatami {start|stop|restart|condrestart|status|help}" + RETVAL=3 +esac + +exit $RETVAL + From a7a5272f2b23c77f6d434c388d659e120175adf1 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 6 Jan 2011 16:43:12 -0800 Subject: [PATCH 018/142] bug 7744: tab action - delete duplicate code that has existed in handleMidMenuItemAfterDetailsTabAction(). --- ui/scripts/cloud.core.js | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/ui/scripts/cloud.core.js b/ui/scripts/cloud.core.js index 25e0db146d7..7d4e7ec053a 100644 --- a/ui/scripts/cloud.core.js +++ b/ui/scripts/cloud.core.js @@ -90,14 +90,10 @@ function doActionToTab(id, $actionLink, apiCommand, $midmenuItem1, $thisTab) { $spinningWheel.hide(); if (result.jobstatus == 1) { // Succeeded - handleMidMenuItemAfterDetailsTabAction($midmenuItem1, true, (label + " action succeeded.")); - $afterActionInfoContainer.find("#after_action_info").text(label + " action succeeded."); - $afterActionInfoContainer.removeClass("errorbox").show(); + handleMidMenuItemAfterDetailsTabAction($midmenuItem1, true, (label + " action succeeded.")); afterActionSeccessFn(json, $midmenuItem1, id); } else if (result.jobstatus == 2) { // Failed - handleMidMenuItemAfterDetailsTabAction($midmenuItem1, false, (label + " action failed. Reason: " + fromdb(result.jobresult.errortext))); - $afterActionInfoContainer.find("#after_action_info").text(label + " action failed. Reason: " + fromdb(result.jobresult.errortext)); - $afterActionInfoContainer.addClass("errorbox").show(); + handleMidMenuItemAfterDetailsTabAction($midmenuItem1, false, (label + " action failed. Reason: " + fromdb(result.jobresult.errortext))); } } }, @@ -129,11 +125,7 @@ function doActionToTab(id, $actionLink, apiCommand, $midmenuItem1, $thisTab) { async: false, success: function(json) { $spinningWheel.hide(); - handleMidMenuItemAfterDetailsTabAction($midmenuItem1, true, (label + " action succeeded.")); - - $afterActionInfoContainer.find("#after_action_info").text(label + " action succeeded."); - $afterActionInfoContainer.removeClass("errorbox").show(); - + handleMidMenuItemAfterDetailsTabAction($midmenuItem1, true, (label + " action succeeded.")); afterActionSeccessFn(json, $midmenuItem1, id); }, error: function(XMLHttpResponse) { From f80e3529886a1cb4acfc10144799c7c1d2cd2cad Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 6 Jan 2011 17:10:27 -0800 Subject: [PATCH 019/142] bug 7744: instance page - not update right panel after a tab action succeeds since the action might not belong to currently selected middle menu item. --- ui/scripts/cloud.core.instance.js | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/ui/scripts/cloud.core.instance.js b/ui/scripts/cloud.core.instance.js index da0e02e4ab7..297f987a2c3 100644 --- a/ui/scripts/cloud.core.instance.js +++ b/ui/scripts/cloud.core.instance.js @@ -1116,8 +1116,7 @@ var vmActionMap = { dialogBeforeActionFn : doStartVM, afterActionSeccessFn: function(json, $midmenuItem1, id) { var jsonObj = json.queryasyncjobresultresponse.jobresult.virtualmachine; - vmToMidmenu(jsonObj, $midmenuItem1); - vmToRightPanel($midmenuItem1); + vmToMidmenu(jsonObj, $midmenuItem1); } }, "Stop Instance": { @@ -1127,8 +1126,7 @@ var vmActionMap = { dialogBeforeActionFn : doStopVM, afterActionSeccessFn: function(json, $midmenuItem1, id) { var jsonObj = json.queryasyncjobresultresponse.jobresult.virtualmachine; - vmToMidmenu(jsonObj, $midmenuItem1); - vmToRightPanel($midmenuItem1); + vmToMidmenu(jsonObj, $midmenuItem1); } }, "Reboot Instance": { @@ -1138,8 +1136,7 @@ var vmActionMap = { dialogBeforeActionFn : doRebootVM, afterActionSeccessFn: function(json, $midmenuItem1, id) { var jsonObj = json.queryasyncjobresultresponse.jobresult.virtualmachine; - vmToMidmenu(jsonObj, $midmenuItem1); - vmToRightPanel($midmenuItem1); + vmToMidmenu(jsonObj, $midmenuItem1); } }, "Destroy Instance": { @@ -1149,8 +1146,7 @@ var vmActionMap = { dialogBeforeActionFn : doDestroyVM, afterActionSeccessFn: function(json, $midmenuItem1, id) { var jsonObj = json.queryasyncjobresultresponse.jobresult.virtualmachine; - vmToMidmenu(jsonObj, $midmenuItem1); - vmToRightPanel($midmenuItem1); + vmToMidmenu(jsonObj, $midmenuItem1); } }, "Restore Instance": { @@ -1159,8 +1155,7 @@ var vmActionMap = { dialogBeforeActionFn : doRestoreVM, afterActionSeccessFn: function(json, $midmenuItem1, id) { var jsonObj = json.recovervirtualmachineresponse.virtualmachine; - vmToMidmenu(jsonObj, $midmenuItem1); - vmToRightPanel($midmenuItem1); + vmToMidmenu(jsonObj, $midmenuItem1); } }, "Edit Instance": { @@ -1173,8 +1168,7 @@ var vmActionMap = { dialogBeforeActionFn : doAttachISO, afterActionSeccessFn: function(json, $midmenuItem1, id) { var jsonObj = json.queryasyncjobresultresponse.jobresult.virtualmachine; - vmToMidmenu(jsonObj, $midmenuItem1); - //vmToRightPanel($midmenuItem1); //comment this one out, otherwise, it will call listVM API again. + vmToMidmenu(jsonObj, $midmenuItem1); setBooleanReadField((jsonObj.isoid != null), $("#right_panel_content").find("#tab_content_details").find("#iso")); } }, @@ -1185,8 +1179,7 @@ var vmActionMap = { dialogBeforeActionFn : doDetachISO, afterActionSeccessFn: function(json, $midmenuItem1, id) { var jsonObj = json.queryasyncjobresultresponse.jobresult.virtualmachine; - vmToMidmenu(jsonObj, $midmenuItem1); - //vmToRightPanel($midmenuItem1); //comment this one out, otherwise, it will call listVM API again. + vmToMidmenu(jsonObj, $midmenuItem1); setBooleanReadField((jsonObj.isoid != null), $("#right_panel_content").find("#tab_content_details").find("#iso")); } }, @@ -1220,8 +1213,7 @@ var vmActionMap = { dialogBeforeActionFn : doChangeService, afterActionSeccessFn: function(json, $midmenuItem1, id) { var jsonObj = json.changeserviceforvirtualmachineresponse.virtualmachine; - vmToMidmenu(jsonObj, $midmenuItem1); - vmToRightPanel($midmenuItem1); + vmToMidmenu(jsonObj, $midmenuItem1); } } } From 4fa6fc4d7ce0f645b54d08938498c115b5cda008 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 6 Jan 2011 17:26:26 -0800 Subject: [PATCH 020/142] bug 7744: after tab action succeeds, click middle menu item to show action info if the action belongs to the currently selected middle menu item. --- ui/scripts/cloud.core.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ui/scripts/cloud.core.js b/ui/scripts/cloud.core.js index 7d4e7ec053a..a28af853528 100644 --- a/ui/scripts/cloud.core.js +++ b/ui/scripts/cloud.core.js @@ -167,7 +167,10 @@ function handleMidMenuItemAfterDetailsTabAction($midmenuItem1, isSuccessful, aft if(isSuccessful) $infoIcon.removeClass("error"); else - $infoIcon.addClass("error"); + $infoIcon.addClass("error"); + + if($midmenuItem1.attr("id") == selected_midmenu_id) + $midmenuItem1.click(); } //***** actions for a tab in right panel (end) ************************************************************************** From 56d8fb6a0b4a1efe5694da06ef54870de131420f Mon Sep 17 00:00:00 2001 From: Kelven Yang Date: Thu, 6 Jan 2011 05:27:10 -0800 Subject: [PATCH 021/142] Bug 7015: allow domain admin to be able to access domR console --- .../src/com/cloud/servlet/ConsoleProxyServlet.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/server/src/com/cloud/servlet/ConsoleProxyServlet.java b/server/src/com/cloud/servlet/ConsoleProxyServlet.java index 3914ee5e036..6b599037f69 100644 --- a/server/src/com/cloud/servlet/ConsoleProxyServlet.java +++ b/server/src/com/cloud/servlet/ConsoleProxyServlet.java @@ -365,26 +365,25 @@ public class ConsoleProxyServlet extends HttpServlet { return true; VMInstanceVO vm = _ms.findVMInstanceById(vmId); - UserVmVO userVm; switch(vm.getType()) { case User : - userVm = _ms.findUserVMInstanceById(vmId); - if(userVm.getAccountId() != accountObj.getId()) { + case DomainRouter: + if(vm.getAccountId() != accountObj.getId()) { // access from another normal user if(accountObj.getType() == Account.ACCOUNT_TYPE_NORMAL) { if(s_logger.isDebugEnabled()) { - s_logger.debug("VM access is denied. VM owner account " + userVm.getAccountId() + s_logger.debug("VM access is denied. VM owner account " + vm.getAccountId() + " does not match the account id in session " + accountObj.getId() + " and caller is a normal user"); } return false; } if(accountObj.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || accountObj.getType() == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN) { - if(!_ms.isChildDomain(accountObj.getDomainId(), userVm.getDomainId())) { + if(!_ms.isChildDomain(accountObj.getDomainId(), vm.getDomainId())) { if(s_logger.isDebugEnabled()) { - s_logger.debug("VM access is denied. VM owner account " + userVm.getAccountId() + s_logger.debug("VM access is denied. VM owner account " + vm.getAccountId() + " does not match the account id in session " + accountObj.getId() + " and the domain-admin caller does not manage the target domain"); } return false; @@ -394,7 +393,6 @@ public class ConsoleProxyServlet extends HttpServlet { break; case ConsoleProxy : - case DomainRouter : case SecondaryStorageVm: return false; From c1af79c843d017a29a594be1ada69e8827dd5eee Mon Sep 17 00:00:00 2001 From: Edison Su Date: Thu, 6 Jan 2011 13:27:34 -0500 Subject: [PATCH 022/142] add write permission for system directory in cloud-client package --- cloud.spec | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/cloud.spec b/cloud.spec index 17b4e841868..700d1ae87aa 100644 --- a/cloud.spec +++ b/cloud.spec @@ -433,8 +433,8 @@ fi %defattr(0644,root,root,0755) %{_javadir}/%{name}-utils.jar %{_javadir}/%{name}-api.jar -%attr(755,root,root) %{_bindir}/cloud-sccs -%attr(755,root,root) %{_bindir}/cloud-gitrevs +%attr(0755,root,root) %{_bindir}/cloud-sccs +%attr(0755,root,root) %{_bindir}/cloud-gitrevs %doc %{_docdir}/%{name}-%{version}/sccs-info %doc %{_docdir}/%{name}-%{version}/version-info %doc %{_docdir}/%{name}-%{version}/configure-info @@ -459,7 +459,7 @@ fi %files daemonize %defattr(-,root,root,-) -%attr(755,root,root) %{_bindir}/%{name}-daemonize +%attr(0755,root,root) %{_bindir}/%{name}-daemonize %files deps %defattr(0644,root,root,0755) @@ -496,7 +496,7 @@ fi %{_prefix}/lib*/python*/site-packages/%{name}* %attr(0755,root,root) %{_bindir}/cloud-external-ipallocator.py %attr(0755,root,root) %{_initrddir}/cloud-ipallocator -%dir %attr(770,root,root) %{_localstatedir}/log/%{name}/ipallocator +%dir %attr(0770,root,root) %{_localstatedir}/log/%{name}/ipallocator %files setup %attr(0755,root,root) %{_bindir}/%{name}-setup-databases @@ -507,30 +507,30 @@ fi %{_datadir}/%{name}/setup/server-setup.xml %files client -%defattr(0644,root,root,0755) +%defattr(0644,root,root,0775) %{_sysconfdir}/%{name}/management/* %if %{_premium} %exclude %{_sysconfdir}/%{name}/management/*premium* %endif -%config(noreplace) %attr(640,root,%{name}) %{_sysconfdir}/%{name}/management/db.properties +%config(noreplace) %attr(0640,root,%{name}) %{_sysconfdir}/%{name}/management/db.properties %config(noreplace) %{_sysconfdir}/%{name}/management/log4j-%{name}.xml %config(noreplace) %{_sysconfdir}/%{name}/management/tomcat6.conf -%dir %attr(770,root,%{name}) %{_sysconfdir}/%{name}/management/Catalina -%dir %attr(770,root,%{name}) %{_sysconfdir}/%{name}/management/Catalina/localhost -%dir %attr(770,root,%{name}) %{_sysconfdir}/%{name}/management/Catalina/localhost/client +%dir %attr(0770,root,%{name}) %{_sysconfdir}/%{name}/management/Catalina +%dir %attr(0770,root,%{name}) %{_sysconfdir}/%{name}/management/Catalina/localhost +%dir %attr(0770,root,%{name}) %{_sysconfdir}/%{name}/management/Catalina/localhost/client %config %{_sysconfdir}/sysconfig/%{name}-management %attr(0755,root,root) %{_initrddir}/%{name}-management %dir %{_datadir}/%{name}/management %{_datadir}/%{name}/management/* -%attr(755,root,root) %{_bindir}/%{name}-setup-management -%attr(755,root,root) %{_bindir}/%{name}-update-xenserver-licenses -%dir %attr(770,root,%{name}) %{_sharedstatedir}/%{name}/mnt -%dir %attr(770,%{name},%{name}) %{_sharedstatedir}/%{name}/management -%dir %attr(770,root,%{name}) %{_localstatedir}/cache/%{name}/management -%dir %attr(770,root,%{name}) %{_localstatedir}/cache/%{name}/management/work -%dir %attr(770,root,%{name}) %{_localstatedir}/cache/%{name}/management/temp -%dir %attr(770,root,%{name}) %{_localstatedir}/log/%{name}/management -%dir %attr(770,root,%{name}) %{_localstatedir}/log/%{name}/agent +%attr(0755,root,root) %{_bindir}/%{name}-setup-management +%attr(0755,root,root) %{_bindir}/%{name}-update-xenserver-licenses +%dir %attr(0770,root,%{name}) %{_sharedstatedir}/%{name}/mnt +%dir %attr(0770,%{name},%{name}) %{_sharedstatedir}/%{name}/management +%dir %attr(0770,root,%{name}) %{_localstatedir}/cache/%{name}/management +%dir %attr(0770,root,%{name}) %{_localstatedir}/cache/%{name}/management/work +%dir %attr(0770,root,%{name}) %{_localstatedir}/cache/%{name}/management/temp +%dir %attr(0770,root,%{name}) %{_localstatedir}/log/%{name}/management +%dir %attr(0770,root,%{name}) %{_localstatedir}/log/%{name}/agent %files agent-libs %defattr(0644,root,root,0755) @@ -549,7 +549,7 @@ fi %{_libdir}/%{name}/agent/js %{_libdir}/%{name}/agent/images %attr(0755,root,root) %{_bindir}/%{name}-setup-agent -%dir %attr(770,root,root) %{_localstatedir}/log/%{name}/agent +%dir %attr(0770,root,root) %{_localstatedir}/log/%{name}/agent %files console-proxy @@ -560,7 +560,7 @@ fi %attr(0755,root,root) %{_libexecdir}/console-proxy-runner %{_libdir}/%{name}/console-proxy/* %attr(0755,root,root) %{_bindir}/%{name}-setup-console-proxy -%dir %attr(770,root,root) %{_localstatedir}/log/%{name}/console-proxy +%dir %attr(0770,root,root) %{_localstatedir}/log/%{name}/console-proxy %files cli %{_bindir}/%{name}-tool @@ -573,7 +573,7 @@ fi %files test %defattr(0644,root,root,0755) -%attr(755,root,root) %{_bindir}/%{name}-run-test +%attr(0755,root,root) %{_bindir}/%{name}-run-test %{_javadir}/%{name}-test.jar %{_sharedstatedir}/%{name}/test/* %{_libdir}/%{name}/test/* @@ -596,14 +596,14 @@ fi %{_libdir}/%{name}/agent/premium-scripts/* %files usage -%defattr(0644,root,root,0755) +%defattr(0644,root,root,0775) %{_javadir}/%{name}-usage.jar %attr(0755,root,root) %{_initrddir}/%{name}-usage %attr(0755,root,root) %{_libexecdir}/usage-runner -%dir %attr(770,root,%{name}) %{_localstatedir}/log/%{name}/usage +%dir %attr(0770,root,%{name}) %{_localstatedir}/log/%{name}/usage %{_sysconfdir}/%{name}/usage/usage-components.xml %config(noreplace) %{_sysconfdir}/%{name}/usage/log4j-%{name}_usage.xml -%config(noreplace) %attr(640,root,%{name}) %{_sysconfdir}/%{name}/usage/db.properties +%config(noreplace) %attr(0640,root,%{name}) %{_sysconfdir}/%{name}/usage/db.properties %endif From 205f7b8ee518a8b00ebbd8b3f201e9dc559a4870 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 6 Jan 2011 17:36:26 -0800 Subject: [PATCH 023/142] bug 7744: selected_midmenu_id is not used in multiple-selection middle menu. So, remove the code. --- ui/scripts/cloud.core.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/ui/scripts/cloud.core.js b/ui/scripts/cloud.core.js index a28af853528..a76998198da 100644 --- a/ui/scripts/cloud.core.js +++ b/ui/scripts/cloud.core.js @@ -980,14 +980,10 @@ function listMidMenuItems2(commandString, getSearchParamsFn, jsonResponse1, json if(isMultipleSelectionInMidMenu != true) { $midmenuItem1.click(); } - else { - if(selected_midmenu_id != null && selected_midmenu_id.length > 0) - $("#"+selected_midmenu_id).find("#content").removeClass("selected"); - selected_midmenu_id = getMidmenuIdFn($midmenuItem1.data("jsonObj")); - $midmenuItem1.find("#content").addClass("selected"); - clearRightPanel(); + else { + $midmenuItem1.find("#content").addClass("selected"); toRightPanelFn($midmenuItem1); - //$midmenuItem1.click(); + //$midmenuItem1.click(); //$midmenuItem1.click() is not working in multiple-selection middle menu $midmenuItem1.addClass("ui-selected"); //because instance page is using JQuery selectable widget to do multiple-selection selectedItemsInMidMenu[items[i].id] = $midmenuItem1; //because instance page is using JQuery selectable widget to do multiple-selection From d2196d169e366717fb8fb3c98975683cde952656 Mon Sep 17 00:00:00 2001 From: keshav Date: Thu, 6 Jan 2011 17:45:44 -0800 Subject: [PATCH 024/142] Moved global lock inside storage cleanup method. --- .../com/cloud/storage/StorageManagerImpl.java | 183 +++++++++--------- 1 file changed, 91 insertions(+), 92 deletions(-) diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 0ba0d3f998b..73c90d14731 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -2006,18 +2006,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag try { s_logger.info("Storage Garbage Collection Thread is running."); - GlobalLock scanLock = GlobalLock.getInternLock(this.getClass().getName()); - try { - if (scanLock.lock(3)) { - try { - cleanupStorage(true); - } finally { - scanLock.unlock(); - } - } - } finally { - scanLock.releaseRef(); - } + cleanupStorage(true); } catch (Exception e) { s_logger.error("Caught the following Exception", e); @@ -2027,89 +2016,99 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag @Override public void cleanupStorage(boolean recurring) { + GlobalLock scanLock = GlobalLock.getInternLock(this.getClass().getName()); + + try { + if (scanLock.lock(3)) { + try { + // Cleanup primary storage pools + List storagePools = _storagePoolDao.listAll(); + for (StoragePoolVO pool : storagePools) { + try { + if (recurring && pool.isLocal()) { + continue; + } - // Cleanup primary storage pools - List storagePools = _storagePoolDao.listAll(); - for (StoragePoolVO pool : storagePools) { - try { - if (recurring && pool.isLocal()) { - continue; - } - - List unusedTemplatesInPool = _tmpltMgr.getUnusedTemplatesInPool(pool); - s_logger.debug("Storage pool garbage collector found " + unusedTemplatesInPool.size() + " templates to clean up in storage pool: " + pool.getName()); - for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) { - if (templatePoolVO.getDownloadState() != VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - s_logger.debug("Storage pool garbage collector is skipping templatePoolVO with ID: " + templatePoolVO.getId() + " because it is not completely downloaded."); - continue; - } - - if (!templatePoolVO.getMarkedForGC()) { - templatePoolVO.setMarkedForGC(true); - _vmTemplatePoolDao.update(templatePoolVO.getId(), templatePoolVO); - s_logger.debug("Storage pool garbage collector has marked templatePoolVO with ID: " + templatePoolVO.getId() + " for garbage collection."); - continue; - } - - _tmpltMgr.evictTemplateFromStoragePool(templatePoolVO); - } - } catch (Exception e) { - s_logger.warn("Problem cleaning up primary storage pool " + pool, e); - } - } + List unusedTemplatesInPool = _tmpltMgr.getUnusedTemplatesInPool(pool); + s_logger.debug("Storage pool garbage collector found " + unusedTemplatesInPool.size() + " templates to clean up in storage pool: " + pool.getName()); + for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) { + if (templatePoolVO.getDownloadState() != VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + s_logger.debug("Storage pool garbage collector is skipping templatePoolVO with ID: " + templatePoolVO.getId() + " because it is not completely downloaded."); + continue; + } - // Cleanup secondary storage hosts - List secondaryStorageHosts = _hostDao.listSecondaryStorageHosts(); - for (HostVO secondaryStorageHost : secondaryStorageHosts) { - try { - long hostId = secondaryStorageHost.getId(); - List destroyedTemplateHostVOs = _vmTemplateHostDao.listDestroyed(hostId); - s_logger.debug("Secondary storage garbage collector found " + destroyedTemplateHostVOs.size() + " templates to cleanup on secondary storage host: " - + secondaryStorageHost.getName()); - for (VMTemplateHostVO destroyedTemplateHostVO : destroyedTemplateHostVOs) { - if (!_tmpltMgr.templateIsDeleteable(destroyedTemplateHostVO)) { - s_logger.debug("Not deleting template at: " + destroyedTemplateHostVO.getInstallPath()); - continue; - } - - String installPath = destroyedTemplateHostVO.getInstallPath(); - - if (installPath != null) { - Answer answer = _agentMgr.easySend(hostId, new DeleteTemplateCommand(destroyedTemplateHostVO.getInstallPath())); - - if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to delete template at: " + destroyedTemplateHostVO.getInstallPath()); - } else { - _vmTemplateHostDao.remove(destroyedTemplateHostVO.getId()); - s_logger.debug("Deleted template at: " + destroyedTemplateHostVO.getInstallPath()); - } - } else { - _vmTemplateHostDao.remove(destroyedTemplateHostVO.getId()); - } - } - } catch (Exception e) { - s_logger.warn("problem cleaning up secondary storage " + secondaryStorageHost, e); - } - } - - List vols = _volsDao.listRemovedButNotDestroyed(); - for (VolumeVO vol : vols) { - try { - Long poolId = vol.getPoolId(); - Answer answer = null; - StoragePoolVO pool = _storagePoolDao.findById(poolId); - final DestroyCommand cmd = new DestroyCommand(pool, vol, null); - answer = sendToPool(pool, cmd); - if (answer != null && answer.getResult()) { - s_logger.debug("Destroyed " + vol); - vol.setDestroyed(true); - _volsDao.update(vol.getId(), vol); - } - } catch (Exception e) { - s_logger.warn("Unable to destroy " + vol.getId(), e); - } - } + if (!templatePoolVO.getMarkedForGC()) { + templatePoolVO.setMarkedForGC(true); + _vmTemplatePoolDao.update(templatePoolVO.getId(), templatePoolVO); + s_logger.debug("Storage pool garbage collector has marked templatePoolVO with ID: " + templatePoolVO.getId() + " for garbage collection."); + continue; + } + _tmpltMgr.evictTemplateFromStoragePool(templatePoolVO); + } + } catch (Exception e) { + s_logger.warn("Problem cleaning up primary storage pool " + pool, e); + } + } + + // Cleanup secondary storage hosts + List secondaryStorageHosts = _hostDao.listSecondaryStorageHosts(); + for (HostVO secondaryStorageHost : secondaryStorageHosts) { + try { + long hostId = secondaryStorageHost.getId(); + List destroyedTemplateHostVOs = _vmTemplateHostDao.listDestroyed(hostId); + s_logger.debug("Secondary storage garbage collector found " + destroyedTemplateHostVOs.size() + " templates to cleanup on secondary storage host: " + + secondaryStorageHost.getName()); + for (VMTemplateHostVO destroyedTemplateHostVO : destroyedTemplateHostVOs) { + if (!_tmpltMgr.templateIsDeleteable(destroyedTemplateHostVO)) { + s_logger.debug("Not deleting template at: " + destroyedTemplateHostVO.getInstallPath()); + continue; + } + + String installPath = destroyedTemplateHostVO.getInstallPath(); + + if (installPath != null) { + Answer answer = _agentMgr.easySend(hostId, new DeleteTemplateCommand(destroyedTemplateHostVO.getInstallPath())); + + if (answer == null || !answer.getResult()) { + s_logger.debug("Failed to delete template at: " + destroyedTemplateHostVO.getInstallPath()); + } else { + _vmTemplateHostDao.remove(destroyedTemplateHostVO.getId()); + s_logger.debug("Deleted template at: " + destroyedTemplateHostVO.getInstallPath()); + } + } else { + _vmTemplateHostDao.remove(destroyedTemplateHostVO.getId()); + } + } + } catch (Exception e) { + s_logger.warn("problem cleaning up secondary storage " + secondaryStorageHost, e); + } + } + + List vols = _volsDao.listRemovedButNotDestroyed(); + for (VolumeVO vol : vols) { + try { + Long poolId = vol.getPoolId(); + Answer answer = null; + StoragePoolVO pool = _storagePoolDao.findById(poolId); + final DestroyCommand cmd = new DestroyCommand(pool, vol, null); + answer = sendToPool(pool, cmd); + if (answer != null && answer.getResult()) { + s_logger.debug("Destroyed " + vol); + vol.setDestroyed(true); + _volsDao.update(vol.getId(), vol); + } + } catch (Exception e) { + s_logger.warn("Unable to destroy " + vol.getId(), e); + } + } + } finally { + scanLock.unlock(); + } + } + } finally { + scanLock.releaseRef(); + } } @Override From c04ee3d85f0f06d065e637c2fc1e427f792ad673 Mon Sep 17 00:00:00 2001 From: will Date: Thu, 6 Jan 2011 18:11:01 -0800 Subject: [PATCH 025/142] Removing one more check for networkoffering.type --- ui/scripts/cloud.core.network.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/scripts/cloud.core.network.js b/ui/scripts/cloud.core.network.js index 79bbf7c649b..9bf4d9a937a 100644 --- a/ui/scripts/cloud.core.network.js +++ b/ui/scripts/cloud.core.network.js @@ -1122,7 +1122,7 @@ function bindAddNetworkButton($button) { var networkOfferings = json.listnetworkofferingsresponse.networkoffering; if (networkOfferings != null && networkOfferings.length > 0) { for (var i = 0; i < networkOfferings.length; i++) { - if (networkOfferings[i].type == "Direct" && networkOfferings[i].isdefault) { + if (networkOfferings[i].isdefault) { // Create a network from this. $.ajax({ data: createURL("command=createNetwork&name="+name+"&displayText="+desc+"&networkOfferingId="+networkOfferings[i].id+"&zoneId="+zoneObj.id+vlan+scopeParams+"&gateway="+todb(gateway)+"&netmask="+todb(netmask)+"&startip="+todb(startip)+"&endip="+todb(endip)), From df35baa165175044c838cad017f136f9e1f21810 Mon Sep 17 00:00:00 2001 From: NIKITA Date: Thu, 6 Jan 2011 18:31:12 -0800 Subject: [PATCH 026/142] New Custom Design for Cloud Console --- ui/css/main.css | 2 +- ui/custom/custom1/css/custom1.css | 367 ++++++++++++++++++ .../custom1/images/custom1_actionpanel_bg.gif | Bin 0 -> 381 bytes .../images/custom1_actionpanel_border.gif | Bin 0 -> 171 bytes .../images/custom1_actionpanel_hover.gif | Bin 0 -> 345 bytes .../custom1/images/custom1_adv_searchbg.gif | Bin 0 -> 326 bytes .../custom1/images/custom1_contenttab_ON.gif | Bin 0 -> 2073 bytes .../images/custom1_contenttab_hover.gif | Bin 0 -> 551 bytes .../images/custom1_filter_downarrow.gif | Bin 0 -> 340 bytes .../custom1/images/custom1_filter_uparrow.gif | Bin 0 -> 341 bytes .../custom1/images/custom1_header_bg.jpg | Bin 0 -> 623 bytes .../custom1/images/custom1_headerleft.jpg | Bin 0 -> 6729 bytes .../custom1/images/custom1_language_bg.gif | Bin 0 -> 848 bytes .../images/custom1_language_bg_hover.gif | Bin 0 -> 921 bytes .../custom1/images/custom1_language_icon.gif | Bin 0 -> 571 bytes .../custom1_leftmenu_contentselected.gif | Bin 0 -> 183 bytes .../images/custom1_leftmenu_expanded.gif | Bin 0 -> 1584 bytes .../images/custom1_leftmenu_highlighted.gif | Bin 0 -> 253 bytes .../custom1/images/custom1_leftmenu_hover.gif | Bin 0 -> 204 bytes .../custom1/images/custom1_leftmenubg.gif | Bin 0 -> 229 bytes ui/custom/custom1/images/custom1_logo.jpg | Bin 0 -> 4527 bytes .../images/custom1_mgmtconsole_logo.jpg | Bin 0 -> 5608 bytes .../custom1/images/custom1_midmenu_hover.gif | Bin 0 -> 368 bytes .../images/custom1_midmenu_selected.gif | Bin 0 -> 249 bytes .../custom1/images/custom1_midmenubg.gif | Bin 0 -> 476 bytes .../custom1/images/custom1_search_textbg.gif | Bin 0 -> 753 bytes ui/index.jsp | 1 + 27 files changed, 369 insertions(+), 1 deletion(-) create mode 100644 ui/custom/custom1/css/custom1.css create mode 100644 ui/custom/custom1/images/custom1_actionpanel_bg.gif create mode 100644 ui/custom/custom1/images/custom1_actionpanel_border.gif create mode 100644 ui/custom/custom1/images/custom1_actionpanel_hover.gif create mode 100644 ui/custom/custom1/images/custom1_adv_searchbg.gif create mode 100644 ui/custom/custom1/images/custom1_contenttab_ON.gif create mode 100644 ui/custom/custom1/images/custom1_contenttab_hover.gif create mode 100644 ui/custom/custom1/images/custom1_filter_downarrow.gif create mode 100644 ui/custom/custom1/images/custom1_filter_uparrow.gif create mode 100644 ui/custom/custom1/images/custom1_header_bg.jpg create mode 100644 ui/custom/custom1/images/custom1_headerleft.jpg create mode 100644 ui/custom/custom1/images/custom1_language_bg.gif create mode 100644 ui/custom/custom1/images/custom1_language_bg_hover.gif create mode 100644 ui/custom/custom1/images/custom1_language_icon.gif create mode 100644 ui/custom/custom1/images/custom1_leftmenu_contentselected.gif create mode 100644 ui/custom/custom1/images/custom1_leftmenu_expanded.gif create mode 100644 ui/custom/custom1/images/custom1_leftmenu_highlighted.gif create mode 100644 ui/custom/custom1/images/custom1_leftmenu_hover.gif create mode 100644 ui/custom/custom1/images/custom1_leftmenubg.gif create mode 100644 ui/custom/custom1/images/custom1_logo.jpg create mode 100644 ui/custom/custom1/images/custom1_mgmtconsole_logo.jpg create mode 100644 ui/custom/custom1/images/custom1_midmenu_hover.gif create mode 100644 ui/custom/custom1/images/custom1_midmenu_selected.gif create mode 100644 ui/custom/custom1/images/custom1_midmenubg.gif create mode 100644 ui/custom/custom1/images/custom1_search_textbg.gif diff --git a/ui/css/main.css b/ui/css/main.css index 36c97b229bf..25225cc553c 100644 --- a/ui/css/main.css +++ b/ui/css/main.css @@ -299,7 +299,7 @@ a:hover { .vmpopup_container_closebutton { width:13px; height:13px; - float:left; + float:right; background:url(../images/vm_closebutton.gif) no-repeat top left; margin:8px 0 0 0; padding:0; diff --git a/ui/custom/custom1/css/custom1.css b/ui/custom/custom1/css/custom1.css new file mode 100644 index 00000000000..82215920360 --- /dev/null +++ b/ui/custom/custom1/css/custom1.css @@ -0,0 +1,367 @@ +@charset "UTF-8"; +/* CSS Document */ + +#main_header { + min-width:980px; + width:100%; + height:44px; + float:left; + background:#b84634 url(../../custom1/images/custom1_header_bg.jpg) repeat-x top left; + margin:0; + padding:0; +} + +.header_left { + width:309px; + height:44px; + float:left; + background:url(../../custom1/images/custom1_headerleft.jpg) no-repeat top left; + margin:0; + padding:0; +} + +.logo { + width:80px; + height:37px; + float:left; + background:url(../../custom1/images/custom1_logo.jpg) no-repeat top left; + margin:0 0 0 8px; + display:inline; + padding:0; +} + +.mgmtconsole_logo { + width:157px; + height:21px; + float:left; + background:url(../../custom1/images/custom1_mgmtconsole_logo.jpg) no-repeat top left; + margin:15px 0 0 9px; + display:inline; + padding:0; +} + + +.language_dropdownpanel { + width:103px; + height:19px; + float:left; + position:relative; + background:url(../../custom1/images/custom1_language_bg.gif) no-repeat top left; + margin:-3px 0 0 8px; + display:inline; + padding:0; + cursor:pointer; + cursor:hand; +} + +.language_dropdownpanel:hover { + background:url(../../custom1/images/custom1_language_bg_hover.gif) no-repeat top left; +} + +.language_icon { + width: 13px; + height:12px; + float:left; + background:url(../../custom1/images/custom1_language_icon.gif) no-repeat top left; + margin:3px 0 0 5px; + display:inline; + padding:0; +} + +.language_dropdownbox { + width:101px; + height:auto; + position:absolute; + background:#a44031 repeat top left; + border:1px solid #d87d58; + margin:0; + padding:0 0 15px 0; + top:17px; + z-index:1010; +} + +.leftmenu_panel { + width:221px; + height:100%; + min-height:1025px; + float:left; + background:#f3f3f3 repeat top left; + border-right:1px dotted #262626; + border-top:1px solid #FFF; + margin:0 0 0 -100%; + padding:0; +} + +.leftmenu_list{ + width:100%; + height:auto; + float:left; + margin:0; + padding:0; + background:url(../../custom1/images/custom1_leftmenubg.gif) repeat-x bottom left; + border-bottom:1px dotted #333; +} + +.leftmenu_expandedbox{ + width:100%; + height:auto; + float:left; + position:relative; + background:#9fa983 url(../../custom1/images/custom1_leftmenu_expanded.gif) repeat-x top left; + border-bottom:1px solid #FFF; + margin:0; + padding:0; + overflow-x:scoll; + overflow-x:auto; + overflow-y:hidden; +} + +.leftmenu_content_flevel.selected{ + background:#8a8a8a url(../../custom1/images/custom1_leftmenu_highlighted.gif) repeat-x top left; + border-bottom:1px dotted #333; + font-weight:bold; + color:#FFF; +} + +.leftmenu_content_flevel:hover{ + background:#f7f7f7 url(../../custom1/images/custom1_leftmenu_hover.gif) repeat-x top left; +} + +.leftmenu_content:hover{ + color:#7c8559; + background:#919b6c repeat top left; +} + +.leftmenu_content.selected{ + color:#FFF; + background:#b6b6b6 url(../../custom1/images/custom1_leftmenu_contentselected.gif) repeat-x top left; + border-bottom:1px solid #666666; +} + +.leftmenu_secondindent{ + min-width:180px; + max-width:auto; + height:auto; + float:left; + color:#333; + margin:7px 0 0 30px; + display:inline; + padding:0; +} + +.leftmenu_thirdindent{ + min-width:160px; + max-width:auto; + height:auto; + float:left; + color:#333; + margin:7px 0 0 50px; + display:inline; + padding:0; +} + +.leftmenu_fourthindent{ + min-width:200px; + max-width:auto; + height:auto; + float:left; + color:#333; + margin:7px 0 0 70px; + display:inline; + padding:0; +} + +.leftmenu_fifthindent{ + min-width:200px; + max-width:auto; + height:auto; + float:left; + color:#333; + margin:7px 0 0 100px; + display:inline; + padding:0; +} + +.leftmenu_sixthindent{ + min-width:200px; + max-width:auto; + height:auto; + float:left; + color:#333; + margin:7px 0 0 120px; + display:inline; + padding:0; +} + +.leftmenu_domainindent{ + min-width:180px; + max-width:auto; + height:auto; + float:left; + color:#333; + margin:7px 0 0 30px; + display:inline; + padding:0; +} + + +.actionpanel { + width:100%; + height:27px; + float:left; + background: url(../../custom1/images/custom1_actionpanel_bg.gif) repeat-x top left; + margin:0; + padding:0; +} + +.searchpanel { + width:223px; + height:27px; + float:left; + margin:0; + padding:0; + background:url(../../custom1/images/custom1_actionpanel_border.gif) no-repeat top right; + list-style:none +} + +.searchpanel_filterbutton { + width:16px; + height:16px; + float:left; + margin:5px 0 0 4px; + display:inline; + background:url(../../custom1/images/custom1_filter_downarrow.gif) no-repeat top left; + cursor:pointer; + cursor:hand; +} + +.searchpanel_filterbutton.up { + background:url(../../custom1/images/custom1_filter_uparrow.gif) no-repeat top left; +} + +.search_textbg { + width:186px; + height:16px; + float:left; + background:url(../../custom1/images/custom1_search_textbg.gif) no-repeat top left; + margin:0; + padding:0; +} + +.actionpanel_button_wrapper{ + width:auto; + height:27px; + float:left; + margin:0; + padding:0; + background:url(../../custom1/images/custom1_actionpanel_border.gif) no-repeat top right; +} + +.actionpanel_button_links{ + width:auto; + height:auto; + color:#333; + font-size:10px; + font-weight:normal; + text-decoration:none; + float:left; + margin:7px 11px 0 5px; + padding:0; +} + + +.actionpanel_button:hover{ + background:url(../../custom1/images/custom1_actionpanel_hover.gif) repeat-x top right; + color:#FFF; +} + +.midmenu_panel { + width:221px; + min-height:1000px; + height:auto; + float:left; + position:relative; + background:#fdfaf0 repeat top left; + border-right:1px solid #aeb9c5; + margin:27px 0 0 -100%; + display:inline; + padding:0; +} + +.midmenu_list{ + width:220px; + height:auto; + float:left; + background:#fef8e5 url(../../custom1/images/custom1_midmenubg.gif) repeat-x bottom left; + border-bottom:1px dotted #333; + margin:0; + padding:0; +} + +.midmenu_content:hover{ + background:#f6efce url(../../custom1/images/custom1_midmenu_hover.gif) repeat-x top left; + color:#333; +} + +.midmenu_content.selected { + background:#b6b6b6 url(../../custom1/images/custom1_midmenu_selected.gif) repeat-x top left; + color:#333; + +} + + +.tabbox { + width:100%; + height:auto; + float:left; + margin:0; + padding:0; + border:none; +} + +.content_tabs { + width:101px; + height:27px; + float:left; + font-size:11px; + margin:0 0 0 0; + text-align:center; + padding:6px 0 0 0; + display:inline; + +} + +.content_tabs.on { + background:url(../../custom1/images/custom1_contenttab_ON.gif) no-repeat bottom left; + color:#FFF; + border-right:1px dotted #333; + + +} + +.content_tabs.off { + background:none; + color:#333; + cursor:pointer; + cursor:hand; + border-right:1px dotted #333; + + +} + +.content_tabs.off:hover { + background:url(../../custom1/images/custom1_contenttab_hover.gif) no-repeat bottom left; + color:#333; + cursor:pointer; + cursor:hand; +} + +.adv_searchpopup_bg { + width:100%; + height:auto; + float:left; + background:#777777 url(../../custom1/images/custom1_adv_searchbg.gif) repeat-x top left; + border-bottom:1px solid #2d2d2d; + margin:0; + padding:0 0 9px 0; +} diff --git a/ui/custom/custom1/images/custom1_actionpanel_bg.gif b/ui/custom/custom1/images/custom1_actionpanel_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..897a2219a80d0d709fdc49ff339ad4c6134f07e2 GIT binary patch literal 381 zcmV-@0fPQVNk%w1VF~~n0M!5hpP!$QkdT#?m9Vk0n3$N8lar>VrlX^yt*)+&jEtL` zn~si-sj8~FyuP!ww#UrRyuZQ1#>l_J#kRP)%Fxuz)!NL|*~7`q%hJ}w$;`;k(aY1= z$j;KWxVg&G*38x0%+uM+($~z>*vr(}vbDCy&e6)y)ydG*%hcM;)Y`(v$-ctH!NthF z!^OtS�=Z#L3Oa&C$We$h*G5%hK4()!Mwj!oS1D$IQ^n)7iPaz5oCK0000000000 z00000A^8LV00000EC2ui015yb000J>z)z)CDGEQR+-PZOrkWs-Xd|L+Hd0K;Uh^>pUGTc7kw%b5i*2_EE0-}EfOmdHxQB#Hj*=v zIt`ken-d)qprIWd4y7ce4yO(StgWsHu(7fXv|Ww`|$6 z*|TTwKYaAWxr>L6o#^Z9+qq}ou08vXpE-Z((zR_nc5c|X`OM`TXD;77ed*e<)8{vA z+_Y`SE(Ro^_>%?9(*cnnI~iCt9vE;mmHJ8unE0x#>^p3b#S%C>D${e378jG_)(9Cs PEtW$G6*gS00u0swq}xml literal 0 HcmV?d00001 diff --git a/ui/custom/custom1/images/custom1_actionpanel_hover.gif b/ui/custom/custom1/images/custom1_actionpanel_hover.gif new file mode 100644 index 0000000000000000000000000000000000000000..77378ff5c948d3c98890847cafe4cff2a1e871a4 GIT binary patch literal 345 zcmZ?wbhEHbWM`0OxXQp#RaI49Uf$HyR99D5Q&ZE@($dr0+uq*3_u!EU6DCfZHht!- z*-4Gj$y6%`w|ZeO}$)uN@#cI@7_a`oCd^X5;QGIh(2-MjW3oWF4Kn)MskZ`!hE z{igW~m+ahkaPyAclcr2tx?=VEOsc5!ZD!!xww;f0*KS5f25SJiH-lIJ literal 0 HcmV?d00001 diff --git a/ui/custom/custom1/images/custom1_adv_searchbg.gif b/ui/custom/custom1/images/custom1_adv_searchbg.gif new file mode 100644 index 0000000000000000000000000000000000000000..9afafc9ce12b1eafb0b54a3cff2580dc1a4a0b65 GIT binary patch literal 326 zcmZ?wbhEHbWMc4TxXQp#US3{RRaH?@QC(dtE+4F?Aa41 zPOPo1t*fhRXlR%=ZQ7hUb7st#F>BVW=H}*w3l~n9FrlWVX71d%?d|Qoy}dm>Ju_#{ zY;A4r=;)}guWxH>>+J08?(UvEdGh@E^ZWYxrcRyO*w{E}(xm?W{wY(YG&MCfG}JRt z02F_+fOYGDNRXcx*peN%jyjn1xV1ldSk&ks642_h>86WPi_XK38dHNbC%!0&njt=w zi_29h)kw-$W6BD3hXsD@%|B}_WH_2QgoU-V)YSO8wdLe^C-6)X6Jwsn%s7*gbq*`j Td?toPi@TpJQyWJys`Dx`?XrLdX%P&Vn!HJWQcH@`nFz3B$9XV=5Yv&)tPuOjVB}^V%@Xnk#0^!I8B8+&Lv~`e=2y42iVQVxH0@~*scUP72ma4Ex+(s@1f4(nXA?kDL{wE(GgVU~t63$Rl1LdzWYzRkRZ~+dtGtv)53`;m z<)l9>$}Z1NEyznRN-0Tx{pcn65FBO#KLk5;$OHy!ZR%+2fHyUFcD8p>yIR_*)K-%Z zU9BJb##%qpO~yJq#^2LvZ9^k)6B!w62?=W%iPgo`AK!i~e-o^&ZwiDUdR*-$%Dt`%{`R2O9 z+`C5?wF3WTqsZ$&fr9)SYP;@3FGZd?rCfd0%IT#=nrUZh#7Wm0r+UMK7k@j` zm?tdDfFIoS5h?1PFSLBD-|k+Xf!JenEC=4(TAq8c8`qZ)aS`)XhQK&?3Vk)`FP~nd zNP%TTn$s!@!z$W*3voOTt>XKiJt~T$L0j|1-n|a*C?UK$klf)~ihsEgjtDM)5=LJr zJ4}ZMyvVrRUiGrTE#_o-?yI_m%5vZ81?j@i6#o}_UD78j^dkZTU%axXC5S5?#&tux z)?$Fy-O|&GbsYklc-^pVolZmFuJlsWz#laZLv1QJ7g7a}_6;7-#hV)6A6tA=| zS?jEddW43xder0o6m#&wRz327#zhWjNKRibY*6PTrC~_3ytZNBXl2LR(3uY(!bUFh zYkO$Ns5^~=m-r@Rx?W@P&rgWT!xmuFa~N4xtC-#`g&NLkV0aEd4JO=&Igt}LGG>Sq zXp~$eBQU2Viixra-e9;5ct?&$g~v6`_@J*`oJ31H_J}LbIpF1$G)-H1iArbi^2w-G zJk(rsRLILW#^CwNF3+OBrf6jv@zMzL(ef22++|(~VHeNSbb*UWy%{qFNi{md2;W7nH8V zE|J;487c|V)*P_v4qRg3zPWthDoJIB0^5_3VR$scT7XF>blv%wX95WP4$g}1Y7whPa<>6B|SOU?B}yZnK2B$OfDr+rN9X| z3k6PHpwMiq74tw2pwmbjJGWD%d9|@Gftyt{7us50RsV6l+l6A-it`249e2(V3WvR# z74rrdclPXo5dnxdAokDit8I{y?iTODsOvVKz`ue@NP@N_ghSBiatoNmDLWT3#p3sL_tD^2$XPQIY=FI#0TiK)IAtNIyfXtC!(cHfAA6#6JN|_%02}w!DEwu*oi^lBQ+ISs2es$m40mkV$<+@a4t&a*d zNqa}X7+cWmqh-gUb>&H8g!9UpL9Edjw|W;<9TlT(*5{{DuU!T~0jP{gH~<*`4RjFA AY5)KL literal 0 HcmV?d00001 diff --git a/ui/custom/custom1/images/custom1_contenttab_hover.gif b/ui/custom/custom1/images/custom1_contenttab_hover.gif new file mode 100644 index 0000000000000000000000000000000000000000..f8bf1abbdf0a415aa00d25b37940cb2618106e9a GIT binary patch literal 551 zcmV+?0@(dWNk%w1VPyaz0J8u9|NsBe($dq@)7skF+1c6H*x1$8)zs9~*Vot9*4EqG z+x`9h-rnB!_V)Mp_u$~*A^8LV00000EC2ui0A&Cn000F4P^mHLuvE&sXXl!hg`QYu zV|tDo8eZ@#!gOulc&_h!@BhG{aQGt(j07W0sazs!%^Q+=)J2__=QLU6UaPcia!f9p z&*-#z&2GEj@VI=gE|Ben0zR*|`}==@e0q6CmY0~Bnwy-R zfCvQ$pp~Gbo{puTmZ_n7sjRM?ucEZIwzs&sy1Tr+zPt$t3B#hqwZX^5$hgb2&BD6R z(#5vV$JW=w+S}aS-rwNi;^XAv2IuF)2I}hx>*?C)=1#Ld zpS*(z6DnNDu%W|;5YZh-I8kCngcC2yJD|}3M~oEIJ1Xo*(j&-?98;=X$+D%(moQ_> zoJq5$&6_xL&J=J!fX|;mdHU=b^e0iEM2{vddUUAMqC%faH5#=lRj63AYTe4UtJkk! z!-^eCwyfE+Xw!ZT;FE1zr~%vxa4VPYPrE?z&fR-AZcw>*-)fCZxUk{Fh!ZPb%($`R z$B-jSo=my2<;$2eYu?Pcv**vC7Xuhgy0q!js8geMU_dd01*&7qo=v;9ZPTm~zrM}8 px9{Ho8niCF8@Tb~$VUq&Ts*n+=eCzOhfcjZ>IM&BTkjnK06Sb4HoE`- literal 0 HcmV?d00001 diff --git a/ui/custom/custom1/images/custom1_filter_downarrow.gif b/ui/custom/custom1/images/custom1_filter_downarrow.gif new file mode 100644 index 0000000000000000000000000000000000000000..35bc3330338c82a1138f516300d07c47785ddf30 GIT binary patch literal 340 zcmZ?wbhEHb6krfwxXQp#R#sMATpSx48x|H85D?()?d|I7T2N5n;NW0mW0RAUlb)WQ zl$3Ps+O_M~ub((~Y4+^dJ9g~o>*=39eR@__R&Q_b)Tz_9ZQB-~kXT+`K4HRyuFmc$ z(`TlnrA?VKW!kjqsi~=Tb#-p;?)mxoSFc`Ov3l*A4V!Ml0i{y)gsBo@&eN977GbDGFSrucByo9 literal 0 HcmV?d00001 diff --git a/ui/custom/custom1/images/custom1_filter_uparrow.gif b/ui/custom/custom1/images/custom1_filter_uparrow.gif new file mode 100644 index 0000000000000000000000000000000000000000..264da97f4949ba323747c5a6d905a4cf392cb922 GIT binary patch literal 341 zcmZ?wbhEHb6krfwxXQp#R#xWi?Oj}4Tu@LD78Vu|5a8fqoI8yjn5W0Rhqo|Kf7 zlaq7s;KA$HuO}xbZ{ECl_Uzdw&Rv{3b()u#*NWBay1Tn)&6?%r?mlVKq%|8h#U~^t zr=_*FwqCn-Ej2Z@tFt>HA>qJ*1MAkUD=#nKwf|s$&x9K{Zd6xS*VNR+$H&*z)lHi= zeaiG%3}gYtpDbW~Iv^6{CkD162TyHB9Vy}2lU#~3tmgaqv?i~JS|9F}aQbZ(bL)l* zA3cF{FSg8T$k^>H*>UP^+>N*V-H%x+b?nNynwn(g_}Z15n|OM7G?aKJP89FuVV*u? p<}7BWx%1{PU}9LjWa%;n&E=~Yw1rnMR#~DWsIY#CnxG?tH2~=#cY6Q; literal 0 HcmV?d00001 diff --git a/ui/custom/custom1/images/custom1_header_bg.jpg b/ui/custom/custom1/images/custom1_header_bg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2902bf6e53c2112b6b5e5b46620fce48e8daff9f GIT binary patch literal 623 zcmex=C5UDGKfoZ!!Jxyy$IK|mz$D1XEXer(2tx-0 z1JEp>E8&2Vjft6+or95)fr*(BE(&C@ure}nG7B&;F|aZ-F>%ABfTk%LG6^|~hz1%d zIVDb9c=6%KBxYe{7oaVSj4Z6Y2tx!JnG_9$MFJBGn^ZnHHf}ulP>9*Nd9jOX%Kuvo zJV4u+1epaH>=|Cp{o9$QCbGxp$uSo*^_Rwd`7Srj@5;8P6@4{$zcyddDKpBzD_>P= zw<*t_h2nLBJ2F%8m~T4P!G-UoGf75tGYsubJJUPi+&=jEQyUh{n7)T%NaYgq{4C~3@;@5KM33VeD?0_@T}9XO1k4u6>OaM;?e%ePqhAW g|K7dj)`JP_c2+0npQu}P*Z7$Jiof?_-~7J`0GK(g$N&HU literal 0 HcmV?d00001 diff --git a/ui/custom/custom1/images/custom1_headerleft.jpg b/ui/custom/custom1/images/custom1_headerleft.jpg new file mode 100644 index 0000000000000000000000000000000000000000..570bff9fd4b18b861174eeb995acf3d6022a5960 GIT binary patch literal 6729 zcma)AWmJ?=wEc#mJEc1%Mj8oeX{ABByE`NXq$P%S2oVq%LJ*KHm2QCnl3ZXO z`SYD`eQVuy_qzA&v(Nr<*LnE)umTXPDXA&}AT$85MSZ}-0YIYYXX6qCfB@poe)N3IP581MPnU{6Fzu$I(C_6pH%)2l)Rk9=-x3*Z?m`1Pmep z&`3aF63{~rPzwO4yFefm&;Je(8YVgh78o0q5kMjT2Lgf7G0-q^hyfGO&f@Bz&UJ(?jg|+gm!oR=iSPQKxp6Fsl7Ae@U>DjVBA^|{P z5IQ<84muhL<6lw`K!OHl79b^)(=J5+ZRHhF%Th$nMv?k$LNHQD!Iphho>kEX<3z_= zR~YkQ4!{S4Q2fCpfDCZ$QWIx(3w@p>|2F=J^QXX72dSxx-;L1X#{ua=qJ6rjIQRC6 zv2oHAQl6M&9@YU)WJ9$VVF=NAx3P77-os-v2=vN-^!q5agmV8QFkO!?sb~#ZF_-MP z7N_+Z<(-DgVps4^)wX{C+m{w~(|8f;lYyG1=4TUB$sY1o@j9YI&$XZFE+vljmzfgB z)7Z5!sd+P{Ux$#bIqQ~+A&$)u%sFUk-Cw!Y~v{kvCwV$rw!K+GkaZI0usS1Jl9| zYPU(axbi8BD`Vts;_-j;e&)Joy;@uQZ1lZnFwM+X^#nZLIt`R)g9R?u()V`c6n8Z| zm=!*;JdMqKd?ommbd`XbeY*P^N+Fw?BfDGq>QCHKFd2t28SOxZ;te&Ew`;-o_T*=3 z&*xJGZIi3ToympOS)6k8*ZaXdV3%_ajkJABTqGVf8ruLHGUfrGkwUMMm^Wmx9h9yE z(OVMB;m3duZo77)Y`p|@ImP0!u^Pa8 zHDERG(~oXwr)X)*@o3Y4q&|#X1fW;KjuY<0Nh7kOhOz4E`lEHe!F49;p!{=n*P8+eCqrb?d{y~8bKSTPBdkok;gaT`7N%omNGTPCrAMUbALE`6%kHxpaVVlbSRpN-B? zv*8OW(_g(=yC(5hXWmRpj=3j<9@DPp_XmGN2ji0Ok@hNRl=<)!Qu&ocIftD4z*8RC zc~ZBDYu<@`n)e4#DStl1^4AEiaZ`OZOv^?e$eX4Ze(~m?1_O&j-pf6>V->P6#d_S5 zLXCcR-WTnzq0Rw8d=`k;xl?z7tcXsjNt~p&atkaiJ-fsS!h$TZ46AB>ntDc`tUhJS z`i+}tb?6;G07%-_ME`jg;Kja?Wz5nxf zS&L<%n!b8XLw<1$-);%R1jfP(+hYkEaYiog={7ATEEOB%+eDq&^&c9C`@C+FD=0gt zp-OwS@5#oZ&6dj#8&hOBLCX_gmp*bWZo3n^1A20S^ z;j~V5D3%^g9ZwiypqTY&f7YLtxJk0oll7F}UG>qrt7Po&-Y9O(MT{&7xNpZAqer2k z$IZSAY2ysUj2XmJmxO=~(*KNyT`@d+H%D9b&YI6Y*{_6ek7Ypdy*Y-Z>BZ9TOWs3f z9cu_)y)=gwB_E84Oyf0em2jE?Ylp!E@xs$dhMOe^$=C9DglK=5qTpRJpMR`RELz1i z@=15HW1d-PD1W#y@Jk6b!b8jr{hBs<)yzgb-X;JhW}TbiANI>Wl!n#y2TweG@1h^; zbfo!WnLt!bTL@-7(qrWXV8vMCWs3KfB?^`40L@}I2Akr#2xE@L=dLm50?Z3^N|pr? zOg_}oBi2}N<&5gsYL@0MoZc5`E}KuYHD;F>5wqXpL0OEChN3pS#+Mw$PGyZgLK?Tl zRW^`PvB;WGUlCCgB+}f&pzP}`&AU&R9hGH^8?zNm%YBN{qc0Ad1 zQnauK=%R&OVd4^9*{eWSb<`k_`kwj5-+56Fw8~+OB=u3bngZykSbp;owrm>mc0BYp`En;6>|hB5^h^uf%ZWRu2DhxEyNs9*Rjj+ z10t325k45ObjQ|Jx6vQ)U^3bdDp#V>B=-!gDvk|;1L_rYs^s!{->HAloYNU(eSjP5 z?)9(<;gEc!A+8g4ynAPrI)S3NthOV)e1YF&5Ny(;cGtW|W;=8Ud&5LT(cvd0x0>vK zBHObLuKdwPo2jZ#?Q_xhqv}oQ*NFu5H$|1~SQ_ztjieX8dtq5fzH@=-(Z3C|3LN*$*C-YU4S5zK}r#hkUCIRsu^>(hn=z$`Z&X zzO#rC&MutA$K+?K4Pf;gu5KDY{0pD+G4+ybOAMb$3dJU^NAEIm_*Ny^LQ$G zTdI%s^6b}+8MR01VBjykowHMJjAh+6|BYjdyd$%`k)xN^O5R!a8U^nz?c|c7Z}3?} zeISa3;=|2a>a(l|99SoNKft7wkdAR*X@)ZDR_Eb=FeDsgF^=ek1lOW^$DE9FW za*nC5Ff$dOJ3{ueO=Y1*QSoc!;T$DoDbLD%KI2G}?N`P}AEK0XXjBqZTvY*EFx9H6 z!m#3X-{Du+YtQ_5VJ;gybt1o&JBsyW%Mk}p7fV{h_Ml|t-j&BnX2zlf!9kgd$M}On z86~W`kL%Q{%c-5&&d(i^M%YZjK9HbNRUapnBP|j%eGLMo21V%8Dym$QLX9td2NdI} zmkGG3uq$h-VI4bIaw#MsznmMl?0epCC)2?!Gv!LcR=CXMb7j}I1*f+te?FEjc?{M{ z)CiHoG*H(R)1WaFw1ZXMXCKYqxQRB|o8&huXorPXaOFRzO~qreU>!H8K45p1CH>jd z6uRX*Cqmcl++}p8VjkUgZjTL5JY0AS6#eAd%}^PRtX8MNB*nr>Y9Fq_ZYGPUmopQ4 z0HzrW>9+&QOJ~(2f@73w7(Q`;O+w)|xr?_-CVo%09)QfHv1j9w7mMS&+r|XrHS_aE z`G=#cv|bcWBwrQrH<=tO6Xh|V7x7sb>Ev;JMdqi1e3o@Ds*ginR8l6-d%%dZ-ZoLe zFavzvlKzgOr1Nz;`cWze^KLfjJJBicCj2C}&0W@c7S!#~kq60Fa0{~zF6QK#OC?2; zSl;p^4Ovq6h$K^rHeeQuJCSf&Z-SAs62%qJ|gCj>?k z&T=Z##A7@I3~Ylx$gZ;==XlQIP}NNyK9wmkjY>iAzpT^Y&F9qjmLkv`#$wLb$QUn2 zmZuTg3&kI-fGBSG8w5$tNZ>7Nc+k}6F=H<+zW1P)zW7w~1OdI-5Z205R4r#ytW%K^ zUm?gURgcxV&Z-D{&y+#~sIo)C>F6T-5RM`UhLUb0(*}NXtLWUdC7#?VX4XBN6v3!z z;s}o7JeBFOSYlFN4i)B!Gjcy1y<}2GXV$mhMh9V=Y1dGZnSo=ym@!#l`WJ$$33g2I z$9IZ3)H&O*GBUX=xaDT^j|ms;Gj69p*e?@3DKP9m`vlvv?$J0xm{i$`V?G*J6~*6p zqUYnJVf(>r&jwus44SmxanMA>y^BGxVCN;;l7zf7vY}Vm0^>LtIrdBdBk~|77|!>B-^E_hyLcY!KS^Y5n#%~i=tyGsaA6{uB71s~E}>XG zRJi#oe$nXxSlA;tDkrod6~C*L?(aO*h&ys!h^ZjM`TiFeP>E!U_NkWA^n($RJ_q zo7L<;>Z%Tqq*`**tbg>hJdho`E^d#FevL`Kt;Hm3b-*!>D#BsOY_@)(FX>gU z9w5|cplr}k*lrkw6D^RSklCeg*m2aQ+ri4()#kRrN8$w1{W!1lA*G*|CFyC_cS=z| zo`HE5ab9!J3$b!z-r(e|4-98_vYW*0w567xr2|`hM^ErZ>`cwXeOh)+4pTba_lTDt zE2-ekL@CBRANzR(!(LJ1*Yv~x-Ie4%vGl6J%Dy&uHh8&}y`$CjRR?o@11B-T6P2)_ zFdNdg4^?)B>Oe2^tmGqtqo7mAklLms$Ic?5nZ#6XYj#W=rrK;ehfoZsjRR$5>c=6s zcqM%iie%SBy7!6$f6LBD%&%y=SzpCf0{VIp-Nf|4Wb9yMSNjA=%ZRlu+G#ssGoASf zLh-`yv)~50plQ4C%?VDr1YA@?x}?WcN={;xT`6t_I=I%h(1CIfH6wrKB1XjEwklB9 z!`2EHts_G0;p*CD{f&B6Y^m71ov`7}Tr?cI6Skc-v{UbYBIz;-^r^`sH?&&GsH2ob z_9sPH;|M>`H3cZ7O9_V5*C+WlUk~g+4qtrR%%54hRYEx8j%|@;)$FopAFd{w&{?}$ z;LzjkUeg*HK??;l+qd32jd?_&b013^sOZYLt$4}<9 zjik+-?*5zN5$Z1CYZ))o+6B{e1Kt<2PIy+j5v1`oVy!l2`Kd)kA6w-=W3&;KVv7W%_h>XC``s zIfVBhdRIMMdwG`UjNMmOF~NDu(ZN&y%+;xv(tEOOwE^I1xQ7hq@GQGw1Bya+w^ z%ol1az|9H&xB+r7Ma#jLR|9dxjh(JNt*Q*9U(l71ahBwL+Ukld zmDhj8PHa_)Te|h9>|m(~hd4=(t-dEq>8J8^ zVfw!+B|X@rP8GP5vJPsez0Ns}m6<5%oU56KHA#~|tQ;><5~B(t(t=v%8*Shg4n@so zF;g(?2g(2IS{$PJ%_kDJxYYi&*Ph*?EvE2~&*ah4QZrSM^$rjzewNY_LHhzzYH4?? z1X}=O7Je(>Ic_lRZJ*pJewC;b$#(*fa4z1zdgttnazP6?9PR7-wB#Uk1=f`@9!(uv z)jt{2>lSPOqWcZRgOkt2WbHq zvZNkIr4X7FZ@5s0v2t_#`7N~V`g50u)#HnI(Zhz2K1~DfCdb%cNkU3yJ4W`TCV7Op zhK3Zn_w6Z5*s%gWHCjC53t`RA#QeH4XL;%umNVNdi=Ww!ks`~n-y}*l2pD7-e`V?H zx+_oKH!sYr6XF%==xi7jGjC{FQqlDCgh}xSyUokiQYCS>2diX(ZT+!_rsdh}3}0@od(~ET z<#)pAXr5TxQ3!QqeNc6Hfdk?X#8AQnusn>`HHwM?qV{wY(-m@kgHFeV;;8eMhv43i zlTLITR3K2XmyX(r$r$jU z)VHIfYIikSxVi)7M#)t&i5!ch7ux&)DGErAd|8EIPIT0}*R%)sZZ9V|B$F+QEJO;|_ktr@1jnKo zKEGe0hH|Hpv#(k{&gA2E2!$NmC?;T{$@vVEsRvK-BJy`3h>S&5Y(2tPex{wt!b54E zODfE$x9Xy^F?Z~vF+#XqzO08cQBR%RbEfYiHl)0Rs7fx=jUIE1J^$dXX#I2ZS{I^G zB=(UTN}$-e*Gu{Sk)uWteA%E*F(IuY()t7EIO+F$2fdbsf~yh>MVD zHO}Y(&>KpVSYxTf;3w9I>OQ-cCn_`Zc?>lv84WyxL5^BFt zgBM2Ded1968kV_G(E|1h!Q1Nw=Yzhn)y4ex-OVv+n?F2j ze=pqUGTJLT>mdvZw=MT(Qa8Fiw=M`+b?)B-PlmRiq>Y7Npqx5q-RNKi?R4 z^=x`(lk&!mPo49d$S>&W_H`R&@e&GwozhE;B%8}mm3}(ex`YscHfKWSFPlBN1OM?B z+7P-Ksc4V6sqED}dsUF^^9QnK*n8J@8}dZsO6IoT;5K%RAlzs0r1#b*1zw9HIDYaW z$W&qp=ZbO0w^OFSpZLlrRC!DD(E~7Zc&HKt$q(3k0Om`ZrDgCf`W}FE2fV3Xr=zE3@PEo`CkTJ(E$sEjaI zPwJ>ksd?W_ax$jmD&*;DNK4g7n4Qg%fZt6gWkW53p+K*_v*~5$+U}Wsh;x!{o7c{j zf8J=qWmA2dSbsNEZw5gX2{o6fP^AMA8i^kN`w&m8~(6Ctz-r3)<)zi-ewcmFNw_O&0F0GhdAGiPkA8;n061;W zLs1TBBkR4Z4+(jSJ`Nk+yAPFE&mP_Et|t%j>k_M% zw0g=hY0ahgu`Qy0_)U+r@dKc19oRv?+?c(yLsWGTru>%@)vUB0Y141@PuBj^E~QeL zPnLF%9j3m-RL^u}Jz00VLRGnYwAc{(0PNkT-~TDw-MvR|&=2?ja=HI%J51(j$cX;~ YFxAtUeI*%>a@@donNzPrzlUG{0Sym)RR910 literal 0 HcmV?d00001 diff --git a/ui/custom/custom1/images/custom1_language_bg.gif b/ui/custom/custom1/images/custom1_language_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..5c668e733e35f1ecb44097da6fd32be54571dec7 GIT binary patch literal 848 zcmZ?wbhEHbOlJ^gxXQq=%t3d#quz1{y<4>*x9fl?beV(R?b?vt5w7*Ug&X196TwN&;?I2d{E9xD@YlE!+EIq|?pPz?-E3`(o{{XM3-8GrFGZ zb1m2RR!zvIIG5FKhSzhv_s2Qht_fc2Zgerq=|-{tt(xGgS>6oP0E$0Zz{co+NRXcx z*#0}PKi{Om!_{(d;sh71-ZPAhp0#TH{wYCHQ}uSbKfe;aAc&tm?dR$#PTVgyetdDT zMP?Rbin0L9FGfa&=DJ3P#(JifrsnqEy1w3)zS^$ddWME+Gn;$n_RpW$(bLwiBEYO6 zsMNQlaoW5&8zwdNOqj8LM(vz+6T0fRE@`iudT8F(x$74&Nva7c%$&XZ=z-IlXYFa4 z(B8Ij4%?zbYj5wrv~}~GJKJvwE3-`8a&r2;$t~M2Z`*f#?(WXDhxdCa{{GS(?-+NH zLE_=I7n8LEc+Ly14qp{&;PanPQo!6NVO#N61+B*^F4Fr0PWl}CeB5{TX{YIzSerF9 zQ#Q;H{(5qXt2ft?{}U#2^)2emS+t_WRGsx!hfm~Ah6gFRo0n$KRQIr}bzS3j@W^17ZyVri58>UbjCgosyaOp|MZ6~hZ zOJ-a6rOTv?=RyOMvTVxqwq(bOTwhgf-KLAhg13S%yT0Hs5jNm5`EZb#Lq$M7`;DZK zXz=68=4p`&3(_YU1qilJj*x$Q#Dj^$#(|Mptfat6#N&vetFYIKKvv;o55eOy0h0os jiWTH+Jj#&S@bQRXT*^;X@d%5=Rw?d~048Qf1_o;Yr0!Vm literal 0 HcmV?d00001 diff --git a/ui/custom/custom1/images/custom1_language_bg_hover.gif b/ui/custom/custom1/images/custom1_language_bg_hover.gif new file mode 100644 index 0000000000000000000000000000000000000000..ec770413b9785870289018a30b416e36271438d8 GIT binary patch literal 921 zcmZ?wbhEHbOlJ^gxXQrLp)cQ|FV|@x-(etst2X3z9T0`yt_`_a6MVhUccQuK3SX0( zB>}f;f^XG?oC~ns5NdHL-sNJX)3sdR>semcvc0cmdG(kmZ3wmOF;?m~Rl1(zy~soV zc1>`!D2oOXZeEES}iulJJq#0O)K8hm z$kf%*IB{-s)1`bWJwtnzkeT`3KyPe0Lx!$1$!Vdo(|L*&{=4fZ~sv=%}Bd5sXMTQl-n?K)mJogp|7>^`7_KSy>tmSaoBaxATS_zE?`rDonc~`ETf1{V!`JV#^cG$? z7US*Cx<$b1bMFzsu(K>zI7L?-cp~7k`$v0Z>-vX>woS`k#G>XOtHt?6J|-$MA|{JX z!AZXC$b`d_R1K82omP|m+Z;2D#Px<$SxHiv4BM+t3}ause4G)F_B4j U8&?PxDOkBOi#9B95@4_f07?gZYXATM literal 0 HcmV?d00001 diff --git a/ui/custom/custom1/images/custom1_language_icon.gif b/ui/custom/custom1/images/custom1_language_icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..d4ac50fc4f943183a3b645cdc50e422c78cbab4b GIT binary patch literal 571 zcmZ?wbhEHbnj&d^)|n~e&yb_4Idxed2!+7+iO=YFPMIB$ENes zdcHh)cy?0f$?p2c`*+-)UH{?1t%v)zy}o>QwU_1BH!p5)Ty=i>l&wjgAMW42wq)*_ z0NZ=pH>`BkySjMxg_#r2PwTqSQSfNrj<+{1J=nSR_WBi<8j|mAUUR&&{>JM0kM{3+ zv~T;%b0@yNdU1JT;m3z}4>ndjJ$mrX_Nk})o1dRJa&zs{!?ihYuAIL(XYz-;w=XT2 z_2$~8_qVRUxq9j4`IC93s@a=qGX~1K3Nx~CFmMLRa54z0Gq^GGDKdC#F~o*jic4^_Gc)NMF*5KdFj_Mi nGlVeMFnnUvo6xc1LxMA-h|a&>56czZCi6tH`7#P{FjxZs-=p$d literal 0 HcmV?d00001 diff --git a/ui/custom/custom1/images/custom1_leftmenu_contentselected.gif b/ui/custom/custom1/images/custom1_leftmenu_contentselected.gif new file mode 100644 index 0000000000000000000000000000000000000000..5a631e83b8a52c27311734f23167d069fdd3dd1d GIT binary patch literal 183 zcmZ?wbhEHbWMdFzIKsfNZQHh+H*fCTx%0q*1KYQ6-?wky(W6KI|Np;d&z{SdFW%KgA~<~8|$4zw3oXh?CNP)RyjVllsI#T3W2LhB+L%1&QxV_>ib0Cguw ATmS$7 literal 0 HcmV?d00001 diff --git a/ui/custom/custom1/images/custom1_leftmenu_expanded.gif b/ui/custom/custom1/images/custom1_leftmenu_expanded.gif new file mode 100644 index 0000000000000000000000000000000000000000..be340094672f55a670a850b7d64feac0307a6150 GIT binary patch literal 1584 zcmd^8`%lw%6#YUAQh64t>zGauwjdH^%1lv^f+BRHvWfB-YH<)nks%Lp*zfoI`L-Jr zMMMSW0u1N_`hLG3w6vuZl*yFIROUc4-J&xvjBb&{)%_d0Ik~@_oO{o`$;qPaq9m6P zplaw91oexUeL}2XgmJ`7feH*Nfk*@Tg_zL|4=4avit*(@r~zgVtQ|(hI$-j^TnUpS z!Ngj?m0$)ptargYDaMmwS_fH3Du9lmT^Wcnj$qIDl2-q`v6Y{WJa{2ev4%s7J7viRO^HXm6*(g z45|R5X@}H^a-~d}0oB-1j=Z$FW1rLjB<53CD@~#Y0__Qf1vQR-r5ZxjUf2+!7MR@d zx7;GW0!a0MCu3?Hh{Rl}w$+?#%1~L6lV?8G*ieZM<;pOL0q7jC(uzv;h{A#>tcXMh z)ON%;+R!7S>s+vE2$5S5jUB;Sv-M6`>p=N(Ol7MUXv^6h`($RsGz!ZtXbqa8vLRXr z(k(n9^jb0_ZC!ahIS^~TpFs>RMCYnEjW%?Pj>t?XS6;@Emr0F?NDDeSg`M0&W-Co) ztKmtR?DoCgBD&m!sJ(m5$hpQ0fu{Uq{T6`+D6FW?fpl_qe2ZP(WAx@hR$_HIpp=pG>*W08CHXAQw||gbEVRP$c)~xC{K=YL|9w*0qB2I z(f{E8yEWl$f13#?;0<)LRG3~)55_hgo)TV7EQzP3HWW9XEqfRlL!OSib-Xm28@=P9 z%ja&k`~AJjQb7{Ik4TDZ4%fP3JuUC1x89f?ew57)%h(=BShq7S^a?Gz#euPS*&Xqj z2h;0LjEr|>9{jbSu-137S&1B%{?i=;LrYO@nxwn(573B+cYCfQoS#$RyZ)p0FlS>VvXDvcWH0oSkIwcj3!%gk8=EPUM8fLw zSR%J&%@mn-@e*S`Ag=n^?087(a|JGt736SSmaZbOqPPDIIj?M=q~e11@1n7;QcDT` zVRX<>2;+oBe@Hx3n?6ALtO9#X{9Lil(Up}_v2B;y=vGzA0H*R6vx>|NPi7n7$)tX+3geaPHt3U45_#e z-~(coSopLgiQN(IS)Yz4?WZpIlk;=Z-Nf7|`>2AEV25xOiNF)nYr#CRy)&D})?Ess zLeNxk4Mf3Jfr;e%&uV_4tf4O6NP85dxw$hm^~H^>n2VYp)21zp6FE;Uo2T+_TaxZ< zjhIkR)7GTc-7E^+^Kv3%x3q3LXCu6Lr|3ya-L1^`tXqD`v;A2&b1px)r~YPPZ|bXi LV0|!^3T^urXNjBI literal 0 HcmV?d00001 diff --git a/ui/custom/custom1/images/custom1_leftmenu_highlighted.gif b/ui/custom/custom1/images/custom1_leftmenu_highlighted.gif new file mode 100644 index 0000000000000000000000000000000000000000..e724225936728dd1615f92943034aabcdb1257c2 GIT binary patch literal 253 zcmZ?wbhEHb6l9QMIKsf-?d=^L99&RP(A?admX=msT^$`AT~Sfd*47puA0H7B5f&Df znVDHqQsV3D+tt;Tl$4a4n_FLB@9*y)7#Qg1?;jKt#DE(p{$v45>VQa)oeZp13JQHG zne#GMt;^YMRiJbJL(2V%*4rWXqxU5kIOs_AA89Q*nWH6oVMPg-X~g;)YfKNmt=b>c zQQ@Q4&G}+WRd3pk`yX~#JFUO{zNE44{QK9^4UJ9B4eV|09i45gJ-vPXJwlTvPnkN2 bdB)6HvuAM3o4;V;JpLt1mn~nS$Y2cs)@@!f literal 0 HcmV?d00001 diff --git a/ui/custom/custom1/images/custom1_leftmenu_hover.gif b/ui/custom/custom1/images/custom1_leftmenu_hover.gif new file mode 100644 index 0000000000000000000000000000000000000000..74bb0bb96ad91ee01becd78194fbc9cf7df738a4 GIT binary patch literal 204 zcmZ?wbhEHbYERuBIlh)?p+5mG#{#HcgFYW}<f;d>u%_5JNUM0 zck6}vn>I`7X6(NIwzP0>!@@v>+{@Ah3W4qI63v4N^-}1}e?w$Y9Dp2` ziAS0lPt%N-f^yFlMim^NU)wp#vb+yRxXGB;eXQ5Hhkr8*+=1LahzvpoNCIZo#aCG> zQ&35}@2PfBNMrr?2k0d42z&xLRhdiS^8rW556Y>XtJw<}lA;H~n=3SJ%Tdv#in&Mh z1YRO_@x#JyxT+;0cHT)MW9#d3b6Xx#^nJY*?)q~9*`#Ln)n28@Hw#ZqIcQp*_{)kM zk22CrWOd_JLs^@&^r$3Vri$IwVdv&(b(h!^`-*2$3td)F+1X8ICUmBnQA?VFF+ruo zZmU$<%ZuaX-5@-*C3=3c%OKGJI^g;b{@oG(+3~LH1@(5uLyF(xQ6<@nVeJwbvA_C+ z%oR75DDWPKTKjR(l1-N637X*MCKrJIP?s^n^Kh{kkH{mDUuQsOe^DnYMTSz-UNw&ug zAd&5L$W!f{EwG#LQvhT0DkAaQiPr-QO;v*X{wrpoZtV;x)!Bk|Yq>5vZt1V5$}B?} z_D{`&vSpHrNi6z>^&)zWSL?WE3|O66UwjU;w$2uX@FD3cRr$2Msb@r$QjuozsIT!&3#Nn8nrT*9K_xGISZ{@kED{=G8185k z6=C;j(^l^8#=DTWr<78xQ`4N=tg9*aHmUa?H-Tx0ztbS8@bVv4>rBEDEkvB3KA2>X z_tT#HL|#lVy>nm3AjCU92)#3IYePDV2#^<~Cghd3H#eKJ{hj8OqQ+vm#`5q`68|Mq zKRrT6M-wrq1OOaL`~Ye)Mfxm!@%lzspGByLkDGCfG@k;Y%U0qc+#PFUsG&?2evJ#;1LltL4$s*N&k{_EuA=@dGj zfW!YZu3u|Wrk)xyoA-7>iSEaIp=yU2(RRtRf$^C(fA0vWwzo-+v+Sgp9t*?e?ZCiyBl|H+{n~T_NL1Hm&i;=krZnT z=+`luuHt%$dyl`0J_Y z$Ly_g3ai=4(k=|wx>T6_P(SRbFiYZ5CT#%5N9r|*L1f*_GZ6a5@a!>&5f4GjxsBfT z4+=IR{2lXbQ}XUQZ>AsXh{FUlE!#kZT^wF>KWGCHT8336t}&(<4y6I6(}fF}3+#y3x?^n1!jG4Y(u; zq|lHy!hV_{dU13b=Vo-5s^)S)(w)Ac(pE_OqX1_EnKX)jOHNCAd<2P!jl0y?{m3wp zGe^~}TDe_Fhdxo}4R@^8uc(}3hSN$r7&;z{c=s`~kwRezucZ|*qckw}PGG9!vTlsx zwbP^=xCmA*Ace!NcgPl<(Xtikhil$c1M|HK;y9+eNMU! zO(53#21xoXy`E#{`BN7~GG0zomc-pr4Dpx(%s<8iS9AF`W&aJzJMjIAJu^A7m{9s1 zuzTec328i*Jayl=0rt$)%Z6<(qmvvfRJgH3%Nv|rcFp~fy*2_*uIkM(T++s4^V3(}J6PPyRr5$A+(?KX){&2zo`y^OV5P zE#i);WD%Xjl3gYi505T>)cUfzw4(HPMF*`==ev*f9>tovbDB6II%XV3DNC-8{=o9> zHTTJ1%*o2jmYA2MvB9&|Ml~(i^T$OJP267e^nB}Aab?eH(B`bc7YoXx1H?Rbu?V$N z;Xrk-DoMIDF<&B^dTqj<6?r>Vb_01+6+RS8h8H0K{DsV~2@7r2?o!Q6ac~5?6Zd&c z_c=BC7FtIrD895uwIw?A==PCxu}3TYc{ntdKEMq3WFFO7@PVpKal4uu7x`63oAaXb z{EZrwh=j~_ifrc^>+{UE%krou@Io?7RNJN2#C^%t*F2}cxxn5hz}sH;iJLlCTP5XJ z>w-`e(!~}(*tYpR7&gl@Il4}^s5yFGP9{bdFqPF4q}HRqHT%BM5*pM=K+t1(0%<88 z>?Benh_2rb^=qek;ou+;5m*cNzuk>L6!qC zve$BL#+r$)1MTZF z^W4;?wZTdX?^cV*qz6Jn{Wx5kLMJh)#-CR1BxpiC^tw%VxX5K!$%_yM!`X(WRXmL& zasuzD=u#*JAKd_lcLEds9=H|vbpxJi;a!p8E;Y5x;Z>1?)15>9 z$jflyJJWtT87*A_xNO43n_{HHys6dQwW0RtlDfmb^`leO_oqV9&n$;T*aq;d`jKhx zqcrP{Y#c{WJ`-VIMni+!vMg8MPAU(jXC5b6F`8ebICoP$KB7q4zazx<4eL%SI>gy~ zfJRzdlT>^WkRj)UD?aa>C?9+-ikEQ zcZc(?rX$x*Gc=5>oI|$g-!su0hh;mOnI^>J#`^s{Pz^-e{ zB7SUZk7`mG@#NmGm%gesFn9b45}CJDW|4 ztSxI6P0ziI-3Ub906F1>TYpUgZP31n&x5|$9JpJi^4ZX&x+KvoI*)6gb+}EoI!q(# zPqz*p68w6w8{%57COR+kOr+sFHv+N3wa9D7dL|Klf(clRm`vU%_?M@sdyBSTX2^>xA?2R$^t?h4 zdWv%Tp7v7cs_n=t))PSoAI1I9gNazvs--0M3coKq=0GJutq5_9%j6B9&Kh}0D|j!? zz&NEba;e>NhI~B5%Z!PYyaiH&PT*G2;J)YkFe;WlbugVPi@Py#8!x(s^@Gzw_KA3% zk|ss125eD`77v+LnmEH;bp5yh$EcqhZq9TseyIK7ONKPDBqvn2@T9U9(kkiA6JG&k z@&+lN9V#Sj8p0)2jPmN^=_vO}?yJbZfU){*B2I0RjrDiRgQuYe%2WfNDtc{e)mAMRKl>45 zESRqqnroj^Dk4FvGlPDDCtgNGfijkzjW-{^Xtz6t+B-q zEK%lQp}g6{olaJwazJf1R90?Yp9~k<6nB4c&S*L|t%xUV`CE&<=l9dMAdPnwmUJ;n zu9TBt4~NKdMvZs0TLR*Bn{rKYuPYquJ>I6u&_U&}aQ4Lu&r{XD=5E(T)>(aPDsW3P zK!@BwG!!f8BGi6{cx+JheBHcPfH5*Np^&hNXe(Y$A?-=^$ICQV`cx0XdJuIKKL|Ud zDn$|1-vA80i1};r4sWuW-M6AP^ZH!!?<*%97q6a*mh-kt?1Lzi;P{4BJVzz=ibkPI zsR*rzs{N1hy>e;nQc7AD%{}`SIuq?bly-NkV6%YJvf3m#$9k6Ir}@x0NNxjOV5H7@ z3`<-&pt%+yAtH!rCckHUt)eJl`J(4D2_F+!@~d`4=#%A~utG^cduJO*??OvjqF&Fl zN}HYrf^v#-W7 zqP6>5FQ3bSne_r?4v^Sdwp}Eop-TBi8rF*(KC|KNIcN>k^3ulr^GCQFC5SB-4V}@^ zgl~S6W3u1;9`nIx$C{g@Puyo)ZJ(&g=y0_fcU?40Fx~}~KVqv;mJzVXXQEH5_$bEV zcs?|~f?9r?9)j$U5Xi^8vS8g3;Q(7sunkAKw#gk>9f+{oL{gJPWZDn5>*k522)?T|(JbsjFwzlF$BIIj@@(iObNm8Wdf35SyCXx!?Rp{FwRW-o{Zwl=2pLxD$ zy;q0p4QE=VN2t#G5tC3IC{n|pM(f*V8G+pb7WCLd+TJ{--x`az(o&r(#!v6zO^ncE z8O(%EAxq2J_%n4C?`QfQ$+n|TiJ$qiuu{oV z#%po6D1W~|m%UNUmEfY#SJm6kTy$9fLL-^|Tdo4D)!Jwz0)FQ9DceOa%wOkU9?6^S zcMM+ys*mjuBX@Q%G7hD-8<@Q%g~isP#iNZP6ZM13T)er(4^Q%R{J*uk0$RrYp^7rq zbK^^*8<)atlG%-=E|_A>oq$~)fs63NiGudMjJv(>pn2ERm;uHe*lsIFWvwE literal 0 HcmV?d00001 diff --git a/ui/custom/custom1/images/custom1_mgmtconsole_logo.jpg b/ui/custom/custom1/images/custom1_mgmtconsole_logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6598db09dbe698d31c047e1b821cd259e5b3229e GIT binary patch literal 5608 zcma))WmMGP+J=ARARtJGbcckbbPt` zkA;Jci-QNk`(J)f?llk@IRQYy`jnDNiH+LOK0$=W``u@wm+TMzd{qwRP`TfW^{={E z__(;Be`)s?87>~cO3p@s|5S-m<^baRhS+2{ zWPk!N5bM9mhr#dH+balFWxDkx9Rs}+Q8$^RCifgr**jp;B?*N0$ zqc)U^n7dfn-d8*sHe2_%QxoB`(2e?k!mUfo$QPj*J%`3en&cEmV_`33M`;} zshXvPUA3!NXkkKNfSsjWJYHwZ3-?HQL%U?VO0LEZHZf`Mv`v^v@qgl7A&W5}mM~F~l3}a2W z%XE56?|tz%HicwF5rl2G=VrL}UAk^XKxfCwsOt8=Q0c00z5L{sgq5DSr7hOScj6D_$OHLK+tV;&hCtoQ>^oF)lK zRBocl&`QhG{_j-sI!4Mg#P~+$)ZZ8~ZELj#Gv5nn9KNYruR`?)DMm?f{2?-0P?Rl^ z4mJ@#G+ke26`YD$ZPM|jYjcWn?Td1arYZhd zqRpSt)df|($4PI^wsIA4hOCGsD5sZlzX&D|1eKnFY~E~UbJ|0^g5mKEhyjc#jbMi( zU|g4Ai^Q+E;=9cgmx>csV6B*bj1;L3KjN6ojx5)h?B!WGZ%&y05jCPdPP)y7)jVRb_+=ji-{?@*TR?-F_|P z>csti&<4VdQ#vxqxlU!GFLamy4tL&j)#;dl~s~hLec*iIr z-Gs#VL6Q2yPbS-Yy&uw-EW~LFu=J0)H@+&Ru$Tkk8S;)_wjtJgp=UK{Z*SsKhDudV zf(^ZE^-c|OY$W^m^O;LjjAPYyZCzV)%GRvZ0JWOzBXS~&8oq)@Lk|dHFG;GXby#yC z^~P!9;Fg+8-E&g5w^6e z3PqP{$fl&~>;=qko6`f4vZP`8>!iLk7dx{*_Xe0ub!J*IQ*=^jwWY9s*XOeD<#Div z=5*93Q0__3QF54I@59XS3VpXnZn^nWM zw_*`g5u%;y8pX?$WtyGPrPOT*7sdiNEkB5F84zUnj5sY=Q91b|zj-#pgWKE!U;@R1 zgEwYmm>H4=R6_$)VKX~Kqj)14@dzz+$}wkm2cbfMJ7Wi`70WjOg4o#a+`-&*TQ>uqRYR&o)+@_O80HC zq&e0=lDxC8AVn;`j9T{nFDIFga88TfietQd@}<4Ev&XIxCG*Uawvy3W65rUUF3rBI zib^4(vKVuF))Uz#S4uu{eC{#+@_l4oir@Wduz16_p%8eyB34&o(8_W_7GmO*N@D(p ztUoLA6=&g1zLRmyK0mLg=4r{9v;I_>wg4#$kL&GbWGnZ_oia!3cTqw}KWzxLAp%2j z`oXcDosA z`dqCnJ!K}WP`(naKY8KyopkG#Jp-Os)76-$?IgfWM;#dwZ=IwxkEd^5=5gvawHzbW zx@FdLF~Vo;IpfC7J=~|HJc~i93#NTYwstS2!6bVekVW#!FsKp|p?P-NdwUFu4Z z4@`hMPil?D27BWC#!~~#hY&@MI0HVpiFma)^g~XlmL*9EwqxGVmSz;SVR?gL9~SE; z9=Ah>FVltJ>Kb_-$cLnxQjE}%$MGidT%_CqZn@nl20!+Nk?4{2$tQ%W|H!{xXVW`r z^F12~tseRrgN#;b4Vn#5<_}=9JeaKZsND27sWcay4>UfPRiD%vUj{G3^<&mWc%%B3 z=DsHciN!A9?}_Qz4h~`7MQ*_?vp|NKYF~EK3xsdp6}81-$c};Cf>8W*%cq3QS`c*A z;duM{b^CXlIkB5PXCUI-0JDz5I-Jy@1N)v_7-#2^Ef`tJ7!Hn5%`71rF#qeD7zVvo8?D#Dl?% z1u%8XPChv2SK8CwBE|?lr13{D{kkItqg?XV11rmUSvk@>;1^=Lu79VI`8`z3Zhj^` zHeeZfy9~Gbq1ISKeMyW^emv0OZ*J{)YYiPonm6D(67a2W__85c@XMsmW2n=t*ix;- z%sBEobXH(u)u}?JQoNGyndZIm8LJexTw@kV30taX1z~@)x*k@KYiqIGR=gpQwpLw% z4W86))YR2SZRml2jDoyfTw~Peqi_n0ot<7hgW~Z&KW7ve`FNRC;T^zl(XJwtoOUZS zTlrHvCc+;UZ57|o00j>(5%kLuR!ulfzCm_0e3$h5&B0m=R^czYp%B2u2C?yKQRqe=GLs$25G^>)S{X4-{pM${*JdaTvVOPb`63+ldWZ zbC^~clt227=0cD7%YGz?f|?KYkSzM#%wXP>Ah6~00s1(<7@oz0wE+5LJ6~Eb9!%KN6E$S*N+0zX#F*7Ju z>+)xdD2~_8N>v+WRiFXWnLWz)Ria-Fr+dd*ju}+7t#_vXHuTu6y02`a#tt&eZm5qr zbts^s+IC2a2y>fvav_<7EKjNm^$8KUM_42t7-D13cSbzRDEHWbS$E58tVkgB_-ofI?ohX8( zhH{&QpZe3b`EF{Qb1tzZgGrHReL^Wka@dff4C~94BgB|!O0Ukhf>~n3Gh5pkYq19` zT_VtQ3Xw)b14Kx-G*W(I*WNJqkF9u4fF84qJsxK2_XiDP*c*4(!vwK<{@XopHE}sl zwHfQYGTA#y^sK_COe-2}mb1@gd22B<-Y|7%0P8ISD`1oAGW2o8ukibUrl`C(J!229Wfk3OOOs%?v$h>qd{2aO-19sSd3 zpOZcxW75W1*(!X~;a35$vkY)-a&yVAk6Dr_uq|iK(NxdqJw7kEZG^PsdbH3 z;11_)YWt*tg?74DCa|rR(r4jbk=r7%$T%wO$f|&U*3^_Eiwrp`Y7OFz@ti)h zuvAJB(qq@y8kQe!CsWPS&KM2M?3O#nhiBG}&5S4q+9}qmX_&k^qSBaOP=msxb^SK> zlEk%?%0-d=gwJWin0{Lf@(LW%wH&BCz^p@wc$~IA5 zvlTDf*hPkYoS)U$)P)X3FYgE=|91QOJ*0u8Gl`!JMu7$kYkhv|soli19!X3MM-lBF zmZJ{Zx=TVPwI8*ONxez1hWk5hnsM;W_FAItH%T7X8L&Q^$yR7r(=l+aR?v|&65Mx5 zdJ!(>tKP$-Qqn;1y-!2R!t|q<=eT`$YO}?Y=fnQUa2ULr#qkkrfl>(V@>0f$y;z;v zp$;RC=((6qM!Q5D`e*v7c|>+0lL*4>O3lF<^GE0(2iXlbgoDKFEs ztk736D2tRn<9_!1&j$(Ccn>O1{wth{z^s-#z!mzzkG$4HF3fL|E0r&w6-iA%8LNbg zz&GI-VcdE-VD+&e6wL3 zCQ?_Wu(atVqH-9Lt?OlO9y*1xg(MUn$WE;l1|1^mPI`LVQ=uH{oF$ivXG6?UM+lmZ zfk_Ps*ttKNWv6L+bcU-xlTIwvb5~&BCOw=^S)hEvz(R$7$@=Uecl6~VR~rq4nlIxVyT4jMft-1FB- zG3XPq5U&$ajfAlDaMk8wU-qt@;7i{Dq>=mtZI}FyH2 zMf5L@_2W<7jr9oy;g4g?FXE?qH6M@+(R1TOZWj?Dm{6c@M5Y0M|ZU4Q2qHBsjXlJ?91VLgyLeIqf+?`87-3fq?KcTc5C?;#7tcFj=m^_Fg?+g*GRwg>O||b z@cQbOh5h*LPKzRrjcnuexvyDIs~@Rd(_9lKr^T%*#~%_bn4xk^un$~yh&{TN7W2EB zHnj?}d~w`de+Ot#c!j6Oq3t5Vvu*f}s`Uje9kWo=y6T`N4@NvjNs=xmna0D5y$hc^ zVBy-A0OJn<&aziwXU)6Pkov*DUDEDnC&jJ5?V1;h;$m$|i{Jlh!atZ=)Gl68AQk=@ zJe9?5w{9bQ2I=J0C9l=rQ)tz@4I#08fO2`ht3MjjO59v~j&rZ8M#|7;pXUT$$#h)% z)zsY94x@?!5I)PzgX4$moeGG#5f{{4VDcT{ea(cHk4u_cAGu~+Yz2h>AUTc9o#vuXL6VJPs|uRy#a_CfH`t5P?*K*jqE6oJ ziyIUo8HUnJ)*nAtudj#YNV?z7xfc&t@9!i+i|znjiAu5Znde73N_3S2!FF=MTR>=j8NwYx`;nL_r4tQ>kEBr}~hnKNvQN`b{+%qZWn@ zQ>hZIXTqwb_X(_{nT4n}RN^$F?_?T4scY7EU$iD(jK zVppX`83Z*5BP(S~mkDYU)HGSIN*Fb<+NQ<;!Xc+^lbxl|! zT9@cO%3iRnwg3Pkon#I`YHZ_8z^w0K@%L)YR0~)z!JVxxT)>%*@Qu(b3r0 z*#H0k#KgqK#l_0X%FfQtySux>!otA7z`eb_xVX5+#>UXl(9+VP}phjO_bIG;~WheNG$D%fnc!R>Y#;Ba_DCV$G2v|24`yWN_&Tz;tA z?UTG-kLmmU5P^b%0fmN#h=vA>jEoeIkdOkCl$Dm00GXPb9-E$@prN9pnjru?&&G}K literal 0 HcmV?d00001 diff --git a/ui/custom/custom1/images/custom1_midmenubg.gif b/ui/custom/custom1/images/custom1_midmenubg.gif new file mode 100644 index 0000000000000000000000000000000000000000..61c908f249310f76a7452f026aa7cf4dc8153959 GIT binary patch literal 476 zcmZ?wbhEHb}K&eMOt-~IaqwB^PBpHKb*)%<+HKmkzv z$pY4`10q3wVqp7upjE(tCB}ujVG@UfUgz}FPN!nxm>L?)PP2w6M76afc99(i<;0sG*6{BQBOMOFAS0fh-KNpt*OYh_fy$Ta1H}W%!@z3L* z!@P)j@v>!NbH&)%nb)pcx@OZlcCNMC6qhn9a_!o z7&_cgBo*C^w2)MO0+I(Hs9YwBN8|u+RL*AqLf^yp_C0+!($f+W^Z9@uunGVkkEf`p z$nADB7z~%orP1k`Os3Q6oSsz|7Z-1DZyy{Suvjb_jmBoP%gV}@mX^d~abshn)oOJ( z9OIL+j*d=+QbniJDHMv)Xf&J6GMQ|De}8#-nM$Q96bifDzP`RbI4l$l{1}z~luD(0 zdwZZ*va_?(*2b186k`*U8r>X!KrlaV;Bvb`5EKXmTU%SbUwFGV+l*T6a=Udp{fJ1+ z<#J0(O5`$md3m`=B$A9u1{Qb^2CT zt5&O<)o2$Nm-_qro12;K?VPTzE(W7XC=_zLxO_ez1VzAqfIWcytD_Hn_yj0q&b`xeGdMXTorpld zyuJ_cI|qk`g&bIXaPY0b=s4ot3((`xtEa%}nOQaIY+zti8WCFvF&dLpn%|~BG_S;{ z$Qm@#7afZBg*@|Gb2weZ^JmH<{3Ebxpnh=gW9R?)lU&AAg zMUuiANqAIjUo30^PfP`TFu1X%d(V*#aeV~>*c7Cy3ikAgGA!eDHYPOoNVxXmIUxl& zfx$HA@uUH$gu#?7)j|psi}Np~W_&f{yn><=vR)afc=)Bv_yTP#1gr)gNI(73*H%Fh zJ|U&qEw@h+?jwSVq{;B3hS9Y*u)@bJy@Uum25DMI8L60{rlJCJCA|a)C!3i*lFEDW O@;Z*1-kjtIT=@%6Lxhe1 literal 0 HcmV?d00001 diff --git a/ui/index.jsp b/ui/index.jsp index fd6677c2b85..9326576a920 100644 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -12,6 +12,7 @@ + From b07162f30a838903152a3fab0522979eff132fc9 Mon Sep 17 00:00:00 2001 From: anthony Date: Thu, 6 Jan 2011 19:41:00 -0800 Subject: [PATCH 027/142] merge from 2.1.x deb87aa5e7f05569590abd4aa3dac4f11ab1cf84 correct definition --- .../com/cloud/hypervisor/xen/resource/CitrixResourceBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 011d5e8a605..513b9fad1a2 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -2604,7 +2604,7 @@ public abstract class CitrixResourceBase implements ServerResource { } } - void startVM(Connection conn, Host host, VM vm, String vmName) { + void startVM(Connection conn, Host host, VM vm, String vmName) throws XmlRpcException { try { vm.startOn(conn, host, false, true); } catch (Exception e) { From 044308095bc5c2687ae1d1357bc292fe46ca78b7 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 7 Jan 2011 10:47:24 -0500 Subject: [PATCH 028/142] add home-made qemu dependence --- cloud.spec | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cloud.spec b/cloud.spec index 700d1ae87aa..46dacd70b05 100644 --- a/cloud.spec +++ b/cloud.spec @@ -223,6 +223,12 @@ Requires: kvm Requires: qemu-cloud-system-x86 Requires: qemu-cloud-img %endif + +%if %{rhel} >= 6 +Requires: cloud-qemu-kvm +Requires: cloud-qemu-img +%endif + Requires: libcgroup Requires: /usr/bin/uuidgen Requires: augeas >= 0.7.1 From 274edf1478ef9f650e8db8d143904e92cfd65ee9 Mon Sep 17 00:00:00 2001 From: abhishek Date: Fri, 7 Jan 2011 10:33:11 -0800 Subject: [PATCH 029/142] fixing sec group rules creation, and also adding some description in commands. checking in so that ui work can begin. --- .../AuthorizeSecurityGroupIngressCmd.java | 28 ++++++------------- .../security/dao/SecurityGroupDaoImpl.java | 4 +-- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/api/src/com/cloud/api/commands/AuthorizeSecurityGroupIngressCmd.java b/api/src/com/cloud/api/commands/AuthorizeSecurityGroupIngressCmd.java index 008f4fe8a0d..e1da8de662c 100644 --- a/api/src/com/cloud/api/commands/AuthorizeSecurityGroupIngressCmd.java +++ b/api/src/com/cloud/api/commands/AuthorizeSecurityGroupIngressCmd.java @@ -40,7 +40,6 @@ import com.cloud.user.Account; import com.cloud.user.UserContext; import com.cloud.utils.StringUtils; -//FIXME - add description @Implementation(responseObject=IngressRuleResponse.class) @SuppressWarnings("rawtypes") public class AuthorizeSecurityGroupIngressCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(AuthorizeSecurityGroupIngressCmd.class.getName()); @@ -54,40 +53,31 @@ public class AuthorizeSecurityGroupIngressCmd extends BaseAsyncCmd { @Parameter(name=ApiConstants.PROTOCOL, type=CommandType.STRING, description="TCP is default. UDP is the other supported protocol") private String protocol; - //FIXME - add description - @Parameter(name=ApiConstants.START_PORT, type=CommandType.INTEGER) + @Parameter(name=ApiConstants.START_PORT, type=CommandType.INTEGER, description="start port for this ingress rule") private Integer startPort; - //FIXME - add description - @Parameter(name=ApiConstants.END_PORT, type=CommandType.INTEGER) + @Parameter(name=ApiConstants.END_PORT, type=CommandType.INTEGER, description="end port for this ingress rule") private Integer endPort; - //FIXME - add description - @Parameter(name=ApiConstants.ICMP_TYPE, type=CommandType.INTEGER) + @Parameter(name=ApiConstants.ICMP_TYPE, type=CommandType.INTEGER, description="type of the icmp message being sent") private Integer icmpType; - //FIXME - add description - @Parameter(name=ApiConstants.ICMP_CODE, type=CommandType.INTEGER) + @Parameter(name=ApiConstants.ICMP_CODE, type=CommandType.INTEGER, description="error code for this icmp message") private Integer icmpCode; - //FIXME - add description - @Parameter(name=ApiConstants.SECURITY_GROUP_NAME, type=CommandType.STRING, required=true) + @Parameter(name=ApiConstants.SECURITY_GROUP_NAME, type=CommandType.STRING, required=true, description="the security group name") private String securityGroupName; - //FIXME - add description - @Parameter(name=ApiConstants.CIDR_LIST, type=CommandType.LIST, collectionType=CommandType.STRING) + @Parameter(name=ApiConstants.CIDR_LIST, type=CommandType.LIST, collectionType=CommandType.STRING, description="the cidr list associated") private List cidrList; - //FIXME - add description - @Parameter(name=ApiConstants.USER_SECURITY_GROUP_LIST, type=CommandType.MAP) + @Parameter(name=ApiConstants.USER_SECURITY_GROUP_LIST, type=CommandType.MAP, description="user to security group mapping") private Map userSecurityGroupList; - //FIXME - add description - @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING) + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="an optional account for the security group. Must be used with domainId.") private String accountName; - //FIXME - add description - @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG) + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="an optional domainId for the security group. If the account parameter is used, domainId must also be used.") private Long domainId; diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java b/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java index 20e6880f14b..f4df776966e 100644 --- a/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java +++ b/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java @@ -40,7 +40,7 @@ public class SecurityGroupDaoImpl extends GenericDaoBase AccountIdNameSearch = createSearchBuilder(); AccountIdNameSearch.and("accountId", AccountIdNameSearch.entity().getAccountId(), SearchCriteria.Op.EQ); - AccountIdNameSearch.and("groupName", AccountIdNameSearch.entity().getName(), SearchCriteria.Op.EQ); + AccountIdNameSearch.and("name", AccountIdNameSearch.entity().getName(), SearchCriteria.Op.EQ); AccountIdNamesSearch = createSearchBuilder(); AccountIdNamesSearch.and("accountId", AccountIdNamesSearch.entity().getAccountId(), SearchCriteria.Op.EQ); @@ -74,7 +74,7 @@ public class SecurityGroupDaoImpl extends GenericDaoBase public SecurityGroupVO findByAccountAndName(Long accountId, String name) { SearchCriteria sc = AccountIdNameSearch.create(); sc.setParameters("accountId", accountId); - sc.setParameters("groupName", name); + sc.setParameters("name", name); return findOneIncludingRemovedBy(sc); } From 8284abedf5a21f49ee69295e03ea5015f68358c5 Mon Sep 17 00:00:00 2001 From: will Date: Fri, 7 Jan 2011 10:39:31 -0800 Subject: [PATCH 030/142] bug 7902: Fixed problem with updating secstorage.ssl.cert.domain as it was incorrect set to be validated as a boolean and also was set to be validated as an ip range. - Fixed error message returned when validating boolean to not return double-quotes as that breaks JSON. --- server/src/com/cloud/configuration/Config.java | 2 +- .../src/com/cloud/configuration/ConfigurationManagerImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 57cfce0d2a8..e7f2becfbc7 100644 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -154,7 +154,7 @@ public enum Config { MaxTemplateAndIsoSize("Advanced", ManagementServer.class, Long.class, "max.template.iso.size", "50", "The maximum size for a downloaded template or ISO (in GB).", null), SecStorageAllowedInternalDownloadSites("Advanced", ManagementServer.class, String.class, "secstorage.allowed.internal.sites", null, "Comma separated list of cidrs internal to the datacenter that can host template download servers", null), SecStorageEncryptCopy("Advanced", ManagementServer.class, Boolean.class, "secstorage.encrypt.copy", "false", "Use SSL method used to encrypt copy traffic between zones", "true,false"), - SecStorageSecureCopyCert("Advanced", ManagementServer.class, Boolean.class, "secstorage.ssl.cert.domain", "realhostip.com", "SSL certificate used to encrypt copy traffic between zones", "realhostip.com"), + SecStorageSecureCopyCert("Advanced", ManagementServer.class, String.class, "secstorage.ssl.cert.domain", "realhostip.com", "SSL certificate used to encrypt copy traffic between zones", null), DirectAttachSecurityGroupsEnabled("Advanced", ManagementServer.class, Boolean.class, "direct.attach.security.groups.enabled", "false", "Ec2-style distributed firewall for direct-attach VMs", "true,false"), DirectAttachNetworkEnabled("Advanced", ManagementServer.class, Boolean.class, "direct.attach.network.externalIpAllocator.enabled", "false", "Direct-attach VMs using external DHCP server", "true,false"), DirectAttachNetworkExternalAPIURL("Advanced", ManagementServer.class, String.class, "direct.attach.network.externalIpAllocator.url", null, "Direct-attach VMs using external DHCP server (API url)", null), diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 968f025a330..c5ad0ff51ae 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -285,7 +285,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura if (type.equals(Boolean.class)) { if (!(value.equals("true") || value.equals("false"))) { s_logger.error("Configuration variable " + name + " is expecting true or false in stead of " + value); - return "Please enter either \"true\" or \"false\"."; + return "Please enter either 'true' or 'false'."; } return null; } From d95c7a4adeb983747f31debfed190ef0a6217c5b Mon Sep 17 00:00:00 2001 From: Chiradeep Vittal Date: Fri, 7 Jan 2011 10:50:52 -0800 Subject: [PATCH 031/142] hypervisor type is required, right now the parameter exception is thrown inside the resource svc --- api/src/com/cloud/api/commands/AddHostCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/com/cloud/api/commands/AddHostCmd.java b/api/src/com/cloud/api/commands/AddHostCmd.java index a1f7b02754d..e73eb037864 100644 --- a/api/src/com/cloud/api/commands/AddHostCmd.java +++ b/api/src/com/cloud/api/commands/AddHostCmd.java @@ -63,7 +63,7 @@ public class AddHostCmd extends BaseCmd { @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required=true, description="the Zone ID for the host") private Long zoneId; - @Parameter(name=ApiConstants.HYPERVISOR, type=CommandType.STRING, required=false, description="hypervisor type of the host") + @Parameter(name=ApiConstants.HYPERVISOR, type=CommandType.STRING, required=true, description="hypervisor type of the host") private String hypervisor; From 789912de6a099ba8bc079e465742751bb74d721d Mon Sep 17 00:00:00 2001 From: alena Date: Fri, 7 Jan 2011 10:47:45 -0800 Subject: [PATCH 032/142] Removed guestIpType parameter from listNetwork offerings command --- .../com/cloud/api/commands/ListNetworkOfferingsCmd.java | 9 +-------- .../cloud/configuration/ConfigurationManagerImpl.java | 4 ---- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/api/src/com/cloud/api/commands/ListNetworkOfferingsCmd.java b/api/src/com/cloud/api/commands/ListNetworkOfferingsCmd.java index 1864b4e06b9..64c726bd64f 100644 --- a/api/src/com/cloud/api/commands/ListNetworkOfferingsCmd.java +++ b/api/src/com/cloud/api/commands/ListNetworkOfferingsCmd.java @@ -49,9 +49,6 @@ public class ListNetworkOfferingsCmd extends BaseListCmd { @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="list network offerings by display text") private String displayText; - @Parameter(name=ApiConstants.TYPE, type=CommandType.STRING, description="list by type of the network") - private String type; - @Parameter(name=ApiConstants.TRAFFIC_TYPE, type=CommandType.STRING, description="list by traffic type") private String trafficType; @@ -78,11 +75,7 @@ public class ListNetworkOfferingsCmd extends BaseListCmd { public String getDisplayText() { return displayText; } - - public String getType() { - return type; - } - + public String getTrafficType() { return trafficType; } diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index c5ad0ff51ae..8edd2c78c9e 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -2739,7 +2739,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura Object id = cmd.getId(); Object name = cmd.getNetworkOfferingName(); Object displayText = cmd.getDisplayText(); - Object type = cmd.getType(); Object trafficType = cmd.getTrafficType(); Object isDefault = cmd.getIsDefault(); Object specifyVlan = cmd.getSpecifyVlan(); @@ -2765,9 +2764,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura if (displayText != null) { sc.addAnd("displayText", SearchCriteria.Op.LIKE, "%" + displayText + "%"); } - if (type != null) { - sc.addAnd("guestIpType", SearchCriteria.Op.EQ, type); - } if (trafficType != null) { sc.addAnd("trafficType", SearchCriteria.Op.EQ, trafficType); From 1c29a5f8241835ee24aa4bb8f35c5f967adce9eb Mon Sep 17 00:00:00 2001 From: will Date: Fri, 7 Jan 2011 11:01:26 -0800 Subject: [PATCH 033/142] Listing only virtual network offering --- ui/scripts/cloud.core.init.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/scripts/cloud.core.init.js b/ui/scripts/cloud.core.init.js index 2710f480f3a..6380a64a7ef 100644 --- a/ui/scripts/cloud.core.init.js +++ b/ui/scripts/cloud.core.init.js @@ -163,7 +163,7 @@ var md5Hashed = true; //configuration bindAndListMidMenuItems($("#leftmenu_service_offering"), "listServiceOfferings", serviceOfferingGetSearchParams, "listserviceofferingsresponse", "serviceoffering", "jsp/serviceoffering.jsp", afterLoadServiceOfferingJSP, serviceOfferingToMidmenu, serviceOfferingToRightPanel, getMidmenuId, false); bindAndListMidMenuItems($("#leftmenu_disk_offering"), "listDiskOfferings", diskOfferingGetSearchParams, "listdiskofferingsresponse", "diskoffering", "jsp/diskoffering.jsp", afterLoadDiskOfferingJSP, diskOfferingToMidmenu, diskOfferingToRightPanel, getMidmenuId, false); - bindAndListMidMenuItems($("#leftmenu_network_offering"), "listNetworkOfferings&type=Virtual", networkOfferingGetSearchParams, "listnetworkofferingsresponse", "networkoffering", "jsp/networkoffering.jsp", afterLoadNetworkOfferingJSP, networkOfferingToMidmenu, networkOfferingToRightPanel, getMidmenuId, false); + bindAndListMidMenuItems($("#leftmenu_network_offering"), "listNetworkOfferings&traffictype=Guest", networkOfferingGetSearchParams, "listnetworkofferingsresponse", "networkoffering", "jsp/networkoffering.jsp", afterLoadNetworkOfferingJSP, networkOfferingToMidmenu, networkOfferingToRightPanel, getMidmenuId, false); } $("#leftmenu_global_setting").bind("click", function(event) { From e57a4bce001016c271baa70c06a9ee0a7f09cfa3 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Fri, 7 Jan 2011 11:09:06 -0800 Subject: [PATCH 034/142] bug 7744:create shared function clickItemInMultipleSelectionMidmenu(). --- ui/scripts/cloud.core.js | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/ui/scripts/cloud.core.js b/ui/scripts/cloud.core.js index a76998198da..d187a8c4b29 100644 --- a/ui/scripts/cloud.core.js +++ b/ui/scripts/cloud.core.js @@ -168,9 +168,13 @@ function handleMidMenuItemAfterDetailsTabAction($midmenuItem1, isSuccessful, aft $infoIcon.removeClass("error"); else $infoIcon.addClass("error"); - - if($midmenuItem1.attr("id") == selected_midmenu_id) - $midmenuItem1.click(); + + if($midmenuItem1.attr("id") == selected_midmenu_id) { + if($("#midmenu_container").find("#multiple_selection_sub_container").length == 0) //single-selection middle menu + $midmenuItem1.click(); + else //multiple-selection middle menu + clickItemInMultipleSelectionMidmenu($midmenuItem1); + } } //***** actions for a tab in right panel (end) ************************************************************************** @@ -907,7 +911,8 @@ function createMultipleSelectionSubContainer() { if($midmenuItem1.find("#content").hasClass("inaction") == false) { //only items not in action are allowed to be selected var id =$midmenuItem1.data("jsonObj").id; selectedItemsInMidMenu[id] = $midmenuItem1; - $midmenuItem1.find("#content").addClass("selected"); + $midmenuItem1.find("#content").addClass("selected"); //css of vmops + selected_midmenu_id = $midmenuItem1.attr("id"); } clearRightPanel(); var toRightPanelFn = $midmenuItem1.data("toRightPanelFn"); @@ -981,12 +986,7 @@ function listMidMenuItems2(commandString, getSearchParamsFn, jsonResponse1, json $midmenuItem1.click(); } else { - $midmenuItem1.find("#content").addClass("selected"); - toRightPanelFn($midmenuItem1); - //$midmenuItem1.click(); //$midmenuItem1.click() is not working in multiple-selection middle menu - - $midmenuItem1.addClass("ui-selected"); //because instance page is using JQuery selectable widget to do multiple-selection - selectedItemsInMidMenu[items[i].id] = $midmenuItem1; //because instance page is using JQuery selectable widget to do multiple-selection + clickItemInMultipleSelectionMidmenu($midmenuItem1); } } } @@ -1003,6 +1003,19 @@ function listMidMenuItems2(commandString, getSearchParamsFn, jsonResponse1, json return count; } +function clickItemInMultipleSelectionMidmenu($midmenuItem1) { + $midmenuItem1.find("#content").addClass("selected"); //css of vmops + $midmenuItem1.addClass("ui-selected"); //css of JQuery selectable widget + + var toRightPanelFn = $midmenuItem1.data("toRightPanelFn"); + toRightPanelFn($midmenuItem1); + + var jsonObj = $midmenuItem1.data("jsonObj"); + selectedItemsInMidMenu[jsonObj.id] = $midmenuItem1; + + selected_midmenu_id = $midmenuItem1.attr("id"); +} + var currentLeftMenuId; var currentRightPanelJSP = null; function listMidMenuItems(commandString, getSearchParamsFn, jsonResponse1, jsonResponse2, rightPanelJSP, afterLoadRightPanelJSPFn, toMidmenuFn, toRightPanelFn, getMidmenuIdFn, isMultipleSelectionInMidMenu, leftmenuId, refreshDataBindingFn) { From 318a5c7d0c6af4e45ec704a68b6025b99e56e4ed Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Fri, 7 Jan 2011 11:58:13 -0800 Subject: [PATCH 035/142] IP Address page - fix a bug "networkObj is undefined" when login as user-role. --- ui/scripts/cloud.core.ipaddress.js | 110 +++++++++++++++++++---------- 1 file changed, 73 insertions(+), 37 deletions(-) diff --git a/ui/scripts/cloud.core.ipaddress.js b/ui/scripts/cloud.core.ipaddress.js index c9b098e24c5..62d04619637 100644 --- a/ui/scripts/cloud.core.ipaddress.js +++ b/ui/scripts/cloud.core.ipaddress.js @@ -333,19 +333,39 @@ function ipToRightPanel($midmenuItem1) { if(ipObj.forvirtualnetwork == true) { //(public network) if(isIpManageable(ipObj.domainid, ipObj.account) == true) { //Port Forwarding tab - var firewallServiceObj = ipFindNetworkServiceByName("Firewall", networkObj); - var portForwardingCapabilityObj = ipFindCapabilityByName("PortForwarding", firewallServiceObj); - if(firewallServiceObj != null && portForwardingCapabilityObj != null && portForwardingCapabilityObj.value == "true") - $("#tab_port_forwarding").show(); - else - $("#tab_port_forwarding").hide(); + if(networkObj != null) { + var firewallServiceObj = ipFindNetworkServiceByName("Firewall", networkObj); + if(firewallServiceObj != null) { + var portForwardingCapabilityObj = ipFindCapabilityByName("PortForwarding", firewallServiceObj); + if(portForwardingCapabilityObj != null) { + if(portForwardingCapabilityObj.value == "true") + $("#tab_port_forwarding").show(); + else + $("#tab_port_forwarding").hide(); + } + else { + $("#tab_port_forwarding").hide(); + } + } + else { + $("#tab_port_forwarding").hide(); + } + } + else { + $("#tab_port_forwarding").hide(); + } //Load Balancer tab - var lbServiceObj = ipFindNetworkServiceByName("Lb", networkObj); - if(lbServiceObj != null) - $("#tab_load_balancer").show(); - else - $("#tab_load_balancer").hide(); + if(networkObj != null) { + var lbServiceObj = ipFindNetworkServiceByName("Lb", networkObj); + if(lbServiceObj != null) + $("#tab_load_balancer").show(); + else + $("#tab_load_balancer").hide(); + } + else { + $("#tab_load_balancer").hide(); + } //VPN tab var vpnServiceObj = ipFindNetworkServiceByName("Vpn", networkObj); @@ -388,15 +408,20 @@ function ipJsonToPortForwardingTab() { $thisTab.find("#tab_container").hide(); $thisTab.find("#tab_spinning_wheel").show(); - var firewallServiceObj = ipFindNetworkServiceByName("Firewall", networkObj); - var supportedProtocolsCapabilityObj = ipFindCapabilityByName("SupportedProtocols", firewallServiceObj); - if(supportedProtocolsCapabilityObj != null) { - var protocols = supportedProtocolsCapabilityObj.value.toUpperCase(); //e.g. "tcp,udp" => "TCP,UDP" - var array1 = protocols.split(","); - var $protocolField = $("#create_port_forwarding_row").find("#protocol").empty(); - for(var i=0; i"+array1[i]+"") + if(networkObj != null) { + var firewallServiceObj = ipFindNetworkServiceByName("Firewall", networkObj); + if(firewallServiceObj != null) { + var supportedProtocolsCapabilityObj = ipFindCapabilityByName("SupportedProtocols", firewallServiceObj); + if(supportedProtocolsCapabilityObj != null) { + var protocols = supportedProtocolsCapabilityObj.value.toUpperCase(); //e.g. "tcp,udp" => "TCP,UDP" + var array1 = protocols.split(","); + var $protocolField = $("#create_port_forwarding_row").find("#protocol").empty(); + for(var i=0; i"+array1[i]+"") + } + } } + refreshCreatePortForwardingRow(); $.ajax({ @@ -438,18 +463,23 @@ function ipJsonToLoadBalancerTab() { $thisTab.find("#tab_container").hide(); $thisTab.find("#tab_spinning_wheel").show(); - var lbServiceObj = ipFindNetworkServiceByName("Lb", networkObj); - var supportedLbAlgorithmsCapabilityObj = ipFindCapabilityByName("SupportedLbAlgorithms", lbServiceObj); - if(lbServiceObj != null && supportedLbAlgorithmsCapabilityObj != null) { - var algorithms = supportedLbAlgorithmsCapabilityObj.value; //e.g. "roundrobin,leastconn,sourceip" - var array1 = algorithms.split(","); - var $algorithmField1 = $("#create_load_balancer_row").find("#algorithm_select").empty(); - var $algorithmField2 = $("#load_balancer_template").find("#row_container_edit").find("#algorithm_select").empty(); - for(var i=0; i"+array1[i]+""); - $algorithmField2.append(""); - } - } + if(networkObj != null) { + var lbServiceObj = ipFindNetworkServiceByName("Lb", networkObj); + if(lbServiceObj != null) { + var supportedLbAlgorithmsCapabilityObj = ipFindCapabilityByName("SupportedLbAlgorithms", lbServiceObj); + if(supportedLbAlgorithmsCapabilityObj != null) { + var algorithms = supportedLbAlgorithmsCapabilityObj.value; //e.g. "roundrobin,leastconn,sourceip" + var array1 = algorithms.split(","); + var $algorithmField1 = $("#create_load_balancer_row").find("#algorithm_select").empty(); + var $algorithmField2 = $("#load_balancer_template").find("#row_container_edit").find("#algorithm_select").empty(); + for(var i=0; i"+array1[i]+""); + $algorithmField2.append(""); + } + } + } + } + refreshCreateLoadBalancerRow(); $.ajax({ @@ -943,12 +973,18 @@ function ipJsonToDetailsTab() { buildActionLinkForTab("Disable Static NAT", ipActionMap, $actionMenu, $midmenuItem1, $thisTab); noAvailableActions = false; } else { - if(ipObj.issourcenat != true) { - var firewallServiceObj = ipFindNetworkServiceByName("Firewall", networkObj); - var staticNatCapabilityObj = ipFindCapabilityByName("StaticNat", firewallServiceObj); - if(firewallServiceObj != null && staticNatCapabilityObj != null && staticNatCapabilityObj.value == "true") - buildActionLinkForTab("Enable Static NAT", ipActionMap, $actionMenu, $midmenuItem1, $thisTab); - + if(ipObj.issourcenat != true) { + if(networkObj != null) { + var firewallServiceObj = ipFindNetworkServiceByName("Firewall", networkObj); + if(firewallServiceObj != null) { + var staticNatCapabilityObj = ipFindCapabilityByName("StaticNat", firewallServiceObj); + if(staticNatCapabilityObj != null) { + if(staticNatCapabilityObj.value == "true") + buildActionLinkForTab("Enable Static NAT", ipActionMap, $actionMenu, $midmenuItem1, $thisTab); + } + } + } + buildActionLinkForTab("Release IP", ipActionMap, $actionMenu, $midmenuItem1, $thisTab); noAvailableActions = false; } From 7843b30ff2bd75837291407b3cb9c21fbd39ccdd Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Fri, 7 Jan 2011 12:07:24 -0800 Subject: [PATCH 036/142] IP Address page - fix a bug "networkObj is undefined" when login as user-role. --- ui/scripts/cloud.core.ipaddress.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ui/scripts/cloud.core.ipaddress.js b/ui/scripts/cloud.core.ipaddress.js index 62d04619637..990e9e72644 100644 --- a/ui/scripts/cloud.core.ipaddress.js +++ b/ui/scripts/cloud.core.ipaddress.js @@ -1001,6 +1001,8 @@ function ipJsonToDetailsTab() { } function ipFindNetworkServiceByName(pName, networkObj) { + if(networkObj == null) + return null; for(var i=0; i Date: Wed, 5 Jan 2011 15:18:02 -0800 Subject: [PATCH 037/142] got rid of monitor --- .../cloud/agent/api/to/VirtualMachineTO.java | 31 ------------------- .../xen/resource/CitrixResourceBase.java | 21 ------------- 2 files changed, 52 deletions(-) diff --git a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java index 9fda4e46446..0e2be2bc31d 100644 --- a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java +++ b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java @@ -38,7 +38,6 @@ public class VirtualMachineTO { String bootArgs; String[] bootupScripts; boolean rebootOnCrash; - Monitor monitor; VolumeTO[] disks; NicTO[] nics; @@ -70,14 +69,6 @@ public class VirtualMachineTO { return name; } - public Monitor getMonitor() { - return monitor; - } - - public void setMonitor(Monitor monitor) { - this.monitor = monitor; - } - public void setName(String name) { this.name = name; } @@ -187,26 +178,4 @@ public class VirtualMachineTO { public void setNics(NicTO[] nics) { this.nics = nics; } - - public static interface Monitor { - - } - - public static class SshMonitor implements Monitor { - String ip; - int port; - - public String getIp() { - return ip; - } - - public int getPort() { - return port; - } - - public SshMonitor(String ip, int port) { - this.ip = ip; - this.port = port; - } - } } diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 513b9fad1a2..d7aa0500dd9 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -148,8 +148,6 @@ import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.PortForwardingRuleTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VirtualMachineTO; -import com.cloud.agent.api.to.VirtualMachineTO.Monitor; -import com.cloud.agent.api.to.VirtualMachineTO.SshMonitor; import com.cloud.agent.api.to.VolumeTO; import com.cloud.dc.Vlan; import com.cloud.exception.InternalErrorException; @@ -829,25 +827,6 @@ public abstract class CitrixResourceBase implements ServerResource { } } } - - Monitor monitor = vmSpec.getMonitor(); - if (monitor != null && monitor instanceof SshMonitor) { - SshMonitor sshMon = (SshMonitor)monitor; - String privateIp = sshMon.getIp(); - int cmdPort = sshMon.getPort(); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Ping command port, " + privateIp + ":" + cmdPort); - } - - String result = connect(conn, vmName, privateIp, cmdPort); - if (result != null) { - throw new CloudRuntimeException("Can not ping System vm " + vmName + "due to:" + result); - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Ping command port succeeded for vm " + vmName); - } - } state = State.Running; return new StartAnswer(cmd); From 2e29f21e5a4dad1c7a28760d03f70e4e25482eb8 Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Thu, 6 Jan 2011 11:29:10 -0800 Subject: [PATCH 038/142] changes for injectors --- api/src/com/cloud/event/ActionEvent.java | 22 +++ .../src/com/cloud/network/NetworkManager.java | 4 + .../com/cloud/network/NetworkManagerImpl.java | 166 +++++++++--------- server/src/com/cloud/vm/ItWorkVO.java | 58 ++++-- .../cloud/vm/VirtualMachineManagerImpl.java | 65 ++++++- .../utils/component/ComponentLocator.java | 1 + 6 files changed, 221 insertions(+), 95 deletions(-) create mode 100644 api/src/com/cloud/event/ActionEvent.java diff --git a/api/src/com/cloud/event/ActionEvent.java b/api/src/com/cloud/event/ActionEvent.java new file mode 100644 index 00000000000..658d2b014ad --- /dev/null +++ b/api/src/com/cloud/event/ActionEvent.java @@ -0,0 +1,22 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.event; + +public @interface ActionEvent { + +} diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index d8dd1982248..19cea4603bd 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -32,6 +32,7 @@ import com.cloud.network.Network.Capability; import com.cloud.network.Network.Service; import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; +import com.cloud.network.guru.NetworkGuru; import com.cloud.network.rules.FirewallRule; import com.cloud.network.vpn.RemoteAccessVpnElement; import com.cloud.offerings.NetworkOfferingVO; @@ -140,4 +141,7 @@ public interface NetworkManager extends NetworkService { List listPodVlans(long podId); + Network getBasicZoneDefaultPublicNetwork(long zoneId); + + Pair implementNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 3addb3b067e..7d27a7f06b4 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -20,8 +20,6 @@ package com.cloud.network; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.Iterator; @@ -36,11 +34,7 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; -import com.cloud.agent.AgentManager; -import com.cloud.agent.AgentManager.OnError; -import com.cloud.agent.api.Answer; import com.cloud.agent.api.to.NicTO; -import com.cloud.agent.manager.Commands; import com.cloud.alert.AlertManager; import com.cloud.api.BaseCmd; import com.cloud.api.commands.AssociateIPAddrCmd; @@ -75,12 +69,10 @@ import com.cloud.event.UsageEventVO; import com.cloud.event.dao.EventDao; import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.AccountLimitException; -import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; @@ -92,12 +84,14 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.NetworkDao; +<<<<<<< HEAD import com.cloud.network.dao.RemoteAccessVpnDao; +======= +>>>>>>> changes for injectors import com.cloud.network.element.NetworkElement; import com.cloud.network.guru.NetworkGuru; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRulesManager; -import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.PortForwardingRuleVO; @@ -111,6 +105,10 @@ import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.resource.Resource; import com.cloud.resource.Resource.ReservationStrategy; +<<<<<<< HEAD +======= +import com.cloud.service.ServiceOfferingVO; +>>>>>>> changes for injectors import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; @@ -165,7 +163,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Inject EventDao _eventDao = null; @Inject ConfigurationDao _configDao; @Inject UserVmDao _vmDao = null; - @Inject AgentManager _agentMgr; + @Inject ResourceLimitDao _limitDao = null; + @Inject CapacityDao _capacityDao = null; @Inject AlertManager _alertMgr; @Inject AccountManager _accountMgr; @Inject ConfigurationManager _configMgr; @@ -173,8 +172,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Inject NetworkOfferingDao _networkOfferingDao = null; @Inject NetworkDao _networksDao = null; @Inject NicDao _nicDao = null; - @Inject RemoteAccessVpnDao _remoteAccessVpnDao = null; - @Inject VirtualNetworkApplianceManager _routerMgr; @Inject RulesManager _rulesMgr; @Inject LoadBalancingRulesManager _lbMgr; @Inject UsageEventDao _usageEventDao; @@ -355,77 +352,77 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override public boolean associateIP(final DomainRouterVO router, final List ipAddrList, final boolean add, long vmId) { - Commands cmds = new Commands(OnError.Continue); - boolean sourceNat = false; - Map> vlanIpMap = new HashMap>(); - for (final String ipAddress: ipAddrList) { - IPAddressVO ip = _ipAddressDao.findById(new Ip(ipAddress)); - - VlanVO vlan = _vlanDao.findById(ip.getVlanId()); - ArrayList ipList = vlanIpMap.get(vlan.getId()); - if (ipList == null) { - ipList = new ArrayList(); - } - ipList.add(ip); - vlanIpMap.put(vlan, ipList); - } - for (Map.Entry> vlanAndIp: vlanIpMap.entrySet()) { - boolean firstIP = true; - ArrayList ipList = vlanAndIp.getValue(); - Collections.sort(ipList, new Comparator() { - @Override - public int compare(IPAddressVO o1, IPAddressVO o2) { - return o1.getAddress().compareTo(o2.getAddress()); - } }); - - for (final IPAddressVO ip: ipList) { - sourceNat = ip.isSourceNat(); - VlanVO vlan = vlanAndIp.getKey(); - String vlanId = vlan.getVlanTag(); - String vlanGateway = vlan.getVlanGateway(); - String vlanNetmask = vlan.getVlanNetmask(); - - String vifMacAddress = null; - if (firstIP && add) { - String[] macAddresses = _dcDao.getNextAvailableMacAddressPair(ip.getDataCenterId()); - vifMacAddress = macAddresses[1]; - } - String vmGuestAddress = null; - if(vmId!=0){ - vmGuestAddress = _vmDao.findById(vmId).getGuestIpAddress(); - } - - //cmds.addCommand(new IPAssocCommand(router.getInstanceName(), router.getPrivateIpAddress(), ip.getAddress(), add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, vmGuestAddress)); - - firstIP = false; - } - } - - Answer[] answers = null; - try { - answers = _agentMgr.send(router.getHostId(), cmds); - } catch (final AgentUnavailableException e) { - s_logger.warn("Agent unavailable", e); - return false; - } catch (final OperationTimedoutException e) { - s_logger.warn("Timed Out", e); - return false; - } - - if (answers == null) { - return false; - } - - if (answers.length != ipAddrList.size()) { - return false; - } - - // FIXME: this used to be a loop for all answers, but then we always returned the - // first one in the array, so what should really be done here? - if (answers.length > 0) { - Answer ans = answers[0]; - return ans.getResult(); - } +// Commands cmds = new Commands(OnError.Continue); +// boolean sourceNat = false; +// Map> vlanIpMap = new HashMap>(); +// for (final String ipAddress: ipAddrList) { +// IPAddressVO ip = _ipAddressDao.findById(new Ip(ipAddress)); +// +// VlanVO vlan = _vlanDao.findById(ip.getVlanId()); +// ArrayList ipList = vlanIpMap.get(vlan.getId()); +// if (ipList == null) { +// ipList = new ArrayList(); +// } +// ipList.add(ip); +// vlanIpMap.put(vlan, ipList); +// } +// for (Map.Entry> vlanAndIp: vlanIpMap.entrySet()) { +// boolean firstIP = true; +// ArrayList ipList = vlanAndIp.getValue(); +// Collections.sort(ipList, new Comparator() { +// @Override +// public int compare(IPAddressVO o1, IPAddressVO o2) { +// return o1.getAddress().compareTo(o2.getAddress()); +// } }); +// +// for (final IPAddressVO ip: ipList) { +// sourceNat = ip.isSourceNat(); +// VlanVO vlan = vlanAndIp.getKey(); +// String vlanId = vlan.getVlanTag(); +// String vlanGateway = vlan.getVlanGateway(); +// String vlanNetmask = vlan.getVlanNetmask(); +// +// String vifMacAddress = null; +// if (firstIP && add) { +// String[] macAddresses = _dcDao.getNextAvailableMacAddressPair(ip.getDataCenterId()); +// vifMacAddress = macAddresses[1]; +// } +// String vmGuestAddress = null; +// if(vmId!=0){ +// vmGuestAddress = _vmDao.findById(vmId).getGuestIpAddress(); +// } +// +// //cmds.addCommand(new IPAssocCommand(router.getInstanceName(), router.getPrivateIpAddress(), ip.getAddress(), add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, vmGuestAddress)); +// +// firstIP = false; +// } +// } +// +// Answer[] answers = null; +// try { +// answers = _agentMgr.send(router.getHostId(), cmds); +// } catch (final AgentUnavailableException e) { +// s_logger.warn("Agent unavailable", e); +// return false; +// } catch (final OperationTimedoutException e) { +// s_logger.warn("Timed Out", e); +// return false; +// } +// +// if (answers == null) { +// return false; +// } +// +// if (answers.length != ipAddrList.size()) { +// return false; +// } +// +// // FIXME: this used to be a loop for all answers, but then we always returned the +// // first one in the array, so what should really be done here? +// if (answers.length > 0) { +// Answer ans = answers[0]; +// return ans.getResult(); +// } return true; } @@ -995,8 +992,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return to; } + @Override @DB - protected Pair implementNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + public Pair implementNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { Transaction.currentTxn(); Pair implemented = new Pair(null, null); diff --git a/server/src/com/cloud/vm/ItWorkVO.java b/server/src/com/cloud/vm/ItWorkVO.java index a823c7be11b..c150a125851 100644 --- a/server/src/com/cloud/vm/ItWorkVO.java +++ b/server/src/com/cloud/vm/ItWorkVO.java @@ -36,9 +36,15 @@ public class ItWorkVO { Cleanup; } - enum State { - Working, - Cancelling, + enum ResourceType { + Volume, + Nic + } + + enum Step { + Prepare, + Start, + Started, } @Id @@ -58,21 +64,53 @@ public class ItWorkVO { String threadName; @Column(name="state") - State state; + Step step; @Column(name="cancel_taken") @Temporal(value=TemporalType.TIMESTAMP) Date taken; + @Column(name="instance_id") + long instanceId; + + public long getInstanceId() { + return instanceId; + } + + @Column(name="resource_id") + long resourceId; + + @Column(name="resource_type") + ResourceType resourceType; + + + public long getResourceId() { + return resourceId; + } + + public void setResourceId(long resourceId) { + this.resourceId = resourceId; + } + + public ResourceType getResourceType() { + return resourceType; + } + + public void setResourceType(ResourceType resourceType) { + this.resourceType = resourceType; + } + protected ItWorkVO() { } - protected ItWorkVO(String id, long managementServerId, Type type) { + protected ItWorkVO(String id, long managementServerId, Type type, long instanceId) { this.id = id; this.managementServerId = managementServerId; this.type = type; this.threadName = Thread.currentThread().getName(); - this.state = State.Working; + this.step = Step.Prepare; + this.instanceId = instanceId; + this.resourceType = null; } public String getId() { @@ -99,12 +137,12 @@ public class ItWorkVO { return threadName; } - public State getState() { - return state; + public Step getStep() { + return step; } - public void setState(State state) { - this.state = state; + public void setStep(Step state) { + this.step = state; } public Date getTaken() { diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 7f58a0c3bf6..81034be3feb 100644 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -17,6 +17,7 @@ */ package com.cloud.vm; +import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -61,6 +62,10 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.HypervisorGuru; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; +import com.cloud.network.element.NetworkElement; +import com.cloud.network.guru.NetworkGuru; +import com.cloud.resource.Resource; +import com.cloud.resource.Resource.ReservationStrategy; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; @@ -90,6 +95,7 @@ import com.cloud.vm.VirtualMachine.Event; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.ConsoleProxyDao; import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.SecondaryStorageVmDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; @@ -115,6 +121,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster @Inject private ConsoleProxyDao _consoleDao; @Inject private SecondaryStorageVmDao _secondaryDao; @Inject private UsageEventDao _usageEventDao; + @Inject private NicDao _nicsDao; @Inject(adapter=DeploymentPlanner.class) private Adapters _planners; @@ -200,6 +207,58 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster return vm; } + protected void reserveNics(VirtualMachineProfile vmProfile, DeployDestination dest, ReservationContext context) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { + List nics = _nicsDao.listBy(vmProfile.getId()); + for (NicVO nic : nics) { + Pair implemented = _networkMgr.implementNetwork(nic.getNetworkId(), dest, context); + NetworkGuru concierge = implemented.first(); + NetworkVO network = implemented.second(); + NicProfile profile = null; + if (nic.getReservationStrategy() == ReservationStrategy.Start) { + nic.setState(Resource.State.Reserving); + nic.setReservationId(context.getReservationId()); + _nicsDao.update(nic.getId(), nic); + URI broadcastUri = nic.getBroadcastUri(); + if (broadcastUri == null) { + network.getBroadcastUri(); + } + + URI isolationUri = nic.getIsolationUri(); + + profile = new NicProfile(nic, network, broadcastUri, isolationUri); + concierge.reserve(profile, network, vmProfile, dest, context); + nic.setIp4Address(profile.getIp4Address()); + nic.setIp6Address(profile.getIp6Address()); + nic.setMacAddress(profile.getMacAddress()); + nic.setIsolationUri(profile.getIsolationUri()); + nic.setBroadcastUri(profile.getBroadCastUri()); + nic.setReserver(concierge.getName()); + nic.setState(Resource.State.Reserved); + nic.setNetmask(profile.getNetmask()); + nic.setGateway(profile.getGateway()); + nic.setAddressFormat(profile.getFormat()); + _nicsDao.update(nic.getId(), nic); + } else { + profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri()); + } + + for (NetworkElement element : _networkElements) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Asking " + element.getName() + " to prepare for " + nic); + } + element.prepare(network, profile, vmProfile, dest, context); + } + + vmProfile.addNic(profile); + _networksDao.changeActiveNicsBy(network.getId(), 1); + } + } + + protected void prepareNics(VirtualMachineProfile vmProfile, DeployDestionation dest, ReservationContext context) { + + } + + @Override public T allocate(T vm, VMTemplateVO template, @@ -337,11 +396,15 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster @Override public T advanceStart(T vm, Map params, User caller, Account account, HypervisorType hyperType) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { State state = vm.getState(); - if (state == State.Starting || state == State.Running) { + if (state == State.Running) { s_logger.debug("VM is already started: " + vm); return vm; } + if (state == State.Starting) { + + } + if (state != State.Stopped) { s_logger.debug("VM " + vm + " is not in a state to be started: " + state); return null; diff --git a/utils/src/com/cloud/utils/component/ComponentLocator.java b/utils/src/com/cloud/utils/component/ComponentLocator.java index ce326a15752..453f3ae6085 100755 --- a/utils/src/com/cloud/utils/component/ComponentLocator.java +++ b/utils/src/com/cloud/utils/component/ComponentLocator.java @@ -90,6 +90,7 @@ public class ComponentLocator implements ComponentLocatorMBean { protected String _serverName; protected Object _component; protected HashMap, Class> _factories; + protected List _injectors; static { Runtime.getRuntime().addShutdownHook(new CleanupThread()); From e496a99c1c645f9361ac0383be6a934981701a9f Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Thu, 6 Jan 2011 15:06:55 -0800 Subject: [PATCH 039/142] added processing for events --- .../com/cloud/offering/NetworkOffering.java | 1 + .../DefaultComponentLibrary.java | 7 ++ .../cloud/vm/VirtualMachineManagerImpl.java | 99 +++++++++---------- setup/db/create-schema.sql | 3 + .../component/AnnotationInterceptor.java | 23 +++++ .../utils/component/ComponentLibrary.java | 2 + .../utils/component/ComponentLocator.java | 76 ++++++++++++-- .../com/cloud/utils/component/Injector.java | 19 ---- .../com/cloud/utils/db/DatabaseCallback.java | 50 +++++++++- 9 files changed, 199 insertions(+), 81 deletions(-) create mode 100644 utils/src/com/cloud/utils/component/AnnotationInterceptor.java delete mode 100644 utils/src/com/cloud/utils/component/Injector.java diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java index 6a36b071370..9f4b70ba245 100644 --- a/api/src/com/cloud/offering/NetworkOffering.java +++ b/api/src/com/cloud/offering/NetworkOffering.java @@ -85,6 +85,7 @@ public interface NetworkOffering { Availability getAvailability(); + boolean isDnsService(); boolean isGatewayService(); diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index 04a13bfb1ee..d1a550a5f90 100644 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -115,9 +115,11 @@ import com.cloud.user.dao.UserDaoImpl; import com.cloud.user.dao.UserStatisticsDaoImpl; import com.cloud.utils.Pair; import com.cloud.utils.component.Adapter; +import com.cloud.utils.component.AnnotationInterceptor; import com.cloud.utils.component.ComponentLibrary; import com.cloud.utils.component.ComponentLocator.ComponentInfo; import com.cloud.utils.component.Manager; +import com.cloud.utils.db.DatabaseCallback; import com.cloud.utils.db.GenericDao; import com.cloud.vm.ItWorkDaoImpl; import com.cloud.vm.UserVmManagerImpl; @@ -334,4 +336,9 @@ public class DefaultComponentLibrary implements ComponentLibrary { factories.put(EntityManager.class, EntityManagerImpl.class); return factories; } + + @Override + public void addInterceptors(List> interceptors) { + interceptors.add(new DatabaseCallback()); + } } diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 81034be3feb..cda2c647325 100644 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -17,7 +17,6 @@ */ package com.cloud.vm; -import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -62,10 +61,6 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.HypervisorGuru; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; -import com.cloud.network.element.NetworkElement; -import com.cloud.network.guru.NetworkGuru; -import com.cloud.resource.Resource; -import com.cloud.resource.Resource.ReservationStrategy; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; @@ -208,53 +203,53 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster } protected void reserveNics(VirtualMachineProfile vmProfile, DeployDestination dest, ReservationContext context) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { - List nics = _nicsDao.listBy(vmProfile.getId()); - for (NicVO nic : nics) { - Pair implemented = _networkMgr.implementNetwork(nic.getNetworkId(), dest, context); - NetworkGuru concierge = implemented.first(); - NetworkVO network = implemented.second(); - NicProfile profile = null; - if (nic.getReservationStrategy() == ReservationStrategy.Start) { - nic.setState(Resource.State.Reserving); - nic.setReservationId(context.getReservationId()); - _nicsDao.update(nic.getId(), nic); - URI broadcastUri = nic.getBroadcastUri(); - if (broadcastUri == null) { - network.getBroadcastUri(); - } - - URI isolationUri = nic.getIsolationUri(); - - profile = new NicProfile(nic, network, broadcastUri, isolationUri); - concierge.reserve(profile, network, vmProfile, dest, context); - nic.setIp4Address(profile.getIp4Address()); - nic.setIp6Address(profile.getIp6Address()); - nic.setMacAddress(profile.getMacAddress()); - nic.setIsolationUri(profile.getIsolationUri()); - nic.setBroadcastUri(profile.getBroadCastUri()); - nic.setReserver(concierge.getName()); - nic.setState(Resource.State.Reserved); - nic.setNetmask(profile.getNetmask()); - nic.setGateway(profile.getGateway()); - nic.setAddressFormat(profile.getFormat()); - _nicsDao.update(nic.getId(), nic); - } else { - profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri()); - } - - for (NetworkElement element : _networkElements) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Asking " + element.getName() + " to prepare for " + nic); - } - element.prepare(network, profile, vmProfile, dest, context); - } - - vmProfile.addNic(profile); - _networksDao.changeActiveNicsBy(network.getId(), 1); - } +// List nics = _nicsDao.listBy(vmProfile.getId()); +// for (NicVO nic : nics) { +// Pair implemented = _networkMgr.implementNetwork(nic.getNetworkId(), dest, context); +// NetworkGuru concierge = implemented.first(); +// NetworkVO network = implemented.second(); +// NicProfile profile = null; +// if (nic.getReservationStrategy() == ReservationStrategy.Start) { +// nic.setState(Resource.State.Reserving); +// nic.setReservationId(context.getReservationId()); +// _nicsDao.update(nic.getId(), nic); +// URI broadcastUri = nic.getBroadcastUri(); +// if (broadcastUri == null) { +// network.getBroadcastUri(); +// } +// +// URI isolationUri = nic.getIsolationUri(); +// +// profile = new NicProfile(nic, network, broadcastUri, isolationUri); +// concierge.reserve(profile, network, vmProfile, dest, context); +// nic.setIp4Address(profile.getIp4Address()); +// nic.setIp6Address(profile.getIp6Address()); +// nic.setMacAddress(profile.getMacAddress()); +// nic.setIsolationUri(profile.getIsolationUri()); +// nic.setBroadcastUri(profile.getBroadCastUri()); +// nic.setReserver(concierge.getName()); +// nic.setState(Resource.State.Reserved); +// nic.setNetmask(profile.getNetmask()); +// nic.setGateway(profile.getGateway()); +// nic.setAddressFormat(profile.getFormat()); +// _nicsDao.update(nic.getId(), nic); +// } else { +// profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri()); +// } +// +// for (NetworkElement element : _networkElements) { +// if (s_logger.isDebugEnabled()) { +// s_logger.debug("Asking " + element.getName() + " to prepare for " + nic); +// } +// element.prepare(network, profile, vmProfile, dest, context); +// } +// +// vmProfile.addNic(profile); +// _networksDao.changeActiveNicsBy(network.getId(), 1); +// } } - protected void prepareNics(VirtualMachineProfile vmProfile, DeployDestionation dest, ReservationContext context) { + protected void prepareNics(VirtualMachineProfile vmProfile, DeployDestination dest, ReservationContext context) { } @@ -416,7 +411,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster Journal journal = new Journal.LogJournal("Creating " + vm, s_logger); - ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, ItWorkVO.Type.Start); + ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, ItWorkVO.Type.Start, vm.getId()); work = _workDao.persist(work); ReservationContextImpl context = new ReservationContextImpl(work.getId(), journal, caller, account); @@ -626,7 +621,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster stateTransitTo(vm, Event.OperationSucceeded, null); if (cleanup) { - ItWorkVO work = new ItWorkVO(reservationId, _nodeId, Type.Cleanup); + ItWorkVO work = new ItWorkVO(reservationId, _nodeId, Type.Cleanup, vm.getId()); _workDao.persist(work); } diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 253dee46224..eb22d1fd532 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -103,6 +103,9 @@ CREATE TABLE `cloud`.`op_it_work` ( `type` char(32) NOT NULL COMMENT 'type of work', `state` char(32) NOT NULL COMMENT 'state', `cancel_taken` timestamp COMMENT 'time it was taken over', + `instance_id` bigint unsigned NOT NULL COMMENT 'vm instance', + `resource_type` char(32) COMMENT 'type of resource being worked on', + `resource_id` bigint unsigned COMMENT 'resource id being worked on', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/utils/src/com/cloud/utils/component/AnnotationInterceptor.java b/utils/src/com/cloud/utils/component/AnnotationInterceptor.java new file mode 100644 index 00000000000..e614fcc6751 --- /dev/null +++ b/utils/src/com/cloud/utils/component/AnnotationInterceptor.java @@ -0,0 +1,23 @@ +/** + * + */ +package com.cloud.utils.component; + +import java.lang.reflect.AnnotatedElement; + +import net.sf.cglib.proxy.Callback; + +/** + * AnnotationIntercepter says it can intercept an annotation. + */ +public interface AnnotationInterceptor { + boolean needToIntercept(AnnotatedElement element); + + T interceptStart(AnnotatedElement element); + + void interceptComplete(AnnotatedElement element, T attach); + + void interceptException(AnnotatedElement element, T attach); + + Callback getCallback(); +} diff --git a/utils/src/com/cloud/utils/component/ComponentLibrary.java b/utils/src/com/cloud/utils/component/ComponentLibrary.java index f1b67e073c1..a0f0e8a3def 100644 --- a/utils/src/com/cloud/utils/component/ComponentLibrary.java +++ b/utils/src/com/cloud/utils/component/ComponentLibrary.java @@ -50,4 +50,6 @@ public interface ComponentLibrary { Map>> getAdapters(); Map, Class> getFactories(); + + void addInterceptors(List> interceptors); } diff --git a/utils/src/com/cloud/utils/component/ComponentLocator.java b/utils/src/com/cloud/utils/component/ComponentLocator.java index 453f3ae6085..3390fe205e5 100755 --- a/utils/src/com/cloud/utils/component/ComponentLocator.java +++ b/utils/src/com/cloud/utils/component/ComponentLocator.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.Serializable; import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; @@ -48,6 +49,8 @@ import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.CallbackFilter; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.Factory; +import net.sf.cglib.proxy.MethodInterceptor; +import net.sf.cglib.proxy.MethodProxy; import net.sf.cglib.proxy.NoOp; import org.apache.log4j.Logger; @@ -59,8 +62,6 @@ import org.xml.sax.helpers.DefaultHandler; import com.cloud.utils.Pair; import com.cloud.utils.PropertiesUtil; -import com.cloud.utils.db.DatabaseCallback; -import com.cloud.utils.db.DatabaseCallbackFilter; import com.cloud.utils.db.GenericDao; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.mgmt.JmxUtil; @@ -79,18 +80,18 @@ public class ComponentLocator implements ComponentLocatorMBean { protected static final ThreadLocal s_tl = new ThreadLocal(); protected static final ConcurrentHashMap, Singleton> s_singletons = new ConcurrentHashMap, Singleton>(111); protected static final HashMap s_locators = new HashMap(); - protected static final Callback[] s_callbacks = new Callback[] { NoOp.INSTANCE, new DatabaseCallback() }; - protected static final CallbackFilter s_callbackFilter = new DatabaseCallbackFilter(); protected static final HashMap, InjectInfo> s_factories = new HashMap, InjectInfo>(); protected static Boolean s_once = false; - + protected static Callback[] s_callbacks; + protected static CallbackFilter s_callbackFilter; + protected static final List> s_interceptors = new ArrayList>(); + protected HashMap> _adapterMap; protected HashMap> _managerMap; protected LinkedHashMap>> _daoMap; protected String _serverName; protected Object _component; protected HashMap, Class> _factories; - protected List _injectors; static { Runtime.getRuntime().addShutdownHook(new CleanupThread()); @@ -150,6 +151,9 @@ public class ComponentLocator implements ComponentLocatorMBean { _managerMap.putAll(library.getManagers()); adapters.putAll(library.getAdapters()); _factories.putAll(library.getFactories()); + synchronized(s_interceptors) { + library.addInterceptors(s_interceptors); + } } _daoMap.putAll(handler.daos); @@ -183,6 +187,17 @@ public class ComponentLocator implements ComponentLocatorMBean { s_logger.info("Skipping configuration using " + filename); return; } + + synchronized(s_interceptors) { + s_callbacks = new Callback[s_interceptors.size() + 2]; + int i = 0; + s_callbacks[i++] = NoOp.INSTANCE; + s_callbacks[i++] = new InterceptorDispatcher(); + for (AnnotationInterceptor interceptor : s_interceptors) { + s_callbacks[i++] = interceptor.getCallback(); + } + s_callbackFilter = new InterceptorFilter(); + } XmlHandler handler = result.first(); HashMap>> adapters = result.second(); @@ -830,7 +845,7 @@ public class ComponentLocator implements ComponentLocatorMBean { if (info.name == null) { throw new CloudRuntimeException("Missing name attribute for " + interphace.getName()); } - info.name = info.name + "-" + clazzName; + info.name = info.name; s_logger.debug("Looking for class " + clazzName); try { info.clazz = Class.forName(clazzName); @@ -1013,4 +1028,51 @@ public class ComponentLocator implements ComponentLocatorMBean { this.state = State.Instantiated; } } + + protected class InterceptorDispatcher implements MethodInterceptor { + + @Override + public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { + ArrayList, Object>> interceptors = new ArrayList, Object>>(); + for (AnnotationInterceptor interceptor : s_interceptors) { + if (interceptor.needToIntercept(method)) { + Object obj = interceptor.interceptStart(method); + interceptors.add(new Pair, Object>((AnnotationInterceptor)interceptor, obj)); + } + } + boolean success = false; + try { + Object obj = methodProxy.invokeSuper(object, args); + success = true; + return obj; + } finally { + for (Pair, Object> interceptor : interceptors) { + if (success) { + interceptor.first().interceptComplete(method, interceptor.second()); + } else { + interceptor.first().interceptException(method, interceptor.second()); + } + } + } + } + } + + protected static class InterceptorFilter implements CallbackFilter { + @Override + public int accept(Method method) { + int index = 0; + for (int i = 2; i < s_callbacks.length; i++) { + AnnotationInterceptor interceptor = (AnnotationInterceptor)s_callbacks[i]; + if (interceptor.needToIntercept(method)) { + if (index == 0) { + index = i; + } else { + return 1; + } + } + } + + return index; + } + } } diff --git a/utils/src/com/cloud/utils/component/Injector.java b/utils/src/com/cloud/utils/component/Injector.java deleted file mode 100644 index e278ab5ba08..00000000000 --- a/utils/src/com/cloud/utils/component/Injector.java +++ /dev/null @@ -1,19 +0,0 @@ -/** - * - */ -package com.cloud.utils.component; - -import java.lang.annotation.Annotation; -import java.lang.reflect.AnnotatedElement; - -/** - * Injector implements customized Injectors for ComponentLocator. - * - */ -public interface Injector { - /** - * Can this injector handle injecting into this type of class? - */ - boolean canInject(AnnotatedElement element, Annotation ann); - -} diff --git a/utils/src/com/cloud/utils/db/DatabaseCallback.java b/utils/src/com/cloud/utils/db/DatabaseCallback.java index 5587084c80d..623c1c1fda9 100644 --- a/utils/src/com/cloud/utils/db/DatabaseCallback.java +++ b/utils/src/com/cloud/utils/db/DatabaseCallback.java @@ -17,20 +17,64 @@ */ package com.cloud.utils.db; +import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; +import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; -public class DatabaseCallback implements MethodInterceptor { +import com.cloud.utils.component.AnnotationInterceptor; + +public class DatabaseCallback implements MethodInterceptor, AnnotationInterceptor { @Override public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { - Transaction txn = Transaction.open(method.getName()); + Transaction txn = interceptStart(method); try { return methodProxy.invokeSuper(object, args); } finally { - txn.close(); + interceptComplete(method, txn); } } + + @Override + public boolean needToIntercept(AnnotatedElement element) { + DB db = element.getAnnotation(DB.class); + if (db != null) { + return db.txn(); + } + + Class clazz = element.getClass().getDeclaringClass(); + do { + db = clazz.getAnnotation(DB.class); + if (db != null) { + return db.txn(); + } + clazz = clazz.getSuperclass(); + } while (clazz != Object.class && clazz != null); + + return false; + } + + @Override + public Transaction interceptStart(AnnotatedElement element) { + return Transaction.open(((Method)element).getName()); + } + + @Override + public void interceptComplete(AnnotatedElement element, Transaction txn) { + txn.close(); + } + + @Override + public void interceptException(AnnotatedElement element, Transaction txn) { + txn.close(); + } + + @Override + public Callback getCallback() { + return this; + } + } From 4b360258ee73902ed37bfec99199c9193e0d5fd3 Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Thu, 6 Jan 2011 15:25:56 -0800 Subject: [PATCH 040/142] allow multiple ways to intercept --- .../com/cloud/dc/dao/DataCenterDaoImpl.java | 8 +++---- .../utils/component/ComponentLocator.java | 22 +++++++++++-------- .../com/cloud/utils/db/DatabaseCallback.java | 9 ++++++-- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/server/src/com/cloud/dc/dao/DataCenterDaoImpl.java b/server/src/com/cloud/dc/dao/DataCenterDaoImpl.java index 38728608fb6..4dd5ce8582d 100644 --- a/server/src/com/cloud/dc/dao/DataCenterDaoImpl.java +++ b/server/src/com/cloud/dc/dao/DataCenterDaoImpl.java @@ -58,10 +58,10 @@ public class DataCenterDaoImpl extends GenericDaoBase implem protected SearchBuilder PublicZonesSearch; protected SearchBuilder ChildZonesSearch; - protected static final DataCenterIpAddressDaoImpl _ipAllocDao = ComponentLocator.inject(DataCenterIpAddressDaoImpl.class); - protected static final DataCenterLinkLocalIpAddressDaoImpl _LinkLocalIpAllocDao = ComponentLocator.inject(DataCenterLinkLocalIpAddressDaoImpl.class); - protected static final DataCenterVnetDaoImpl _vnetAllocDao = ComponentLocator.inject(DataCenterVnetDaoImpl.class); - protected static final PodVlanDaoImpl _podVlanAllocDao = ComponentLocator.inject(PodVlanDaoImpl.class); + protected final DataCenterIpAddressDaoImpl _ipAllocDao = ComponentLocator.inject(DataCenterIpAddressDaoImpl.class); + protected final DataCenterLinkLocalIpAddressDaoImpl _LinkLocalIpAllocDao = ComponentLocator.inject(DataCenterLinkLocalIpAddressDaoImpl.class); + protected final DataCenterVnetDaoImpl _vnetAllocDao = ComponentLocator.inject(DataCenterVnetDaoImpl.class); + protected final PodVlanDaoImpl _podVlanAllocDao = ComponentLocator.inject(PodVlanDaoImpl.class); protected long _prefix; protected Random _rand = new Random(System.currentTimeMillis()); protected TableGenerator _tgMacAddress; diff --git a/utils/src/com/cloud/utils/component/ComponentLocator.java b/utils/src/com/cloud/utils/component/ComponentLocator.java index 3390fe205e5..95c81e1aeff 100755 --- a/utils/src/com/cloud/utils/component/ComponentLocator.java +++ b/utils/src/com/cloud/utils/component/ComponentLocator.java @@ -62,6 +62,8 @@ import org.xml.sax.helpers.DefaultHandler; import com.cloud.utils.Pair; import com.cloud.utils.PropertiesUtil; +import com.cloud.utils.db.DatabaseCallback; +import com.cloud.utils.db.DatabaseCallbackFilter; import com.cloud.utils.db.GenericDao; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.mgmt.JmxUtil; @@ -82,8 +84,8 @@ public class ComponentLocator implements ComponentLocatorMBean { protected static final HashMap s_locators = new HashMap(); protected static final HashMap, InjectInfo> s_factories = new HashMap, InjectInfo>(); protected static Boolean s_once = false; - protected static Callback[] s_callbacks; - protected static CallbackFilter s_callbackFilter; + protected static Callback[] s_callbacks = new Callback[] { NoOp.INSTANCE, new DatabaseCallback()}; + protected static CallbackFilter s_callbackFilter = new DatabaseCallbackFilter(); protected static final List> s_interceptors = new ArrayList>(); protected HashMap> _adapterMap; @@ -189,14 +191,16 @@ public class ComponentLocator implements ComponentLocatorMBean { } synchronized(s_interceptors) { - s_callbacks = new Callback[s_interceptors.size() + 2]; - int i = 0; - s_callbacks[i++] = NoOp.INSTANCE; - s_callbacks[i++] = new InterceptorDispatcher(); - for (AnnotationInterceptor interceptor : s_interceptors) { - s_callbacks[i++] = interceptor.getCallback(); + if (s_interceptors.size() > 0) { + s_callbacks = new Callback[s_interceptors.size() + 2]; + int i = 0; + s_callbacks[i++] = NoOp.INSTANCE; + s_callbacks[i++] = new InterceptorDispatcher(); + for (AnnotationInterceptor interceptor : s_interceptors) { + s_callbacks[i++] = interceptor.getCallback(); + } + s_callbackFilter = new InterceptorFilter(); } - s_callbackFilter = new InterceptorFilter(); } XmlHandler handler = result.first(); diff --git a/utils/src/com/cloud/utils/db/DatabaseCallback.java b/utils/src/com/cloud/utils/db/DatabaseCallback.java index 623c1c1fda9..ba25e32b242 100644 --- a/utils/src/com/cloud/utils/db/DatabaseCallback.java +++ b/utils/src/com/cloud/utils/db/DatabaseCallback.java @@ -40,12 +40,17 @@ public class DatabaseCallback implements MethodInterceptor, AnnotationIntercepto @Override public boolean needToIntercept(AnnotatedElement element) { - DB db = element.getAnnotation(DB.class); + if (!(element instanceof Method)) { + return false; + + } + Method method = (Method)element; + DB db = method.getAnnotation(DB.class); if (db != null) { return db.txn(); } - Class clazz = element.getClass().getDeclaringClass(); + Class clazz = method.getDeclaringClass(); do { db = clazz.getAnnotation(DB.class); if (db != null) { From 6dc922408d04d88b0c9c45ead4f0d9fe7559da21 Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Fri, 7 Jan 2011 13:41:00 -0800 Subject: [PATCH 041/142] unit test working --- api/src/com/cloud/event/ActionEvent.java | 1 - client/tomcatconf/components.xml.in | 1 + .../DefaultComponentLibrary.java | 6 --- .../utils/component/ComponentLibrary.java | 1 - .../utils/component/ComponentLocator.java | 44 ++++++++++++------- 5 files changed, 29 insertions(+), 24 deletions(-) diff --git a/api/src/com/cloud/event/ActionEvent.java b/api/src/com/cloud/event/ActionEvent.java index 658d2b014ad..b890172ec77 100644 --- a/api/src/com/cloud/event/ActionEvent.java +++ b/api/src/com/cloud/event/ActionEvent.java @@ -18,5 +18,4 @@ package com.cloud.event; public @interface ActionEvent { - } diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index f152f103fcd..5f1d7fd299e 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -23,6 +23,7 @@ documented, please contact the author. --> + diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index d1a550a5f90..d0c1b05bdd3 100644 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -115,11 +115,9 @@ import com.cloud.user.dao.UserDaoImpl; import com.cloud.user.dao.UserStatisticsDaoImpl; import com.cloud.utils.Pair; import com.cloud.utils.component.Adapter; -import com.cloud.utils.component.AnnotationInterceptor; import com.cloud.utils.component.ComponentLibrary; import com.cloud.utils.component.ComponentLocator.ComponentInfo; import com.cloud.utils.component.Manager; -import com.cloud.utils.db.DatabaseCallback; import com.cloud.utils.db.GenericDao; import com.cloud.vm.ItWorkDaoImpl; import com.cloud.vm.UserVmManagerImpl; @@ -337,8 +335,4 @@ public class DefaultComponentLibrary implements ComponentLibrary { return factories; } - @Override - public void addInterceptors(List> interceptors) { - interceptors.add(new DatabaseCallback()); - } } diff --git a/utils/src/com/cloud/utils/component/ComponentLibrary.java b/utils/src/com/cloud/utils/component/ComponentLibrary.java index a0f0e8a3def..5ed4c9512e7 100644 --- a/utils/src/com/cloud/utils/component/ComponentLibrary.java +++ b/utils/src/com/cloud/utils/component/ComponentLibrary.java @@ -51,5 +51,4 @@ public interface ComponentLibrary { Map, Class> getFactories(); - void addInterceptors(List> interceptors); } diff --git a/utils/src/com/cloud/utils/component/ComponentLocator.java b/utils/src/com/cloud/utils/component/ComponentLocator.java index 95c81e1aeff..3bdaf05986a 100755 --- a/utils/src/com/cloud/utils/component/ComponentLocator.java +++ b/utils/src/com/cloud/utils/component/ComponentLocator.java @@ -153,9 +153,6 @@ public class ComponentLocator implements ComponentLocatorMBean { _managerMap.putAll(library.getManagers()); adapters.putAll(library.getAdapters()); _factories.putAll(library.getFactories()); - synchronized(s_interceptors) { - library.addInterceptors(s_interceptors); - } } _daoMap.putAll(handler.daos); @@ -190,19 +187,6 @@ public class ComponentLocator implements ComponentLocatorMBean { return; } - synchronized(s_interceptors) { - if (s_interceptors.size() > 0) { - s_callbacks = new Callback[s_interceptors.size() + 2]; - int i = 0; - s_callbacks[i++] = NoOp.INSTANCE; - s_callbacks[i++] = new InterceptorDispatcher(); - for (AnnotationInterceptor interceptor : s_interceptors) { - s_callbacks[i++] = interceptor.getCallback(); - } - s_callbackFilter = new InterceptorFilter(); - } - } - XmlHandler handler = result.first(); HashMap>> adapters = result.second(); try { @@ -869,6 +853,34 @@ public class ComponentLocator implements ComponentLocatorMBean { @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { + if (qName.equals("interceptors") && s_interceptors.size() == 0) { + synchronized(s_interceptors){ + if (s_interceptors.size() == 0) { + String libraryName = getAttribute(atts, "library"); + try { + Class libraryClazz = Class.forName(libraryName); + InterceptorLibrary library = (InterceptorLibrary)libraryClazz.newInstance(); + library.addInterceptors(s_interceptors); + if (s_interceptors.size() > 0) { + s_callbacks = new Callback[s_interceptors.size() + 2]; + int i = 0; + s_callbacks[i++] = NoOp.INSTANCE; + s_callbacks[i++] = new InterceptorDispatcher(); + for (AnnotationInterceptor interceptor : s_interceptors) { + s_callbacks[i++] = interceptor.getCallback(); + } + s_callbackFilter = new InterceptorFilter(); + } + } catch (ClassNotFoundException e) { + throw new CloudRuntimeException("Unable to find " + libraryName, e); + } catch (InstantiationException e) { + throw new CloudRuntimeException("Unable to instantiate " + libraryName, e); + } catch (IllegalAccessException e) { + throw new CloudRuntimeException("Illegal access " + libraryName, e); + } + } + } + } if (!parse) { if (qName.equals(_serverName)) { parse = true; From 386d4a540d1513c5f5b3a321dc2b52a557a1a307 Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Fri, 7 Jan 2011 13:46:20 -0800 Subject: [PATCH 042/142] merge changes --- server/src/com/cloud/network/NetworkManager.java | 2 -- server/src/com/cloud/network/NetworkManagerImpl.java | 12 ++---------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 19cea4603bd..6d3896751de 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -141,7 +141,5 @@ public interface NetworkManager extends NetworkService { List listPodVlans(long podId); - Network getBasicZoneDefaultPublicNetwork(long zoneId); - Pair implementNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 7d27a7f06b4..6108150bac5 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -42,10 +42,12 @@ import com.cloud.api.commands.CreateNetworkCmd; import com.cloud.api.commands.DisassociateIPAddrCmd; import com.cloud.api.commands.ListNetworksCmd; import com.cloud.api.commands.RestartNetworkCmd; +import com.cloud.capacity.dao.CapacityDao; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.ResourceCount.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.configuration.dao.ResourceLimitDao; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.DataCenterVO; @@ -84,19 +86,13 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.NetworkDao; -<<<<<<< HEAD -import com.cloud.network.dao.RemoteAccessVpnDao; -======= ->>>>>>> changes for injectors import com.cloud.network.element.NetworkElement; import com.cloud.network.guru.NetworkGuru; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.PortForwardingRule; -import com.cloud.network.rules.PortForwardingRuleVO; import com.cloud.network.rules.RulesManager; -import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.network.vpn.RemoteAccessVpnElement; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.Availability; @@ -105,10 +101,6 @@ import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.resource.Resource; import com.cloud.resource.Resource.ReservationStrategy; -<<<<<<< HEAD -======= -import com.cloud.service.ServiceOfferingVO; ->>>>>>> changes for injectors import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; From be174f7f368e0779149fff753d627a2b0f04f11c Mon Sep 17 00:00:00 2001 From: anthony Date: Fri, 7 Jan 2011 13:29:11 -0800 Subject: [PATCH 043/142] correct checking answer --- server/src/com/cloud/agent/manager/AgentManagerImpl.java | 2 +- .../cloud/consoleproxy/AgentBasedConsoleProxyManager.java | 2 +- server/src/com/cloud/server/ManagementServerImpl.java | 2 +- server/src/com/cloud/storage/StorageManagerImpl.java | 8 +++----- .../storage/secondary/SecondaryStorageManagerImpl.java | 8 ++++---- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java index b908ae4d341..f0a50327f00 100755 --- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -1531,7 +1531,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Long dcId = host.getDataCenterId(); ReadyCommand ready = new ReadyCommand(dcId); Answer answer = easySend(hostId, ready); - if (answer == null) { + if (answer == null || !answer.getResult()) { // this is tricky part for secondary storage // make it as disconnected, wait for secondary storage VM to be up // return the attache instead of null, even it is disconnectede diff --git a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java index c953144543c..e77fec8d2e4 100644 --- a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java +++ b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java @@ -91,7 +91,7 @@ public class AgentBasedConsoleProxyManager implements ConsoleProxyManager, Virtu return -1; } GetVncPortAnswer answer = (GetVncPortAnswer) _agentMgr.easySend(vm.getHostId(), new GetVncPortCommand(vm.getId(), vm.getName())); - return answer == null ? -1 : answer.getPort(); + return (answer == null || !answer.getResult()) ? -1 : answer.getPort(); } @Override diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 20944dcd134..8c042489443 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -2729,7 +2729,7 @@ public class ManagementServerImpl implements ManagementServer { } GetVncPortAnswer answer = (GetVncPortAnswer) _agentMgr.easySend(vm.getHostId(), new GetVncPortCommand(vm.getId(), vm.getInstanceName())); - if(answer != null) { + if(answer != null && answer.getResult()) { return new Pair(answer.getAddress(), answer.getPort()); } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 73c90d14731..74c5198cb4f 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1477,11 +1477,9 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag DeleteStoragePoolCommand cmd = new DeleteStoragePoolCommand(sPool); final Answer answer = _agentMgr.easySend(host.getHostId(), cmd); - if (answer != null) { - if (answer.getResult() == true) { - deleteFlag = true; - break; - } + if (answer != null && answer.getResult()) { + deleteFlag = true; + break; } } diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index 4b47bb2df79..ace1022cd41 100644 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -315,7 +315,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V setupCmd.setCopyPassword(copyPasswd); setupCmd.setCopyUserName(TemplateConstants.DEFAULT_HTTP_AUTH_USER); Answer answer = _agentMgr.easySend(storageHost.getId(), setupCmd); - if (answer != null) { + if (answer != null && answer.getResult()) { if (s_logger.isDebugEnabled()) { s_logger.debug("Successfully programmed http auth into " + secStorageVm.getName()); } @@ -359,7 +359,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V } } Answer answer = _agentMgr.easySend(storageHost.getId(), cpc); - if (answer != null) { + if (answer != null && answer.getResult()) { if (s_logger.isDebugEnabled()) { s_logger.debug("Successfully programmed firewall rules into " + secStorageVm.getName()); } @@ -1083,7 +1083,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V final RebootCommand cmd = new RebootCommand(secStorageVm.getInstanceName()); final Answer answer = _agentMgr.easySend(secStorageVm.getHostId(), cmd); - if (answer != null) { + if (answer != null && answer.getResult()) { if (s_logger.isDebugEnabled()) { s_logger.debug("Successfully reboot secondary storage vm " + secStorageVm.getName()); } @@ -1274,7 +1274,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V MigrateCommand cmd = new MigrateCommand(secStorageVm.getInstanceName(), host.getPrivateIpAddress(), false); Answer answer = _agentMgr.easySend(fromHost.getId(), cmd); - if (answer == null) { + if (answer == null || !answer.getResult()) { return false; } From 1044a99756b64fe1980f5f07db880454a07976d5 Mon Sep 17 00:00:00 2001 From: anthony Date: Fri, 7 Jan 2011 13:49:12 -0800 Subject: [PATCH 044/142] check answer --- .../src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 0b4819018b8..129cd3f90a2 100644 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -1531,7 +1531,7 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx final RebootCommand cmd = new RebootCommand(proxy.getInstanceName()); final Answer answer = _agentMgr.easySend(proxy.getHostId(), cmd); - if (answer != null) { + if (answer != null && answer.getResult()) { if (s_logger.isDebugEnabled()) { s_logger.debug("Successfully reboot console proxy " + proxy.getName()); } @@ -1708,7 +1708,7 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx MigrateCommand cmd = new MigrateCommand(proxy.getInstanceName(), host.getPrivateIpAddress(), false); Answer answer = _agentMgr.easySend(fromHost.getId(), cmd); - if (answer == null) { + if (answer == null || !answer.getResult()) { return false; } From a1bdec8fa1d5bb5c6d646375a6d8446e192764ca Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Fri, 7 Jan 2011 14:08:31 -0800 Subject: [PATCH 045/142] add missing libraries --- .../DefaultInterceptorLibrary.java | 32 +++++++++++++++++++ .../utils/component/InterceptorLibrary.java | 26 +++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 server/src/com/cloud/configuration/DefaultInterceptorLibrary.java create mode 100644 utils/src/com/cloud/utils/component/InterceptorLibrary.java diff --git a/server/src/com/cloud/configuration/DefaultInterceptorLibrary.java b/server/src/com/cloud/configuration/DefaultInterceptorLibrary.java new file mode 100644 index 00000000000..846f8d0533b --- /dev/null +++ b/server/src/com/cloud/configuration/DefaultInterceptorLibrary.java @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.configuration; + +import java.util.List; + +import com.cloud.utils.component.AnnotationInterceptor; +import com.cloud.utils.component.InterceptorLibrary; +import com.cloud.utils.db.DatabaseCallback; + +public class DefaultInterceptorLibrary implements InterceptorLibrary { + + @Override + public void addInterceptors(List> interceptors) { + interceptors.add(new DatabaseCallback()); + } +} diff --git a/utils/src/com/cloud/utils/component/InterceptorLibrary.java b/utils/src/com/cloud/utils/component/InterceptorLibrary.java new file mode 100644 index 00000000000..1da4ffd746b --- /dev/null +++ b/utils/src/com/cloud/utils/component/InterceptorLibrary.java @@ -0,0 +1,26 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.utils.component; + +import java.util.List; + +public interface InterceptorLibrary { + + void addInterceptors(List> interceptors); + +} From 335e81cc52971ffc7a9bda5d1ad79e4c95d488eb Mon Sep 17 00:00:00 2001 From: alena Date: Fri, 7 Jan 2011 14:03:29 -0800 Subject: [PATCH 046/142] Fixed listNetworks for regular user to return system network information --- server/src/com/cloud/network/NetworkManagerImpl.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 6108150bac5..6020d0efc0a 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -1430,6 +1430,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag isSystem = false; } + //Account/domainId parameters and isSystem are mutually exclusive + if (isSystem && (accountName != null || domainId != null)) { + throw new InvalidParameterValueException("System network belongs to system, account and domainId parameters can't be specified"); + } + if (_accountMgr.isAdmin(account.getType())) { if (domainId != null) { if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId)) { @@ -1492,7 +1497,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (type != null) { sc.addAnd("guestType", SearchCriteria.Op.EQ, type); } - if (account.getType() != Account.ACCOUNT_TYPE_ADMIN || (accountName != null && domainId != null)) { + + if (!isSystem && (account.getType() != Account.ACCOUNT_TYPE_ADMIN || (accountName != null && domainId != null))) { sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId); } From 70241d78ecbca8964c770e623af53ffddd6e34e4 Mon Sep 17 00:00:00 2001 From: Chiradeep Vittal Date: Fri, 7 Jan 2011 14:28:18 -0800 Subject: [PATCH 047/142] bug 6694: trim excess fat from passed in parameters status 6694: resolved fixed --- .../api/commands/CreatePortForwardingRuleCmd.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java index 17bc361f43c..2686617a9fb 100644 --- a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java @@ -74,11 +74,11 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements @Override public String getProtocol() { - return protocol; + return protocol.trim(); } public String getPublicPort() { - return publicPort; + return publicPort.trim(); } @Override @@ -133,17 +133,17 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements @Override public Ip getSourceIpAddress() { - return new Ip(ipAddress); + return new Ip(ipAddress.trim()); } @Override public int getSourcePortStart() { - return Integer.parseInt(publicPort); + return Integer.parseInt(publicPort.trim()); } @Override public int getSourcePortEnd() { - return Integer.parseInt(publicPort); + return Integer.parseInt(publicPort.trim()); } @Override From e6dd262657bb8f5e7798f9e73057f28936c12f18 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Fri, 7 Jan 2011 14:42:52 -0800 Subject: [PATCH 048/142] bug 6361: correct parameter name of API response. --- ui/scripts/cloud.core.securitygroup.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/scripts/cloud.core.securitygroup.js b/ui/scripts/cloud.core.securitygroup.js index b1c8aa3d74b..a96682e480a 100644 --- a/ui/scripts/cloud.core.securitygroup.js +++ b/ui/scripts/cloud.core.securitygroup.js @@ -221,7 +221,7 @@ function securityGroupJsonToDetailsTab() { dataType: "json", async: false, success: function(json) { - var items = json.listsecurityGroupsresponse.securitygroup; + var items = json.listsecuritygroupsresponse.securitygroup; if(items != null && items.length > 0) { jsonObj = items[0]; $midmenuItem1.data("jsonObj", jsonObj); @@ -264,7 +264,7 @@ function securityGroupJsonToIngressRuleTab() { data: createURL("command=listSecurityGroups"+"&domainid="+securityGroupObj.domainid+"&account="+securityGroupObj.account+"&securitygroupname="+securityGroupObj.name), dataType: "json", success: function(json) { - var securityGroupObj = json.listsecurityGroupsresponse.securitygroup[0]; + var securityGroupObj = json.listsecuritygroupsresponse.securitygroup[0]; var items = securityGroupObj.ingressrule; var $container = $thisTab.find("#tab_container").empty(); if (items != null && items.length > 0) { From d3bac931b4efff2525428cb3b5ce1b6539f3b17f Mon Sep 17 00:00:00 2001 From: alena Date: Fri, 7 Jan 2011 15:03:19 -0800 Subject: [PATCH 049/142] Deploy from server-setup.xml: Fixed createDefaultNetworks to use correct guru names --- .../com/cloud/server/ConfigurationServerImpl.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index dcce0270332..d9ba64972f2 100644 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -62,6 +62,10 @@ import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.TrafficType; import com.cloud.network.dao.NetworkDao; +import com.cloud.network.guru.ControlNetworkGuru; +import com.cloud.network.guru.DirectPodBasedNetworkGuru; +import com.cloud.network.guru.PodBasedNetworkGuru; +import com.cloud.network.guru.PublicNetworkGuru; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.Availability; import com.cloud.offerings.NetworkOfferingVO; @@ -722,11 +726,11 @@ public class ConfigurationServerImpl implements ConfigurationServer { long id = 1; HashMap guruNames = new HashMap(); - guruNames.put(TrafficType.Public, "PublicNetworkGuru-com.cloud.network.guru.PublicNetworkGuru"); - guruNames.put(TrafficType.Management, "PodBasedNetworkGuru-com.cloud.network.guru.PodBasedNetworkGuru"); - guruNames.put(TrafficType.Control, "ControlNetworkGuru-com.cloud.network.guru.ControlNetworkGuru"); - guruNames.put(TrafficType.Storage, "PodBasedNetworkGuru-com.cloud.network.guru.PodBasedNetworkGuru"); - guruNames.put(TrafficType.Guest, "DirectPodBasedNetworkGuru-com.cloud.network.guru.DirectPodBasedNetworkGuru"); + guruNames.put(TrafficType.Public, PublicNetworkGuru.class.getSimpleName()); + guruNames.put(TrafficType.Management, PodBasedNetworkGuru.class.getSimpleName()); + guruNames.put(TrafficType.Control, ControlNetworkGuru.class.getSimpleName()); + guruNames.put(TrafficType.Storage, PodBasedNetworkGuru.class.getSimpleName()); + guruNames.put(TrafficType.Guest, DirectPodBasedNetworkGuru.class.getSimpleName()); for (DataCenterVO zone : zones) { From bd35fd20a08ebfbcdc39da3573557c098b86cef7 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Fri, 7 Jan 2011 15:47:39 -0800 Subject: [PATCH 050/142] bug 6361: change element ID from network_group_xxx to security_group_xxx. --- ui/2.1/jsp/tab_networking.jsp | 16 +++++----- ui/2.1/scripts/cloud.core.network.js | 44 ++++++++++++++-------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/ui/2.1/jsp/tab_networking.jsp b/ui/2.1/jsp/tab_networking.jsp index 5f1774690e7..714e60c30c9 100755 --- a/ui/2.1/jsp/tab_networking.jsp +++ b/ui/2.1/jsp/tab_networking.jsp @@ -8,7 +8,7 @@ long milliseconds = new Date().getTime(); - - - - diff --git a/ui/scripts/cloud.core.js b/ui/scripts/cloud.core.js index d187a8c4b29..3c52fcf8f1e 100644 --- a/ui/scripts/cloud.core.js +++ b/ui/scripts/cloud.core.js @@ -722,18 +722,19 @@ function afterAddingMidMenuItem($midmenuItem1, isSuccessful, extraMessage) { } } +var $currentMidmenuItem; function bindClickToMidMenu($midmenuItem1, toRightPanelFn, getMidmenuIdFn) { $midmenuItem1.bind("click", function(event){ - var thisMidmenuItem = $(this); + $currentMidmenuItem = $(this); if(selected_midmenu_id != null && selected_midmenu_id.length > 0) $("#"+selected_midmenu_id).find("#content").removeClass("selected"); - selected_midmenu_id = getMidmenuIdFn(thisMidmenuItem.data("jsonObj")); + selected_midmenu_id = getMidmenuIdFn($currentMidmenuItem.data("jsonObj")); - thisMidmenuItem.find("#content").addClass("selected"); + $currentMidmenuItem.find("#content").addClass("selected"); clearRightPanel(); - toRightPanelFn(thisMidmenuItem); + toRightPanelFn($currentMidmenuItem); return false; }); } @@ -1014,6 +1015,7 @@ function clickItemInMultipleSelectionMidmenu($midmenuItem1) { selectedItemsInMidMenu[jsonObj.id] = $midmenuItem1; selected_midmenu_id = $midmenuItem1.attr("id"); + $currentMidmenuItem = $midmenuItem1; } var currentLeftMenuId; diff --git a/ui/scripts/cloud.core.securitygroup.js b/ui/scripts/cloud.core.securitygroup.js index e8bac5d716e..f675a65f48c 100644 --- a/ui/scripts/cloud.core.securitygroup.js +++ b/ui/scripts/cloud.core.securitygroup.js @@ -159,6 +159,9 @@ function initAddIngressRuleDialog() { $("#add_ingressrule_button").unbind("click").bind("click", function(event) { if($("#tab_ingressrule").hasClass("off")) $("#tab_ingressrule").click(); + + $dialogAddIngressRule.find("#spinning_wheel").hide(); + $dialogAddIngressRule.find("#info_container").hide(); $dialogAddIngressRule.find("#protocol").val("TCP"); $dialogAddIngressRule.find("#protocol").change(); @@ -181,57 +184,66 @@ function initAddIngressRuleDialog() { $("#dialog_add_ingress_rule") .dialog('option', 'buttons', { "Add": function() { - var thisDialog = $(this); - - var moreCriteria = []; - moreCriteria.push("&domainid="+domainId); - moreCriteria.push("&account="+account); - moreCriteria.push("&securitygroupname="+securityGroupName); - - var protocol = thisDialog.find("#protocol").val(); - if (protocol!=null && protocol.length > 0) - moreCriteria.push("&protocol="+encodeURIComponent(protocol)); - - // validate values (begin) + var $thisDialog = $(this); + $thisDialog.find("#info_container").hide(); + + // validate values var isValid = true; if(protocol == "ICMP") { - isValid &= validateNumber("Type", thisDialog.find("#icmp_type"), thisDialog.find("#icmp_type_errormsg"), -1, 40, false); //required - isValid &= validateNumber("Code", thisDialog.find("#icmp_code"), thisDialog.find("#icmp_code_errormsg"), -1 , 15, false); //required + isValid &= validateNumber("Type", $thisDialog.find("#icmp_type"), $thisDialog.find("#icmp_type_errormsg"), -1, 40, false); //required + isValid &= validateNumber("Code", $thisDialog.find("#icmp_code"), $thisDialog.find("#icmp_code_errormsg"), -1 , 15, false); //required } else { //TCP, UDP - isValid &= validateNumber("Start Port", thisDialog.find("#start_port"), thisDialog.find("#start_port_errormsg"), 1, 65535, false); //required - isValid &= validateNumber("End Port", thisDialog.find("#end_port"), thisDialog.find("#end_port_errormsg"), 1, 65535, false); //required + isValid &= validateNumber("Start Port", $thisDialog.find("#start_port"), $thisDialog.find("#start_port_errormsg"), 1, 65535, false); //required + isValid &= validateNumber("End Port", $thisDialog.find("#end_port"), $thisDialog.find("#end_port_errormsg"), 1, 65535, false); //required } - if(thisDialog.find("input[name='ingress_rule_type']:checked").val() == "cidr") { - isValid &= validateCIDR("CIDR", thisDialog.find(".cidr_template").eq(0).find("#cidr"), thisDialog.find(".cidr_template").eq(0).find("#cidr_errormsg"), false); //required - for(var i=1; i 0) + moreCriteria.push("&protocol="+encodeURIComponent(protocol)); + if(protocol == "ICMP") { - var icmpType = thisDialog.find("#icmp_type").val(); + var icmpType = $thisDialog.find("#icmp_type").val(); if (icmpType!=null && icmpType.length > 0) moreCriteria.push("&icmptype="+encodeURIComponent(icmpType)); - var icmpCode = thisDialog.find("#icmp_code").val(); + var icmpCode = $thisDialog.find("#icmp_code").val(); if (icmpCode!=null && icmpCode.length > 0) moreCriteria.push("&icmpcode="+encodeURIComponent(icmpCode)); } else { //TCP, UDP - var startPort = thisDialog.find("#start_port").val(); + var startPort = $thisDialog.find("#start_port").val(); if (startPort!=null && startPort.length > 0) moreCriteria.push("&startport="+encodeURIComponent(startPort)); - var endPort = thisDialog.find("#end_port").val(); + var endPort = $thisDialog.find("#end_port").val(); if (endPort!=null && endPort.length > 0) moreCriteria.push("&endport="+encodeURIComponent(endPort)); } @@ -254,25 +266,13 @@ function initAddIngressRuleDialog() { moreCriteria.push("&usersecuritygrouplist["+i+"].account="+accountElementArray[i].value+"&usersecuritygrouplist["+i+"].group="+securitygroupElementArray[i].value); } } - - thisDialog.dialog("close"); - - var ingressRuleTemplate = $("#security_group_ingress_rule_template").clone(true); - var loadingImg = ingressRuleTemplate.find(".adding_loading"); - var rowContainer = ingressRuleTemplate.find("#row_container"); - loadingImg.find(".adding_text").text("Adding...."); - loadingImg.show(); - rowContainer.hide(); - template.find("#ingress_rule_grid").append(ingressRuleTemplate.fadeIn("slow")); - template.find("#ingress_rule_grid").find("#no_ingress_rule").hide(); - + $.ajax({ data: createURL("command=authorizeSecurityGroupIngress"+moreCriteria.join("")), dataType: "json", success: function(json) { var jobId = json.authorizesecuritygroupingress.jobid; - var timerKey = "ingressRuleJob_"+jobId; - ingressRuleTemplate.attr("id","ingressRule_"+jobId); //temporary id until API call returns real id + var timerKey = "ingressRuleJob_"+jobId; $("body").everyTime( 5000, timerKey, @@ -286,34 +286,35 @@ function initAddIngressRuleDialog() { return; //Job has not completed } else { $("body").stopTime(timerKey); - if (result.jobstatus == 1) { // Succeeded - var items = result.jobresult.securitygroup.ingressrule; - ingressRuleJSONToTemplate(items[0], ingressRuleTemplate).data("parentSecurityGroupId", securityGroupId).data("parentSecurityGroupDomainId", domainId).data("parentSecurityGroupAccount", account).data("parentSecurityGroupName",securityGroupName); + if (result.jobstatus == 1) { // Succeeded + $thisDialog.find("#spinning_wheel").hide(); + $thisDialog.dialog("close"); + var items = result.jobresult.securitygroup.ingressrule; + + var $subgridItem = $("#ingressrule_tab_template").clone(true); + securityGroupIngressRuleJSONToTemplate(items[0], $subgridItem).data("parentSecurityGroupId", securityGroupId).data("parentSecurityGroupDomainId", domainId).data("parentSecurityGroupAccount", account).data("parentSecurityGroupName",securityGroupName); + $subgridItem.find("#after_action_info").text("Ingress rule was added successfully."); + $subgridItem.find("#after_action_info_container").removeClass("error").addClass("success").show(); + $("#right_panel_content").find("#tab_content_ingressrule").find("#tab_container").prepend($subgridItem.show()); + if(items.length > 1) { - for(var i=1; i Date: Mon, 10 Jan 2011 13:45:37 -0800 Subject: [PATCH 083/142] bug 7722: open vswitch - fix issue that flows un-delete when VM stop --- scripts/vm/hypervisor/xenserver/vmops | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index 1a13c40eff5..6af2deced19 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -150,6 +150,7 @@ def vlanRemapUtils(session, args): cmd.insert(4, args.pop("ofports")) cmd.insert(5, args.pop("macs")) cmd.insert(6, args.pop("remap")) + cmd.insert(7, args.pop("reCreate")) elif op == "setTag": cmd.insert(3, args.pop("bridge")) cmd.insert(4, args.pop("vifName")) From bc74fefe68d412516381a457771384c622c99094 Mon Sep 17 00:00:00 2001 From: alena Date: Mon, 10 Jan 2011 14:25:56 -0800 Subject: [PATCH 084/142] Api xmlDocWriter: create 2 output .xml files; one contains commands in the order defined in commands.properties.in file, another - commands in alphabetical order. --- .../com/cloud/api/doc/ApiXmlDocWriter.java | 229 +++++++++++------- 1 file changed, 142 insertions(+), 87 deletions(-) diff --git a/server/src/com/cloud/api/doc/ApiXmlDocWriter.java b/server/src/com/cloud/api/doc/ApiXmlDocWriter.java index 1e68f8bd219..06e488133c6 100644 --- a/server/src/com/cloud/api/doc/ApiXmlDocWriter.java +++ b/server/src/com/cloud/api/doc/ApiXmlDocWriter.java @@ -28,10 +28,14 @@ import java.io.ObjectOutputStream; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Enumeration; import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; import java.util.List; import java.util.Properties; +import java.util.TreeMap; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -48,20 +52,20 @@ import com.google.gson.annotations.SerializedName; import com.thoughtworks.xstream.XStream; public class ApiXmlDocWriter { - public static final Logger s_logger = Logger - .getLogger(ApiXmlDocWriter.class.getName()); + public static final Logger s_logger = Logger.getLogger(ApiXmlDocWriter.class.getName()); private static final short DOMAIN_ADMIN_COMMAND = 2; private static final short USER_COMMAND = 8; - private static Properties all_api_commands = new Properties(); - private static Properties domain_admin_api_commands = new Properties(); - private static Properties regular_user_api_commands = new Properties(); - + private static LinkedHashMap all_api_commands = new LinkedHashMap(); + private static LinkedHashMap domain_admin_api_commands = new LinkedHashMap(); + private static LinkedHashMap regular_user_api_commands = new LinkedHashMap(); + private static TreeMap all_api_commands_sorted = new TreeMap(); + private static TreeMap domain_admin_api_commands_sorted = new TreeMap(); + private static TreeMap regular_user_api_commands_sorted = new TreeMap(); private static String dirName=""; public static void main (String[] args) { - Properties preProcessedCommands = new Properties(); - Enumeration command = null; + LinkedProperties preProcessedCommands = new LinkedProperties(); String[] fileNames = null; List argsList = Arrays.asList(args); @@ -95,9 +99,11 @@ public class ApiXmlDocWriter { } } + Iterator propertiesIterator = preProcessedCommands.keys.iterator(); //Get command classes and response object classes - for (Object key : preProcessedCommands.keySet()) { - String preProcessedCommand = preProcessedCommands.getProperty((String)key); + while (propertiesIterator.hasNext()) { + String key = (String)propertiesIterator.next(); + String preProcessedCommand = preProcessedCommands.getProperty(key); String[] commandParts = preProcessedCommand.split(";"); String commandName = commandParts[0]; all_api_commands.put(key, commandName); @@ -111,7 +117,9 @@ public class ApiXmlDocWriter { } } - command = all_api_commands.propertyNames(); + all_api_commands_sorted.putAll(all_api_commands); + domain_admin_api_commands_sorted.putAll(domain_admin_api_commands); + regular_user_api_commands_sorted.putAll(regular_user_api_commands); try { //Create object writer @@ -128,101 +136,62 @@ public class ApiXmlDocWriter { ObjectOutputStream out = xs.createObjectOutputStream(new FileWriter(dirName + "/commands.xml"), "commands"); ObjectOutputStream rootAdmin = xs.createObjectOutputStream(new FileWriter(rootAdminDirName + "/" + "rootAdminSummary.xml"), "commands"); - ObjectOutputStream outDomainAdmin = xs.createObjectOutputStream(new FileWriter(domainAdminDirName + "/" + "domainAdminSummary.xml"), "commands"); + ObjectOutputStream rootAdminSorted = xs.createObjectOutputStream(new FileWriter(rootAdminDirName + "/" + "rootAdminSummarySorted.xml"), "commands"); + ObjectOutputStream domainAdmin = xs.createObjectOutputStream(new FileWriter(domainAdminDirName + "/" + "domainAdminSummary.xml"), "commands"); + ObjectOutputStream outDomainAdminSorted = xs.createObjectOutputStream(new FileWriter(domainAdminDirName + "/" + "domainAdminSummarySorted.xml"), "commands"); ObjectOutputStream regularUser = xs.createObjectOutputStream(new FileWriter(regularUserDirName + "/regularUserSummary.xml"), "commands"); + ObjectOutputStream regularUserSorted = xs.createObjectOutputStream(new FileWriter(regularUserDirName + "/regularUserSummarySorted.xml"), "commands"); - while (command.hasMoreElements()) { + //Write commands in the order they are represented in commands.properties.in file + Iterator it = all_api_commands.keySet().iterator(); + while (it.hasNext()) { ObjectOutputStream singleCommandOs = null; - String key = (String) command.nextElement(); - Class clas = Class.forName(all_api_commands.getProperty(key)); - ArrayList request = new ArrayList(); - ArrayList response = new ArrayList(); + String key = (String)it.next(); - //Create a new command, set name and description - Command apiCommand = new Command(); - apiCommand.setName(key); - - - Implementation impl = (Implementation)clas.getAnnotation(Implementation.class); - if (impl == null) - impl = (Implementation)clas.getSuperclass().getAnnotation(Implementation.class); - String commandDescription = impl.description(); - if (commandDescription != null) - apiCommand.setDescription(commandDescription); - else - System.out.println("Command " + apiCommand.getName() + " misses description"); - - //Get request parameters - Field[] fields = clas.getDeclaredFields(); - - //Get fields from superclass - Class superClass = clas.getSuperclass(); - String superName = superClass.getName(); - if (!superName.equals(BaseCmd.class.getName()) && !superName.equals(BaseAsyncCmd.class.getName()) && !superName.equals(BaseAsyncCreateCmd.class.getName())) { - Field[] superClassFields = superClass.getDeclaredFields(); - if (superClassFields != null && !superClass.getName().equals(BaseListCmd.class.getName())) { - Field[] tmpFields = new Field[fields.length + superClassFields.length]; - System.arraycopy(fields, 0, tmpFields, 0, fields.length); - System.arraycopy(superClassFields, 0, tmpFields, fields.length, superClassFields.length); - fields = tmpFields; - } - superClass = superClass.getSuperclass(); - } - - for (Field f : fields) { - Parameter parameterAnnotation = f.getAnnotation(Parameter.class); - if (parameterAnnotation != null) { - Argument reqArg = new Argument(parameterAnnotation.name()); - reqArg.setRequired(parameterAnnotation.required()); - if (!parameterAnnotation.description().isEmpty() && parameterAnnotation.expose()) - reqArg.setDescription(parameterAnnotation.description()); - else if (parameterAnnotation.expose()) { - //System.out.println("Description is missing for the parameter " + parameterAnnotation.name() + " of the command " + apiCommand.getName() ); - } - request.add(reqArg); - } - } - - Class responseClas = impl.responseObject(); - - //Get response parameters - Field[] responseFields = responseClas.getDeclaredFields(); - for (Field responseField : responseFields) { - SerializedName nameAnnotation = responseField.getAnnotation(SerializedName.class); - Param descAnnotation = responseField.getAnnotation(Param.class); - Argument respArg = new Argument(nameAnnotation.value()); - if (descAnnotation != null) - respArg.setDescription(descAnnotation.description()); - response.add(respArg); - } - - apiCommand.setRequest(request); - apiCommand.setResponse(response); - - //Write command to xml file - out.writeObject(apiCommand); - rootAdmin.writeObject(apiCommand); - - //Write single command to xml file + //Write admin commands + writeCommand(out, key); + writeCommand(rootAdmin, key); + + //Write single commands to separate xml files singleCommandOs = xs.createObjectOutputStream(new FileWriter(rootAdminDirName + "/" + key + ".xml"), "command"); if (domain_admin_api_commands.containsKey(key)){ - outDomainAdmin.writeObject(apiCommand); + writeCommand(domainAdmin, key); singleCommandOs = xs.createObjectOutputStream(new FileWriter(domainAdminDirName + "/" + key + ".xml"), "command"); } if (regular_user_api_commands.containsKey(key)){ singleCommandOs = xs.createObjectOutputStream(new FileWriter(regularUserDirName + "/" + key + ".xml"), "command"); - regularUser.writeObject(apiCommand); + writeCommand(regularUser, key); } - singleCommandOs.writeObject(apiCommand); + writeCommand(singleCommandOs, key); singleCommandOs.close(); } + //Write sorted commands + it = all_api_commands_sorted.keySet().iterator(); + while (it.hasNext()) { + String key = (String)it.next(); + + writeCommand(rootAdminSorted, key); + + + if (domain_admin_api_commands.containsKey(key)){ + writeCommand(outDomainAdminSorted, key); + } + + if (regular_user_api_commands.containsKey(key)){ + writeCommand(regularUserSorted, key); + } + } + out.close(); rootAdmin.close(); - outDomainAdmin.close(); + rootAdminSorted.close(); + domainAdmin.close(); + outDomainAdminSorted.close(); regularUser.close(); + regularUserSorted.close(); //gzip directory with xml doc zipDir(dirName + "xmldoc.zip", xmlDocDir); @@ -236,6 +205,76 @@ public class ApiXmlDocWriter { } } + + private static void writeCommand(ObjectOutputStream out, String command) throws ClassNotFoundException, IOException{ + Class clas = Class.forName(all_api_commands.get(command)); + ArrayList request = new ArrayList(); + ArrayList response = new ArrayList(); + + //Create a new command, set name and description + Command apiCommand = new Command(); + apiCommand.setName(command); + + + Implementation impl = (Implementation)clas.getAnnotation(Implementation.class); + if (impl == null) + impl = (Implementation)clas.getSuperclass().getAnnotation(Implementation.class); + String commandDescription = impl.description(); + if (commandDescription != null) + apiCommand.setDescription(commandDescription); + else + System.out.println("Command " + apiCommand.getName() + " misses description"); + + //Get request parameters + Field[] fields = clas.getDeclaredFields(); + + //Get fields from superclass + Class superClass = clas.getSuperclass(); + String superName = superClass.getName(); + if (!superName.equals(BaseCmd.class.getName()) && !superName.equals(BaseAsyncCmd.class.getName()) && !superName.equals(BaseAsyncCreateCmd.class.getName())) { + Field[] superClassFields = superClass.getDeclaredFields(); + if (superClassFields != null && !superClass.getName().equals(BaseListCmd.class.getName())) { + Field[] tmpFields = new Field[fields.length + superClassFields.length]; + System.arraycopy(fields, 0, tmpFields, 0, fields.length); + System.arraycopy(superClassFields, 0, tmpFields, fields.length, superClassFields.length); + fields = tmpFields; + } + superClass = superClass.getSuperclass(); + } + + for (Field f : fields) { + Parameter parameterAnnotation = f.getAnnotation(Parameter.class); + if (parameterAnnotation != null) { + Argument reqArg = new Argument(parameterAnnotation.name()); + reqArg.setRequired(parameterAnnotation.required()); + if (!parameterAnnotation.description().isEmpty() && parameterAnnotation.expose()) + reqArg.setDescription(parameterAnnotation.description()); + else if (parameterAnnotation.expose()) { + //System.out.println("Description is missing for the parameter " + parameterAnnotation.name() + " of the command " + apiCommand.getName() ); + } + request.add(reqArg); + } + } + + Class responseClas = impl.responseObject(); + + //Get response parameters + Field[] responseFields = responseClas.getDeclaredFields(); + for (Field responseField : responseFields) { + SerializedName nameAnnotation = responseField.getAnnotation(SerializedName.class); + Param descAnnotation = responseField.getAnnotation(Param.class); + Argument respArg = new Argument(nameAnnotation.value()); + if (descAnnotation != null) + respArg.setDescription(descAnnotation.description()); + response.add(respArg); + } + + apiCommand.setRequest(request); + apiCommand.setResponse(response); + + out.writeObject(apiCommand); + } + private static void zipDir(String zipFileName, String dir) throws Exception { File dirObj = new File(dir); ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileName)); @@ -273,4 +312,20 @@ public class ApiXmlDocWriter { } dir.delete(); } + + + private static class LinkedProperties extends Properties { + private final LinkedList keys = new LinkedList(); + + public Enumeration keys() { + return Collections.enumeration(keys); + } + + public Object put(Object key, Object value) { + //System.out.println("Adding key" + key); + keys.add(key); + return super.put(key, value); + } + } + } \ No newline at end of file From 432cbc845834ad45299026ebc9f44fde252690e7 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 10 Jan 2011 14:51:17 -0800 Subject: [PATCH 085/142] hide/show security group left menu when direct.attach.security.groups.enabled is false/true. --- ui/index.jsp | 2 +- ui/scripts/cloud.core.init.js | 12 ++++++------ ui/scripts/cloud.core.js | 11 +++++++++-- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/ui/index.jsp b/ui/index.jsp index f4981b01ec4..8cfdc03f77f 100644 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -412,7 +412,7 @@ -
    + +
    +
    +
    +
    + <%=t.t("zone")%>:
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + <%=t.t("type")%>:
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + <%=t.t("ip.address")%>:
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + <%=t.t("state")%>:
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + <%=t.t("version")%>:
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + <%=t.t("last.disconnected")%>:
    +
    +
    +
    +
    +
    +
    diff --git a/ui/scripts/cloud.core.secondarystorage.js b/ui/scripts/cloud.core.secondarystorage.js index 7d6e8733159..52c63384170 100644 --- a/ui/scripts/cloud.core.secondarystorage.js +++ b/ui/scripts/cloud.core.secondarystorage.js @@ -72,7 +72,16 @@ function secondaryStorageJsonToDetailsTab() { $thisTab.find("#id").text(fromdb(jsonObj.id)); $thisTab.find("#grid_header_title").text(fromdb(jsonObj.name)); $thisTab.find("#name").text(fromdb(jsonObj.name)); - + + $thisTab.find("#zonename").text(fromdb(jsonObj.zonename)); + $thisTab.find("#type").text(jsonObj.type); + $thisTab.find("#ipaddress").text(jsonObj.ipaddress); + + setHostStateInRightPanel(fromdb(jsonObj.state), $thisTab.find("#state")) + + $thisTab.find("#version").text(jsonObj.version); + setDateField(jsonObj.disconnected, $thisTab.find("#disconnected")); + //actions *** var $actionLink = $thisTab.find("#action_link"); $actionLink.bind("mouseover", function(event) { From 72b4552f01ae403a54e1f82f9cb8b059cd5de1da Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 11 Jan 2011 16:40:36 -0800 Subject: [PATCH 123/142] bug 7861: secondary storage page - implement "Delete Secondary Storage" action. --- ui/jsp/zone.jsp | 4 +- ui/scripts/cloud.core.secondarystorage.js | 56 ++++++++++++++++++++--- ui/scripts/cloud.core.zone.js | 4 ++ 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/ui/jsp/zone.jsp b/ui/jsp/zone.jsp index b4004953eb9..9d54c1ae090 100644 --- a/ui/jsp/zone.jsp +++ b/ui/jsp/zone.jsp @@ -22,8 +22,10 @@
    <%=t.t("details")%>
    + + + + + diff --git a/ui/scripts/cloud.core.secondarystorage.js b/ui/scripts/cloud.core.secondarystorage.js index a8dfcb888dd..a140dea0d09 100644 --- a/ui/scripts/cloud.core.secondarystorage.js +++ b/ui/scripts/cloud.core.secondarystorage.js @@ -18,10 +18,8 @@ function afterLoadSecondaryStorageJSP($midmenuItem1) { var $topButtonContainer = clearButtonsOnTop(); - $("#top_buttons").appendTo($topButtonContainer); - - //initDialog("dialog_add_external_cluster_in_secondaryStorage_page", 320); - + $("#top_buttons").appendTo($topButtonContainer); + initDialog("dialog_add_secondarystorage"); secondaryStorageRefreshDataBinding(); } @@ -31,15 +29,9 @@ function secondaryStorageRefreshDataBinding() { } function secondaryStorageJsonToRightPanel($midmenuItem1) { - $("#right_panel_content").data("$midmenuItem1", $midmenuItem1); - - /* - bindEventHandlerToDialogAddVlanForZone(); - bindAddPodButton($("#add_pod_button"), $midmenuItem1); - bindAddSecondaryStorageButton($("#add_secondarystorage_button"), $midmenuItem1); - */ - - secondaryStorageJsonToDetailsTab(); + $("#right_panel_content").data("$midmenuItem1", $midmenuItem1); + bindAddSecondaryStorageButton($midmenuItem1.data("zoneObj")); + secondaryStorageJsonToDetailsTab(); } function secondaryStorageJsonToDetailsTab() { diff --git a/ui/scripts/cloud.core.zone.js b/ui/scripts/cloud.core.zone.js index 80d50941262..d0a765fc5f0 100644 --- a/ui/scripts/cloud.core.zone.js +++ b/ui/scripts/cloud.core.zone.js @@ -52,7 +52,7 @@ function zoneJsonToRightPanel($leftmenuItem1) { bindAddPodButton($("#add_pod_button"), $leftmenuItem1); //bindAddVLANButton($("#add_vlan_button"), $leftmenuItem1); - bindAddSecondaryStorageButton($("#add_secondarystorage_button"), $leftmenuItem1); + bindAddSecondaryStorageButton($leftmenuItem1.data("jsonObj")); var pods; var zoneObj = $leftmenuItem1.data("jsonObj"); @@ -581,13 +581,8 @@ function bindAddVLANButton($button, $leftmenuItem1) { } -function bindAddSecondaryStorageButton($button, $leftmenuItem1) { - $button.show(); - $button.unbind("click").bind("click", function(event) { - //if($("#tab_content_secondarystorage").css("display") == "none") - // $("#tab_secondarystorage").click(); - - var zoneObj = $leftmenuItem1.data("jsonObj"); +function bindAddSecondaryStorageButton(zoneObj) { + $("#add_secondarystorage_button").unbind("click").bind("click", function(event) { $("#dialog_add_secondarystorage").find("#zone_name").text(fromdb(zoneObj.name)); $("#dialog_add_secondarystorage").find("#info_container").hide(); @@ -615,16 +610,8 @@ function bindAddSecondaryStorageButton($button, $leftmenuItem1) { dataType: "json", success: function(json) { $thisDialog.find("#spinning_wheel").hide(); - $thisDialog.dialog("close"); - - $("#zone_"+zoneId).find("#secondarystorage_header").click(); - /* - var $subgridItem = $("#secondary_storage_tab_template").clone(true); - secondaryStorageJSONToTemplate(json.addsecondarystorageresponse.secondarystorage, $subgridItem); - $subgridItem.find("#after_action_info").text("Secondary storage was added successfully."); - $subgridItem.find("#after_action_info_container").removeClass("error").addClass("success").show(); - $("#tab_content_secondarystorage").find("#tab_container").append($subgridItem.show()); - */ + $thisDialog.dialog("close"); + $("#zone_"+zoneId).find("#secondarystorage_header").click(); }, error: function(XMLHttpResponse) { handleError(XMLHttpResponse, function() { From ad4ed5b2fdc8778c7e0f01b5ebfad1c864e657d0 Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Tue, 11 Jan 2011 11:19:21 -0800 Subject: [PATCH 130/142] added hypervisor type to vm --- api/src/com/cloud/vm/VirtualMachine.java | 3 + core/src/com/cloud/vm/ConsoleProxyVO.java | 59 +--- core/src/com/cloud/vm/DomainRouterVO.java | 54 +--- .../com/cloud/vm/SecondaryStorageVmVO.java | 58 +--- core/src/com/cloud/vm/UserVmVO.java | 37 +-- core/src/com/cloud/vm/VMInstanceVO.java | 56 +--- .../cloud/agent/manager/AgentManagerImpl.java | 2 +- .../src/com/cloud/configuration/Config.java | 8 +- .../consoleproxy/ConsoleProxyManagerImpl.java | 4 +- .../VirtualNetworkApplianceManagerImpl.java | 6 +- .../SecondaryStorageManagerImpl.java | 4 +- server/src/com/cloud/vm/ItWorkDao.java | 16 +- server/src/com/cloud/vm/ItWorkDaoImpl.java | 45 +++ server/src/com/cloud/vm/ItWorkVO.java | 56 ++-- .../src/com/cloud/vm/UserVmManagerImpl.java | 17 +- .../com/cloud/vm/VirtualMachineManager.java | 7 +- .../cloud/vm/VirtualMachineManagerImpl.java | 286 ++++++++++++------ .../cloud/vm/VirtualMachineProfileImpl.java | 12 +- .../src/com/cloud/vm/dao/VMInstanceDao.java | 2 +- .../com/cloud/vm/dao/VMInstanceDaoImpl.java | 4 +- setup/db/create-schema.sql | 22 +- .../com/cloud/utils/time/InaccurateClock.java | 9 +- 22 files changed, 381 insertions(+), 386 deletions(-) diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java index b6ccd7724e2..de435368305 100755 --- a/api/src/com/cloud/vm/VirtualMachine.java +++ b/api/src/com/cloud/vm/VirtualMachine.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.Set; import com.cloud.acl.ControlledEntity; +import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.utils.fsm.FiniteState; import com.cloud.utils.fsm.StateMachine; @@ -223,4 +224,6 @@ public interface VirtualMachine extends RunningOn, ControlledEntity { public long getServiceOfferingId(); Type getType(); + + HypervisorType getHypervisorType(); } diff --git a/core/src/com/cloud/vm/ConsoleProxyVO.java b/core/src/com/cloud/vm/ConsoleProxyVO.java index 0fd99fc9978..e863cb2d233 100644 --- a/core/src/com/cloud/vm/ConsoleProxyVO.java +++ b/core/src/com/cloud/vm/ConsoleProxyVO.java @@ -28,6 +28,8 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.persistence.Transient; + +import com.cloud.hypervisor.Hypervisor.HypervisorType; /** * ConsoleProxyVO domain object @@ -97,64 +99,11 @@ public class ConsoleProxyVO extends VMInstanceVO implements ConsoleProxy { /** * Correct constructor to use. */ - public ConsoleProxyVO(long id, long serviceOfferingId, String name, long templateId, long guestOSId, long dataCenterId, long domainId, long accountId, int activeSession) { - super(id, serviceOfferingId, name, name, Type.ConsoleProxy, templateId, guestOSId, domainId, accountId, false); + public ConsoleProxyVO(long id, long serviceOfferingId, String name, long templateId, HypervisorType hypervisorType, long guestOSId, long dataCenterId, long domainId, long accountId, int activeSession) { + super(id, serviceOfferingId, name, name, Type.ConsoleProxy, templateId, hypervisorType, guestOSId, domainId, accountId, false); this.activeSession = activeSession; } - public ConsoleProxyVO(ConsoleProxyVO that) { - this(that.id, that.serviceOfferingId, that.instanceName, that.guestMacAddress, that.guestIpAddress, that.guestNetmask, that.privateMacAddress, that.privateIpAddress, that.privateNetmask, that.templateId, that.guestOSId, that.publicMacAddress, that.publicIpAddress, that.publicNetmask, that.vlanDbId, that.vlanId, that.podId, that.dataCenterId, that.domainId, that.accountId, that.gateway, that.hostId, that.dns1, that.dns2, that.domain, that.ramSize, that.activeSession); - this.vncPassword = that.vncPassword; - this.sslEnabled = that.sslEnabled; - this.sessionDetails = that.sessionDetails; - } - - public ConsoleProxyVO( - long id, - long serviceOfferingId, - String name, - String guestMacAddress, - String guestIpAddress, - String guestNetMask, - String privateMacAddress, - String privateIpAddress, - String privateNetmask, - long templateId, - long guestOSId, - String publicMacAddress, - String publicIpAddress, - String publicNetmask, - Long vlanDbId, - String vlanId, - long podId, - long dataCenterId, - long domainId, - long accountId, - String gateway, - Long hostId, - String dns1, - String dns2, - String domain, - int ramSize, - int activeSession) { - super(id, serviceOfferingId, name, name, Type.ConsoleProxy, templateId, guestOSId, - privateMacAddress, privateIpAddress, privateNetmask, dataCenterId, podId, domainId, accountId, true, hostId); - this.gateway = gateway; - this.publicIpAddress = publicIpAddress; - this.publicNetmask = publicNetmask; - this.publicMacAddress = publicMacAddress; - this.guestIpAddress = guestIpAddress; - this.guestMacAddress = guestMacAddress; - this.guestNetmask = guestNetMask; - this.vlanDbId = vlanDbId; - this.vlanId = vlanId; - this.dns1 = dns1; - this.dns2 = dns2; - this.domain = domain; - this.ramSize = ramSize; - this.activeSession = activeSession; - } - protected ConsoleProxyVO() { super(); } diff --git a/core/src/com/cloud/vm/DomainRouterVO.java b/core/src/com/cloud/vm/DomainRouterVO.java index 3eb47f2aa19..3daa59d5838 100755 --- a/core/src/com/cloud/vm/DomainRouterVO.java +++ b/core/src/com/cloud/vm/DomainRouterVO.java @@ -26,6 +26,7 @@ import javax.persistence.Enumerated; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; +import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.router.VirtualRouter; import com.cloud.utils.net.NetUtils; @@ -92,66 +93,17 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter { @Enumerated(EnumType.STRING) private Role role = Role.DHCP_FIREWALL_LB_PASSWD_USERDATA; - public DomainRouterVO(DomainRouterVO that) { - this(that.id, that.serviceOfferingId, that.instanceName, that.privateMacAddress, that.privateIpAddress, that.privateNetmask, that.templateId, that.guestOSId, that.guestMacAddress, that.guestIpAddress, that.guestNetmask, that.accountId, that.domainId, that.publicMacAddress, that.publicIpAddress, that.publicNetmask, that.vlanDbId, that.vlanId, that.podId, that.dataCenterId, that.ramSize, that.gateway, that.domain, that.dns1, that.dns2); - this.vnet = that.vnet; - this.role = that.role; - } - - public DomainRouterVO(long id, - long serviceOfferingId, - String name, - String privateMacAddress, - String privateIpAddress, - String privateNetmask, - long templateId, - long guestOSId, - String guestMacAddress, - String guestIpAddress, - String guestNetmask, - long accountId, - long domainId, - String publicMacAddress, - String publicIpAddress, - String publicNetMask, - Long vlanDbId, String vlanId, - long podId, - long dataCenterId, - int ramSize, - String gateway, - String domain, - String dns1, - String dns2) { - super(id, serviceOfferingId, name, name, Type.DomainRouter, templateId, guestOSId, privateMacAddress, privateIpAddress, privateNetmask, dataCenterId, podId, domainId, accountId, true, null); - this.privateMacAddress = privateMacAddress; - this.guestMacAddress = guestMacAddress; - this.guestIpAddress = guestIpAddress; - this.publicIpAddress = publicIpAddress; - this.publicMacAddress = publicMacAddress; - this.publicNetmask = publicNetMask; - this.vlanDbId = vlanDbId; - this.vlanId = vlanId; - this.ramSize = ramSize; - this.gateway = gateway; - this.domain = domain; - this.dns1 = dns1; - this.dns2 = dns2; - this.dataCenterId = dataCenterId; - this.accountId = accountId; - this.domainId = domainId; - this.guestNetmask = guestNetmask; - } - public DomainRouterVO(long id, long serviceOfferingId, String name, long templateId, + HypervisorType hypervisorType, long guestOSId, long domainId, long accountId, long networkConfigurationId, boolean haEnabled) { - super(id, serviceOfferingId, name, name, Type.DomainRouter, templateId, guestOSId, domainId, accountId, haEnabled); + super(id, serviceOfferingId, name, name, Type.DomainRouter, templateId, hypervisorType, guestOSId, domainId, accountId, haEnabled); this.networkId = networkConfigurationId; } diff --git a/core/src/com/cloud/vm/SecondaryStorageVmVO.java b/core/src/com/cloud/vm/SecondaryStorageVmVO.java index 5afb42c8633..c4d2e6ecad5 100644 --- a/core/src/com/cloud/vm/SecondaryStorageVmVO.java +++ b/core/src/com/cloud/vm/SecondaryStorageVmVO.java @@ -26,6 +26,8 @@ import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; + +import com.cloud.hypervisor.Hypervisor.HypervisorType; /** * SecondaryStorageVmVO domain object @@ -89,63 +91,11 @@ public class SecondaryStorageVmVO extends VMInstanceVO implements SecondaryStora - public SecondaryStorageVmVO(long id, long serviceOfferingId, String name, long templateId, long guestOSId, long dataCenterId, + public SecondaryStorageVmVO(long id, long serviceOfferingId, String name, long templateId, HypervisorType hypervisorType, long guestOSId, long dataCenterId, long domainId, long accountId) { - super(id, serviceOfferingId, name, name, Type.SecondaryStorageVm, templateId, guestOSId, domainId, accountId, true); + super(id, serviceOfferingId, name, name, Type.SecondaryStorageVm, templateId, hypervisorType, guestOSId, domainId, accountId, true); } - public SecondaryStorageVmVO( - long id, - long serviceOfferingId, - String name, - String guestMacAddress, - String guestIpAddress, - String guestNetMask, - String privateMacAddress, - String privateIpAddress, - String privateNetmask, - long templateId, - long guestOSId, - String publicMacAddress, - String publicIpAddress, - String publicNetmask, - Long vlanDbId, - String vlanId, - long podId, - long dataCenterId, - long domainId, - long accountId, - String gateway, - Long hostId, - String dns1, - String dns2, - String domain, - int ramSize, - String guid, - String nfsShare) { - super(id, serviceOfferingId, name, name, Type.SecondaryStorageVm, templateId, guestOSId, - privateMacAddress, privateIpAddress, privateNetmask, dataCenterId, podId, domainId, accountId, true, hostId); - this.gateway = gateway; - this.publicIpAddress = publicIpAddress; - this.publicNetmask = publicNetmask; - this.publicMacAddress = publicMacAddress; - this.guestIpAddress = guestIpAddress; - this.guestMacAddress = guestMacAddress; - this.guestNetmask = guestNetMask; - this.vlanDbId = vlanDbId; - this.vlanId = vlanId; - this.dns1 = dns1; - this.dns2 = dns2; - this.domain = domain; - this.ramSize = ramSize; - this.setGuid(guid); - this.nfsShare = nfsShare; - } - - public SecondaryStorageVmVO(SecondaryStorageVmVO that) { - this(that.id, that.serviceOfferingId, that.instanceName, that.guestMacAddress, that.guestIpAddress, that.guestNetmask, that.privateMacAddress, that.privateIpAddress, that.privateNetmask, that.templateId, that.guestOSId, that.publicMacAddress, that.publicIpAddress, that.publicNetmask, that.vlanDbId, that.vlanId, that.podId, that.dataCenterId, that.domainId, that.accountId, that.gateway, that.hostId, that.dns1, that.dns2, that.domain, that.ramSize, that.guid, that.nfsShare); - } - protected SecondaryStorageVmVO() { super(); } diff --git a/core/src/com/cloud/vm/UserVmVO.java b/core/src/com/cloud/vm/UserVmVO.java index 40ac9912bda..89ba6f70e5d 100755 --- a/core/src/com/cloud/vm/UserVmVO.java +++ b/core/src/com/cloud/vm/UserVmVO.java @@ -23,6 +23,7 @@ import javax.persistence.Entity; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; +import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.uservm.UserVm; @Entity @@ -66,6 +67,7 @@ public class UserVmVO extends VMInstanceVO implements UserVm { transient String password; + @Override public String getPassword() { return password; } @@ -140,49 +142,18 @@ public class UserVmVO extends VMInstanceVO implements UserVm { String instanceName, String displayName, long templateId, + HypervisorType hypervisorType, long guestOsId, boolean haEnabled, long domainId, long accountId, long serviceOfferingId, String userData, String name) { - super(id, serviceOfferingId, name, instanceName, Type.User, templateId, guestOsId, domainId, accountId, haEnabled); + super(id, serviceOfferingId, name, instanceName, Type.User, templateId, hypervisorType, guestOsId, domainId, accountId, haEnabled); this.userData = userData; this.displayName = displayName != null ? displayName : null; } - public UserVmVO(long id, - String name, - long templateId, - long guestOSId, - long accountId, - long domainId, - long serviceOfferingId, - String guestMacAddress, - String guestIpAddress, - String guestNetMask, - String externalIpAddress, - String externalMacAddress, - Long vlanDbId, - Long routerId, - long podId, - long dcId, - boolean haEnabled, - String displayName, - String userData) { - super(id, serviceOfferingId, name, name, Type.User, templateId, guestOSId, guestMacAddress, guestIpAddress, guestNetMask, dcId, podId, domainId, accountId, haEnabled, null); - this.domainRouterId = routerId; - this.guestIpAddress = guestIpAddress; - this.guestNetmask = guestNetMask; - this.guestMacAddress = guestMacAddress; - this.externalIpAddress = externalIpAddress; - this.externalMacAddress = externalMacAddress; - this.setUserData(userData); - this.setExternalVlanDbId(vlanDbId); - this.isoId = null; - this.displayName = displayName; - } - protected UserVmVO() { super(); } diff --git a/core/src/com/cloud/vm/VMInstanceVO.java b/core/src/com/cloud/vm/VMInstanceVO.java index 3714f5778ee..bd22f50feb2 100644 --- a/core/src/com/cloud/vm/VMInstanceVO.java +++ b/core/src/com/cloud/vm/VMInstanceVO.java @@ -35,6 +35,7 @@ import javax.persistence.TableGenerator; import javax.persistence.Temporal; import javax.persistence.TemporalType; +import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.utils.db.GenericDao; import com.cloud.utils.db.StateMachine; import com.cloud.utils.fsm.FiniteStateObject; @@ -139,12 +140,17 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject -1) { - this.templateId = vmTemplateId; - } else { - this.templateId = null; - } - this.guestOSId = guestOSId; - this.privateIpAddress = privateIpAddress; - this.privateMacAddress = privateMacAddress; - this.privateNetmask = privateNetmask; - this.hostId = hostId; - this.dataCenterId = dataCenterId; - this.podId = podId; - this.type = type; - this.haEnabled = haEnabled; - this.instanceName = instanceName; - this.updated = 0; - this.updateTime = new Date(); - this.vncPassword = Long.toHexString(new Random().nextLong()); - this.state = State.Creating; - this.serviceOfferingId = serviceOfferingId; - this.domainId = domainId; - this.accountId = accountId; - } - protected VMInstanceVO() { } @@ -239,6 +202,11 @@ public class VMInstanceVO implements VirtualMachine, FiniteStateObject avoid) { VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl( - vm, template, offering, null, null, null); + vm, template, offering, null, null); DeployDestination dest = null; DataCenterDeployment plan = new DataCenterDeployment(dc.getId(), pod.getId(), sp.getClusterId(), null); diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 7e14f81c86a..abbc40bac62 100644 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -213,7 +213,13 @@ public enum Config { SSOKey("Hidden", ManagementServer.class, String.class, "security.singlesignon.key", null, "A Single Sign-On key used for logging into the cloud", null), SSOAuthTolerance("Advanced", ManagementServer.class, Long.class, "security.singlesignon.tolerance.millis", "300000", "The allowable clock difference in milliseconds between when an SSO login request is made and when it is received.", null), //NetworkType("Hidden", ManagementServer.class, String.class, "network.type", "vlan", "The type of network that this deployment will use.", "vlan,direct"), - HashKey("Hidden", ManagementServer.class, String.class, "security.hash.key", null, "for generic key-ed hash", null); + HashKey("Hidden", ManagementServer.class, String.class, "security.hash.key", null, "for generic key-ed hash", null), + + VmOpWaitInterval("Advanced", ManagementServer.class, Integer.class, "vm.op.wait.interval", "120", "Seconds to wait before checking if a previous operation has succeeded", null), + VmOpLockStateRetry("Advanced", ManagementServer.class, Integer.class, "vm.op.lock.state.retry", "5", "Times to retry locking the state of a VM for operations", "-1 means try forever"), + VmOpCleanupInterval("Advanced", ManagementServer.class, Long.class, "vm.op.cleanup.interval", "86400", "Interval to run the thread that cleans up the vm operations in seconds", "Seconds"), + VmOpCleanupWait("Advanced", ManagementServer.class, Long.class, "vm.op.cleanup.wait", "3600", "Seconds to wait before cleanuping up any vm work items", "Seconds"), + VmOpCancelInterval("Advanced", ManagementServer.class, Long.class, "vm.op.cancel.interval", "3600", "Seconds to wait before cancelling a operation", "Seconds"); private final String _category; private final Class _componentClass; diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index ef2a5b62ba1..a82f7229c54 100644 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -562,7 +562,7 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyVmId); Account systemAcct = _accountMgr.getSystemAccount(); User systemUser = _accountMgr.getSystemUser(); - return _itMgr.start(proxy, null, systemUser, systemAcct, null); + return _itMgr.start(proxy, null, systemUser, systemAcct); } public ConsoleProxyVO assignProxyFromRunningPool(long dataCenterId) { @@ -713,7 +713,7 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx for (NetworkOfferingVO offering : offerings) { networks.add(new Pair(_networkMgr.setupNetwork(systemAcct, offering, plan, null, null, false, false).get(0), null)); } - ConsoleProxyVO proxy = new ConsoleProxyVO(id, _serviceOffering.getId(), name, _template.getId(), _template.getGuestOSId(), dataCenterId, systemAcct.getDomainId(), systemAcct.getId(), 0); + ConsoleProxyVO proxy = new ConsoleProxyVO(id, _serviceOffering.getId(), name, _template.getId(), _template.getHypervisorType(), _template.getGuestOSId(), dataCenterId, systemAcct.getDomainId(), systemAcct.getId(), 0); try { proxy = _itMgr.allocate(proxy, _template, _serviceOffering, networks, plan, null, systemAcct); } catch (InsufficientCapacityException e) { diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 6c02479f1ac..d811faeb1f2 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -1069,7 +1069,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian networks.add(new Pair(controlConfig, null)); router = new DomainRouterVO(id, _offering.getId(), VirtualMachineName.getRouterName(id, _instance), _template.getId(), - _template.getGuestOSId(), owner.getDomainId(), owner.getId(), guestNetwork.getId(), _offering.getOfferHA()); + _template.getHypervisorType(), _template.getGuestOSId(), owner.getDomainId(), owner.getId(), guestNetwork.getId(), _offering.getOfferHA()); router = _itMgr.allocate(router, _template, _offering, networks, plan, null, owner); if(router != null){ EventUtils.saveEvent(User.UID_SYSTEM, owner.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ROUTER_CREATE, "successfully create router : " + router.getName(), startEventId); @@ -1134,7 +1134,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian networks.add(new Pair(controlConfig, null)); router = new DomainRouterVO(id, _offering.getId(), VirtualMachineName.getRouterName(id, _instance), _template.getId(), - _template.getGuestOSId(), owner.getDomainId(), owner.getId(), guestNetwork.getId(), _offering.getOfferHA()); + _template.getHypervisorType(), _template.getGuestOSId(), owner.getDomainId(), owner.getId(), guestNetwork.getId(), _offering.getOfferHA()); router.setRole(Role.DHCP_USERDATA); router = _itMgr.allocate(router, _template, _offering, networks, plan, null, owner); if(router != null){ @@ -1440,7 +1440,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian private DomainRouterVO start(DomainRouterVO router, User user, Account caller) throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { s_logger.debug("Starting router " + router); - if (_itMgr.start(router, null, user, caller, null) != null) { + if (_itMgr.start(router, null, user, caller) != null) { return _routerDao.findById(router.getId()); } else { return null; diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index c2272b80601..1410de77c9d 100644 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -261,7 +261,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId); Account systemAcct = _accountMgr.getSystemAccount(); User systemUser = _accountMgr.getSystemUser(); - return _itMgr.start(secStorageVm, null, systemUser, systemAcct, null); + return _itMgr.start(secStorageVm, null, systemUser, systemAcct); } @@ -463,7 +463,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V s_logger.info("Unable to setup due to concurrent operation. " + e); return new HashMap(); } - SecondaryStorageVmVO secStorageVm = new SecondaryStorageVmVO(id, _serviceOffering.getId(), name, _template.getId(), + SecondaryStorageVmVO secStorageVm = new SecondaryStorageVmVO(id, _serviceOffering.getId(), name, _template.getId(), _template.getHypervisorType(), _template.getGuestOSId(), dataCenterId, systemAcct.getDomainId(), systemAcct.getId()); try { secStorageVm = _itMgr.allocate(secStorageVm, _template, _serviceOffering, networks, plan, null, systemAcct); diff --git a/server/src/com/cloud/vm/ItWorkDao.java b/server/src/com/cloud/vm/ItWorkDao.java index 51c60943a9c..93b30c1654c 100644 --- a/server/src/com/cloud/vm/ItWorkDao.java +++ b/server/src/com/cloud/vm/ItWorkDao.java @@ -18,7 +18,21 @@ package com.cloud.vm; import com.cloud.utils.db.GenericDao; +import com.cloud.vm.VirtualMachine.State; public interface ItWorkDao extends GenericDao { - + /** + * find a work item based on the instanceId and the state. + * + * @param instanceId vm instance id + * @param state state + * @return ItWorkVO if found; null if not. + */ + ItWorkVO findByInstance(long instanceId, State state); + + /** + * cleanup rows that are either Done or Cancelled and been that way + * for at least wait time. + */ + void cleanup(long wait); } diff --git a/server/src/com/cloud/vm/ItWorkDaoImpl.java b/server/src/com/cloud/vm/ItWorkDaoImpl.java index 87ee53ae2fd..b7df1275f5b 100644 --- a/server/src/com/cloud/vm/ItWorkDaoImpl.java +++ b/server/src/com/cloud/vm/ItWorkDaoImpl.java @@ -20,10 +20,55 @@ package com.cloud.vm; import javax.ejb.Local; import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.time.InaccurateClock; +import com.cloud.vm.ItWorkVO.Step; +import com.cloud.vm.VirtualMachine.State; @Local(value=ItWorkDao.class) public class ItWorkDaoImpl extends GenericDaoBase implements ItWorkDao { + protected final SearchBuilder AllFieldsSearch; + protected final SearchBuilder CleanupSearch; + protected ItWorkDaoImpl() { super(); + + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("instance", AllFieldsSearch.entity().getInstanceId(), Op.EQ); + AllFieldsSearch.and("op", AllFieldsSearch.entity().getState(), Op.EQ); + AllFieldsSearch.and("step", AllFieldsSearch.entity().getStep(), Op.EQ); + AllFieldsSearch.done(); + + CleanupSearch = createSearchBuilder(); + CleanupSearch.and("step", CleanupSearch.entity().getState(), Op.IN); + CleanupSearch.and("time", CleanupSearch.entity().getUpdatedAt(), Op.LT); + CleanupSearch.done(); + } + + @Override + public ItWorkVO findByInstance(long instanceId, State state) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("instance", instanceId); + sc.setParameters("op", state); + + return findOneBy(sc); + } + + @Override + public void cleanup(long wait) { + SearchCriteria sc = CleanupSearch.create(); + sc.setParameters("step", Step.Done, Step.Cancelled); + sc.setParameters("time", InaccurateClock.getTimeInSeconds() - wait); + + remove(sc); + } + + @Override + public boolean update(String id, ItWorkVO work) { + work.setUpdatedAt(InaccurateClock.getTimeInSeconds()); + + return super.update(id, work); } } diff --git a/server/src/com/cloud/vm/ItWorkVO.java b/server/src/com/cloud/vm/ItWorkVO.java index c150a125851..56539d31920 100644 --- a/server/src/com/cloud/vm/ItWorkVO.java +++ b/server/src/com/cloud/vm/ItWorkVO.java @@ -17,48 +17,43 @@ */ package com.cloud.vm; -import java.util.Date; - import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; -import com.cloud.utils.db.GenericDao; +import com.cloud.utils.time.InaccurateClock; +import com.cloud.vm.VirtualMachine.State; @Entity @Table(name="op_it_work") public class ItWorkVO { - enum Type { - Start, - Cleanup; - } - enum ResourceType { Volume, Nic } enum Step { + Reserve, Prepare, Start, Started, + Cancelled, + Done } @Id @Column(name="id") String id; - @Column(name=GenericDao.CREATED_COLUMN) - Date created; + @Column(name="created_at") + long createdAt; @Column(name="mgmt_server_id") long managementServerId; @Column(name="type") - Type type; + State type; @Column(name="thread") String threadName; @@ -66,9 +61,8 @@ public class ItWorkVO { @Column(name="state") Step step; - @Column(name="cancel_taken") - @Temporal(value=TemporalType.TIMESTAMP) - Date taken; + @Column(name="updated_at") + long updatedAt; @Column(name="instance_id") long instanceId; @@ -103,7 +97,7 @@ public class ItWorkVO { protected ItWorkVO() { } - protected ItWorkVO(String id, long managementServerId, Type type, long instanceId) { + protected ItWorkVO(String id, long managementServerId, State type, long instanceId) { this.id = id; this.managementServerId = managementServerId; this.type = type; @@ -111,25 +105,27 @@ public class ItWorkVO { this.step = Step.Prepare; this.instanceId = instanceId; this.resourceType = null; + this.createdAt = InaccurateClock.getTimeInSeconds(); + this.updatedAt = createdAt; } public String getId() { return id; } - public Date getCreated() { - return created; + public Long getCreatedAt() { + return createdAt; } - + public long getManagementServerId() { return managementServerId; } - public Type getType() { + public State getState() { return type; } - public void setType(Type type) { + public void setState(State type) { this.type = type; } @@ -145,7 +141,19 @@ public class ItWorkVO { this.step = state; } - public Date getTaken() { - return taken; + public long getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(long updatedAt) { + this.updatedAt = updatedAt; + } + + public long getSecondsTaskIsInactive() { + return InaccurateClock.getTimeInSeconds() - this.updatedAt; + } + + public long getSecondsTaskHasBeenCreated() { + return InaccurateClock.getTimeInSeconds() - this.createdAt; } } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index c49fbee38c1..e11c465f853 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -2291,8 +2291,15 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } } - UserVmVO vm = new UserVmVO(id, instanceName, cmd.getDisplayName(), - template.getId(), template.getGuestOSId(), offering.getOfferHA(), domainId, owner.getId(), offering.getId(), userData, hostName); + HypervisorType hypervisorType = null; + if (template == null || template.getHypervisorType() == null || template.getHypervisorType() == HypervisorType.None) { + hypervisorType = cmd.getHypervisor(); + } else { + hypervisorType = template.getHypervisorType(); + } + + UserVmVO vm = new UserVmVO(id, instanceName, cmd.getDisplayName(), template.getId(), hypervisorType, + template.getGuestOSId(), offering.getOfferHA(), domainId, owner.getId(), offering.getId(), userData, hostName); if (_itMgr.allocate(vm, template, offering, rootDiskOffering, dataDiskOfferings, networks, null, plan, cmd.getHypervisor(), owner) == null) { @@ -2346,7 +2353,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager AccountVO owner = _accountDao.findById(vm.getAccountId()); try { - vm = _itMgr.start(vm, null, caller, owner, cmd.getHypervisor()); + vm = _itMgr.start(vm, null, caller, owner); } catch (Exception e) { e.printStackTrace(); } @@ -2500,9 +2507,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager userId = accountAndUserValidation(vmId, account, userId, vm); UserVO user = _userDao.findById(userId); - VolumeVO disk = _volsDao.findByInstance(vmId).get(0); - HypervisorType hyperType = _volsDao.getHypervisorType(disk.getId()); - return _itMgr.start(vm, null, user, account, hyperType); + return _itMgr.start(vm, null, user, account); } @Override diff --git a/server/src/com/cloud/vm/VirtualMachineManager.java b/server/src/com/cloud/vm/VirtualMachineManager.java index a866e168450..c3020e1311b 100644 --- a/server/src/com/cloud/vm/VirtualMachineManager.java +++ b/server/src/com/cloud/vm/VirtualMachineManager.java @@ -35,7 +35,6 @@ import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.utils.Pair; import com.cloud.utils.component.Manager; -import com.cloud.vm.VirtualMachine.Event; /** * Manages allocating resources to vms. @@ -71,7 +70,7 @@ public interface VirtualMachineManager extends Manager { HypervisorType hyperType, Account owner) throws InsufficientCapacityException; - T start(T vm, Map params, User caller, Account account, HypervisorType hyperType) throws InsufficientCapacityException, ResourceUnavailableException; + T start(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException; boolean stop(T vm, User caller, Account account) throws ResourceUnavailableException; @@ -79,9 +78,9 @@ public interface VirtualMachineManager extends Manager { void registerGuru(VirtualMachine.Type type, VirtualMachineGuru guru); - boolean stateTransitTo(VMInstanceVO vm, Event e, Long id); + boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId); - T advanceStart(T vm, Map params, User caller, Account account, HypervisorType hyperType) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException; + T advanceStart(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, OperationTimedoutException; boolean advanceStop(T vm, boolean forced, User caller, Account account) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException; diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 787db4ac2c0..ab41c08edd4 100644 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -22,6 +22,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import javax.ejb.Local; import javax.naming.ConfigurationException; @@ -38,8 +41,6 @@ import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.manager.Commands; import com.cloud.cluster.ClusterManager; -import com.cloud.cluster.ClusterManagerListener; -import com.cloud.cluster.ManagementServerHostVO; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.DataCenter; @@ -81,12 +82,13 @@ import com.cloud.utils.Pair; import com.cloud.utils.component.Adapters; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; +import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.StateListener; import com.cloud.utils.fsm.StateMachine2; -import com.cloud.vm.ItWorkVO.Type; +import com.cloud.vm.ItWorkVO.Step; import com.cloud.vm.VirtualMachine.Event; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.ConsoleProxyDao; @@ -97,39 +99,47 @@ import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; @Local(value=VirtualMachineManager.class) -public class VirtualMachineManagerImpl implements VirtualMachineManager, ClusterManagerListener { +public class VirtualMachineManagerImpl implements VirtualMachineManager { private static final Logger s_logger = Logger.getLogger(VirtualMachineManagerImpl.class); String _name; - @Inject private StorageManager _storageMgr; - @Inject private NetworkManager _networkMgr; - @Inject private AgentManager _agentMgr; - @Inject private VMInstanceDao _vmDao; - @Inject private ServiceOfferingDao _offeringDao; - @Inject private VMTemplateDao _templateDao; - @Inject private UserDao _userDao; - @Inject private AccountDao _accountDao; - @Inject private DomainDao _domainDao; - @Inject private ClusterManager _clusterMgr; - @Inject private ItWorkDao _workDao; - @Inject private UserVmDao _userVmDao; - @Inject private DomainRouterDao _routerDao; - @Inject private ConsoleProxyDao _consoleDao; - @Inject private SecondaryStorageVmDao _secondaryDao; - @Inject private UsageEventDao _usageEventDao; - @Inject private NicDao _nicsDao; + @Inject protected StorageManager _storageMgr; + @Inject protected NetworkManager _networkMgr; + @Inject protected AgentManager _agentMgr; + @Inject protected VMInstanceDao _vmDao; + @Inject protected ServiceOfferingDao _offeringDao; + @Inject protected VMTemplateDao _templateDao; + @Inject protected UserDao _userDao; + @Inject protected AccountDao _accountDao; + @Inject protected DomainDao _domainDao; + @Inject protected ClusterManager _clusterMgr; + @Inject protected ItWorkDao _workDao; + @Inject protected UserVmDao _userVmDao; + @Inject protected DomainRouterDao _routerDao; + @Inject protected ConsoleProxyDao _consoleDao; + @Inject protected SecondaryStorageVmDao _secondaryDao; + @Inject protected UsageEventDao _usageEventDao; + @Inject protected NicDao _nicsDao; @Inject(adapter=DeploymentPlanner.class) - private Adapters _planners; + protected Adapters _planners; @Inject(adapter=StateListener.class) - private Adapters> _stateListner; + protected Adapters> _stateListner; + Map> _vmGurus = new HashMap>(); Map _hvGurus = new HashMap(); - private StateMachine2 _stateMachine; + protected StateMachine2 _stateMachine; - private int _retry; - private long _nodeId; + ScheduledExecutorService _executor = null; + + protected int _retry; + protected long _nodeId; + protected long _cleanupWait; + protected long _cleanupInterval; + protected long _cancelWait; + protected long _opWaitInterval; + protected int _lockStateRetry; @Override public void registerGuru(VirtualMachine.Type type, VirtualMachineGuru guru) { @@ -153,7 +163,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster s_logger.debug("Allocating entries for VM: " + vm); } - VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, serviceOffering, owner, params, hyperType); + VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, serviceOffering, owner, params); vm.setDataCenterId(plan.getDataCenterId()); if (plan.getPodId() != null) { @@ -338,6 +348,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster @Override public boolean start() { + _executor.scheduleAtFixedRate(new CleanupTask(), _cleanupInterval, _cleanupInterval, TimeUnit.SECONDS); return true; } @@ -364,8 +375,14 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster _hvGurus.put(guru.getHypervisorType(), guru); } + _cancelWait = NumbersUtil.parseLong(params.get(Config.VmOpCancelInterval.key()), 3600); + _cleanupWait = NumbersUtil.parseLong(params.get(Config.VmOpCleanupWait.key()), 3600); + _cleanupInterval = NumbersUtil.parseLong(params.get(Config.VmOpCleanupInterval.key()), 86400) * 1000; + _opWaitInterval = NumbersUtil.parseLong(params.get(Config.VmOpWaitInterval.key()), 120) * 1000; + _lockStateRetry = NumbersUtil.parseInt(params.get(Config.VmOpLockStateRetry.key()), 5); + + _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Vm-Operations-Cleanup")); _nodeId = _clusterMgr.getId(); - _clusterMgr.registerListener(this); setStateMachine(); @@ -381,9 +398,9 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster } @Override - public T start(T vm, Map params, User caller, Account account, HypervisorType hyperType) throws InsufficientCapacityException, ResourceUnavailableException { + public T start(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ResourceUnavailableException { try { - return advanceStart(vm, params, caller, account, hyperType); + return advanceStart(vm, params, caller, account); } catch (ConcurrentOperationException e) { throw new CloudRuntimeException("Unable to start a VM due to concurrent operation", e); } @@ -400,55 +417,130 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster return null; } + protected boolean checkWorkItems(VMInstanceVO vm, State state) throws ConcurrentOperationException { + while (true) { + ItWorkVO vo = _workDao.findByInstance(vm.getId(), state); + if (vo == null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unable to find work for " + vm); + } + return true; + } + + if (vo.getStep() == Step.Done || vo.getStep() == Step.Cancelled) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Work for " + vm + " is " + vo.getStep()); + } + return true; + } + + if (vo.getSecondsTaskIsInactive() > _cancelWait) { + s_logger.warn("The task item for vm " + vm + " has been inactive for " + vo.getSecondsTaskIsInactive()); + return false; + } + + try { + Thread.sleep(_opWaitInterval); + } catch (InterruptedException e) { + s_logger.info("Waiting for " + vm + " but is interrupted"); + throw new ConcurrentOperationException("Waiting for " + vm + " but is interrupted"); + } + s_logger.debug("Waiting some more to make sure there's no activity on " + vm); + } + + + } + + @DB + protected Pair changeToStartState(VirtualMachineGuru vmGuru, T vm, User caller, Account account) throws ConcurrentOperationException { + long vmId = vm.getId(); + + ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Starting, vm.getId()); + int retry = _lockStateRetry; + while (retry-- > 0) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + if (_vmDao.updateIf(vm, Event.StartRequested, null, work.getId())) { + + Journal journal = new Journal.LogJournal("Creating " + vm, s_logger); + work = _workDao.persist(work); + ReservationContextImpl context = new ReservationContextImpl(work.getId(), journal, caller, account); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Successfully transitioned to start state for " + vm + " reservation id = " + work.getId()); + } + return new Pair(vmGuru.findById(vmId), context); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Determining why we're unable to update the state to Starting for " + vm); + } + + try { + VMInstanceVO instance = _vmDao.lockRow(vmId, true); + if (instance == null) { + throw new ConcurrentOperationException("Unable to acquire lock on " + vm); + } + + State state = instance.getState(); + if (state == State.Running) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("VM is already started: " + vm); + } + return new Pair(vmGuru.findById(vmId), null); + } + + if (state.isTransitional()) { + if (!checkWorkItems(vm, state)) { + throw new ConcurrentOperationException("There are concurrent operations on the VM " + vm); + } else { + continue; + } + } + + if (state != State.Stopped) { + s_logger.debug("VM " + vm + " is not in a state to be started: " + state); + return null; + } + + } finally { + txn.commit(); + } + } + + throw new ConcurrentOperationException("Unable to change the state of " + vm); + } + @Override - public T advanceStart(T vm, Map params, User caller, Account account, HypervisorType hyperType) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { - State state = vm.getState(); - if (state == State.Running) { - s_logger.debug("VM is already started: " + vm); + public T advanceStart(T vm, Map params, User caller, Account account) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { + long vmId = vm.getId(); + + VirtualMachineGuru vmGuru = getVmGuru(vm); + + Pair start = changeToStartState(vmGuru, vm, caller, account); + assert (start != null) : "Should never happen"; + + vm = start.first(); + ReservationContext ctx = start.second(); + + if (ctx == null) { // No need to start because it's already running. return vm; } - if (state == State.Starting) { - - } - - if (state != State.Stopped) { - s_logger.debug("VM " + vm + " is not in a state to be started: " + state); - return null; - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating actual resources for VM " + vm); - } - - Journal journal = new Journal.LogJournal("Creating " + vm, s_logger); - - ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, ItWorkVO.Type.Start, vm.getId()); - work = _workDao.persist(work); - - ReservationContextImpl context = new ReservationContextImpl(work.getId(), journal, caller, account); - ServiceOfferingVO offering = _offeringDao.findById(vm.getServiceOfferingId()); VMTemplateVO template = _templateDao.findById(vm.getTemplateId()); DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterId(), vm.getPodId(), null, null); - HypervisorGuru hvGuru; - if (hyperType != null && !hyperType.equals(HypervisorType.None)) { - hvGuru = _hvGurus.get(hyperType); - } else { - hvGuru = _hvGurus.get(template.getHypervisorType()); - } - @SuppressWarnings("unchecked") - VirtualMachineGuru vmGuru = (VirtualMachineGuru)_vmGurus.get(vm.getType()); - - vm.setReservationId(work.getId()); + HypervisorGuru hvGuru = _hvGurus.get(vm.getHypervisorType()); + + Journal journal = start.second().getJournal(); ExcludeList avoids = new ExcludeList(); int retry = _retry; DeployDestination dest = null; while (retry-- != 0) { // It's != so that it can match -1. - VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, null, params, hyperType); + VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, null, params); for (DeploymentPlanner planner : _planners) { dest = planner.plan(vmProfile, plan, avoids); @@ -474,12 +566,9 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster stateTransitTo(vm, Event.OperationRetry, dest.getHost().getId()); } - vm.setDataCenterId(dest.getDataCenter().getId()); - vm.setPodId(dest.getPod().getId()); - try { _storageMgr.prepare(vmProfile, dest); - _networkMgr.prepare(vmProfile, dest, context); + _networkMgr.prepare(vmProfile, dest, ctx); } catch (ConcurrentOperationException e) { stateTransitTo(vm, Event.OperationFailed, null); throw e; @@ -497,17 +586,17 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster return null; } - vmGuru.finalizeVirtualMachineProfile(vmProfile, dest, context); + vmGuru.finalizeVirtualMachineProfile(vmProfile, dest, ctx); VirtualMachineTO vmTO = hvGuru.implement(vmProfile); Commands cmds = new Commands(OnError.Revert); cmds.addCommand(new StartCommand(vmTO)); - vmGuru.finalizeDeployment(cmds, vmProfile, dest, context); + vmGuru.finalizeDeployment(cmds, vmProfile, dest, ctx); try { Answer[] answers = _agentMgr.send(dest.getHost().getId(), cmds); - if (getStartAnswer(answers).getResult() && vmGuru.finalizeStart(cmds, vmProfile, dest, context)) { + if (getStartAnswer(answers).getResult() && vmGuru.finalizeStart(cmds, vmProfile, dest, ctx)) { if (!stateTransitTo(vm, Event.OperationSucceeded, dest.getHost().getId())) { throw new CloudRuntimeException("Unable to transition to a new state."); } @@ -633,22 +722,13 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster stateTransitTo(vm, Event.OperationSucceeded, null); if (cleanup) { - ItWorkVO work = new ItWorkVO(reservationId, _nodeId, Type.Cleanup, vm.getId()); + ItWorkVO work = new ItWorkVO(reservationId, _nodeId, State.Stopping, vm.getId()); _workDao.persist(work); } return stopped; } - @Override - public void onManagementNodeJoined(List nodeList, long selfNodeId) { - - } - - @Override - public void onManagementNodeLeft(List nodeList, long selfNodeId) { - } - private void setStateMachine() { _stateMachine = new StateMachine2(); @@ -698,21 +778,36 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster _stateMachine.registerListeners(_stateListner); } - @Override - public boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long id) { + protected boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId, String reservationId) { + vm.setReservationId(reservationId); if (vm instanceof UserVmVO) { - return _stateMachine.transitTO(vm, e, id, _userVmDao); + return _stateMachine.transitTO(vm, e, hostId, _userVmDao); } else if (vm instanceof ConsoleProxyVO) { - return _stateMachine.transitTO(vm, e, id, _consoleDao); + return _stateMachine.transitTO(vm, e, hostId, _consoleDao); } else if (vm instanceof SecondaryStorageVmVO) { - return _stateMachine.transitTO(vm, e, id, _secondaryDao); + return _stateMachine.transitTO(vm, e, hostId, _secondaryDao); } else if (vm instanceof DomainRouterVO) { - return _stateMachine.transitTO(vm, e, id, _routerDao); + return _stateMachine.transitTO(vm, e, hostId, _routerDao); } else { - return _stateMachine.transitTO(vm, e, id, _vmDao); + return _stateMachine.transitTO(vm, e, hostId, _vmDao); } } + @Override + public boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId) { + if (vm instanceof UserVmVO) { + return _stateMachine.transitTO(vm, e, hostId, _userVmDao); + } else if (vm instanceof ConsoleProxyVO) { + return _stateMachine.transitTO(vm, e, hostId, _consoleDao); + } else if (vm instanceof SecondaryStorageVmVO) { + return _stateMachine.transitTO(vm, e, hostId, _secondaryDao); + } else if (vm instanceof DomainRouterVO) { + return _stateMachine.transitTO(vm, e, hostId, _routerDao); + } else { + return _stateMachine.transitTO(vm, e, hostId, _vmDao); + } + } + @Override public boolean remove(T vm, User user, Account caller) { return _vmDao.remove(vm.getId()); @@ -742,4 +837,17 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster return true; } + + protected class CleanupTask implements Runnable { + + @Override + public void run() { + s_logger.trace("VM Operation Thread Running"); + try { + _workDao.cleanup(_cleanupWait); + } catch (Exception e) { + s_logger.error("VM Operations failed due to ", e); + } + } + } } diff --git a/server/src/com/cloud/vm/VirtualMachineProfileImpl.java b/server/src/com/cloud/vm/VirtualMachineProfileImpl.java index 60b7135e000..28551ac3989 100644 --- a/server/src/com/cloud/vm/VirtualMachineProfileImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineProfileImpl.java @@ -51,9 +51,8 @@ public class VirtualMachineProfileImpl implements Virtua BootloaderType _bootloader; VirtualMachine.Type _type; - HypervisorType _hyperType; - public VirtualMachineProfileImpl(T vm, VMTemplateVO template, ServiceOfferingVO offering, Account owner, Map params, HypervisorType hyperType) { + public VirtualMachineProfileImpl(T vm, VMTemplateVO template, ServiceOfferingVO offering, Account owner, Map params) { _vm = vm; _template = template; _offering = offering; @@ -63,11 +62,10 @@ public class VirtualMachineProfileImpl implements Virtua _params = new HashMap(); } _type = vm.getType(); - _hyperType = hyperType; } public VirtualMachineProfileImpl(T vm) { - this(vm, null, null, null, null, null); + this(vm, null, null, null, null); } public VirtualMachineProfileImpl(VirtualMachine.Type type) { @@ -112,11 +110,7 @@ public class VirtualMachineProfileImpl implements Virtua @Override public HypervisorType getHypervisorType() { - if (_hyperType != null && !_hyperType.equals(HypervisorType.None)) { - return _hyperType; - } - getTemplate(); - return _template.getHypervisorType(); + return _vm.getHypervisorType(); } @Override diff --git a/server/src/com/cloud/vm/dao/VMInstanceDao.java b/server/src/com/cloud/vm/dao/VMInstanceDao.java index d5675245bcd..8ad0edcd9f5 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDao.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDao.java @@ -53,7 +53,7 @@ public interface VMInstanceDao extends GenericDao, StateDao< */ public List listNonExpungedByZoneAndTemplate(long zoneId, long templateId); - boolean updateIf(VMInstanceVO vm, VirtualMachine.Event event, Long hostId); + boolean updateIf(VMInstanceVO vm, VirtualMachine.Event event, Long hostId, String reservationId); /** * Find vm instance with names like. diff --git a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index bd70da428e7..5875a4420e1 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -154,7 +154,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem } @Override - public boolean updateIf(VMInstanceVO vm, VirtualMachine.Event event, Long hostId) { + public boolean updateIf(VMInstanceVO vm, VirtualMachine.Event event, Long hostId, String reservationId) { State oldState = vm.getState(); State newState = oldState.getNextState(event); @@ -173,10 +173,12 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem sc.setParameters("update", vm.getUpdated()); vm.incrUpdated(); + vm.setReservationId(reservationId); UpdateBuilder ub = getUpdateBuilder(vm); ub.set(vm, "state", newState); ub.set(vm, "hostId", hostId); ub.set(vm, _updateTimeAttr, new Date()); + int result = update(vm, sc); if (result == 0 && s_logger.isDebugEnabled()) { diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 0db72fcf6d5..8bd572757b2 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -98,11 +98,11 @@ DROP TABLE IF EXISTS `cloud`.`host_tags`; CREATE TABLE `cloud`.`op_it_work` ( `id` char(40) COMMENT 'id', `mgmt_server_id` bigint unsigned COMMENT 'management server id', - `created` timestamp NOT NULL COMMENT 'when was this work detail created', + `created_on` bigint unsigned NOT NULL COMMENT 'when was this work detail created', `thread` varchar(255) NOT NULL COMMENT 'thread name', `type` char(32) NOT NULL COMMENT 'type of work', `state` char(32) NOT NULL COMMENT 'state', - `cancel_taken` timestamp COMMENT 'time it was taken over', + `updated_on` bigint unsigned NOT NULL COMMENT 'time it was taken over', `instance_id` bigint unsigned NOT NULL COMMENT 'vm instance', `resource_type` char(32) COMMENT 'type of resource being worked on', `resource_id` bigint unsigned COMMENT 'resource id being worked on', @@ -746,7 +746,23 @@ CREATE TABLE `cloud`.`vm_instance` ( `domain_id` bigint unsigned NOT NULL, `service_offering_id` bigint unsigned NOT NULL COMMENT 'service offering id', `reservation_id` char(40) COMMENT 'reservation id', - PRIMARY KEY (`id`) + `hypervisor_type` char(32) COMMENT 'hypervisor type', + PRIMARY KEY (`id`), + INDEX `i_vm_instance__removed`(`removed`), + INDEX `i_vm_instance__type`(`type`), + INDEX `i_vm_instance__pod_id`(`pod_id`), + INDEX `i_vm_instance__update_time`(`update_time`), + INDEX `i_vm_instance__update_count`(`update_count`), + INDEX `i_vm_instance__state`(`state`), + INDEX `i_vm_instance__data_center_id`(`data_center_id`), + CONSTRAINT `fk_vm_instance__host_id` FOREIGN KEY `fk_vm_instance__host_id` (`host_id`) REFERENCES `host` (`id`), + CONSTRAINT `fk_vm_instance__last_host_id` FOREIGN KEY `fk_vm_instance__last_host_id` (`last_host_id`) REFERENCES `host`(`id`), + CONSTRAINT `fk_vm_instance__template_id` FOREIGN KEY `fk_vm_instance__template_id` (`vm_template_id`) REFERENCES `vm_template` (`id`), + INDEX `i_vm_instance__template_id`(`vm_template_id`), + CONSTRAINT `fk_vm_instance__account_id` FOREIGN KEY `fk_vm_instance__account_id` (`account_id`) REFERENCES `account` (`id`), + INDEX `i_vm_instance__account_id`(`account_id`), + CONSTRAINT `fk_vm_instance__service_offering_id` FOREIGN KEY `fk_vm_instance__service_offering_id` (`service_offering_id`) REFERENCES `service_offering` (`id`), + INDEX `i_vm_instance__service_offering_id`(`service_offering_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`user_vm` ( diff --git a/utils/src/com/cloud/utils/time/InaccurateClock.java b/utils/src/com/cloud/utils/time/InaccurateClock.java index 821b39fce31..3e61db3b847 100644 --- a/utils/src/com/cloud/utils/time/InaccurateClock.java +++ b/utils/src/com/cloud/utils/time/InaccurateClock.java @@ -36,8 +36,8 @@ public class InaccurateClock extends Thread { @Override public void run() { while (true) { - time = System.currentTimeMillis(); - try { + try { + time = System.currentTimeMillis(); Thread.sleep(1000); } catch(Exception e) { } @@ -51,4 +51,9 @@ public class InaccurateClock extends Thread { return System.currentTimeMillis(); } } + + public static long getTimeInSeconds() { + // This is obviously not accurate because it >> 10 is / 1024 but it's close enough since we're inaccurate. + return getTime() >> 10; + } } From 7f597e594c70d5b4a7122f207be52347cf21c6ea Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Tue, 11 Jan 2011 11:43:57 -0800 Subject: [PATCH 131/142] added work list to vm start --- .../com/cloud/deploy/DeploymentPlanner.java | 33 ++- .../src/com/cloud/vm/UserVmManagerImpl.java | 3 + .../cloud/vm/VirtualMachineManagerImpl.java | 202 +++++++++--------- setup/db/create-index-fk.sql | 18 -- 4 files changed, 137 insertions(+), 119 deletions(-) diff --git a/api/src/com/cloud/deploy/DeploymentPlanner.java b/api/src/com/cloud/deploy/DeploymentPlanner.java index 668b6952f6a..c010d5a7ff6 100644 --- a/api/src/com/cloud/deploy/DeploymentPlanner.java +++ b/api/src/com/cloud/deploy/DeploymentPlanner.java @@ -10,6 +10,7 @@ import com.cloud.dc.DataCenter; import com.cloud.dc.Pod; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientServerCapacityException; +import com.cloud.exception.ResourceUnavailableException; import com.cloud.host.Host; import com.cloud.org.Cluster; import com.cloud.storage.StoragePool; @@ -50,11 +51,11 @@ public interface DeploymentPlanner extends Adapter { Set _hostIds; Set _poolIds; - public void add(InsufficientCapacityException e) { + public boolean add(InsufficientCapacityException e) { Class scope = e.getScope(); if (scope == null) { - return; + return false; } if (Host.class.isAssignableFrom(scope)) { @@ -67,7 +68,35 @@ public interface DeploymentPlanner extends Adapter { addCluster(e.getId()); } else if (StoragePool.class.isAssignableFrom(scope)) { addPool(e.getId()); + } else { + return false; } + + return true; + } + + public boolean add(ResourceUnavailableException e) { + Class scope = e.getScope(); + + if (scope == null) { + return false; + } + + if (Host.class.isAssignableFrom(scope)) { + addHost(e.getResourceId()); + } else if (Pod.class.isAssignableFrom(scope)) { + addPod(e.getResourceId()); + } else if (DataCenter.class.isAssignableFrom(scope)) { + addDataCenter(e.getResourceId()); + } else if (Cluster.class.isAssignableFrom(scope)) { + addCluster(e.getResourceId()); + } else if (StoragePool.class.isAssignableFrom(scope)) { + addPool(e.getResourceId()); + } else { + return false; + } + + return true; } public void addPool(long poolId) { diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index e11c465f853..17434421845 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -2427,6 +2427,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager UserVmVO vm = profile.getVirtualMachine(); _networkGroupMgr.handleVmStateTransition(vm, State.Running); _ovsNetworkMgr.handleVmStateTransition(vm, State.Running); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_START, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getName(), vm.getServiceOfferingId(), vm.getTemplateId(), null); + _usageEventDao.persist(usageEvent); + return true; } diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index ab41c08edd4..d583832e272 100644 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -69,16 +69,17 @@ import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.StorageManager; import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.Volume; import com.cloud.storage.Volume.VolumeType; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; -import com.cloud.uservm.UserVm; import com.cloud.utils.Journal; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; +import com.cloud.utils.Ternary; import com.cloud.utils.component.Adapters; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.Inject; @@ -413,7 +414,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { } } - assert 1 == 0 : "Why there is no Start Answer???"; + assert false : "Why there is no Start Answer???"; return null; } @@ -452,12 +453,12 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { } @DB - protected Pair changeToStartState(VirtualMachineGuru vmGuru, T vm, User caller, Account account) throws ConcurrentOperationException { + protected Ternary changeToStartState(VirtualMachineGuru vmGuru, T vm, User caller, Account account) throws ConcurrentOperationException { long vmId = vm.getId(); ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, State.Starting, vm.getId()); int retry = _lockStateRetry; - while (retry-- > 0) { + while (retry-- != 0) { Transaction txn = Transaction.currentTxn(); txn.start(); if (_vmDao.updateIf(vm, Event.StartRequested, null, work.getId())) { @@ -469,7 +470,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { if (s_logger.isDebugEnabled()) { s_logger.debug("Successfully transitioned to start state for " + vm + " reservation id = " + work.getId()); } - return new Pair(vmGuru.findById(vmId), context); + return new Ternary(vmGuru.findById(vmId), context, work); } if (s_logger.isDebugEnabled()) { @@ -487,7 +488,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { if (s_logger.isDebugEnabled()) { s_logger.debug("VM is already started: " + vm); } - return new Pair(vmGuru.findById(vmId), null); + return null; } if (state.isTransitional()) { @@ -517,112 +518,115 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { VirtualMachineGuru vmGuru = getVmGuru(vm); - Pair start = changeToStartState(vmGuru, vm, caller, account); - assert (start != null) : "Should never happen"; + Ternary start = changeToStartState(vmGuru, vm, caller, account); + if (start == null) { + return vmGuru.findById(vmId); + } vm = start.first(); ReservationContext ctx = start.second(); + ItWorkVO work = start.third(); - if (ctx == null) { // No need to start because it's already running. - return vm; - } + T startedVm = null; - ServiceOfferingVO offering = _offeringDao.findById(vm.getServiceOfferingId()); - VMTemplateVO template = _templateDao.findById(vm.getTemplateId()); - - DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterId(), vm.getPodId(), null, null); - - HypervisorGuru hvGuru = _hvGurus.get(vm.getHypervisorType()); - - Journal journal = start.second().getJournal(); - - ExcludeList avoids = new ExcludeList(); - int retry = _retry; - DeployDestination dest = null; - while (retry-- != 0) { // It's != so that it can match -1. - VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, null, params); - - for (DeploymentPlanner planner : _planners) { - dest = planner.plan(vmProfile, plan, avoids); - if (dest != null) { - avoids.addHost(dest.getHost().getId()); - journal.record("Deployment found ", vmProfile, dest); - break; + try { + ServiceOfferingVO offering = _offeringDao.findById(vm.getServiceOfferingId()); + VMTemplateVO template = _templateDao.findById(vm.getTemplateId()); + + DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterId(), vm.getPodId(), null, null); + + HypervisorGuru hvGuru = _hvGurus.get(vm.getHypervisorType()); + VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, null, params); + + Journal journal = start.second().getJournal(); + + ExcludeList avoids = new ExcludeList(); + int retry = _retry; + while (retry-- != 0) { // It's != so that it can match -1. + + DeployDestination dest = null; + for (DeploymentPlanner planner : _planners) { + dest = planner.plan(vmProfile, plan, avoids); + if (dest != null) { + avoids.addHost(dest.getHost().getId()); + journal.record("Deployment found ", vmProfile, dest); + break; + } } - } - - if (dest == null) { - if (retry != (_retry -1)) { - stateTransitTo(vm, Event.OperationFailed, null); - } - throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId()); - } - - if (retry == (_retry -1)) { - if (!stateTransitTo(vm, Event.StartRequested, dest.getHost().getId())) { - throw new ConcurrentOperationException("Unable to start vm " + vm + " due to concurrent operations"); - } - } else { + + if (dest == null) { + throw new InsufficientServerCapacityException("Unable to create a deployment for " + vmProfile, DataCenter.class, plan.getDataCenterId()); + } + stateTransitTo(vm, Event.OperationRetry, dest.getHost().getId()); - } - - try { - _storageMgr.prepare(vmProfile, dest); - _networkMgr.prepare(vmProfile, dest, ctx); - } catch (ConcurrentOperationException e) { - stateTransitTo(vm, Event.OperationFailed, null); - throw e; - } catch (ResourceUnavailableException e) { - s_logger.warn("Unable to contact storage.", e); - avoids.addCluster(dest.getCluster().getId()); - continue; - } catch (InsufficientCapacityException e) { - s_logger.warn("Insufficient capacity ", e); - avoids.add(e); - continue; - } catch (RuntimeException e) { - s_logger.warn("Failed to start instance " + vm, e); - stateTransitTo(vm, Event.OperationFailed, null); - return null; - } - - vmGuru.finalizeVirtualMachineProfile(vmProfile, dest, ctx); - - VirtualMachineTO vmTO = hvGuru.implement(vmProfile); - - Commands cmds = new Commands(OnError.Revert); - cmds.addCommand(new StartCommand(vmTO)); - - vmGuru.finalizeDeployment(cmds, vmProfile, dest, ctx); - try { - Answer[] answers = _agentMgr.send(dest.getHost().getId(), cmds); - if (getStartAnswer(answers).getResult() && vmGuru.finalizeStart(cmds, vmProfile, dest, ctx)) { - if (!stateTransitTo(vm, Event.OperationSucceeded, dest.getHost().getId())) { - throw new CloudRuntimeException("Unable to transition to a new state."); + + try { + _storageMgr.prepare(vmProfile, dest); + _networkMgr.prepare(vmProfile, dest, ctx); + } catch (ResourceUnavailableException e) { + if (!avoids.add(e)) { + if (e.getScope() == Volume.class || e.getScope() == Nic.class) { + throw e; + } else { + throw new CloudRuntimeException("Resource is not available to start the VM.", e); + } } - if(vm instanceof UserVm){ - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_START, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getName(), vm.getServiceOfferingId(), vm.getTemplateId(), null); - _usageEventDao.persist(usageEvent); + s_logger.info("Unable to contact resource.", e); + continue; + } catch (InsufficientCapacityException e) { + if (!avoids.add(e)) { + if (e.getScope() == Volume.class || e.getScope() == Nic.class) { + throw e; + } else { + throw new CloudRuntimeException("Insufficient capacity to start the VM.", e); + } } - return vm; + s_logger.info("Insufficient capacity ", e); + continue; + } catch (RuntimeException e) { + s_logger.warn("Failed to start instance " + vm, e); + throw new CloudRuntimeException("Failed to start " + vm, e); + } + + vmGuru.finalizeVirtualMachineProfile(vmProfile, dest, ctx); + + VirtualMachineTO vmTO = hvGuru.implement(vmProfile); + + Commands cmds = new Commands(OnError.Revert); + cmds.addCommand(new StartCommand(vmTO)); + + vmGuru.finalizeDeployment(cmds, vmProfile, dest, ctx); + try { + Answer[] answers = _agentMgr.send(dest.getHost().getId(), cmds); + if (getStartAnswer(answers).getResult() && vmGuru.finalizeStart(cmds, vmProfile, dest, ctx)) { + if (!stateTransitTo(vm, Event.OperationSucceeded, dest.getHost().getId())) { + throw new CloudRuntimeException("Unable to transition to a new state."); + } + startedVm = vm; + break; + } + s_logger.info("Unable to start VM on " + dest.getHost() + " due to " + answers[0].getDetails()); + } catch (AgentUnavailableException e) { + s_logger.debug("Unable to send the start command to host " + dest.getHost()); + continue; + } catch (OperationTimedoutException e) { + s_logger.debug("Unable to send the start command to host " + dest.getHost()); + continue; } - s_logger.info("Unable to start VM on " + dest.getHost() + " due to " + answers[0].getDetails()); - } catch (AgentUnavailableException e) { - s_logger.debug("Unable to send the start command to host " + dest.getHost()); - continue; - } catch (OperationTimedoutException e) { - s_logger.debug("Unable to send the start command to host " + dest.getHost()); - continue; } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creation complete for VM " + vm); + } + } finally { + if (startedVm == null) { + stateTransitTo(vm, Event.OperationFailed, null); + } + work.setStep(Step.Done); + _workDao.update(work.getId(), work); } - stateTransitTo(vm, Event.OperationFailed, null); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creation complete for VM " + vm); - } - - return null; + return startedVm; } @Override diff --git a/setup/db/create-index-fk.sql b/setup/db/create-index-fk.sql index 033ec9f2343..921618f025c 100755 --- a/setup/db/create-index-fk.sql +++ b/setup/db/create-index-fk.sql @@ -95,24 +95,6 @@ ALTER TABLE `cloud`.`cluster_details` ADD CONSTRAINT `fk_cluster_details__cluste ALTER TABLE `cloud`.`vm_template` ADD INDEX `i_vm_template__removed`(`removed`); ALTER TABLE `cloud`.`vm_template` ADD INDEX `i_vm_template__public`(`public`); -ALTER TABLE `cloud`.`vm_instance` ADD INDEX `i_vm_instance__removed`(`removed`); -ALTER TABLE `cloud`.`vm_instance` ADD INDEX `i_vm_instance__type`(`type`); -ALTER TABLE `cloud`.`vm_instance` ADD INDEX `i_vm_instance__pod_id`(`pod_id`); -ALTER TABLE `cloud`.`vm_instance` ADD INDEX `i_vm_instance__update_time`(`update_time`); -ALTER TABLE `cloud`.`vm_instance` ADD INDEX `i_vm_instance__update_count`(`update_count`); -ALTER TABLE `cloud`.`vm_instance` ADD INDEX `i_vm_instance__state`(`state`); -ALTER TABLE `cloud`.`vm_instance` ADD INDEX `i_vm_instance__data_center_id`(`data_center_id`); -ALTER TABLE `cloud`.`vm_instance` ADD CONSTRAINT `fk_vm_instance__host_id` FOREIGN KEY `fk_vm_instance__host_id` (`host_id`) REFERENCES `host` (`id`); -ALTER TABLE `cloud`.`vm_instance` ADD INDEX `i_vm_instance__host_id`(`host_id`); -ALTER TABLE `cloud`.`vm_instance` ADD INDEX `i_vm_instance__last_host_id`(`last_host_id`); - -ALTER TABLE `cloud`.`vm_instance` ADD CONSTRAINT `fk_vm_instance__template_id` FOREIGN KEY `fk_vm_instance__template_id` (`vm_template_id`) REFERENCES `vm_template` (`id`); -ALTER TABLE `cloud`.`vm_instance` ADD INDEX `i_vm_instance__template_id`(`vm_template_id`); -ALTER TABLE `cloud`.`vm_instance` ADD CONSTRAINT `fk_vm_instance__account_id` FOREIGN KEY `fk_vm_instance__account_id` (`account_id`) REFERENCES `account` (`id`); -ALTER TABLE `cloud`.`vm_instance` ADD INDEX `i_vm_instance__account_id`(`account_id`); -ALTER TABLE `cloud`.`vm_instance` ADD CONSTRAINT `fk_vm_instance__service_offering_id` FOREIGN KEY `fk_vm_instance__service_offering_id` (`service_offering_id`) REFERENCES `service_offering` (`id`); -ALTER TABLE `cloud`.`vm_instance` ADD INDEX `i_vm_instance__service_offering_id`(`service_offering_id`); - ALTER TABLE `cloud`.`service_offering` ADD CONSTRAINT `fk_service_offering__id` FOREIGN KEY `fk_service_offering__id`(`id`) REFERENCES `disk_offering`(`id`) ON DELETE CASCADE; ALTER TABLE `cloud`.`user_vm` ADD CONSTRAINT `fk_user_vm__domain_router_id` FOREIGN KEY `fk_user_vm__domain_router_id` (`domain_router_id`) REFERENCES `domain_router` (`id`); From 6e6e8ff8763a21fc71a3d3b950a05c8643c55c0a Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Tue, 11 Jan 2011 16:44:26 -0800 Subject: [PATCH 132/142] better expunge and destroy of volumes --- .../cloud/api/commands/DeleteVolumeCmd.java | 3 +- api/src/com/cloud/storage/StorageService.java | 3 +- api/src/com/cloud/storage/Volume.java | 12 +- .../consoleproxy/ConsoleProxyManagerImpl.java | 61 +---- .../network/ovs/OvsNetworkManagerImpl.java | 13 +- .../VirtualNetworkApplianceManagerImpl.java | 47 +--- .../src/com/cloud/storage/StorageManager.java | 12 +- .../com/cloud/storage/StorageManagerImpl.java | 240 ++++++++---------- .../src/com/cloud/storage/dao/VolumeDao.java | 6 +- .../com/cloud/storage/dao/VolumeDaoImpl.java | 206 ++++----------- .../SecondaryStorageManagerImpl.java | 67 +---- server/src/com/cloud/vm/ItWorkDaoImpl.java | 4 +- server/src/com/cloud/vm/ItWorkVO.java | 10 +- .../src/com/cloud/vm/UserVmManagerImpl.java | 2 - setup/db/create-schema.sql | 8 +- 15 files changed, 202 insertions(+), 492 deletions(-) diff --git a/api/src/com/cloud/api/commands/DeleteVolumeCmd.java b/api/src/com/cloud/api/commands/DeleteVolumeCmd.java index c0919c7895c..bd23f442885 100644 --- a/api/src/com/cloud/api/commands/DeleteVolumeCmd.java +++ b/api/src/com/cloud/api/commands/DeleteVolumeCmd.java @@ -26,6 +26,7 @@ import com.cloud.api.Implementation; import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; import com.cloud.api.response.SuccessResponse; +import com.cloud.exception.ConcurrentOperationException; @Implementation(description="Deletes a detached disk volume.", responseObject=SuccessResponse.class) public class DeleteVolumeCmd extends BaseCmd { @@ -63,7 +64,7 @@ public class DeleteVolumeCmd extends BaseCmd { } @Override - public void execute(){ + public void execute() throws ConcurrentOperationException { boolean result = _storageService.deleteVolume(this); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/com/cloud/storage/StorageService.java b/api/src/com/cloud/storage/StorageService.java index f8fd6d290dc..e51e7392a6d 100644 --- a/api/src/com/cloud/storage/StorageService.java +++ b/api/src/com/cloud/storage/StorageService.java @@ -27,6 +27,7 @@ import com.cloud.api.commands.DeletePoolCmd; import com.cloud.api.commands.DeleteVolumeCmd; import com.cloud.api.commands.PreparePrimaryStorageForMaintenanceCmd; import com.cloud.api.commands.UpdateStoragePoolCmd; +import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; @@ -60,7 +61,7 @@ public interface StorageService { */ Volume createVolume(CreateVolumeCmd cmd); - boolean deleteVolume(DeleteVolumeCmd cmd) throws InvalidParameterValueException; + boolean deleteVolume(DeleteVolumeCmd cmd) throws ConcurrentOperationException; /** * Delete the storage pool * @param cmd - the command specifying poolId diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/Volume.java index 6856fb135d0..2e650fb5179 100755 --- a/api/src/com/cloud/storage/Volume.java +++ b/api/src/com/cloud/storage/Volume.java @@ -38,8 +38,7 @@ public interface Volume extends ControlledEntity, BasedOn { Creating("The volume is being created. getPoolId() should reflect the pool where it is being created."), Ready("The volume is ready to be used."), Used("The volume is used"), - Destroy("The volume is set to be desctroyed but can be recovered."), - Destroyed("The volume is destroyed. Should be removed."); + Destroy("The volume is set to be destroyed but can be recovered."); String _description; @@ -75,17 +74,13 @@ public interface Volume extends ControlledEntity, BasedOn { private final static StateMachine s_fsm = new StateMachine(); static { s_fsm.addTransition(Allocated, Event.Create, Creating); - s_fsm.addTransition(Allocated, Event.Destroy, Destroyed); + s_fsm.addTransition(Allocated, Event.Destroy, Destroy); s_fsm.addTransition(Creating, Event.OperationRetry, Creating); s_fsm.addTransition(Creating, Event.OperationFailed, Allocated); s_fsm.addTransition(Creating, Event.OperationSucceeded, Ready); s_fsm.addTransition(Creating, Event.Destroy, Destroy); s_fsm.addTransition(Ready, Event.Destroy, Destroy); s_fsm.addTransition(Ready, Event.Start, Used); - s_fsm.addTransition(Destroy, Event.OperationSucceeded, Destroyed); - s_fsm.addTransition(Destroy, Event.OperationFailed, Destroy); - s_fsm.addTransition(Destroy, Event.OperationRetry, Destroy); - s_fsm.addTransition(Destroy, Event.Recover, Ready); } } @@ -95,8 +90,7 @@ public interface Volume extends ControlledEntity, BasedOn { OperationFailed, OperationSucceeded, OperationRetry, - Destroy, - Recover; + Destroy; } enum SourceType { diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index a82f7229c54..57c2032bb19 100644 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -1557,64 +1557,13 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx } @Override - @DB public boolean destroyProxy(long vmId) { - AsyncJobExecutor asyncExecutor = BaseAsyncJobExecutor.getCurrentExecutor(); - if (asyncExecutor != null) { - AsyncJobVO job = asyncExecutor.getJob(); - - if (s_logger.isInfoEnabled()) { - s_logger.info("Destroy console proxy " + vmId + ", update async job-" + job.getId()); - } - _asyncMgr.updateAsyncJobAttachment(job.getId(), "console_proxy", vmId); - } - - ConsoleProxyVO vm = _consoleProxyDao.findById(vmId); - if (vm == null || vm.getState() == State.Destroyed) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to find vm or vm is destroyed: " + vmId); - } - return true; - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Destroying console proxy vm " + vmId); - } - - if (!_itMgr.stateTransitTo(vm, VirtualMachine.Event.DestroyRequested, null)) { - s_logger.debug("Unable to destroy the vm because it is not in the correct state: " + vmId); - return false; - } - - Transaction txn = Transaction.currentTxn(); - List vols = null; + ConsoleProxyVO proxy = _consoleProxyDao.findById(vmId); try { - vols = _volsDao.findByInstance(vmId); - if (vols.size() != 0) { - _storageMgr.destroy(vm, vols); - } - - return true; - } finally { - try { - txn.start(); - // release critical system resources used by the VM before we - // delete them - if (vm.getPublicIpAddress() != null) { -// freePublicIpAddress(vm.getPublicIpAddress(), vm.getDataCenterId(), vm.getPodId()); - } - vm.setPublicIpAddress(null); - - _consoleProxyDao.remove(vm.getId()); - - txn.commit(); - } catch (Exception e) { - s_logger.error("Caught this error: ", e); - txn.rollback(); - return false; - } finally { - s_logger.debug("console proxy vm is destroyed : " + vm.getName()); - } + return _itMgr.expunge(proxy, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount()); + } catch (ResourceUnavailableException e) { + s_logger.warn("Unable to expunge " + proxy, e); + return false; } } diff --git a/server/src/com/cloud/network/ovs/OvsNetworkManagerImpl.java b/server/src/com/cloud/network/ovs/OvsNetworkManagerImpl.java index 09638b16a4d..88466315989 100644 --- a/server/src/com/cloud/network/ovs/OvsNetworkManagerImpl.java +++ b/server/src/com/cloud/network/ovs/OvsNetworkManagerImpl.java @@ -44,10 +44,10 @@ import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; import com.cloud.vm.DomainRouterVO; -import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.NicDao; @@ -108,7 +108,7 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { public boolean configure(String name, Map params) throws ConfigurationException { _name = name; - _isEnabled = _configDao.getValue(Config.OvsNetwork.key()).equalsIgnoreCase("true") ? true : false; + _isEnabled = Boolean.parseBoolean(_configDao.getValue(Config.OvsNetwork.key())); _serverId = ((ManagementServer)ComponentLocator.getComponent(ManagementServer.Name)).getId(); _executorPool = Executors.newScheduledThreadPool(10, new NamedThreadFactory("OVS")); _cleanupExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("OVS-Cleanup")); @@ -470,8 +470,9 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { return; } - if (delayMs == null) - delayMs = new Long(100l); + if (delayMs == null) { + delayMs = new Long(100l); + } for (Long vmId: affectedVms) { Transaction txn = Transaction.currentTxn(); @@ -613,14 +614,14 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { @Override public void UserVmCheckAndCreateTunnel(Commands cmds, VirtualMachineProfile profile, DeployDestination dest) throws GreTunnelException { - CheckAndCreateTunnel((VMInstanceVO)profile.getVirtualMachine(), dest); + CheckAndCreateTunnel(profile.getVirtualMachine(), dest); } @Override public void RouterCheckAndCreateTunnel(Commands cmds, VirtualMachineProfile profile, DeployDestination dest) throws GreTunnelException { - CheckAndCreateTunnel((VMInstanceVO)profile.getVirtualMachine(), dest); + CheckAndCreateTunnel(profile.getVirtualMachine(), dest); } @Override diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index d811faeb1f2..dd2248e2403 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -348,51 +348,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian if (s_logger.isDebugEnabled()) { s_logger.debug("Attempting to destroy router " + routerId); } - - DomainRouterVO router = _routerDao.acquireInLockTable(routerId); - + + DomainRouterVO router = _routerDao.findById(routerId); if (router == null) { - s_logger.debug("Unable to acquire lock on router " + routerId); - return false; + return true; } - - try { - if (router.getState() == State.Destroyed || router.getState() == State.Expunging || router.getRemoved() != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to find router or router is destroyed: " + routerId); - } - return true; - } - - if (stopRouterInternal(router.getId())) { - return false; - } - - router = _routerDao.findById(routerId); - if (!_itMgr.stateTransitTo(router, VirtualMachine.Event.DestroyRequested, router.getHostId())) { - s_logger.debug("VM " + router.toString() + " is not in a state to be destroyed."); - return false; - } - } finally { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Release lock on router " + routerId + " for stop"); - } - _routerDao.releaseFromLockTable(routerId); - } - - router.setPublicIpAddress(null); - router.setVlanDbId(null); - _routerDao.update(router.getId(), router); - _routerDao.remove(router.getId()); - - List vols = _volsDao.findByInstance(routerId); - _storageMgr.destroy(router, vols); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Successfully destroyed router: " + routerId); - } - - return true; + return _itMgr.expunge(router, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount()); } @Override diff --git a/server/src/com/cloud/storage/StorageManager.java b/server/src/com/cloud/storage/StorageManager.java index 336750c1556..a269546790d 100755 --- a/server/src/com/cloud/storage/StorageManager.java +++ b/server/src/com/cloud/storage/StorageManager.java @@ -81,14 +81,6 @@ public interface StorageManager extends Manager { */ List unshare(VMInstanceVO vm, HostVO host); - /** - * destroy the storage volumes of a certain vm. - * - * @param vm vm to destroy. - * @param vols volumes to remove from storage pool - */ - void destroy(VMInstanceVO vm, List vols); - /** * Creates volumes for a particular VM. * @param account account to create volumes for. @@ -205,7 +197,7 @@ public interface StorageManager extends Manager { * Marks the specified volume as destroyed in the management server database. The expunge thread will delete the volume from its storage pool. * @param volume */ - void destroyVolume(VolumeVO volume); + void destroyVolume(VolumeVO volume) throws ConcurrentOperationException; /** Create capacity entries in the op capacity table * @param storagePool @@ -282,5 +274,5 @@ public interface StorageManager extends Manager { void release(VirtualMachineProfile profile); - void cleanupVolumes(Long vmId); + void cleanupVolumes(long vmId) throws ConcurrentOperationException; } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 97992cd6ac0..1d6a35a38ed 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -114,7 +114,6 @@ import com.cloud.host.dao.DetailsDao; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.NetworkManager; -import com.cloud.network.VirtualNetworkApplianceService; import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.offering.ServiceOffering; import com.cloud.service.ServiceOfferingVO; @@ -141,7 +140,6 @@ import com.cloud.storage.snapshot.SnapshotScheduler; import com.cloud.template.TemplateManager; import com.cloud.user.Account; import com.cloud.user.AccountManager; -import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; @@ -874,7 +872,11 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag s_logger.debug(e.getMessage()); } if (rootCreated != null) { - destroyVolume(rootCreated); + try { + destroyVolume(rootCreated); + } catch (Exception e1) { + s_logger.warn("Unable to mark a volume as destroyed: " + rootCreated, e1); + } } throw new CloudRuntimeException("Unable to create volumes for " + vm, e); } @@ -953,55 +955,6 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag return true; } - @Override - public void destroy(VMInstanceVO vm, List vols) { - if (s_logger.isDebugEnabled() && vm != null) { - s_logger.debug("Destroying volumes of " + vm.toString()); - } - - for (VolumeVO vol : vols) { - _volsDao.detachVolume(vol.getId()); - _volsDao.destroyVolume(vol.getId()); - - // First delete the entries in the snapshot_policy and - // snapshot_schedule table for the volume. - // They should not get executed after the volume is destroyed. - _snapshotMgr.deletePoliciesForVolume(vol.getId()); - - String volumePath = vol.getPath(); - Long poolId = vol.getPoolId(); - if (poolId != null && volumePath != null && !volumePath.trim().isEmpty()) { - Answer answer = null; - StoragePoolVO pool = _storagePoolDao.findById(poolId); - String vmName = null; - if (vm != null) { - vmName = vm.getInstanceName(); - } - final DestroyCommand cmd = new DestroyCommand(pool, vol, vmName); - boolean removed = false; - List poolhosts = _storagePoolHostDao.listByPoolId(poolId); - for (StoragePoolHostVO poolhost : poolhosts) { - answer = _agentMgr.easySend(poolhost.getHostId(), cmd); - if (answer != null && answer.getResult()) { - removed = true; - break; - } - } - - if (removed) { - _volsDao.remove(vol.getId()); - } else { - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_STORAGE_MISC, vol.getDataCenterId(), vol.getPodId(), - "Storage cleanup required for storage pool: " + pool.getName(), "Volume folder: " + vol.getFolder() + ", Volume Path: " + vol.getPath() + ", Volume id: " +vol.getId()+ ", Volume Name: " +vol.getName()+ ", Storage PoolId: " +vol.getPoolId()); - s_logger.warn("destroy volume " + vol.getFolder() + " : " + vol.getPath() + " failed for Volume id : " +vol.getId()+ " Volume Name: " +vol.getName()+ " Storage PoolId : " +vol.getPoolId()); - } - } else { - _volsDao.remove(vol.getId()); - } - } - - } - @Override public boolean configure(String name, Map params) throws ConfigurationException { _name = name; @@ -1597,13 +1550,13 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag String destPrimaryStorageVolumePath = cvAnswer.getVolumePath(); String destPrimaryStorageVolumeFolder = cvAnswer.getVolumeFolder(); - // Delete the volume on the source storage pool - final DestroyCommand cmd = new DestroyCommand(srcPool, volume, null); - Answer destroyAnswer = _agentMgr.easySend(sourceHostId, cmd); - - if (destroyAnswer == null || !destroyAnswer.getResult()) { - throw new CloudRuntimeException("Failed to delete the volume from the source primary storage pool."); + try { + destroyVolume(volume); + } catch (ConcurrentOperationException e) { + s_logger.warn("Concurrent Operation", e); } + + expungeVolume(volume); volume.setPath(destPrimaryStorageVolumePath); volume.setFolder(destPrimaryStorageVolumeFolder); @@ -1849,16 +1802,14 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag @Override @DB - public void destroyVolume(VolumeVO volume) { + public void destroyVolume(VolumeVO volume) throws ConcurrentOperationException { Transaction txn = Transaction.currentTxn(); txn.start(); - - Long volumeId = volume.getId(); - _volsDao.destroyVolume(volumeId); + + _volsDao.update(volume, Volume.Event.Destroy); + long volumeId = volume.getId(); - EventUtils.saveEvent(User.UID_SYSTEM, volume.getAccountId(), EventTypes.EVENT_VOLUME_DELETE, "Volume " +volume.getName()+ " deleted"); - - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), null, null , null); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volumeId, volume.getName(), null, null , null); _usageEventDao.persist(usageEvent); // Delete the recurring snapshot policies for this volume. @@ -1994,24 +1945,6 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag return answer; } - protected class StorageGarbageCollector implements Runnable { - - public StorageGarbageCollector() { - } - - @Override - public void run() { - try { - s_logger.info("Storage Garbage Collection Thread is running."); - - cleanupStorage(true); - - } catch (Exception e) { - s_logger.error("Caught the following Exception", e); - } - } - } - @Override public void cleanupStorage(boolean recurring) { GlobalLock scanLock = GlobalLock.getInternLock(this.getClass().getName()); @@ -2083,19 +2016,10 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag } } - List vols = _volsDao.listRemovedButNotDestroyed(); + List vols = _volsDao.listVolumesToBeDestroyed(); for (VolumeVO vol : vols) { try { - Long poolId = vol.getPoolId(); - Answer answer = null; - StoragePoolVO pool = _storagePoolDao.findById(poolId); - final DestroyCommand cmd = new DestroyCommand(pool, vol, null); - answer = sendToPool(pool, cmd); - if (answer != null && answer.getResult()) { - s_logger.debug("Destroyed " + vol); - vol.setDestroyed(true); - _volsDao.update(vol.getId(), vol); - } + expungeVolume(vol); } catch (Exception e) { s_logger.warn("Unable to destroy " + vol.getId(), e); } @@ -2470,7 +2394,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag } @Override - public boolean deleteVolume(DeleteVolumeCmd cmd) throws InvalidParameterValueException { + public boolean deleteVolume(DeleteVolumeCmd cmd) throws ConcurrentOperationException { Account account = UserContext.current().getCaller(); Long volumeId = cmd.getId(); @@ -2513,20 +2437,13 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag } // Check that the volume is not already destroyed - if (volume.getDestroyed()) { - throw new InvalidParameterValueException("Please specify a volume that is not already destroyed."); + if (volume.getState() != Volume.State.Destroy) { + destroyVolume(volume); } - try { - // Destroy the volume - destroyVolume(volume); - } catch (Exception e) { - s_logger.warn("Error destroying volume:"+e); - throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Error destroying volume:"+e); - } + expungeVolume(volume); return true; - } private boolean validateVolumeSizeRange(long size) throws InvalidParameterValueException { @@ -2800,41 +2717,90 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag //add code here } - @Override - public void cleanupVolumes(Long vmId) { - VMInstanceVO vm = _vmInstanceDao.findById(vmId); - List volumesForVm = _volsDao.findByInstance(vmId); - for(VolumeVO vol : volumesForVm){ - if(vol.getVolumeType().equals(VolumeType.ROOT)){ - if(vol.getState() != Volume.State.Destroyed) { - assert(vol.getState() == Volume.State.Destroy); - String volumePath = vol.getPath(); - Long poolId = vol.getPoolId(); - if (poolId != null && volumePath != null && !volumePath.trim().isEmpty()) { - Answer answer = null; - StoragePoolVO pool = _storagePoolDao.findById(poolId); - - final DestroyCommand cmd = new DestroyCommand(pool, vol, vm.getName()); - List poolhosts = _storagePoolHostDao.listByPoolId(poolId); - for (StoragePoolHostVO poolhost : poolhosts) { - answer = _agentMgr.easySend(poolhost.getHostId(), cmd); - if (answer != null && answer.getResult()) { - try { - _volsDao.update(vol, Volume.Event.OperationSucceeded); - } catch (ConcurrentOperationException e) { - s_logger.warn("Unable to update volume state. vm: " + vmId + ", vol: " + vol.getId() + " due to ConcurrentOperationException"); - } - break; - } - } - } - } - destroyVolume(vol); + public void expungeVolume(VolumeVO vol) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Expunging " + vol); + } + String vmName = null; + if (vol.getVolumeType() == VolumeType.ROOT && vol.getInstanceId() != null) { + VirtualMachine vm = _vmInstanceDao.findById(vol.getInstanceId()); + vmName = vm.getInstanceName(); + } + + String volumePath = vol.getPath(); + Long poolId = vol.getPoolId(); + if (poolId == null || volumePath == null || volumePath.trim().isEmpty()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Marking volume that was never created as destroyed: " + vol); + } + _volsDao.remove(vol.getId()); + return; + } + + StoragePoolVO pool = _storagePoolDao.findById(poolId); + if (pool == null) { + s_logger.debug("Removing volume as storage pool is gone: " + poolId); + _volsDao.remove(vol.getId()); + return; + } + + DestroyCommand cmd = new DestroyCommand(pool, vol, vmName); + Answer answer = this.sendToPool(pool, cmd); + + if (answer != null && answer.getResult()) { + _volsDao.remove(vol.getId()); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Volume successfully expunged from " + poolId); + } + } else { + s_logger.info("Will retry delete of " + vol + " from " + poolId); + } + } + + @Override @DB + public void cleanupVolumes(long vmId) throws ConcurrentOperationException { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Cleaning storage for vm: " + vmId); + } + List volumesForVm = _volsDao.findByInstance(vmId); + List toBeExpunged = new ArrayList(); + Transaction txn = Transaction.currentTxn(); + txn.start(); + for (VolumeVO vol : volumesForVm) { + if (vol.getVolumeType().equals(VolumeType.ROOT)) { + destroyVolume(vol); + toBeExpunged.add(vol); } else { - //data volume - _volsDao.detachVolume(vol.getId()); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Detaching " + vol); + } + _volsDao.detachVolume(vol.getId()); } } + txn.commit(); + + for (VolumeVO expunge : toBeExpunged) { + expungeVolume(expunge); + } } + + protected class StorageGarbageCollector implements Runnable { + + public StorageGarbageCollector() { + } + + @Override + public void run() { + try { + s_logger.trace("Storage Garbage Collection Thread is running."); + + cleanupStorage(true); + + } catch (Exception e) { + s_logger.error("Caught the following Exception", e); + } + } + } + } diff --git a/server/src/com/cloud/storage/dao/VolumeDao.java b/server/src/com/cloud/storage/dao/VolumeDao.java index cfd3c9ada0c..e35b5e041ff 100755 --- a/server/src/com/cloud/storage/dao/VolumeDao.java +++ b/server/src/com/cloud/storage/dao/VolumeDao.java @@ -36,14 +36,10 @@ public interface VolumeDao extends GenericDao { List findByDetachedDestroyed(); List findByAccountAndPod(long accountId, long podId); List findByTemplateAndZone(long templateId, long zoneId); - List findVMInstancesByStorageHost(long hostId, Volume.MirrorState mState); - List findStrandedMirrorVolumes(); List findVmsStoredOnHost(long hostId); void deleteVolumesByInstance(long instanceId); void attachVolume(long volumeId, long vmId, long deviceId); void detachVolume(long volumeId); - void destroyVolume(long volumeId); - void recoverVolume(long volumeId); boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId); List listRemovedButNotDestroyed(); List findCreatedByInstance(long id); @@ -59,4 +55,6 @@ public interface VolumeDao extends GenericDao { */ boolean update(VolumeVO vol, Volume.Event event) throws ConcurrentOperationException; HypervisorType getHypervisorType(long volumeId); + + List listVolumesToBeDestroyed(); } diff --git a/server/src/com/cloud/storage/dao/VolumeDaoImpl.java b/server/src/com/cloud/storage/dao/VolumeDaoImpl.java index 453d96a71bc..ecdb37b9bb0 100755 --- a/server/src/com/cloud/storage/dao/VolumeDaoImpl.java +++ b/server/src/com/cloud/storage/dao/VolumeDaoImpl.java @@ -32,8 +32,6 @@ import com.cloud.async.AsyncInstanceCreateStatus; import com.cloud.exception.ConcurrentOperationException; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.Volume; -import com.cloud.storage.Volume.Event; -import com.cloud.storage.Volume.MirrorState; import com.cloud.storage.Volume.VolumeType; import com.cloud.storage.VolumeVO; import com.cloud.utils.Pair; @@ -53,22 +51,14 @@ import com.cloud.utils.exception.CloudRuntimeException; public class VolumeDaoImpl extends GenericDaoBase implements VolumeDao { private static final Logger s_logger = Logger.getLogger(VolumeDaoImpl.class); protected final SearchBuilder DetachedAccountIdSearch; - protected final SearchBuilder AccountIdSearch; - protected final SearchBuilder AccountPodSearch; protected final SearchBuilder TemplateZoneSearch; protected final GenericSearchBuilder TotalSizeByPoolSearch; - protected final SearchBuilder InstanceIdSearch; - protected final SearchBuilder InstanceAndTypeSearch; - protected final SearchBuilder InstanceIdDestroyedSearch; - protected final SearchBuilder InstanceIdCreatedSearch; protected final SearchBuilder DetachedDestroyedSearch; - protected final SearchBuilder MirrorSearch; protected final GenericSearchBuilder ActiveTemplateSearch; protected final SearchBuilder RemovedButNotDestroyedSearch; - protected final SearchBuilder PoolIdSearch; - protected final SearchBuilder InstanceAndDeviceIdSearch; protected final SearchBuilder InstanceStatesSearch; - protected final SearchBuilder IdStateSearch; + + protected final SearchBuilder AllFieldsSearch; protected final Attribute _stateAttr; @@ -116,7 +106,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol @Override public List findByAccount(long accountId) { - SearchCriteria sc = AccountIdSearch.create(); + SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("accountId", accountId); sc.setParameters("destroyed", false); return listBy(sc); @@ -124,14 +114,14 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol @Override public List findByInstance(long id) { - SearchCriteria sc = InstanceIdSearch.create(); + SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("instanceId", id); return listBy(sc); } @Override public List findByInstanceAndDeviceId(long instanceId, long deviceId){ - SearchCriteria sc = InstanceAndDeviceIdSearch.create(); + SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("instanceId", instanceId); sc.setParameters("deviceId", deviceId); return listBy(sc); @@ -139,14 +129,14 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol @Override public List findByPoolId(long poolId) { - SearchCriteria sc = PoolIdSearch.create(); + SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("poolId", poolId); return listBy(sc); } @Override public List findCreatedByInstance(long id) { - SearchCriteria sc = InstanceIdCreatedSearch.create(); + SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("instanceId", id); sc.setParameters("status", AsyncInstanceCreateStatus.Created); sc.setParameters("destroyed", false); @@ -164,7 +154,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol @Override public List findByInstanceAndType(long id, VolumeType vType) { - SearchCriteria sc = InstanceAndTypeSearch.create(); + SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("instanceId", id); sc.setParameters("vType", vType.toString()); return listBy(sc); @@ -172,7 +162,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol @Override public List findByInstanceIdDestroyed(long vmId) { - SearchCriteria sc = InstanceIdDestroyedSearch.create(); + SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("instanceId", vmId); sc.setParameters("destroyed", true); return listIncludingRemovedBy(sc); @@ -187,8 +177,8 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol @Override public List findByAccountAndPod(long accountId, long podId) { - SearchCriteria sc = AccountPodSearch.create(); - sc.setParameters("account", accountId); + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("accountId", accountId); sc.setParameters("pod", podId); sc.setParameters("destroyed", false); sc.setParameters("status", AsyncInstanceCreateStatus.Created); @@ -205,38 +195,6 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol return listIncludingRemovedBy(sc); } - @Override @DB - public List findVMInstancesByStorageHost(long hostId, Volume.MirrorState mirrState) { - - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - List result = new ArrayList(); - - try { - String sql = SELECT_VM_SQL; - pstmt = txn.prepareAutoCloseStatement(sql); - pstmt.setLong(1, hostId); - pstmt.setString(2, mirrState.toString()); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - result.add(rs.getLong(1)); - } - return result; - } catch (SQLException e) { - throw new CloudRuntimeException("DB Exception on: " + SELECT_VM_SQL, e); - } catch (Throwable e) { - throw new CloudRuntimeException("Caught: " + SELECT_VM_SQL, e); - } - } - - @Override - public List findStrandedMirrorVolumes() { - SearchCriteria sc = MirrorSearch.create(); - sc.setParameters("mirrorState", MirrorState.ACTIVE.toString()); - - return listIncludingRemovedBy(sc); - } - @Override public boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId) { SearchCriteria sc = ActiveTemplateSearch.create(); @@ -251,7 +209,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol @Override public void deleteVolumesByInstance(long instanceId) { - SearchCriteria sc = InstanceIdSearch.create(); + SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("instanceId", instanceId); expunge(sc); } @@ -276,34 +234,6 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol update(volumeId, volume); } - @Override - public void destroyVolume(long volumeId) { - VolumeVO volume = createForUpdate(volumeId); - volume.setDestroyed(true); - - Volume.State oldState = volume.getState(); - Volume.State newState = oldState.getNextState(Event.Destroy); - - assert newState != null : "Event "+ Event.Destroy + " cannot happen from " + oldState; - volume.setState(newState); - - update(volumeId, volume); - } - - @Override - public void recoverVolume(long volumeId) { - VolumeVO volume = createForUpdate(volumeId); - volume.setDestroyed(false); - - Volume.State oldState = volume.getState(); - Volume.State newState = oldState.getNextState(Event.Recover); - - assert newState != null : "Event "+ Event.Recover + " cannot happen from " + oldState; - volume.setState(newState); - - update(volumeId, volume); - } - @Override public boolean update(VolumeVO vol, Volume.Event event) throws ConcurrentOperationException { Volume.State oldState = vol.getState(); @@ -314,7 +244,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol UpdateBuilder builder = getUpdateBuilder(vol); builder.set(vol, _stateAttr, newState); - SearchCriteria sc = IdStateSearch.create(); + SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("id", vol.getId()); sc.setParameters("state", oldState); @@ -325,6 +255,8 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol } return rows == 1; } + + @Override @DB public HypervisorType getHypervisorType(long volumeId) { /*lookup from cluster of pool*/ @@ -336,8 +268,9 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol pstmt = txn.prepareAutoCloseStatement(sql); pstmt.setLong(1, volumeId); ResultSet rs = pstmt.executeQuery(); - if (rs.next()) - return HypervisorType.getType(rs.getString(1)); + if (rs.next()) { + return HypervisorType.getType(rs.getString(1)); + } return HypervisorType.None; } catch (SQLException e) { throw new CloudRuntimeException("DB Exception on: " + SELECT_HYPERTYPE_FROM_VOLUME, e); @@ -347,98 +280,59 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol } protected VolumeDaoImpl() { - AccountIdSearch = createSearchBuilder(); - AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ); - AccountIdSearch.and("destroyed", AccountIdSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); - AccountIdSearch.done(); + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ); + AllFieldsSearch.and("destroyed", AllFieldsSearch.entity().getDestroyed(), Op.EQ); + AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), Op.EQ); + AllFieldsSearch.and("pod", AllFieldsSearch.entity().getPodId(), Op.EQ); + AllFieldsSearch.and("status", AllFieldsSearch.entity().getStatus(), Op.EQ); + AllFieldsSearch.and("instanceId", AllFieldsSearch.entity().getInstanceId(), Op.EQ); + AllFieldsSearch.and("deviceId", AllFieldsSearch.entity().getDeviceId(), Op.EQ); + AllFieldsSearch.and("poolId", AllFieldsSearch.entity().getPoolId(), Op.EQ); + AllFieldsSearch.and("vType", AllFieldsSearch.entity().getVolumeType(), Op.EQ); + AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ); + AllFieldsSearch.done(); DetachedAccountIdSearch = createSearchBuilder(); - DetachedAccountIdSearch.and("accountId", DetachedAccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ); - DetachedAccountIdSearch.and("destroyed", DetachedAccountIdSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); - DetachedAccountIdSearch.and("instanceId", DetachedAccountIdSearch.entity().getInstanceId(), SearchCriteria.Op.NULL); + DetachedAccountIdSearch.and("accountId", DetachedAccountIdSearch.entity().getAccountId(), Op.EQ); + DetachedAccountIdSearch.and("destroyed", DetachedAccountIdSearch.entity().getDestroyed(), Op.EQ); + DetachedAccountIdSearch.and("instanceId", DetachedAccountIdSearch.entity().getInstanceId(), Op.NULL); DetachedAccountIdSearch.done(); - AccountPodSearch = createSearchBuilder(); - AccountPodSearch.and("account", AccountPodSearch.entity().getAccountId(), SearchCriteria.Op.EQ); - AccountPodSearch.and("pod", AccountPodSearch.entity().getPodId(), SearchCriteria.Op.EQ); - AccountPodSearch.and("destroyed", AccountPodSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); - AccountPodSearch.and("status", AccountPodSearch.entity().getStatus(), SearchCriteria.Op.EQ); - AccountPodSearch.done(); - TemplateZoneSearch = createSearchBuilder(); - TemplateZoneSearch.and("template", TemplateZoneSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); - TemplateZoneSearch.and("zone", TemplateZoneSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + TemplateZoneSearch.and("template", TemplateZoneSearch.entity().getTemplateId(), Op.EQ); + TemplateZoneSearch.and("zone", TemplateZoneSearch.entity().getDataCenterId(), Op.EQ); TemplateZoneSearch.done(); TotalSizeByPoolSearch = createSearchBuilder(SumCount.class); TotalSizeByPoolSearch.select("sum", Func.SUM, TotalSizeByPoolSearch.entity().getSize()); TotalSizeByPoolSearch.select("count", Func.COUNT, (Object[])null); - TotalSizeByPoolSearch.and("poolId", TotalSizeByPoolSearch.entity().getPoolId(), SearchCriteria.Op.EQ); - TotalSizeByPoolSearch.and("removed", TotalSizeByPoolSearch.entity().getRemoved(), SearchCriteria.Op.NULL); + TotalSizeByPoolSearch.and("poolId", TotalSizeByPoolSearch.entity().getPoolId(), Op.EQ); + TotalSizeByPoolSearch.and("removed", TotalSizeByPoolSearch.entity().getRemoved(), Op.NULL); TotalSizeByPoolSearch.done(); - - InstanceIdCreatedSearch = createSearchBuilder(); - InstanceIdCreatedSearch.and("instanceId", InstanceIdCreatedSearch.entity().getInstanceId(), SearchCriteria.Op.EQ); - InstanceIdCreatedSearch.and("status", InstanceIdCreatedSearch.entity().getStatus(), SearchCriteria.Op.EQ); - InstanceIdCreatedSearch.and("destroyed", InstanceIdCreatedSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); - InstanceIdCreatedSearch.done(); - - InstanceIdSearch = createSearchBuilder(); - InstanceIdSearch.and("instanceId", InstanceIdSearch.entity().getInstanceId(), SearchCriteria.Op.EQ); - InstanceIdSearch.done(); - - InstanceAndDeviceIdSearch = createSearchBuilder(); - InstanceAndDeviceIdSearch.and("instanceId", InstanceAndDeviceIdSearch.entity().getInstanceId(), SearchCriteria.Op.EQ); - InstanceAndDeviceIdSearch.and("deviceId", InstanceAndDeviceIdSearch.entity().getDeviceId(), SearchCriteria.Op.EQ); - InstanceAndDeviceIdSearch.done(); - - PoolIdSearch = createSearchBuilder(); - PoolIdSearch.and("poolId", PoolIdSearch.entity().getPoolId(), SearchCriteria.Op.EQ); - PoolIdSearch.done(); - - InstanceAndTypeSearch= createSearchBuilder(); - InstanceAndTypeSearch.and("instanceId", InstanceAndTypeSearch.entity().getInstanceId(), SearchCriteria.Op.EQ); - InstanceAndTypeSearch.and("vType", InstanceAndTypeSearch.entity().getVolumeType(), SearchCriteria.Op.EQ); - InstanceAndTypeSearch.done(); - - InstanceIdDestroyedSearch = createSearchBuilder(); - InstanceIdDestroyedSearch.and("instanceId", InstanceIdDestroyedSearch.entity().getInstanceId(), SearchCriteria.Op.EQ); - InstanceIdDestroyedSearch.and("destroyed", InstanceIdDestroyedSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); - InstanceIdDestroyedSearch.done(); - DetachedDestroyedSearch = createSearchBuilder(); - DetachedDestroyedSearch.and("instanceId", DetachedDestroyedSearch.entity().getInstanceId(), SearchCriteria.Op.NULL); - DetachedDestroyedSearch.and("destroyed", DetachedDestroyedSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); + DetachedDestroyedSearch.and("instanceId", DetachedDestroyedSearch.entity().getInstanceId(), Op.NULL); + DetachedDestroyedSearch.and("destroyed", DetachedDestroyedSearch.entity().getDestroyed(), Op.EQ); DetachedDestroyedSearch.done(); - MirrorSearch = createSearchBuilder(); - MirrorSearch.and("mirrorVolume", MirrorSearch.entity().getMirrorVolume(), Op.NULL); - MirrorSearch.and("mirrorState", MirrorSearch.entity().getMirrorState(), Op.EQ); - MirrorSearch.done(); - ActiveTemplateSearch = createSearchBuilder(Long.class); - ActiveTemplateSearch.and("pool", ActiveTemplateSearch.entity().getPoolId(), SearchCriteria.Op.EQ); - ActiveTemplateSearch.and("template", ActiveTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); - ActiveTemplateSearch.and("removed", ActiveTemplateSearch.entity().getRemoved(), SearchCriteria.Op.NULL); + ActiveTemplateSearch.and("pool", ActiveTemplateSearch.entity().getPoolId(), Op.EQ); + ActiveTemplateSearch.and("template", ActiveTemplateSearch.entity().getTemplateId(), Op.EQ); + ActiveTemplateSearch.and("removed", ActiveTemplateSearch.entity().getRemoved(), Op.NULL); ActiveTemplateSearch.select(null, Func.COUNT, null); ActiveTemplateSearch.done(); RemovedButNotDestroyedSearch = createSearchBuilder(); - RemovedButNotDestroyedSearch.and("destroyed", RemovedButNotDestroyedSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); - RemovedButNotDestroyedSearch.and("removed", RemovedButNotDestroyedSearch.entity().getRemoved(), SearchCriteria.Op.NNULL); + RemovedButNotDestroyedSearch.and("destroyed", RemovedButNotDestroyedSearch.entity().getDestroyed(), Op.EQ); + RemovedButNotDestroyedSearch.and("removed", RemovedButNotDestroyedSearch.entity().getRemoved(), Op.NNULL); RemovedButNotDestroyedSearch.done(); InstanceStatesSearch = createSearchBuilder(); - InstanceStatesSearch.and("instance", InstanceStatesSearch.entity().getInstanceId(), SearchCriteria.Op.EQ); - InstanceStatesSearch.and("states", InstanceStatesSearch.entity().getState(), SearchCriteria.Op.IN); + InstanceStatesSearch.and("instance", InstanceStatesSearch.entity().getInstanceId(), Op.EQ); + InstanceStatesSearch.and("states", InstanceStatesSearch.entity().getState(), Op.IN); InstanceStatesSearch.done(); - IdStateSearch = createSearchBuilder(); - IdStateSearch.and("id", IdStateSearch.entity().getId(), SearchCriteria.Op.EQ); - IdStateSearch.and("state", IdStateSearch.entity().getState(), SearchCriteria.Op.EQ); - IdStateSearch.done(); - _stateAttr = _allAttributes.get("state"); assert _stateAttr != null : "Couldn't get the state attribute"; } @@ -458,4 +352,12 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol public SumCount() { } } + + @Override + public List listVolumesToBeDestroyed() { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("state", Volume.State.Destroy); + + return listBy(sc); + } } diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index 1410de77c9d..258890bc2a3 100644 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -1109,68 +1109,15 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V } @Override - @DB public boolean destroySecStorageVm(long vmId) { - AsyncJobExecutor asyncExecutor = BaseAsyncJobExecutor.getCurrentExecutor(); - if (asyncExecutor != null) { - AsyncJobVO job = asyncExecutor.getJob(); - - if (s_logger.isInfoEnabled()) { - s_logger.info("Destroy secondary storage vm " + vmId + ", update async job-" + job.getId()); - } - _asyncMgr.updateAsyncJobAttachment(job.getId(), "secstorage_vm", vmId); + SecondaryStorageVmVO ssvm = _secStorageVmDao.findById(vmId); + + try { + return _itMgr.expunge(ssvm, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount()); + } catch (ResourceUnavailableException e) { + s_logger.warn("Unable to expunge " + ssvm, e); + return false; } - - SecondaryStorageVmVO vm = _secStorageVmDao.findById(vmId); - if (vm == null || vm.getState() == State.Destroyed) { - String msg = "Unable to find vm or vm is destroyed: " + vmId; - if (s_logger.isDebugEnabled()) { - s_logger.debug(msg); - } - return true; - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Destroying secondary storage vm vm " + vmId); - } - - if (! _itMgr.stateTransitTo(vm, VirtualMachine.Event.DestroyRequested, null)) { - String msg = "Unable to destroy the vm because it is not in the correct state: " + vmId; - s_logger.debug(msg); - return false; - } - - Transaction txn = Transaction.currentTxn(); - List vols = null; - try { - vols = _volsDao.findByInstance(vmId); - if (vols.size() != 0) { - _storageMgr.destroy(vm, vols); - } - - return true; - } finally { - try { - txn.start(); - // release critical system resources used by the VM before we - // delete them - if (vm.getPublicIpAddress() != null) { - freePublicIpAddress(vm.getPublicIpAddress(), vm.getDataCenterId(), vm.getPodId()); - } - vm.setPublicIpAddress(null); - - _secStorageVmDao.remove(vm.getId()); - - txn.commit(); - } catch (Exception e) { - s_logger.error("Caught this error: ", e); - txn.rollback(); - return false; - } finally { - s_logger.debug("secondary storage vm vm is destroyed : " - + vm.getName()); - } - } } @DB diff --git a/server/src/com/cloud/vm/ItWorkDaoImpl.java b/server/src/com/cloud/vm/ItWorkDaoImpl.java index b7df1275f5b..b7159fa417f 100644 --- a/server/src/com/cloud/vm/ItWorkDaoImpl.java +++ b/server/src/com/cloud/vm/ItWorkDaoImpl.java @@ -37,12 +37,12 @@ public class ItWorkDaoImpl extends GenericDaoBase implements I AllFieldsSearch = createSearchBuilder(); AllFieldsSearch.and("instance", AllFieldsSearch.entity().getInstanceId(), Op.EQ); - AllFieldsSearch.and("op", AllFieldsSearch.entity().getState(), Op.EQ); + AllFieldsSearch.and("op", AllFieldsSearch.entity().getType(), Op.EQ); AllFieldsSearch.and("step", AllFieldsSearch.entity().getStep(), Op.EQ); AllFieldsSearch.done(); CleanupSearch = createSearchBuilder(); - CleanupSearch.and("step", CleanupSearch.entity().getState(), Op.IN); + CleanupSearch.and("step", CleanupSearch.entity().getType(), Op.IN); CleanupSearch.and("time", CleanupSearch.entity().getUpdatedAt(), Op.LT); CleanupSearch.done(); } diff --git a/server/src/com/cloud/vm/ItWorkVO.java b/server/src/com/cloud/vm/ItWorkVO.java index 56539d31920..ca94b3825f1 100644 --- a/server/src/com/cloud/vm/ItWorkVO.java +++ b/server/src/com/cloud/vm/ItWorkVO.java @@ -58,7 +58,7 @@ public class ItWorkVO { @Column(name="thread") String threadName; - @Column(name="state") + @Column(name="step") Step step; @Column(name="updated_at") @@ -121,11 +121,11 @@ public class ItWorkVO { return managementServerId; } - public State getState() { + public State getType() { return type; } - public void setState(State type) { + public void setType(State type) { this.type = type; } @@ -137,8 +137,8 @@ public class ItWorkVO { return step; } - public void setStep(Step state) { - this.step = state; + public void setStep(Step step) { + this.step = step; } public long getUpdatedAt() { diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 17434421845..6c8dd565099 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -1027,13 +1027,11 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager // Recover the VM's disks List volumes = _volsDao.findByInstanceIdDestroyed(vmId); for (VolumeVO volume : volumes) { - _volsDao.recoverVolume(volume.getId()); // Create an event Long templateId = volume.getTemplateId(); Long diskOfferingId = volume.getDiskOfferingId(); long sizeMB = volume.getSize()/(1024*1024); StoragePoolVO pool = _storagePoolDao.findById(volume.getPoolId()); - EventUtils.saveEvent(User.UID_SYSTEM, volume.getAccountId(), EventTypes.EVENT_VOLUME_CREATE, "Created volume: "+ volume.getName() +" with size: " + sizeMB + " MB in pool: " + pool.getName()); UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), diskOfferingId, templateId , sizeMB); _usageEventDao.persist(usageEvent); diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 8bd572757b2..1c86fce46b8 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -98,11 +98,11 @@ DROP TABLE IF EXISTS `cloud`.`host_tags`; CREATE TABLE `cloud`.`op_it_work` ( `id` char(40) COMMENT 'id', `mgmt_server_id` bigint unsigned COMMENT 'management server id', - `created_on` bigint unsigned NOT NULL COMMENT 'when was this work detail created', + `created_at` bigint unsigned NOT NULL COMMENT 'when was this work detail created', `thread` varchar(255) NOT NULL COMMENT 'thread name', `type` char(32) NOT NULL COMMENT 'type of work', - `state` char(32) NOT NULL COMMENT 'state', - `updated_on` bigint unsigned NOT NULL COMMENT 'time it was taken over', + `step` char(32) NOT NULL COMMENT 'state', + `updated_at` bigint unsigned NOT NULL COMMENT 'time it was taken over', `instance_id` bigint unsigned NOT NULL COMMENT 'vm instance', `resource_type` char(32) COMMENT 'type of resource being worked on', `resource_id` bigint unsigned COMMENT 'resource id being worked on', @@ -677,7 +677,7 @@ CREATE TABLE `cloud`.`user_ip_address` ( INDEX `i_user_ip_address__source_nat`(`source_nat`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -CREATE VIEW `cloud`.`user_ip_address_view` AS SELECT INET_NTOA(user_ip_address.public_ip_address) as public_ip_address, user_ip_address.data_center_id, user_ip_address.account_id, user_ip_address.domain_id, user_ip_address.source_nat, user_ip_address.allocated, user_ip_address.vlan_db_id, user_ip_address.one_to_one_nat, user_ip_address.state, user_ip_address.mac_address, user_ip_address.network_id as associated_network_id from user_ip_address; +CREATE VIEW `cloud`.`user_ip_address_view` AS SELECT INET_NTOA(user_ip_address.public_ip_address) as ip_address, user_ip_address.data_center_id, user_ip_address.account_id, user_ip_address.domain_id, user_ip_address.source_nat, user_ip_address.allocated, user_ip_address.vlan_db_id, user_ip_address.one_to_one_nat, user_ip_address.state, user_ip_address.mac_address, user_ip_address.network_id as associated_network_id from user_ip_address; CREATE TABLE `cloud`.`user_statistics` ( `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT, From 6d9442be5409813a7fca4541cc839ebef6945e5a Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Tue, 11 Jan 2011 18:02:00 -0800 Subject: [PATCH 133/142] Finished all merges and unit testing --- .../src/com/cloud/api/ApiResponseHelper.java | 2 +- .../consoleproxy/ConsoleProxyManagerImpl.java | 3 ++ .../com/cloud/storage/StorageManagerImpl.java | 6 ++- .../cloud/vm/VirtualMachineManagerImpl.java | 54 +++++++++---------- 4 files changed, 34 insertions(+), 31 deletions(-) diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index b441203afea..e8baf8d2065 100644 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -739,7 +739,7 @@ public class ApiResponseHelper implements ResponseGenerator { volResponse.setDeviceId(volume.getDeviceId()); Long instanceId = volume.getInstanceId(); - if (instanceId != null) { + if (instanceId != null && volume.getState() != Volume.State.Destroy) { VMInstanceVO vm = ApiDBUtils.findVMInstanceById(instanceId); volResponse.setVirtualMachineId(vm.getId()); volResponse.setVirtualMachineName(vm.getName()); diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 57c2032bb19..4e3ad207872 100644 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -562,6 +562,9 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyVmId); Account systemAcct = _accountMgr.getSystemAccount(); User systemUser = _accountMgr.getSystemUser(); + if (proxy.getState() == VirtualMachine.State.Running) { + return proxy; + } return _itMgr.start(proxy, null, systemUser, systemAcct); } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 1d6a35a38ed..254844457bb 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -2723,8 +2723,10 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag } String vmName = null; if (vol.getVolumeType() == VolumeType.ROOT && vol.getInstanceId() != null) { - VirtualMachine vm = _vmInstanceDao.findById(vol.getInstanceId()); - vmName = vm.getInstanceName(); + VirtualMachine vm = _vmInstanceDao.findByIdIncludingRemoved(vol.getInstanceId()); + if (vm != null) { + vmName = vm.getInstanceName(); + } } String volumePath = vol.getPath(); diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index d583832e272..54cfe63342f 100644 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -461,7 +461,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { while (retry-- != 0) { Transaction txn = Transaction.currentTxn(); txn.start(); - if (_vmDao.updateIf(vm, Event.StartRequested, null, work.getId())) { + if (stateTransitTo(vm, Event.StartRequested, null, work.getId())) { Journal journal = new Journal.LogJournal("Creating " + vm, s_logger); work = _workDao.persist(work); @@ -470,6 +470,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { if (s_logger.isDebugEnabled()) { s_logger.debug("Successfully transitioned to start state for " + vm + " reservation id = " + work.getId()); } + txn.commit(); return new Ternary(vmGuru.findById(vmId), context, work); } @@ -477,35 +478,32 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { s_logger.debug("Determining why we're unable to update the state to Starting for " + vm); } - try { - VMInstanceVO instance = _vmDao.lockRow(vmId, true); - if (instance == null) { - throw new ConcurrentOperationException("Unable to acquire lock on " + vm); + VMInstanceVO instance = _vmDao.lockRow(vmId, true); + if (instance == null) { + throw new ConcurrentOperationException("Unable to acquire lock on " + vm); + } + + State state = instance.getState(); + if (state == State.Running) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("VM is already started: " + vm); } - - State state = instance.getState(); - if (state == State.Running) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("VM is already started: " + vm); - } - return null; - } - - if (state.isTransitional()) { - if (!checkWorkItems(vm, state)) { - throw new ConcurrentOperationException("There are concurrent operations on the VM " + vm); - } else { - continue; - } - } - - if (state != State.Stopped) { - s_logger.debug("VM " + vm + " is not in a state to be started: " + state); - return null; - } - - } finally { txn.commit(); + return null; + } + + if (state.isTransitional()) { + if (!checkWorkItems(vm, state)) { + throw new ConcurrentOperationException("There are concurrent operations on the VM " + vm); + } else { + continue; + } + } + + if (state != State.Stopped) { + s_logger.debug("VM " + vm + " is not in a state to be started: " + state); + txn.commit(); + return null; } } From 5b68027d3a26f7c5805b36fa244622eee497701b Mon Sep 17 00:00:00 2001 From: anthony Date: Tue, 11 Jan 2011 17:03:22 -0800 Subject: [PATCH 134/142] bug 7858: for untagged vlan, broadcastRUi is vlan://untagged status 7858: resolved fixed --- .../router/VirtualNetworkApplianceManagerImpl.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index dd2248e2403..5a4371d666f 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -1008,13 +1008,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian defaultNic.setNetmask(sourceNatIp.getNetmask()); defaultNic.setTrafficType(TrafficType.Public); defaultNic.setMacAddress(sourceNatIp.getMacAddress()); - if (sourceNatIp.getVlanTag().equals(Vlan.UNTAGGED)) { - defaultNic.setBroadcastType(BroadcastDomainType.Native); - } else { - defaultNic.setBroadcastType(BroadcastDomainType.Vlan); - defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag())); - defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag())); - } + defaultNic.setBroadcastType(BroadcastDomainType.Vlan); + defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag())); + defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag())); defaultNic.setDeviceId(2); networks.add(new Pair(publicConfigs.get(0), defaultNic)); NicProfile gatewayNic = new NicProfile(); From beb97057e1ab4f369323d8b0c6f14834e18290d4 Mon Sep 17 00:00:00 2001 From: anthony Date: Tue, 11 Jan 2011 18:08:10 -0800 Subject: [PATCH 135/142] reconnect hosts after MS restart --- server/src/com/cloud/host/dao/HostDaoImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/src/com/cloud/host/dao/HostDaoImpl.java b/server/src/com/cloud/host/dao/HostDaoImpl.java index b6622300529..9a49ca11c0f 100644 --- a/server/src/com/cloud/host/dao/HostDaoImpl.java +++ b/server/src/com/cloud/host/dao/HostDaoImpl.java @@ -381,8 +381,10 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao if( event.equals(Event.Ping) || event.equals(Event.AgentConnected)) { ub.set(host, _pingTimeAttr, System.currentTimeMillis() >> 10); } + } + if ( event.equals(Event.ManagementServerDown)) { + ub.set(host, _pingTimeAttr, (( System.currentTimeMillis() >> 10) - ( 10 * 60 ))); } - int result = update(ub, sc, null); assert result <= 1 : "How can this update " + result + " rows? "; From 7add7643e32bd506062095cc83d1c96086d2e45a Mon Sep 17 00:00:00 2001 From: anthony Date: Tue, 11 Jan 2011 18:58:20 -0800 Subject: [PATCH 136/142] bug 7748: need to make sure domr is up before start user VM, if domr is not up within 5 minutes, throw exception status 7748: resolved fixed --- .../VirtualNetworkApplianceManagerImpl.java | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 5a4371d666f..a1fd1da0ce4 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -1034,10 +1034,20 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian EventUtils.saveEvent(User.UID_SYSTEM, owner.getAccountId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_ROUTER_CREATE, "router creation failed", startEventId); } - } - - + } State state = router.getState(); + + if ( state == State.Starting ) { + // wait 300 seconds + for ( int i = 0; i < 300; ) { + try { + Thread.sleep(2); + } catch (Exception e) { + } + i += 2; + state = router.getState(); + } + } if (state != State.Starting && state != State.Running) { long startEventId = EventUtils.saveStartedEvent(User.UID_SYSTEM, owner.getId(), EventTypes.EVENT_ROUTER_START, "Starting router : " +router.getName()); router = this.start(router, _accountService.getSystemUser(), _accountService.getSystemAccount()); @@ -1047,7 +1057,11 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian EventUtils.saveEvent(User.UID_SYSTEM, owner.getAccountId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_ROUTER_START, "failed to start router", startEventId); } } - return router; + state = router.getState(); + if ( state == State.Running ) { + return router; + } + throw new CloudRuntimeException(router.getName() + " is not running , it is in " + state); } @Override From 870d0835a570a17dd5c376e72a69bbc52019061f Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 11 Jan 2011 19:03:20 -0800 Subject: [PATCH 137/142] bug 7722: open vswitch - add entities to tunnel table/vlan mapping table when host connect, this make these tables lock free(for table lock) --- .../xen/resource/CitrixResourceBase.java | 2 +- .../com/cloud/network/ovs/OvsListener.java | 57 ++++++- .../network/ovs/OvsNetworkManagerImpl.java | 143 +++++++++--------- .../ovs/OvsVlanExhaustedException.java | 7 + .../cloud/network/ovs/dao/GreTunnelDao.java | 1 + .../network/ovs/dao/GreTunnelDaoImpl.java | 8 + .../cloud/network/ovs/dao/VlanMappingDao.java | 5 + .../cloud/network/ovs/dao/VlanMappingVO.java | 6 +- setup/db/create-schema.sql | 2 +- 9 files changed, 155 insertions(+), 76 deletions(-) create mode 100644 server/src/com/cloud/network/ovs/OvsVlanExhaustedException.java diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 2461b668bbd..ce63fd67fa6 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -532,7 +532,7 @@ public abstract class CitrixResourceBase implements ServerResource { } } - private Network setupvSwitchNetwork(Connection conn) { + private synchronized Network setupvSwitchNetwork(Connection conn) { try { if (_host.vswitchNetwork == null) { Network vswitchNw = null; diff --git a/server/src/com/cloud/network/ovs/OvsListener.java b/server/src/com/cloud/network/ovs/OvsListener.java index df31e6253b0..213edaf7b5f 100644 --- a/server/src/com/cloud/network/ovs/OvsListener.java +++ b/server/src/com/cloud/network/ovs/OvsListener.java @@ -1,8 +1,11 @@ package com.cloud.network.ovs; import java.util.HashSet; +import java.util.List; import java.util.Set; +import javax.persistence.EntityExistsException; + import org.apache.log4j.Logger; import com.cloud.agent.Listener; @@ -13,23 +16,33 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.PingRoutingWithOvsCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.exception.ConnectionException; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; +import com.cloud.host.dao.HostDao; import com.cloud.network.ovs.dao.GreTunnelDao; import com.cloud.network.ovs.dao.GreTunnelVO; import com.cloud.network.ovs.dao.OvsWorkDao; import com.cloud.network.ovs.dao.OvsWorkVO.Step; +import com.cloud.network.ovs.dao.VlanMappingDao; +import com.cloud.network.ovs.dao.VlanMappingVO; +import com.cloud.utils.component.Inject; public class OvsListener implements Listener { public static final Logger s_logger = Logger.getLogger(OvsListener.class.getName()); OvsNetworkManager _ovsNetworkMgr; OvsWorkDao _workDao; GreTunnelDao _tunnelDao; + VlanMappingDao _mappingDao; + HostDao _hostDao; - public OvsListener(OvsNetworkManager ovsMgr, OvsWorkDao workDao, GreTunnelDao tunnelDao) { + public OvsListener(OvsNetworkManager ovsMgr, OvsWorkDao workDao, GreTunnelDao tunnelDao, + VlanMappingDao mappingDao, HostDao hostDao) { this._ovsNetworkMgr = ovsMgr; this._workDao = workDao; this._tunnelDao = tunnelDao; + this._mappingDao = mappingDao; + this._hostDao = hostDao; } @Override @@ -111,6 +124,48 @@ public class OvsListener implements Listener { @Override public void processConnect(HostVO host, StartupCommand cmd) throws ConnectionException { + if (host.getType() != Host.Type.Routing) { + return; + } + + List maps = _mappingDao.listByHostId(host.getId()); + if (maps.size() == 0) { + for (int i=0; i<512; i++) { + VlanMappingVO vo = new VlanMappingVO(0, host.getId(), i); + _mappingDao.persist(vo); + } + } + + try { + List hosts = _hostDao.listByType(Host.Type.Routing); + for (HostVO h : hosts) { + if (h.getId() == host.getId()) { + continue; + } + + GreTunnelVO t = _tunnelDao.getByFromAndTo(host.getId(), h.getId()); + if (t == null) { + t = new GreTunnelVO(host.getId(), h.getId()); + try { + _tunnelDao.persist(t); + } catch (EntityExistsException e) { + s_logger.debug(String.format("Already has (from=%1$s, to=%2$s)", host.getId(), h.getId())); + } + } + + t = _tunnelDao.getByFromAndTo(h.getId(), host.getId()); + if (t == null) { + t = new GreTunnelVO(h.getId(), host.getId()); + try { + _tunnelDao.persist(t); + } catch (EntityExistsException e) { + s_logger.debug(String.format("Already has (from=%1$s, to=%2$s)", h.getId(), host.getId())); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } } @Override diff --git a/server/src/com/cloud/network/ovs/OvsNetworkManagerImpl.java b/server/src/com/cloud/network/ovs/OvsNetworkManagerImpl.java index 88466315989..da5dd3a6641 100644 --- a/server/src/com/cloud/network/ovs/OvsNetworkManagerImpl.java +++ b/server/src/com/cloud/network/ovs/OvsNetworkManagerImpl.java @@ -12,6 +12,7 @@ import java.util.concurrent.TimeUnit; import javax.ejb.Local; import javax.naming.ConfigurationException; +import javax.persistence.EntityExistsException; import org.apache.log4j.Logger; @@ -112,16 +113,9 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { _serverId = ((ManagementServer)ComponentLocator.getComponent(ManagementServer.Name)).getId(); _executorPool = Executors.newScheduledThreadPool(10, new NamedThreadFactory("OVS")); _cleanupExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("OVS-Cleanup")); - _ovsListener = new OvsListener(this, _workDao, _tunnelDao); + _ovsListener = new OvsListener(this, _workDao, _tunnelDao, _vlanMappingDao, _hostDao); _agentMgr.registerForHostEvents(_ovsListener, true, true, true); - //FIXME: - GreTunnelVO t = _tunnelDao.lockRow(new Long(1), true); - if (t == null) { - t = new GreTunnelVO(0, 0); - _tunnelDao.persist(t); - } - return true; } @@ -249,14 +243,13 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { } - //TODO: think about lock @DB - protected long askVlanId(long accountId, long hostId) { + protected long askVlanId(long accountId, long hostId) throws OvsVlanExhaustedException { assert _isEnabled : "Who call me ??? while OvsNetwokr is not enabled!!!"; final Transaction txn = Transaction.currentTxn(); txn.start(); - VlanMappingVO currVlan = _vlanMappingDao.findByAccountIdAndHostId(accountId, hostId); + VlanMappingVO currVlan = _vlanMappingDao.lockByAccountIdAndHostId(accountId, hostId); long vlan = 0; if (currVlan != null) { @@ -270,31 +263,35 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { } Listmappings = _vlanMappingDao.listByHostId(hostId); - if (mappings.size() > 0) { - ArrayList vlans = new ArrayList(); - for (VlanMappingVO vo : mappings) { - vlans.add(new Long(vo.getVlan())); - } - - // Find first available vlan - int i; - for (i=0; i<4096; i++) { - if (!vlans.contains(new Long(i))) { - vlan = i; + assert mappings.size() > 0: "where is my data!? it should be added when host connected!"; + + VlanMappingVO target = null; + for (VlanMappingVO vo : mappings) { + if (vo.getAccountId() == 0) { + target = _vlanMappingDao.lockRow(vo.getId(), true); + if (target == null || target.getAccountId() != 0) { + s_logger.debug("Someone took vlan mapping host = " + + vo.getHostId() + " vlan = " + vo.getVlan()); + continue; + } else { break; } } - assert i!=4096 : "Terrible, vlan exhausted on this server!!!"; } - VlanMappingVO newVlan = new VlanMappingVO(accountId, hostId, vlan); - _vlanMappingDao.persist(newVlan); + if (target == null) { + throw new OvsVlanExhaustedException("vlan exhausted on host " + hostId); + } + + target.setAccountId(accountId); + target.ref(); + _vlanMappingDao.update(target.getId(), target); _vlanMappingDirtyDao.markDirty(accountId); String s = String.format("allocate a new vlan %1$s(account:%2$s, hostId:%3$s), mark dirty", vlan, accountId, hostId); s_logger.debug("OVSDIRTY:" + s); txn.commit(); - return vlan; + return target.getVlan(); } @DB @@ -309,49 +306,51 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { return; } + final Transaction txn = Transaction.currentTxn(); long hostId = dest.getHost().getId(); long accountId = instance.getAccountId(); - - final Transaction txn = Transaction.currentTxn(); - txn.start(); //TODO: considerate router? Listvms = _userVmDao.listByAccountId(accountId); + DomainRouterVO router = _routerDao.findBy(accountId, instance.getDataCenterId()); + Listins = new ArrayList(); + ins.addAll(vms); + ins.add(router); ListtoHostIds = new ArrayList(); ListfromHostIds = new ArrayList(); - GreTunnelVO tvo = _tunnelDao.acquireInLockTable(new Long(1)); - if (tvo == null) { - throw new GreTunnelException("can't lock gre tunnel table for: from=" + hostId); - } - for (UserVmVO v : vms) { + for (VMInstanceVO v : ins) { Long rh = v.getHostId(); if (rh == null || rh.longValue() == hostId) { continue; } - GreTunnelVO tunnel = _tunnelDao.getByFromAndTo(hostId, rh.longValue()); + txn.start(); + GreTunnelVO tunnel = _tunnelDao.lockByFromAndTo(hostId, + rh.longValue()); + txn.commit(); if (tunnel == null) { - tunnel = new GreTunnelVO(hostId, rh.longValue()); - _tunnelDao.persist(tunnel); - - if (!toHostIds.contains(rh)) { - toHostIds.add(rh); - } + throw new GreTunnelException(String.format( + "No entity(from=%1$s, to=%2$s) of failed to lock", + hostId, rh.longValue())); + } + + if (tunnel.getInPort() == 0 && !toHostIds.contains(rh)) { + toHostIds.add(rh); } - tunnel = _tunnelDao.getByFromAndTo(rh.longValue(), hostId); + txn.start(); + tunnel = _tunnelDao.lockByFromAndTo(rh.longValue(), hostId); + txn.commit(); if (tunnel == null) { - tunnel = new GreTunnelVO(rh.longValue(), hostId); - _tunnelDao.persist(tunnel); - - if (!fromHostIds.contains(rh)) { - fromHostIds.add(rh); - } - } - + throw new GreTunnelException(String.format( + "No entity(from=%1$s, to=%2$s) of failed to lock", + rh.longValue(), hostId)); + } + + if (tunnel.getInPort() == 0 && !fromHostIds.contains(rh)) { + fromHostIds.add(rh); + } } - _tunnelDao.releaseFromLockTable(new Long(1)); - txn.commit(); try { String myIp = dest.getHost().getPrivateIpAddress(); @@ -381,11 +380,9 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { if (tunnels.size() == 0) { return "[]"; } else { - Transaction txn = Transaction.currentTxn(); - txn.start(); List maps = new ArrayList(); for (GreTunnelVO t : tunnels) { - VlanMappingVO m = _vlanMappingDao.lockByAccountIdAndHostId(accountId, t.getTo()); + VlanMappingVO m = _vlanMappingDao.findByAccountIdAndHostId(accountId, t.getTo()); if (m == null) { s_logger.debug("Host " + t.getTo() + " has no VM for account " + accountId + ", skip it"); continue; @@ -393,7 +390,7 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { String s = String.format("%1$s:%2$s", m.getVlan(), t.getInPort()); maps.add(s); } - txn.commit(); + return maps.toString(); } } @@ -409,17 +406,21 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { && vmType != VirtualMachine.Type.DomainRouter) { return; } - - long hostId = instance.getHostId(); - long accountId = instance.getAccountId(); - String tag = Long.toString(askVlanId(accountId, hostId)); - CheckAndUpdateDhcpFlow(instance); - String vlans = getVlanInPortMapping(accountId, hostId); - VmFlowLogVO log = _flowLogDao.findOrNewByVmId(instance.getId(), - instance.getName()); - cmds.addCommand(new OvsSetTagAndFlowCommand(instance.getName(), tag, - vlans, Long.toString(log.getLogsequence()), instance.getId())); + try { + long hostId = instance.getHostId(); + long accountId = instance.getAccountId(); + String tag = Long.toString(askVlanId(accountId, hostId)); + CheckAndUpdateDhcpFlow(instance); + String vlans = getVlanInPortMapping(accountId, hostId); + VmFlowLogVO log = _flowLogDao.findOrNewByVmId(instance.getId(), + instance.getName()); + cmds.addCommand(new OvsSetTagAndFlowCommand(instance.getName(), + tag, vlans, Long.toString(log.getLogsequence()), instance + .getId())); + } catch (OvsVlanExhaustedException e) { + e.printStackTrace(); + } } //FIXME: if router has record in database but not start, this will hang 10 secs due to host @@ -444,9 +445,8 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { } try { - String tag = Long.toString(_vlanMappingDao.findByAccountIdAndHostId(accountId, - router.getHostId()).getVlan()); long hostId = router.getHostId(); + String tag = Long.toString(_vlanMappingDao.findByAccountIdAndHostId(accountId, hostId).getVlan()); VmFlowLogVO log = _flowLogDao.findOrNewByVmId(instance.getId(), instance.getName()); String vlans = getVlanInPortMapping(accountId, hostId); s_logger.debug("ask router " + router.getName() + " on host " @@ -551,7 +551,6 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { s_logger.debug("OVSDIRTY:Clean dirty for account " + instance.getAccountId()); } - //TODO: think about lock @DB protected void checkAndRemove(VMInstanceVO instance) { long accountId = instance.getAccountId(); @@ -559,20 +558,20 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager { final Transaction txn = Transaction.currentTxn(); txn.start(); - VlanMappingVO vo = _vlanMappingDao.findByAccountIdAndHostId(accountId, hostId); + VlanMappingVO vo = _vlanMappingDao.lockByAccountIdAndHostId(accountId, hostId); assert vo!=null: "Why there is no record for account " + accountId + " host " + hostId; if (vo.unref() == 0) { - _vlanMappingDao.remove(vo.getId()); + vo.setAccountId(0); _vlanMappingDirtyDao.markDirty(accountId); String s = String.format("%1$s is the last VM(host:%2$s, accountId:%3$s), remove vlan", instance.getName(), hostId, accountId); s_logger.debug("OVSDIRTY:" + s); } else { - _vlanMappingDao.update(vo.getId(), vo); s_logger.debug(instance.getName() + " reduces reference count of (account,host) = (" + accountId + "," + hostId + ") to " + vo.getRef()); } + _vlanMappingDao.update(vo.getId(), vo); _flowLogDao.deleteByVmId(instance.getId()); txn.commit(); diff --git a/server/src/com/cloud/network/ovs/OvsVlanExhaustedException.java b/server/src/com/cloud/network/ovs/OvsVlanExhaustedException.java new file mode 100644 index 00000000000..fcf9e6dad4d --- /dev/null +++ b/server/src/com/cloud/network/ovs/OvsVlanExhaustedException.java @@ -0,0 +1,7 @@ +package com.cloud.network.ovs; + +public class OvsVlanExhaustedException extends Exception { + public OvsVlanExhaustedException(String msg) { + super(msg); + } +} diff --git a/server/src/com/cloud/network/ovs/dao/GreTunnelDao.java b/server/src/com/cloud/network/ovs/dao/GreTunnelDao.java index 753c70fcac2..2faa31e6af6 100644 --- a/server/src/com/cloud/network/ovs/dao/GreTunnelDao.java +++ b/server/src/com/cloud/network/ovs/dao/GreTunnelDao.java @@ -7,4 +7,5 @@ import com.cloud.utils.db.GenericDao; public interface GreTunnelDao extends GenericDao { List getByFrom(long from); GreTunnelVO getByFromAndTo(long from, long To); + GreTunnelVO lockByFromAndTo(long from, long to); } diff --git a/server/src/com/cloud/network/ovs/dao/GreTunnelDaoImpl.java b/server/src/com/cloud/network/ovs/dao/GreTunnelDaoImpl.java index 6caa68674c5..05a6c4b94d7 100644 --- a/server/src/com/cloud/network/ovs/dao/GreTunnelDaoImpl.java +++ b/server/src/com/cloud/network/ovs/dao/GreTunnelDaoImpl.java @@ -40,5 +40,13 @@ public class GreTunnelDaoImpl extends GenericDaoBase sc.setParameters("to", to); return findOneBy(sc); } + + @Override + public GreTunnelVO lockByFromAndTo(long from, long to) { + SearchCriteria sc = fromToSearch.create(); + sc.setParameters("from", from); + sc.setParameters("to", to); + return lockOneRandomRow(sc, true); + } } diff --git a/server/src/com/cloud/network/ovs/dao/VlanMappingDao.java b/server/src/com/cloud/network/ovs/dao/VlanMappingDao.java index d74bd3e41a4..fe5a58d3707 100644 --- a/server/src/com/cloud/network/ovs/dao/VlanMappingDao.java +++ b/server/src/com/cloud/network/ovs/dao/VlanMappingDao.java @@ -6,9 +6,14 @@ import com.cloud.utils.db.GenericDao; public interface VlanMappingDao extends GenericDao { List listByAccountIdAndHostId(long accountId, long hostId); + List listByHostId(long hostId); + List listByAccountId(long accountId); + List lockByAccountId(long accoutnId); + VlanMappingVO findByAccountIdAndHostId(long accountId, long hostId); + VlanMappingVO lockByAccountIdAndHostId(long accountId, long hostId); } diff --git a/server/src/com/cloud/network/ovs/dao/VlanMappingVO.java b/server/src/com/cloud/network/ovs/dao/VlanMappingVO.java index 3376c05e465..487bfb1153d 100644 --- a/server/src/com/cloud/network/ovs/dao/VlanMappingVO.java +++ b/server/src/com/cloud/network/ovs/dao/VlanMappingVO.java @@ -31,7 +31,7 @@ public class VlanMappingVO { this.hostId = hostId; this.accountId = accountId; this.vlan = vlan; - this.ref = 1; + this.ref = 0; } public VlanMappingVO() { @@ -45,6 +45,10 @@ public class VlanMappingVO { public long getAccountId() { return accountId; } + + public void setAccountId(long accountId) { + this.accountId = accountId; + } public long getVlan() { return vlan; diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 1c86fce46b8..7ca67a16387 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -1354,7 +1354,7 @@ CREATE TABLE `cloud`.`ovs_tunnel_alloc`( `from` bigint unsigned COMMENT 'from host id', `to` bigint unsigned COMMENT 'to host id', `in_port` int unsigned COMMENT 'in port on open vswitch', - PRIMARY KEY(`id`) + PRIMARY KEY(`from`, `to`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`ovs_vlan_mapping_dirty`( From 5b4f410621a4b7fbea90f580372981fae95281fc Mon Sep 17 00:00:00 2001 From: will Date: Tue, 11 Jan 2011 19:08:08 -0800 Subject: [PATCH 138/142] bug 7803: Fixed vm wizard to accomodate the new defaulted networks. The only case that doesn't work yet is when the virtual network is "unavailable". Need to fix that still. --- ui/jsp/instance.jsp | 87 +++++++++++-------------------- ui/scripts/cloud.core.instance.js | 77 ++++++++++++++++++--------- 2 files changed, 83 insertions(+), 81 deletions(-) diff --git a/ui/jsp/instance.jsp b/ui/jsp/instance.jsp index 18060798963..2442cd37fce 100644 --- a/ui/jsp/instance.jsp +++ b/ui/jsp/instance.jsp @@ -354,9 +354,25 @@
    - + + + +