diff --git a/api/src/com/cloud/hypervisor/HypervisorGuru.java b/api/src/com/cloud/hypervisor/HypervisorGuru.java new file mode 100644 index 00000000000..4768ee34ca8 --- /dev/null +++ b/api/src/com/cloud/hypervisor/HypervisorGuru.java @@ -0,0 +1,28 @@ +/** + * 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.hypervisor; + +import com.cloud.offering.ServiceOffering; +import com.cloud.utils.component.Adapter; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineProfile; + +public interface HypervisorGuru extends Adapter { + VirtualMachineProfile design(VirtualMachine vm, ServiceOffering offering); + boolean check(VirtualMachineProfile profile); +} diff --git a/api/src/com/cloud/vm/NicProfile.java b/api/src/com/cloud/vm/NicProfile.java index 621472723ea..98ae97da09e 100644 --- a/api/src/com/cloud/vm/NicProfile.java +++ b/api/src/com/cloud/vm/NicProfile.java @@ -29,6 +29,12 @@ public class NicProfile { URI broadcastUri; ReservationStrategy strategy; String reservationId; + boolean defaultNic; + Integer deviceId; + + public boolean isDefaultNic() { + return defaultNic; + } public String getNetmask() { return netmask; @@ -54,6 +60,10 @@ public class NicProfile { return isolationUri; } + public void setStrategy(ReservationStrategy strategy) { + this.strategy = strategy; + } + public BroadcastDomainType getType() { return broadcastType; } @@ -69,6 +79,18 @@ public class NicProfile { public void setVmId(long vmId) { this.vmId = vmId; } + + public void setDeviceId(int deviceId) { + this.deviceId = deviceId; + } + + public void setDefaultNic(boolean defaultNic) { + this.defaultNic = defaultNic; + } + + public Integer getDeviceId() { + return deviceId; + } public void setGateway(String gateway) { this.gateway = gateway; @@ -142,7 +164,7 @@ public class NicProfile { this.ip4Address = ip4Address; } - public NicProfile(Nic nic, NetworkConfiguration network) { + public NicProfile(Nic nic, NetworkConfiguration network, URI broadcastUri, URI isolationUri) { this.id = nic.getId(); this.gateway = network.getGateway(); this.mode = network.getMode(); @@ -171,6 +193,9 @@ public class NicProfile { this.netmask = netmask; this.strategy = strategy; } + + public NicProfile() { + } public ReservationStrategy getReservationStrategy() { return strategy; diff --git a/api/src/com/cloud/vm/VirtualMachineProfile.java b/api/src/com/cloud/vm/VirtualMachineProfile.java index 4da120f75cb..a675ab42451 100644 --- a/api/src/com/cloud/vm/VirtualMachineProfile.java +++ b/api/src/com/cloud/vm/VirtualMachineProfile.java @@ -25,8 +25,8 @@ import com.cloud.offering.ServiceOffering; public class VirtualMachineProfile { VirtualMachine _vm; - int _cpus; - int _speed; // in mhz + Integer _cpus; + Integer _speed; // in mhz long _ram; // in bytes HypervisorType _hypervisorType; VirtualMachine.Type _type; @@ -34,11 +34,20 @@ public class VirtualMachineProfile { Long _templateId; List _disks; List _nics; + String _os; public VirtualMachineProfile(VirtualMachine.Type type) { this._type = type; } + public String getName() { + return _vm.getInstanceName(); + } + + public String getOs() { + return _os; + } + public long getId() { return _vm.getId(); } @@ -51,11 +60,11 @@ public class VirtualMachineProfile { return _templateId; } - public int getCpus() { + public Integer getCpus() { return _cpus; } - public int getSpeed() { + public Integer getSpeed() { return _speed; } @@ -96,13 +105,14 @@ public class VirtualMachineProfile { this._templateId = templateId; } - public VirtualMachineProfile(VirtualMachine vm, ServiceOffering offering) { + public VirtualMachineProfile(VirtualMachine vm, ServiceOffering offering, String os) { this._cpus = offering.getCpu(); this._speed = offering.getSpeed(); this._ram = offering.getRamSize(); this._templateId = vm.getTemplateId(); this._type = vm.getType(); this._vm = vm; + this._os = os; } protected VirtualMachineProfile() { diff --git a/client/WEB-INF/classes/resources/resource.properties b/client/WEB-INF/classes/resources/resource.properties index e9f563a5947..ac6bb99774a 100644 --- a/client/WEB-INF/classes/resources/resource.properties +++ b/client/WEB-INF/classes/resources/resource.properties @@ -1,22 +1,62 @@ +actions = Actions +add = Add +help = Help +advanced = Advanced +version = Version + +dashboard = Dashboard +instance = Instance +router = Router +storage = Storage +volume = Volume +snapshot = Snapshot +ip.address = IP Address +template = Template +my.template = My Template +featured.template = Featured Template +community.template = Community Template +iso = ISO +my.iso = My ISO +featured.iso = Featured ISO +community.iso = Community ISO +account = Account +domain = Domain +event = Event +alert = Alert + + + +name = Name +display.text = Display Text +os.type = OS Type +public = Public +instance.name = Instance Name +group.name = Group Name +service.offering = Service Offering +password.enabled = Password Enabled +instance.limit = Instance Limit +public.ip.limit = Public IP Limit +disk.volume.limit = Disk Volume Limit +snapshot.limit = Snapshot Limit +template.limit = Template Limit +URL = URL +zone = Zone +bootable = Bootable +group = Group + +disk.offering = Disk Offering +copy.ISO.to = Copy ISO to +no.available.iso = No Available ISO + your.session.has.expired = Your session has expired internet.name.can.not.be.resolved = Internet name can not be resolved management.server.is.not.accessible = Management server is not accessible please.confirm.you.want.to.detach.an.iso.from.the.virtual.machine = Please confirm you want to detach an ISO from the virtual machine please.specify.the.iso.you.wish.to.attach.to.virtual.machine = Please specify the ISO you wish to attach to virtual instance -iso = ISO -no.available.iso = No Available ISO please.specify.the.new.name.you.want.to.change.for.the.virtual.machine = Please specify the new name you want to change for the virtual instance -instance.name = Instance Name please.specify.the.new.group.you.want.to.assign.the.virtual.machine.to = Please specify the new group you want to assign the virtual machine to -group.name = Group Name after.changing.service.offering.you.must.restart.the.virtual.machine.for.new.service.offering.to.take.effect = After changing service offering, you must restart the virtual machine for the new service offering to take effect. -service.offering = Service Offering creating.a.template.of.disk.volume.could.take.up.to.several.hours.depending.on.the.size.of.the.disk.volume = Creating a template of disk volume could take up to several hours depending on the size of the disk volume -name = Name -display.text = Display Text -os.type = OS Type -public = Public -password.enabled = Password Enabled please.confirm.you.want.to.change.the.root.password.for.the.virtual.machine = Please confirm you want to change the ROOT password for the virtual machine please.confirm.you.want.to.enable.HA.for.your.virtual.machine.once.HA.is.enabled.your.virtual.machine.will.be.automatically.restarted.in.the.event.it.is.detected.to.have.failed = Please confirm you want to enable HA for your virtual machine. Once HA is enabled, your virtual machine will be automatically restarted in the event it is detected to have failed. please.confirm.you.want.to.disable.HA.for.the.virtual.machine.once.HA.is.disabled.the.virtual.machine.will.no.longer.be.automatically.restarted.in.the.event.of.a.failure = Please confirm you want to disable HA for the virtual machine. Once HA is disabled, the virtual machine will no longer be be automatically restarted in the event of a failure. @@ -25,19 +65,9 @@ please.confirm.you.want.to.delete.the.ISO = Please confirm you want to delete th the.template.is.used.by.all.zones.please.confirm.you.want.to.delete.it.from.all.zones = The template is used by all zones. Please confirm you want to delete it from all zones. please.confirm.you.want.to.delete.the.template = Please confirm you want to delete the template please.specify.limits.to.the.various.resources.-1.means.the.resource.has.no.limits = Please specify limits to the various resources. -1 means the resource has no limits. -instance.limit = Instance Limit -public.ip.limit = Public IP Limit -disk.volume.limit = Disk Volume Limit -snapshot.limit = Snapshot Limit -template.limit = Template Limit please.confirm.you.want.to.disable.account.that.will.prevent.account.access.to.the.cloud.and.shut.down.all.existing.virtual.machines = Please confirm you want to disable account that will prevent account access to the cloud and shut down all existing virtual machines. please.confirm.you.want.to.lock.account.that.will.prevent.account.access.to.the.cloud = Please confirm you want to lock account that will prevent account access to the cloud. please.confirm.you.want.to.enable.account = Please confirm you want to enable account. -URL = URL -zone = Zone -bootable = Bootable -group = Group -disk.offering = Disk Offering -copy.ISO.to = Copy ISO to + diff --git a/client/WEB-INF/classes/resources/resource_zh.properties b/client/WEB-INF/classes/resources/resource_zh.properties index 307334f028f..44c50ef43ca 100644 --- a/client/WEB-INF/classes/resources/resource_zh.properties +++ b/client/WEB-INF/classes/resources/resource_zh.properties @@ -1,3 +1,29 @@ +actions = 功能 +add = 增加 +help = 幫助 +advanced = 進階 +version = 版本 + +dashboard = 儀器板 +instance = 實例 +router = 路由器 +storage = 貯藏 +volume = 容積 +snapshot = 快照 +ip.address = 網路地址 +template = 模板 +my.template = 我的模板 +featured.template = 特色模板 +community.template = 共有模板 +iso = 空白模板 +my.iso = 我的空白模板 +featured.iso = 特色空白模板 +community.iso = 共有空白模板 +account = 帳戶 +domain = 領土 +event = 事件 +alert = 警報 + Details = 詳述 Volume = 容積 Statistics = 統計 @@ -7,7 +33,6 @@ Service = 服務 HA = 高的可用性 Created = 產生日期 Account = 帳戶 -Domain = 領土 Host = 主機 ISO = 空白模板 diff --git a/core/src/com/cloud/agent/api/Start2Command.java b/core/src/com/cloud/agent/api/Start2Command.java index 4414b888d44..c670aef8e64 100644 --- a/core/src/com/cloud/agent/api/Start2Command.java +++ b/core/src/com/cloud/agent/api/Start2Command.java @@ -12,51 +12,15 @@ public class Start2Command extends Command { return vm; } - /* - long id; - String guestIpAddress; - String gateway; - int ramSize; - String imagePath; - String guestNetworkId; - String guestMacAddress; - String vncPassword; - String externalVlan; - String externalMacAddress; - int utilization; - int cpuWeight; - int cpu; - int networkRateMbps; - int networkRateMulticastMbps; - String hostName; - String arch; - String isoPath; - boolean bootFromISO; - String guestOSDescription; - - ---->console proxy - private ConsoleProxyVO proxy; - private int proxyCmdPort; - private String vncPort; - private String urlPort; - private String mgmt_host; - private int mgmt_port; - private boolean sslEnabled; - - ----->abstract - protected String vmName; - protected String storageHosts[] = new String[2]; - protected List volumes; - protected boolean mirroredVols = false; - protected BootloaderType bootloader = BootloaderType.PyGrub; - - */ - @Override public boolean executeInSequence() { return true; } - public Start2Command() { + protected Start2Command() { + } + + public Start2Command(VirtualMachineTO vm) { + this.vm = vm; } } diff --git a/core/src/com/cloud/agent/api/to/NetworkTO.java b/core/src/com/cloud/agent/api/to/NetworkTO.java index d6e428831f3..009fc1df7b6 100644 --- a/core/src/com/cloud/agent/api/to/NetworkTO.java +++ b/core/src/com/cloud/agent/api/to/NetworkTO.java @@ -17,6 +17,8 @@ */ package com.cloud.agent.api.to; +import java.net.URI; + import com.cloud.network.Network.BroadcastDomainType; import com.cloud.network.Network.TrafficType; @@ -24,16 +26,18 @@ import com.cloud.network.Network.TrafficType; * Transfer object to transfer network settings. */ public class NetworkTO { - private String uuid; - private String ip; - private String netmask; - private String gateway; - private String mac; - private String dns1; - private String dns2; - private Long vlan; - private BroadcastDomainType broadcastType; - private TrafficType type; + protected String uuid; + protected String ip; + protected String netmask; + protected String gateway; + protected String mac; + protected String dns1; + protected String dns2; + protected Long vlan; + protected BroadcastDomainType broadcastType; + protected TrafficType type; + protected URI broadcastUri; + protected URI isolationUri; public NetworkTO() { } @@ -150,4 +154,20 @@ public class NetworkTO { public TrafficType getType() { return type; } + + public URI getBroadcastUri() { + return broadcastUri; + } + + public void setBroadcastUri(URI broadcastUri) { + this.broadcastUri = broadcastUri; + } + + public URI getIsolationUri() { + return isolationUri; + } + + public void setIsolationuri(URI isolationUri) { + this.isolationUri = isolationUri; + } } diff --git a/core/src/com/cloud/agent/api/to/NicTO.java b/core/src/com/cloud/agent/api/to/NicTO.java index 42e4f66bd94..7da291c7e4b 100644 --- a/core/src/com/cloud/agent/api/to/NicTO.java +++ b/core/src/com/cloud/agent/api/to/NicTO.java @@ -8,6 +8,8 @@ public class NicTO extends NetworkTO { Integer controlPort; Integer networkRateMbps; Integer networkRateMulticastMbps; + String bootParams; + boolean defaultNic; public NicTO() { super(); @@ -33,4 +35,25 @@ public class NicTO extends NetworkTO { public Integer getNetworkRateMulticastMbps() { return networkRateMulticastMbps; } + + public String getBootParams() { + return bootParams; + } + + public void setBootParams(String bootParams) { + this.bootParams = bootParams; + } + + public boolean isDefaultNic() { + return defaultNic; + } + + public void setDefaultNic(boolean defaultNic) { + this.defaultNic = defaultNic; + } + + @Override + public String toString() { + return new StringBuilder("[Nic:").append(type).append("-").append(ip).append("-").append(broadcastUri).append("]").toString(); + } } diff --git a/core/src/com/cloud/agent/api/to/VirtualMachineTO.java b/core/src/com/cloud/agent/api/to/VirtualMachineTO.java index b37c2fd2426..d0ab70d9225 100644 --- a/core/src/com/cloud/agent/api/to/VirtualMachineTO.java +++ b/core/src/com/cloud/agent/api/to/VirtualMachineTO.java @@ -21,6 +21,7 @@ import java.util.Map; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.vm.VirtualMachine.Type; +import com.cloud.vm.VirtualMachineProfile; public class VirtualMachineTO { private long id; @@ -28,8 +29,7 @@ public class VirtualMachineTO { private BootloaderType bootloader; Type type; int cpus; - Integer weight; - Integer utilization; + Integer speed; long minRam; long maxRam; String hostName; @@ -42,7 +42,19 @@ public class VirtualMachineTO { VolumeTO[] disks; NicTO[] nics; - public VirtualMachineTO() { + public VirtualMachineTO(VirtualMachineProfile profile, BootloaderType bootloader) { + this.id = profile.getId(); + this.type = profile.getType(); + this.cpus = profile.getCpus(); + this.minRam = profile.getRam(); + this.maxRam = profile.getRam(); + this.speed = profile.getSpeed(); + this.os = profile.getOs(); + this.name = profile.getName(); + this.bootloader = bootloader; + } + + protected VirtualMachineTO() { } public long getId() { @@ -81,22 +93,10 @@ public class VirtualMachineTO { this.cpus = cpus; } - public Integer getWeight() { - return weight; + public Integer getSpeed() { + return speed; } - public void setWeight(Integer weight) { - this.weight = weight; - } - - public Integer getUtilization() { - return utilization; - } - - public void setUtiliziation(Integer utilization) { - this.utilization = utilization; - } - public long getMinRam() { return minRam; } @@ -133,8 +133,13 @@ public class VirtualMachineTO { public void setOs(String os) { this.os = os; } - + public String getBootArgs() { + StringBuilder buf = new StringBuilder(bootArgs != null ? bootArgs : ""); + buf.append(" "); + for (NicTO nic : nics) { + buf.append(""); + } return bootArgs; } @@ -162,12 +167,11 @@ public class VirtualMachineTO { this.disks = disks; } - public NicTO[] getNetworks() { + public NicTO[] getNics() { return nics; } public void setNics(NicTO[] nics) { this.nics = nics; } - } diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index c231b53065c..5088840ffac 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -122,8 +122,6 @@ import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.StoragePoolInfo; -import com.cloud.agent.api.ValidateSnapshotAnswer; -import com.cloud.agent.api.ValidateSnapshotCommand; import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; @@ -139,7 +137,6 @@ import com.cloud.agent.api.storage.CopyVolumeCommand; import com.cloud.agent.api.storage.CreateAnswer; import com.cloud.agent.api.storage.CreateCommand; import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; - import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; @@ -235,6 +232,8 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR protected IAgentControl _agentControl; protected boolean _isRemoteAgent = false; + int _userVMCap = 0; + final int _maxWeight = 256; protected final XenServerHost _host = new XenServerHost(); @@ -670,6 +669,10 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } protected VIF createVif(Connection conn, String vmName, VM vm, NicTO nic) throws XmlRpcException, XenAPIException { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating VIF for " + vmName + " on nic " + nic); + } + VIF.Record vifr = new VIF.Record(); vifr.VM = vm; vifr.device = Integer.toString(nic.getDeviceId()); @@ -677,10 +680,13 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR Pair network = getNetworkForTraffic(conn, nic.getType()); if (nic.getBroadcastType() == BroadcastDomainType.Vlan) { - vifr.network = enableVlanNetwork(conn, nic.getVlan(), network.first(), network.second()); - } else { + URI broadcastUri = nic.getBroadcastUri(); + assert broadcastUri.getScheme().equals(BroadcastDomainType.Vlan.scheme()); + long vlan = Long.parseLong(broadcastUri.getHost()); + vifr.network = enableVlanNetwork(conn, vlan, network.first(), network.second()); + } else if (nic.getBroadcastType() == BroadcastDomainType.Native || nic.getBroadcastType() == BroadcastDomainType.LinkLocal) { vifr.network = network.first(); - } + } if (nic.getNetworkRateMbps() != null) { vifr.qosAlgorithmType = "ratelimit"; @@ -725,17 +731,11 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } } - protected VBD createVbd(Connection conn, String vmName, VM vm, VolumeTO volume, boolean patch) throws XmlRpcException, XenAPIException { + protected VBD createVbd(Connection conn, VolumeTO volume, String vmName, VM vm) throws XmlRpcException, XenAPIException { VolumeType type = volume.getType(); VDI vdi = mount(conn, vmName, volume); - if (patch) { - if (!patchSystemVm(vdi, vmName)) { - throw new CloudRuntimeException("Unable to patch system vm"); - } - } - VBD.Record vbdr = new VBD.Record(); vbdr.VM = vm; vbdr.VDI = vdi; @@ -761,7 +761,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR return vbd; } - protected Pair createVmFromTemplate(Connection conn, VirtualMachineTO vmSpec, Host host) throws XenAPIException, XmlRpcException { + protected VM createVmFromTemplate(Connection conn, VirtualMachineTO vmSpec, Host host) throws XenAPIException, XmlRpcException { String guestOsTypeName = getGuestOsType(vmSpec.getOs()); Set templates = VM.getByNameLabel(conn, guestOsTypeName); assert templates.size() == 1 : "Should only have 1 template but found " + templates.size(); @@ -785,16 +785,27 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR setMemory(conn, vm, vmSpec.getMinRam()); vm.setVCPUsAtStartup(conn, (long)vmSpec.getCpus()); vm.setVCPUsMax(conn, (long)vmSpec.getCpus()); - vm.setVCPUsNumberLive(conn, (long)vmSpec.getCpus()); Map vcpuParams = new HashMap(); - if (vmSpec.getWeight() != null) { - vcpuParams.put("weight", Integer.toString(vmSpec.getWeight())); - } - if (vmSpec.getUtilization() != null) { - vcpuParams.put("cap", Integer.toString(vmSpec.getUtilization())); + Integer speed = vmSpec.getSpeed(); + if (speed != null) { + int utilization = _userVMCap; //cpu_cap + //Configuration cpu.uservm.cap is not available in default installation. Using this parameter is not encouraged + + int cpuWeight = _maxWeight; //cpu_weight + + // weight based allocation + cpuWeight = (int)((speed*0.99) / _host.speed * _maxWeight); + if (cpuWeight > _maxWeight) { + cpuWeight = _maxWeight; + } + + vcpuParams.put("weight", Integer.toString(cpuWeight)); + vcpuParams.put("cap", Integer.toString(utilization)); + } + if (vcpuParams.size() > 0) { vm.setVCPUsParams(conn, vcpuParams); } @@ -824,7 +835,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } } - return new Pair(vm, vmr.uuid); + return vm; } protected String handleVmStartFailure(String vmName, VM vm, String message, Throwable th) { @@ -875,6 +886,20 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR return msg; } + protected VBD createPatchVbd(Connection conn, String vmName, VM vm) throws XmlRpcException, XenAPIException { + VBD.Record cdromVBDR = new VBD.Record(); + cdromVBDR.VM = vm; + cdromVBDR.empty = true; + cdromVBDR.bootable = false; + cdromVBDR.userdevice = "3"; + cdromVBDR.mode = Types.VbdMode.RO; + cdromVBDR.type = Types.VbdType.CD; + VBD cdromVBD = VBD.create(conn, cdromVBDR); + cdromVBD.insert(conn, VDI.getByUuid(conn, _host.systemvmisouuid)); + + return cdromVBD; + } + protected Start2Answer execute(Start2Command cmd) { VirtualMachineTO vmSpec = cmd.getVirtualMachine(); String vmName = vmSpec.getName(); @@ -888,79 +913,24 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR _vms.put(vmName, State.Starting); } - Pair v = createVmFromTemplate(conn, vmSpec, host); - vm = v.first(); + vm = createVmFromTemplate(conn, vmSpec, host); for (VolumeTO disk : vmSpec.getDisks()) { - createVbd(conn, vmName, vm, disk, disk.getType() == VolumeType.ROOT && vmSpec.getType() != VirtualMachine.Type.User); + createVbd(conn, disk, vmName, vm); + } + + if (vmSpec.getType() != VirtualMachine.Type.User) { + createPatchVbd(conn, vmName, vm); } NicTO controlNic = null; - for (NicTO nic : vmSpec.getNetworks()) { - if (nic.getControlPort() != null) { + for (NicTO nic : vmSpec.getNics()) { + if (nic.getType() == TrafficType.Control) { controlNic = nic; } createVif(conn, vmName, vm, nic); } - /* - * - VBD.Record vbdr = new VBD.Record(); - Ternary mount = mounts.get(0); - vbdr.VM = vm; - vbdr.VDI = mount.second(); - vbdr.bootable = !bootFromISO; - vbdr.userdevice = "0"; - vbdr.mode = Types.VbdMode.RW; - vbdr.type = Types.VbdType.DISK; - VBD.create(conn, vbdr); - - for (int i = 1; i < mounts.size(); i++) { - mount = mounts.get(i); - // vdi.setNameLabel(conn, cmd.getVmName() + "-DATA"); - vbdr.VM = vm; - vbdr.VDI = mount.second(); - vbdr.bootable = false; - vbdr.userdevice = Long.toString(mount.third().getDeviceId()); - vbdr.mode = Types.VbdMode.RW; - vbdr.type = Types.VbdType.DISK; - vbdr.unpluggable = true; - VBD.create(conn, vbdr); - - } - - VBD.Record cdromVBDR = new VBD.Record(); - cdromVBDR.VM = vm; - cdromVBDR.empty = true; - cdromVBDR.bootable = bootFromISO; - cdromVBDR.userdevice = "3"; - cdromVBDR.mode = Types.VbdMode.RO; - cdromVBDR.type = Types.VbdType.CD; - VBD cdromVBD = VBD.create(conn, cdromVBDR); - - String isopath = cmd.getISOPath(); - if (isopath != null) { - int index = isopath.lastIndexOf("/"); - - String mountpoint = isopath.substring(0, index); - URI uri = new URI(mountpoint); - isosr = createIsoSRbyURI(uri, cmd.getVmName(), false); - - String isoname = isopath.substring(index + 1); - - VDI isovdi = getVDIbyLocationandSR(isoname, isosr); - - if (isovdi == null) { - String msg = " can not find ISO " + cmd.getISOPath(); - s_logger.warn(msg); - return new StartAnswer(cmd, msg); - } else { - cdromVBD.insert(conn, isovdi); - } - - } - */ - vm.startOn(conn, host, false, true); if (_canBridgeFirewall) { @@ -997,12 +967,15 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR state = State.Running; return new Start2Answer(cmd); } catch (XmlRpcException e) { + s_logger.warn("Exception ", e); String msg = handleVmStartFailure(vmName, vm, "", e); return new Start2Answer(cmd, msg); } catch (XenAPIException e) { + s_logger.warn("Exception ", e); String msg = handleVmStartFailure(vmName, vm, "", e); return new Start2Answer(cmd, msg); } catch (Exception e) { + s_logger.warn("Exception ", e); String msg = handleVmStartFailure(vmName, vm, "", e); return new Start2Answer(cmd, msg); } finally { @@ -3314,19 +3287,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR return new StartConsoleProxyAnswer(cmd, msg); } } - - protected boolean patchSystemVm(VDI vdi, String vmName) { - if (vmName.startsWith("r-")) { - return patchSpecialVM(vdi, vmName, "router"); - } else if (vmName.startsWith("v-")) { - return patchSpecialVM(vdi, vmName, "consoleproxy"); - } else if (vmName.startsWith("s-")) { - return patchSpecialVM(vdi, vmName, "secstorage"); - } else { - throw new CloudRuntimeException("Tried to patch unknown type of system vm"); - } - } - + protected boolean isDeviceUsed(VM vm, Long deviceId) { // Figure out the disk number to attach the VM to @@ -3367,79 +3328,6 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR throw new CloudRuntimeException("Could not find an available slot in VM with name to attach a new disk."); } - protected boolean patchSpecialVM(VDI vdi, String vmname, String vmtype) { - // patch special vm here, domr, domp - VBD vbd = null; - Connection conn = getConnection(); - try { - Host host = Host.getByUuid(conn, _host.uuid); - - Set vms = host.getResidentVMs(conn); - - for (VM vm : vms) { - VM.Record vmrec = null; - try { - vmrec = vm.getRecord(conn); - } catch (Exception e) { - String msg = "VM.getRecord failed due to " + e.toString() + " " + e.getMessage(); - s_logger.warn(msg); - continue; - } - if (vmrec.isControlDomain) { - - /* create VBD */ - VBD.Record vbdr = new VBD.Record(); - vbdr.VM = vm; - vbdr.VDI = vdi; - vbdr.bootable = false; - vbdr.userdevice = getUnusedDeviceNum(vm); - vbdr.unpluggable = true; - vbdr.mode = Types.VbdMode.RW; - vbdr.type = Types.VbdType.DISK; - - vbd = VBD.create(conn, vbdr); - - vbd.plug(conn); - - String device = vbd.getDevice(conn); - - return patchspecialvm(vmname, device, vmtype); - } - } - - } catch (XenAPIException e) { - String msg = "patchSpecialVM faile on " + _host.uuid + " due to " + e.toString(); - s_logger.warn(msg, e); - } catch (Exception e) { - String msg = "patchSpecialVM faile on " + _host.uuid + " due to " + e.getMessage(); - s_logger.warn(msg, e); - } finally { - if (vbd != null) { - try { - if (vbd.getCurrentlyAttached(conn)) { - vbd.unplug(conn); - } - vbd.destroy(conn); - } catch (XmlRpcException e) { - String msg = "Catch XmlRpcException due to " + e.getMessage(); - s_logger.warn(msg, e); - } catch (XenAPIException e) { - String msg = "Catch XenAPIException due to " + e.toString(); - s_logger.warn(msg, e); - } - - } - } - return false; - } - - protected boolean patchspecialvm(String vmname, String device, String vmtype) { - String result = callHostPlugin("vmops", "patchdomr", "vmname", vmname, "vmtype", vmtype, "device", "/dev/" + device); - if (result == null || result.isEmpty()) - return false; - return true; - } - protected String callHostPlugin(String plugin, String cmd, String... params) { //default time out is 300 s return callHostPluginWithTimeOut(plugin, cmd, 300, params); @@ -3950,6 +3838,13 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR try { Host myself = Host.getByUuid(conn, _host.uuid); + Set hcs = myself.getHostCPUs(conn); + _host.cpus = hcs.size(); + for (final HostCpu hc : hcs) { + _host.speed = hc.getSpeed(conn).intValue(); + break; + } + Set srs = SR.getByNameLabel(conn, "XenServer Tools"); if( srs.size() != 1 ) { throw new CloudRuntimeException("There are " + srs.size() + " SRs with name XenServer Tools"); @@ -4551,13 +4446,8 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } cmd.setCaps(caps.toString()); - Set hcs = host.getHostCPUs(conn); - cpus = hcs.size(); - for (final HostCpu hc : hcs) { - speed = hc.getSpeed(conn); - } - cmd.setSpeed(speed); - cmd.setCpus(cpus); + cmd.setSpeed(_host.speed); + cmd.setCpus(_host.cpus); long free = 0; @@ -6248,10 +6138,111 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR public String storagePif1; public String storagePif2; public String pool; + public int speed; + public int cpus; } /*Override by subclass*/ protected String getGuestOsType(String stdType) { return stdType; } + +/* + protected boolean patchSystemVm(VDI vdi, String vmName, VirtualMachine.Type type) { + if (type == VirtualMachine.Type.DomainRouter) { + return patchSpecialVM(vdi, vmName, "router"); + } else if (type == VirtualMachine.Type.ConsoleProxy) { + return patchSpecialVM(vdi, vmName, "consoleproxy"); + } else if (type == VirtualMachine.Type.SecondaryStorageVm) { + return patchSpecialVM(vdi, vmName, "secstorage"); + } else { + throw new CloudRuntimeException("Tried to patch unknown type of system vm"); + } + } + + protected boolean patchSystemVm(VDI vdi, String vmName) { + if (vmName.startsWith("r-")) { + return patchSpecialVM(vdi, vmName, "router"); + } else if (vmName.startsWith("v-")) { + return patchSpecialVM(vdi, vmName, "consoleproxy"); + } else if (vmName.startsWith("s-")) { + return patchSpecialVM(vdi, vmName, "secstorage"); + } else { + throw new CloudRuntimeException("Tried to patch unknown type of system vm"); + } + } + + protected boolean patchSpecialVM(VDI vdi, String vmname, String vmtype) { + // patch special vm here, domr, domp + VBD vbd = null; + Connection conn = getConnection(); + try { + Host host = Host.getByUuid(conn, _host.uuid); + + Set vms = host.getResidentVMs(conn); + + for (VM vm : vms) { + VM.Record vmrec = null; + try { + vmrec = vm.getRecord(conn); + } catch (Exception e) { + String msg = "VM.getRecord failed due to " + e.toString() + " " + e.getMessage(); + s_logger.warn(msg); + continue; + } + if (vmrec.isControlDomain) { + + VBD.Record vbdr = new VBD.Record(); + vbdr.VM = vm; + vbdr.VDI = vdi; + vbdr.bootable = false; + vbdr.userdevice = getUnusedDeviceNum(vm); + vbdr.unpluggable = true; + vbdr.mode = Types.VbdMode.RW; + vbdr.type = Types.VbdType.DISK; + + vbd = VBD.create(conn, vbdr); + + vbd.plug(conn); + + String device = vbd.getDevice(conn); + + return patchspecialvm(vmname, device, vmtype); + } + } + + } catch (XenAPIException e) { + String msg = "patchSpecialVM faile on " + _host.uuid + " due to " + e.toString(); + s_logger.warn(msg, e); + } catch (Exception e) { + String msg = "patchSpecialVM faile on " + _host.uuid + " due to " + e.getMessage(); + s_logger.warn(msg, e); + } finally { + if (vbd != null) { + try { + if (vbd.getCurrentlyAttached(conn)) { + vbd.unplug(conn); + } + vbd.destroy(conn); + } catch (XmlRpcException e) { + String msg = "Catch XmlRpcException due to " + e.getMessage(); + s_logger.warn(msg, e); + } catch (XenAPIException e) { + String msg = "Catch XenAPIException due to " + e.toString(); + s_logger.warn(msg, e); + } + + } + } + return false; + } + + protected boolean patchspecialvm(String vmname, String device, String vmtype) { + String result = callHostPlugin("vmops", "patchdomr", "vmname", vmname, "vmtype", vmtype, "device", "/dev/" + device); + if (result == null || result.isEmpty()) + return false; + return true; + } +*/ + } diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index de3af5a624b..34eb107ecb1 100644 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -138,6 +138,7 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.ExecutionException; import com.cloud.utils.net.NetUtils; import com.cloud.vm.ConsoleProxyVO; +import com.cloud.vm.NicProfile; import com.cloud.vm.State; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; @@ -1035,16 +1036,21 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, VirtualMach AccountVO systemAcct = _accountMgr.getSystemAccount(); DataCenterDeployment plan = new DataCenterDeployment(dataCenterId, 1); - - List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmControlNetwork, NetworkOfferingVO.SystemVmManagementNetwork, NetworkOfferingVO.SystemVmPublicNetwork); - List profiles = new ArrayList(offerings.size()); + + List defaultOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmPublicNetwork); + List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmControlNetwork, NetworkOfferingVO.SystemVmManagementNetwork); + List> networks = new ArrayList>(offerings.size() + 1); + NicProfile defaultNic = new NicProfile(); + defaultNic.setDefaultNic(true); + defaultNic.setDeviceId(2); + networks.add(new Pair(_networkMgr.setupNetworkConfiguration(systemAcct, defaultOffering.get(0), plan), defaultNic)); for (NetworkOfferingVO offering : offerings) { - profiles.add(_networkMgr.setupNetworkConfiguration(_accountMgr.getSystemAccount(), offering, plan)); + networks.add(new Pair(_networkMgr.setupNetworkConfiguration(systemAcct, offering, plan), null)); } ConsoleProxyVO proxy = new ConsoleProxyVO(id, _serviceOffering.getId(), name, _template.getId(), _template.getGuestOSId(), dataCenterId, systemAcct.getDomainId(), systemAcct.getId(), 0); proxy = _consoleProxyDao.persist(proxy); try { - VirtualMachineProfile vmProfile = _vmMgr.allocate(proxy, _template, _serviceOffering, profiles, plan, _accountMgr.getSystemAccount()); + VirtualMachineProfile vmProfile = _vmMgr.allocate(proxy, _template, _serviceOffering, networks, plan, systemAcct); } catch (InsufficientCapacityException e) { s_logger.warn("InsufficientCapacity", e); throw new CloudRuntimeException("Insufficient capacity exception", e); diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java new file mode 100644 index 00000000000..1ed056f0c6e --- /dev/null +++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.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.hypervisor; + +import com.cloud.utils.component.AdapterBase; + +public abstract class HypervisorGuruBase extends AdapterBase implements HypervisorGuru { + protected HypervisorGuruBase() { + super(); + } +} diff --git a/server/src/com/cloud/hypervisor/XenServerGuru.java b/server/src/com/cloud/hypervisor/XenServerGuru.java new file mode 100644 index 00000000000..4579e21b0e8 --- /dev/null +++ b/server/src/com/cloud/hypervisor/XenServerGuru.java @@ -0,0 +1,43 @@ +/** + * 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.hypervisor; + +import javax.ejb.Local; + +import com.cloud.offering.ServiceOffering; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineProfile; + +@Local(value=HypervisorGuru.class) +public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru { + + protected XenServerGuru() { + super(); + } + + @Override + public VirtualMachineProfile design(VirtualMachine vm, ServiceOffering offering) { + return null; + } + + @Override + public boolean check(VirtualMachineProfile profile) { + return true; + } + +} diff --git a/server/src/com/cloud/network/NetworkConfigurationVO.java b/server/src/com/cloud/network/NetworkConfigurationVO.java index dd3ee6cc466..8a9f81520b1 100644 --- a/server/src/com/cloud/network/NetworkConfigurationVO.java +++ b/server/src/com/cloud/network/NetworkConfigurationVO.java @@ -77,6 +77,9 @@ public class NetworkConfigurationVO implements NetworkConfiguration { @Enumerated(value=EnumType.STRING) State state; + @Column(name="dns") + String dns; + public NetworkConfigurationVO() { } @@ -185,6 +188,14 @@ public class NetworkConfigurationVO implements NetworkConfiguration { return dataCenterId; } + public String getDns() { + return dns; + } + + public void setDns(String dns) { + this.dns = dns; + } + @Override public boolean equals(Object obj) { if (!(obj instanceof NetworkConfigurationVO)) { diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 8f147797f31..4871b8520b6 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -18,6 +18,7 @@ package com.cloud.network; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -2476,36 +2477,87 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager int deviceId = 0; + boolean[] deviceIds = new boolean[networks.size()]; + Arrays.fill(deviceIds, false); + + List nics = new ArrayList(networks.size()); + NicVO defaultNic = null; + for (Pair network : networks) { - NetworkGuru concierge = _networkGurus.get(network.first().getGuruName()); - NicProfile profile = concierge.allocate(network.first(), network.second(), vm); + NetworkConfigurationVO config = network.first(); + NetworkGuru concierge = _networkGurus.get(config.getGuruName()); + NicProfile requested = network.second(); + NicProfile profile = concierge.allocate(config, requested, vm); if (profile == null) { continue; } - NicVO vo = new NicVO(concierge.getName(), vm.getId(), network.first().getId()); - vo.setDeviceId(deviceId++); + NicVO vo = new NicVO(concierge.getName(), vm.getId(), config.getId()); vo.setMode(network.first().getMode()); - if (profile.getIp4Address() != null) { - vo.setIp4Address(profile.getIp4Address()); - vo.setState(NicVO.State.Reserved); + + while (deviceIds[deviceId] && deviceId < deviceIds.length) { + deviceId++; } - if (profile.getMacAddress() != null) { - vo.setMacAddress(profile.getMacAddress()); - } + deviceId = applyProfileToNic(vo, profile, deviceId); - if (profile.getMode() != null) { - vo.setMode(profile.getMode()); - } - vo = _nicDao.persist(vo); - nicProfiles.add(new NicProfile(vo, network.first())); + + if (vo.isDefaultNic()) { + if (defaultNic != null) { + throw new IllegalArgumentException("You cannot specify two nics as default nics: nic 1 = " + defaultNic + "; nic 2 = " + vo); + } + defaultNic = vo; + } + + int devId = vo.getDeviceId(); + if (devId > deviceIds.length) { + throw new IllegalArgumentException("Device id for nic is too large: " + vo); + } + if (deviceIds[devId]) { + throw new IllegalArgumentException("Conflicting device id for two different nics: " + devId); + } + + deviceIds[devId] = true; + nics.add(vo); + nicProfiles.add(new NicProfile(vo, network.first(), vo.getBroadcastUri(), vo.getIsolationUri())); } + + if (defaultNic == null && nics.size() > 2) { + throw new IllegalArgumentException("Default Nic was not set."); + } else if (nics.size() == 1) { + nics.get(0).setDefaultNic(true); + } + txn.commit(); return nicProfiles; } + protected Integer applyProfileToNic(NicVO vo, NicProfile profile, Integer deviceId) { + if (profile.getDeviceId() != null) { + vo.setDeviceId(profile.getDeviceId()); + } else if (deviceId != null ) { + vo.setDeviceId(deviceId++); + } + + vo.setDefaultNic(profile.isDefaultNic()); + + if (profile.getIp4Address() != null) { + vo.setIp4Address(profile.getIp4Address()); + vo.setState(NicVO.State.Reserved); + } + + if (profile.getMacAddress() != null) { + vo.setMacAddress(profile.getMacAddress()); + } + + vo.setMode(profile.getMode()); + vo.setNetmask(profile.getNetmask()); + vo.setGateway(profile.getGateway()); + + return deviceId; + } + protected NicTO toNicTO(NicVO nic, NetworkConfigurationVO config) { NicTO to = new NicTO(); to.setDeviceId(nic.getDeviceId()); @@ -2514,6 +2566,17 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager to.setIp(nic.getIp4Address()); to.setNetmask(nic.getNetmask()); to.setMac(nic.getMacAddress()); + if (config.getDns() != null) { + String[] tokens = config.getDns().split(","); + to.setDns1(tokens[0]); + if (tokens.length > 2) { + to.setDns2(tokens[1]); + } + } + to.setGateway(config.getGateway()); + to.setDefaultNic(nic.isDefaultNic()); + to.setBroadcastUri(nic.getBroadcastUri()); + to.setIsolationuri(nic.getIsolationUri()); return to; } @@ -2559,7 +2622,7 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager NicProfile toNicProfile(NicVO nic) { NetworkConfiguration config = _networkProfileDao.findById(nic.getNetworkConfigurationId()); - NicProfile profile = new NicProfile(nic, config); + NicProfile profile = new NicProfile(nic, config, nic.getBroadcastUri(), nic.getIsolationUri()); return profile; } diff --git a/server/src/com/cloud/network/configuration/PodBasedNetworkGuru.java b/server/src/com/cloud/network/configuration/PodBasedNetworkGuru.java index cf72ccd8aa7..6853bafbd65 100644 --- a/server/src/com/cloud/network/configuration/PodBasedNetworkGuru.java +++ b/server/src/com/cloud/network/configuration/PodBasedNetworkGuru.java @@ -25,7 +25,6 @@ import com.cloud.resource.Resource.ReservationStrategy; import com.cloud.user.Account; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.component.Inject; -import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.vm.NicProfile; import com.cloud.vm.VirtualMachineProfile; @@ -61,11 +60,12 @@ public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru { } if (nic != null) { - throw new CloudRuntimeException("Does not support nic configuration"); - } + nic.setStrategy(ReservationStrategy.Start); + } else { + nic = new NicProfile(ReservationStrategy.Start, null, null, null, null); + } - NicProfile profile = new NicProfile(ReservationStrategy.Start, null, null, null, null); - return profile; + return nic; } @Override diff --git a/server/src/com/cloud/network/configuration/PublicNetworkGuru.java b/server/src/com/cloud/network/configuration/PublicNetworkGuru.java index 9e28c4c62fc..54acbfb45ce 100644 --- a/server/src/com/cloud/network/configuration/PublicNetworkGuru.java +++ b/server/src/com/cloud/network/configuration/PublicNetworkGuru.java @@ -28,7 +28,6 @@ import com.cloud.user.Account; import com.cloud.utils.Pair; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.component.Inject; -import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.NicProfile; import com.cloud.vm.VirtualMachineProfile; @@ -59,11 +58,13 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { return null; } - if (nic != null) { - throw new CloudRuntimeException("Unsupported nic settings"); + if (nic == null) { + nic = new NicProfile(ReservationStrategy.Create, null, null, null, null); + } else { + nic.setStrategy(ReservationStrategy.Create); } - - return new NicProfile(ReservationStrategy.Create, null, null, null, null); + + return nic; } @Override diff --git a/server/src/com/cloud/storage/allocator/GarbageCollectingStoragePoolAllocator.java b/server/src/com/cloud/storage/allocator/GarbageCollectingStoragePoolAllocator.java index 7de9b6614e7..2d77c74c136 100644 --- a/server/src/com/cloud/storage/allocator/GarbageCollectingStoragePoolAllocator.java +++ b/server/src/com/cloud/storage/allocator/GarbageCollectingStoragePoolAllocator.java @@ -38,7 +38,7 @@ import com.cloud.vm.VMInstanceVO; @Local(value=StoragePoolAllocator.class) public class GarbageCollectingStoragePoolAllocator extends AbstractStoragePoolAllocator { - private static final Logger s_logger = Logger.getLogger(LocalStoragePoolAllocator.class); + private static final Logger s_logger = Logger.getLogger(GarbageCollectingStoragePoolAllocator.class); StoragePoolAllocator _firstFitStoragePoolAllocator; StoragePoolAllocator _localStoragePoolAllocator; diff --git a/server/src/com/cloud/test/DatabaseConfig.java b/server/src/com/cloud/test/DatabaseConfig.java index cd45cf09d04..828abf33f17 100644 --- a/server/src/com/cloud/test/DatabaseConfig.java +++ b/server/src/com/cloud/test/DatabaseConfig.java @@ -52,7 +52,6 @@ import org.xml.sax.helpers.DefaultHandler; import com.cloud.host.Status; import com.cloud.offering.NetworkOffering; -import com.cloud.offering.NetworkOffering.GuestIpType; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDaoImpl; import com.cloud.storage.DiskOfferingVO; @@ -422,7 +421,6 @@ public class DatabaseConfig { // Check pod CIDRs against each other, and against the guest ip network/netmask pzc.checkAllPodCidrSubnets(); - txn.commit(); } catch (Exception ex) { System.out.print("ERROR IS"+ex); s_logger.error("error", ex); diff --git a/server/src/com/cloud/vm/MauriceMoss.java b/server/src/com/cloud/vm/MauriceMoss.java index 5163afed108..d6a80dc8202 100644 --- a/server/src/com/cloud/vm/MauriceMoss.java +++ b/server/src/com/cloud/vm/MauriceMoss.java @@ -29,7 +29,11 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Start2Answer; +import com.cloud.agent.api.Start2Command; +import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.agent.api.to.VolumeTO; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.deploy.DeployDestination; @@ -38,6 +42,7 @@ import com.cloud.deploy.DeploymentPlanner; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.StorageUnavailableException; import com.cloud.network.NetworkConfigurationVO; import com.cloud.network.NetworkManager; @@ -45,10 +50,15 @@ import com.cloud.offering.ServiceOffering; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.GuestOSVO; +import com.cloud.storage.Storage; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.StorageManager; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Volume.VolumeType; +import com.cloud.storage.dao.GuestOSDao; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.user.AccountVO; import com.cloud.utils.Journal; import com.cloud.utils.NumbersUtil; @@ -72,6 +82,8 @@ public class MauriceMoss implements VmManager { @Inject private AgentManager _agentMgr; @Inject private VMInstanceDao _vmDao; @Inject private ServiceOfferingDao _offeringDao; + @Inject private GuestOSDao _guestOsDao; + @Inject private VMTemplateDao _templateDao; @Inject(adapter=DeploymentPlanner.class) private Adapters _planners; @@ -90,8 +102,15 @@ public class MauriceMoss implements VmManager { if (s_logger.isDebugEnabled()) { s_logger.debug("Allocating entries for VM: " + vm); } + + // Determine the VM's OS description + GuestOSVO guestOS = _guestOsDao.findById(vm.getGuestOSId()); + if (guestOS == null) { + throw new CloudRuntimeException("Guest OS is not set"); + } + //VMInstanceVO vm = _vmDao.findById(vm.getId()); - VirtualMachineProfile vmProfile = new VirtualMachineProfile(vm, serviceOffering); + VirtualMachineProfile vmProfile = new VirtualMachineProfile(vm, serviceOffering, guestOS.getName()); Transaction txn = Transaction.currentTxn(); txn.start(); @@ -145,13 +164,9 @@ public class MauriceMoss implements VmManager { public VirtualMachineProfile allocate(T vm, VMTemplateVO template, ServiceOfferingVO serviceOffering, - List networkProfiles, + List> networks, DeploymentPlan plan, AccountVO owner) throws InsufficientCapacityException { - List> networks = new ArrayList>(networkProfiles.size()); - for (NetworkConfigurationVO profile : networkProfiles) { - networks.add(new Pair(profile, null)); - } return allocate(vm, template, serviceOffering, new Pair(serviceOffering, null), null, networks, plan, owner); } @@ -244,7 +259,13 @@ public class MauriceMoss implements VmManager { ServiceOffering offering = _offeringDao.findById(vm.getServiceOfferingId()); - VirtualMachineProfile vmProfile = new VirtualMachineProfile(vm, offering); + // Determine the VM's OS description + GuestOSVO guestOS = _guestOsDao.findById(vm.getGuestOSId()); + if (guestOS == null) { + throw new CloudRuntimeException("Guest OS is not set"); + } + VirtualMachineProfile vmProfile = new VirtualMachineProfile(vm, offering, guestOS.getName()); + _vmDao.updateIf(vm, Event.StartRequested, null); Set avoids = new HashSet(); int retry = _retry; @@ -265,18 +286,45 @@ public class MauriceMoss implements VmManager { vm.setDataCenterId(dest.getDataCenter().getId()); vm.setPodId(dest.getPod().getId()); - _vmDao.updateIf(vm, Event.StartRequested, dest.getHost().getId()); + _vmDao.updateIf(vm, Event.OperationRetry, dest.getHost().getId()); - VirtualMachineTO vmTO = new VirtualMachineTO(); + VMTemplateVO template = _templateDao.findById(vm.getTemplateId()); + + BootloaderType bt = BootloaderType.PyGrub; + if (template.getFormat() == Storage.ImageFormat.ISO || template.isRequiresHvm()) { + bt = BootloaderType.HVM; + } + + VirtualMachineTO vmTO = new VirtualMachineTO(vmProfile, bt); + VolumeTO[] volumes = null; try { - _storageMgr.prepare(vmProfile, dest); + volumes = _storageMgr.prepare(vmProfile, dest); } catch (ConcurrentOperationException e) { throw e; } catch (StorageUnavailableException e) { s_logger.warn("Unable to contact storage.", e); continue; } - _networkMgr.prepare(vmProfile, dest); + NicTO[] nics = _networkMgr.prepare(vmProfile, dest); + + vmTO.setNics(nics); + vmTO.setDisks(volumes); + + Start2Command cmd = new Start2Command(vmTO); + try { + Start2Answer answer = (Start2Answer)_agentMgr.send(dest.getHost().getId(), cmd); + if (!answer.getResult()) { + s_logger.info("Unable to start VM on " + dest.getHost() + " due to " + answer.getDetails()); + continue; + } + _vmDao.updateIf(vm, Event.OperationSucceeded, dest.getHost().getId()); + } 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()) { diff --git a/server/src/com/cloud/vm/NicVO.java b/server/src/com/cloud/vm/NicVO.java index fdc9f3a730f..239bfba49f9 100644 --- a/server/src/com/cloud/vm/NicVO.java +++ b/server/src/com/cloud/vm/NicVO.java @@ -92,6 +92,9 @@ public class NicVO implements Nic { @Column(name="update_time") Date updateTime; + + @Column(name="default_nic") + boolean defaultNic; public NicVO(String reserver, long instanceId, long configurationId) { this.reserver = reserver; @@ -123,6 +126,14 @@ public class NicVO implements Nic { return state; } + public boolean isDefaultNic() { + return defaultNic; + } + + public void setDefaultNic(boolean defaultNic) { + this.defaultNic = defaultNic; + } + public String getIp6Address() { return ip6Address; } diff --git a/server/src/com/cloud/vm/VirtualMachineChecker.java b/server/src/com/cloud/vm/VirtualMachineChecker.java new file mode 100644 index 00000000000..4bac8882dcf --- /dev/null +++ b/server/src/com/cloud/vm/VirtualMachineChecker.java @@ -0,0 +1,28 @@ +/** + * 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.vm; + +import java.util.List; + +import com.cloud.deploy.DeployDestination; +import com.cloud.utils.Pair; + +public interface VirtualMachineChecker { + boolean finalizeDeployment(VirtualMachineProfile vm, DeployDestination dest); + boolean finalizeDeployments(List> deployments); +} diff --git a/server/src/com/cloud/vm/VmManager.java b/server/src/com/cloud/vm/VmManager.java index 7c33a8969dd..ca97fc5b303 100644 --- a/server/src/com/cloud/vm/VmManager.java +++ b/server/src/com/cloud/vm/VmManager.java @@ -58,7 +58,7 @@ public interface VmManager extends Manager { VirtualMachineProfile allocate(T vm, VMTemplateVO template, ServiceOfferingVO serviceOffering, - List networkProfiles, + List> networkProfiles, DeploymentPlan plan, AccountVO owner) throws InsufficientCapacityException, StorageUnavailableException; diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index f4b0b23ed87..8cfe9c1571b 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -103,7 +103,8 @@ CREATE TABLE `cloud`.`network_configurations` ( `network_offering_id` bigint unsigned NOT NULL COMMENT 'network offering id that this configuration is created from', `data_center_id` bigint unsigned NOT NULL COMMENT 'data center id that this configuration is used in', `guru_name` varchar(255) NOT NULL COMMENT 'who is responsible for this type of network configuration', - `state` varchar(32) NOT NULL COMMENT 'what state is this configuration in', + `state` varchar(32) NOT NULL COMMENT 'what state is this configuration in', + `dns` varchar(255) COMMENT 'comma separated DNS list', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -137,7 +138,8 @@ CREATE TABLE `cloud`.`nics` ( `device_id` int(10) COMMENT 'device id for the network when plugged into the virtual machine', `update_time` timestamp NOT NULL COMMENT 'time the state was changed', `isolation_uri` varchar(255) COMMENT 'id for isolation', - `ip6_address` varchar(32) COMMENT 'ip6 address', + `ip6_address` varchar(32) COMMENT 'ip6 address', + `default_nic` tinyint NOT NULL COMMENT "None", PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/ui/new/index.jsp b/ui/new/index.jsp index 8f2979097bd..8c38a2aee98 100644 --- a/ui/new/index.jsp +++ b/ui/new/index.jsp @@ -105,7 +105,7 @@ long milliseconds = new Date().getTime(); - Advanced + <%=t.t("advanced")%> @@ -173,7 +173,7 @@ long milliseconds = new Date().getTime();
Add
+ <%=t.t("add")%> @@ -182,132 +182,14 @@ long milliseconds = new Date().getTime();
Add
+ <%=t.t("help")%> -
- +
@@ -319,42 +201,7 @@ long milliseconds = new Date().getTime();
-
- - - +
@@ -370,7 +217,7 @@ long milliseconds = new Date().getTime();
Dashboard
- Dashboard + <%=t.t("dashboard")%>
@@ -379,7 +226,7 @@ long milliseconds = new Date().getTime();
Dashboard
- Dashboard + <%=t.t("dashboard")%>
@@ -389,8 +236,8 @@ long milliseconds = new Date().getTime();
- Instances
- Instances + Instance + <%=t.t("instance")%> @@ -401,8 +248,8 @@ long milliseconds = new Date().getTime();
- Instances
- Instances + Instance + <%=t.t("instance")%>
@@ -411,14 +258,14 @@ long milliseconds = new Date().getTime();
- Routers
- Routers + Router
+ <%=t.t("router")%>
- Storage
+ System
System
@@ -430,7 +277,7 @@ long milliseconds = new Date().getTime();
Host
- Hosts + Host @@ -439,7 +286,7 @@ long milliseconds = new Date().getTime();
Host
- Hosts + Host
@@ -449,8 +296,8 @@ long milliseconds = new Date().getTime();
- storage
- Storage + Storage + <%=t.t("storage")%> @@ -458,29 +305,29 @@ long milliseconds = new Date().getTime();
- storage
+ Primary Storage
Primary Storage
- storage
+ secondary Storage
secondary Storage
- storage
- Volumes + Volume
+ <%=t.t("volume")%>
- storage
- Snapshots + Snapshot
+ <%=t.t("snapshot")%>
@@ -490,8 +337,8 @@ long milliseconds = new Date().getTime();
- Network
- Network + IP Address + <%=t.t("ip.address")%> @@ -499,17 +346,10 @@ long milliseconds = new Date().getTime();
- Network
- IP Addresses + IP Address
+ <%=t.t("ip.address")%>
- -
-
-
- Network
- Network Groups -
-
+
@@ -517,8 +357,8 @@ long milliseconds = new Date().getTime();
- Templates
- Templates + Template
+ <%=t.t("template")%>
@@ -527,33 +367,33 @@ long milliseconds = new Date().getTime();
- Templates
- Template + Template
+ <%=t.t("template")%>
-
+ My Template
- My Templates
+ <%=t.t("my.template")%>
-
+ Community Template
- Community
+ <%=t.t("community.template")%>
@@ -563,7 +403,7 @@ long milliseconds = new Date().getTime();
Templates
- ISO + <%=t.t("iso")%>
@@ -572,7 +412,7 @@ long milliseconds = new Date().getTime();
- My ISOs
+ <%=t.t("my.iso")%>
@@ -588,7 +428,7 @@ long milliseconds = new Date().getTime();
- Community
+ <%=t.t("community.iso")%>
@@ -600,8 +440,8 @@ long milliseconds = new Date().getTime();
- Accounts
- Accounts + Account + <%=t.t("account")%> @@ -609,8 +449,8 @@ long milliseconds = new Date().getTime();
- Accounts
- Accounts + Account
+ <%=t.t("account")%>
@@ -621,7 +461,7 @@ long milliseconds = new Date().getTime();
Domain
- Domain + <%=t.t("domain")%> @@ -630,7 +470,7 @@ long milliseconds = new Date().getTime();
Domain
- Domain + <%=t.t("domain")%>
@@ -640,8 +480,8 @@ long milliseconds = new Date().getTime();
- Events
- Events + Event + <%=t.t("event")%> @@ -649,15 +489,15 @@ long milliseconds = new Date().getTime();
- Events
- Events + Event
+ <%=t.t("event")%>
- Events
- Alerts + Alert
+ <%=t.t("alert")%>
@@ -708,7 +548,7 @@ long milliseconds = new Date().getTime();