diff --git a/core/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/core/src/com/cloud/storage/dao/VMTemplateDaoImpl.java index 70e195d4b6d..fe63f235d74 100644 --- a/core/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/core/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -198,7 +198,12 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem accountType = Account.ACCOUNT_TYPE_ADMIN; } - String sql = SELECT_ALL; + String guestOSJoin = ""; + if (isIso) { + guestOSJoin = " INNER JOIN guest_os guestOS on (guestOS.id = t.guest_os_id) INNER JOIN guest_os_hypervisor goh on ( goh.guest_os_id = guestOS.id) "; + } + + String sql = SELECT_ALL + guestOSJoin; String whereClause = ""; if (templateFilter == TemplateFilter.featured) { @@ -277,7 +282,9 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem if (isIso) { sql += " t.format = 'ISO'"; - /*TODO: need to add filter for guest os*/ + if (!hyperType.equals(HypervisorType.None)) { + sql += " AND goh.hypervisor_type = '" + hyperType.toString() + "'"; + } } else { sql += " t.format <> 'ISO'"; if (!hyperType.equals(HypervisorType.None)) { diff --git a/python/incubation/cloud-web-ipallocator b/python/incubation/cloud-web-ipallocator.py similarity index 99% rename from python/incubation/cloud-web-ipallocator rename to python/incubation/cloud-web-ipallocator.py index 3a278d29e56..533acfc4eab 100755 --- a/python/incubation/cloud-web-ipallocator +++ b/python/incubation/cloud-web-ipallocator.py @@ -101,6 +101,8 @@ class dhcp: save"""%(path) augtool < script + self.availIP.remove(ip) + #reset dnsmasq service("dnsmasq", "restart", stdout=None, stderr=None) diff --git a/python/tools/externalIpAllocator/bindir/cloud-external-ipallocator b/python/tools/externalIpAllocator/bindir/cloud-external-ipallocator new file mode 100755 index 00000000000..533acfc4eab --- /dev/null +++ b/python/tools/externalIpAllocator/bindir/cloud-external-ipallocator @@ -0,0 +1,138 @@ +#! /usr/bin/python +import web +import socket, struct +import cloud_utils +from cloud_utils import Command +urls = ("/ipallocator", "ipallocator") +app = web.application(urls, globals()) + +augtool = Command("augtool") +service = Command("service") +class dhcp: + _instance = None + def __init__(self): + self.availIP=[] + self.router=None + self.netmask=None + self.initialized=False + + options = augtool.match("/files/etc/dnsmasq.conf/dhcp-option").stdout.strip() + for option in options.splitlines(): + if option.find("option:router") != -1: + self.router = option.split("=")[1].strip().split(",")[1] + print self.router + + dhcp_range = augtool.get("/files/etc/dnsmasq.conf/dhcp-range").stdout.strip() + dhcp_start = dhcp_range.split("=")[1].strip().split(",")[0] + dhcp_end = dhcp_range.split("=")[1].strip().split(",")[1] + self.netmask = dhcp_range.split("=")[1].strip().split(",")[2] + print dhcp_start, dhcp_end, self.netmask + + start_ip_num = self.ipToNum(dhcp_start); + end_ip_num = self.ipToNum(dhcp_end) + print start_ip_num, end_ip_num + + for ip in range(start_ip_num, end_ip_num + 1): + self.availIP.append(ip) + print self.availIP[0], self.availIP[len(self.availIP) - 1] + + #load the ip already allocated + self.reloadAllocatedIP() + + def ipToNum(self, ip): + return struct.unpack("!I", socket.inet_aton(ip))[0] + + def numToIp(self, num): + return socket.inet_ntoa(struct.pack('!I', num)) + + def getFreeIP(self): + if len(self.availIP) > 0: + ip = self.numToIp(self.availIP[0]) + self.availIP.remove(self.availIP[0]) + return ip + else: + return None + + def getNetmask(self): + return self.netmask + + def getRouter(self): + return self.router + + def getInstance(): + if not dhcp._instance: + dhcp._instance = dhcp() + return dhcp._instance + getInstance = staticmethod(getInstance) + + def reloadAllocatedIP(self): + dhcp_hosts = augtool.match("/files/etc/dnsmasq.conf/dhcp-host").stdout.strip().splitlines() + + for host in dhcp_hosts: + if host.find("dhcp-host") != -1: + allocatedIP = self.ipToNum(host.split("=")[1].strip().split(",")[1]) + if allocatedIP in self.availIP: + self.availIP.remove(allocatedIP) + + def allocateIP(self, mac): + newIP = self.getFreeIP() + dhcp_host = augtool.match("/files/etc/dnsmasq.conf/dhcp-host").stdout.strip() + cnt = len(dhcp_host.splitlines()) + 1 + script = """set %s %s + save"""%("/files/etc/dnsmasq.conf/dhcp-host[" + str(cnt) + "]", str(mac) + "," + newIP) + augtool < script + #reset dnsmasq + service("dnsmasq", "restart", stdout=None, stderr=None) + return newIP + + def releaseIP(self, ip): + dhcp_host = augtool.match("/files/etc/dnsmasq.conf/dhcp-host").stdout.strip() + path = None + for host in dhcp_host.splitlines(): + if host.find(ip) != -1: + path = host.split("=")[0].strip() + + if path == None: + print "Can't find " + str(ip) + " in conf file" + return None + + print path + script = """rm %s + save"""%(path) + augtool < script + + self.availIP.remove(ip) + + #reset dnsmasq + service("dnsmasq", "restart", stdout=None, stderr=None) + +class ipallocator: + def GET(self): + try: + user_data = web.input() + command = user_data.command + print "Processing: " + command + + dhcpInit = dhcp.getInstance() + + if command == "getIpAddr": + mac = user_data.mac + zone_id = user_data.dc + pod_id = user_data.pod + print mac, zone_id, pod_id + freeIP = dhcpInit.allocateIP(mac) + if not freeIP: + return "0,0,0" + print "Find an available IP: " + freeIP + + return freeIP + "," + dhcpInit.getNetmask() + "," + dhcpInit.getRouter() + elif command == "releaseIpAddr": + ip = user_data.ip + zone_id = user_data.dc + pod_id = user_data.pod + dhcpInit.releaseIP(ip) + except: + return None + +if __name__ == "__main__": + app.run() diff --git a/python/tools/externalIpAllocator/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-external-ipallocator.in b/python/tools/externalIpAllocator/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-external-ipallocator.in new file mode 100755 index 00000000000..c7f5d501f6d --- /dev/null +++ b/python/tools/externalIpAllocator/distro/centos/SYSCONFDIR/rc.d/init.d/cloud-external-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 +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 + diff --git a/python/tools/externalIpAllocator/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-external-ipallocator.in b/python/tools/externalIpAllocator/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-external-ipallocator.in new file mode 100755 index 00000000000..c7f5d501f6d --- /dev/null +++ b/python/tools/externalIpAllocator/distro/fedora/SYSCONFDIR/rc.d/init.d/cloud-external-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 +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 + diff --git a/python/tools/externalIpAllocator/distro/ubuntu/SYSCONFDIR/init.d/cloud-external-ipallocator.in b/python/tools/externalIpAllocator/distro/ubuntu/SYSCONFDIR/init.d/cloud-external-ipallocator.in new file mode 100755 index 00000000000..bd6af9c5831 --- /dev/null +++ b/python/tools/externalIpAllocator/distro/ubuntu/SYSCONFDIR/init.d/cloud-external-ipallocator.in @@ -0,0 +1,96 @@ +#!/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 + +. /lib/lsb/init-functions +. /etc/default/rcS + +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@/default/"$SHORTNAME" ] && source @SYSCONFDIR@/default/"$SHORTNAME" +DAEMONIZE=@BINDIR@/@PACKAGE@-daemonize +PROG=@BINDIR@/@PACKAGE@-external-ipallocator +OPTIONS=8083 + +start() { + log_daemon_msg $"Starting $PROGNAME" "$SHORTNAME" + if [ -s "$PIDFILE" ] && kill -0 $(cat "$PIDFILE") >/dev/null 2>&1; then + log_progress_msg "apparently already running" + log_end_msg 0 + exit 0 + fi + if hostname --fqdn >/dev/null 2>&1 ; then + true + else + log_failure_msg "The host name does not resolve properly to an IP address. Cannot start $PROGNAME" + log_end_msg 1 + exit 1 + fi + + if start-stop-daemon --start --quiet \ + --pidfile "$PIDFILE" \ + --exec "$DAEMONIZE" -- -n "$SHORTNAME" -p "$PIDFILE" -l "$LOGFILE" "$PROG" $OPTIONS + RETVAL=$? + then + rc=0 + sleep 1 + if ! kill -0 $(cat "$PIDFILE") >/dev/null 2>&1; then + log_failure_msg "$PROG failed to start" + rc=1 + fi + else + rc=1 + fi + + if [ $rc -eq 0 ]; then + log_end_msg 0 + else + log_end_msg 1 + rm -f "$PIDFILE" + fi +} + +stop() { + echo -n $"Stopping $PROGNAME" "$SHORTNAME" + start-stop-daemon --stop --quiet --oknodo --pidfile "$PIDFILE" + log_end_msg $? + rm -f "$PIDFILE" +} + + +# See how we were called. +case "$1" in + start) + start + ;; + stop) + stop + ;; + status) + status_of_proc -p "$PIDFILE" "$PROG" "$SHORTNAME" + RETVAL=$? + ;; + restart) + stop + sleep 3 + start + ;; + *) + echo $"Usage: $whatami {start|stop|restart|status|help}" + RETVAL=3 +esac + +exit $RETVAL + diff --git a/server/src/com/cloud/api/commands/CreateVolumeCmd.java b/server/src/com/cloud/api/commands/CreateVolumeCmd.java index ca49e6b45f8..b4cc8c2a4c3 100644 --- a/server/src/com/cloud/api/commands/CreateVolumeCmd.java +++ b/server/src/com/cloud/api/commands/CreateVolumeCmd.java @@ -50,7 +50,6 @@ public class CreateVolumeCmd extends BaseCmd { s_properties.add(new Pair(BaseCmd.Properties.DISK_OFFERING_ID, Boolean.FALSE)); s_properties.add(new Pair(BaseCmd.Properties.SNAPSHOT_ID, Boolean.FALSE)); s_properties.add(new Pair(BaseCmd.Properties.SIZE, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.HYPERVISOR_TYPE, Boolean.FALSE)); } public String getName() { diff --git a/server/src/com/cloud/api/commands/DeployVMCmd.java b/server/src/com/cloud/api/commands/DeployVMCmd.java index c669efa99ac..f364d760ac0 100644 --- a/server/src/com/cloud/api/commands/DeployVMCmd.java +++ b/server/src/com/cloud/api/commands/DeployVMCmd.java @@ -28,11 +28,13 @@ import com.cloud.api.BaseCmd; import com.cloud.api.ServerApiException; import com.cloud.async.executor.DeployVMResultObject; import com.cloud.dc.DataCenterVO; +import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.security.NetworkGroupVO; import com.cloud.serializer.SerializerHelper; import com.cloud.server.ManagementServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.VMTemplateVO; import com.cloud.user.Account; import com.cloud.utils.Pair; @@ -56,7 +58,8 @@ public class DeployVMCmd extends BaseCmd { s_properties.add(new Pair(BaseCmd.Properties.USER_ID, Boolean.FALSE)); s_properties.add(new Pair(BaseCmd.Properties.DOMAIN_ID, Boolean.FALSE)); s_properties.add(new Pair(BaseCmd.Properties.NETWORK_GROUP_LIST, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.SIZE, Boolean.FALSE)); + s_properties.add(new Pair(BaseCmd.Properties.SIZE, Boolean.FALSE)); + s_properties.add(new Pair(BaseCmd.Properties.HYPERVISOR, Boolean.FALSE)); } @Override @@ -87,7 +90,9 @@ public class DeployVMCmd extends BaseCmd { String group = (String)params.get(BaseCmd.Properties.GROUP.getName()); String userData = (String) params.get(BaseCmd.Properties.USER_DATA.getName()); String networkGroupList = (String)params.get(BaseCmd.Properties.NETWORK_GROUP_LIST.getName()); - Long size = (Long)params.get(BaseCmd.Properties.SIZE.getName()); + Long size = (Long)params.get(BaseCmd.Properties.SIZE.getName()); + HypervisorType hyperType = HypervisorType.getType((String)params.get(BaseCmd.Properties.HYPERVISOR.getName())); + String password = null; Long accountId = null; @@ -101,6 +106,11 @@ public class DeployVMCmd extends BaseCmd { VMTemplateVO template = getManagementServer().findTemplateById(templateId); if (template == null) { throw new ServerApiException(BaseCmd.VM_INVALID_PARAM_ERROR, "Unable to find template with id " + templateId); + } + + if (template.getFormat().equals(ImageFormat.ISO)) { + /*TODO:Hack here*/ + template.setHypervisorType(HypervisorType.VmWare); } if (diskOfferingId != null) { diff --git a/server/src/com/cloud/api/commands/ListIsosCmd.java b/server/src/com/cloud/api/commands/ListIsosCmd.java index 2f6081cb384..1148383aaba 100644 --- a/server/src/com/cloud/api/commands/ListIsosCmd.java +++ b/server/src/com/cloud/api/commands/ListIsosCmd.java @@ -61,7 +61,7 @@ public class ListIsosCmd extends BaseCmd { s_properties.add(new Pair(BaseCmd.Properties.PAGESIZE, Boolean.FALSE)); s_properties.add(new Pair(BaseCmd.Properties.ZONE_ID, Boolean.FALSE)); /*Filter out the guest OSes are not supported by the hypervisor*/ - s_properties.add(new Pair(BaseCmd.Properties.HYPERVISOR_TYPE, Boolean.FALSE)); + s_properties.add(new Pair(BaseCmd.Properties.HYPERVISOR, Boolean.FALSE)); } @@ -87,7 +87,7 @@ public class ListIsosCmd extends BaseCmd { Boolean bootable = (Boolean)params.get(BaseCmd.Properties.BOOTABLE.getName()); String keyword = (String)params.get(BaseCmd.Properties.KEYWORD.getName()); Long zoneId = (Long)params.get(BaseCmd.Properties.ZONE_ID.getName()); - HypervisorType hyperType = HypervisorType.getType((String)params.get(BaseCmd.Properties.HYPERVISOR_TYPE.getName())); + HypervisorType hyperType = HypervisorType.getType((String)params.get(BaseCmd.Properties.HYPERVISOR.getName())); boolean isAdmin = false;