diff --git a/LICENSE b/LICENSE index 5e29e2b12bc..00afdb41fd6 100644 --- a/LICENSE +++ b/LICENSE @@ -370,7 +370,7 @@ Within the scripts/vm/hypervisor/xenserver directory from OpenStack, LLC http://www.openstack.org swift -Within the tools/appliance/definitions/systemvmtemplate directory +Within the tools/appliance/definitions/systemvmtemplate and tools/appliance/definitions/systemvmtemplate64 directory licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows) Copyright (c) 2010-2012 Patrick Debois diff --git a/api/src/com/cloud/agent/api/routing/DhcpEntryCommand.java b/api/src/com/cloud/agent/api/routing/DhcpEntryCommand.java index f0ce70e9a80..fd8d84c8c3a 100644 --- a/api/src/com/cloud/agent/api/routing/DhcpEntryCommand.java +++ b/api/src/com/cloud/agent/api/routing/DhcpEntryCommand.java @@ -31,6 +31,7 @@ public class DhcpEntryCommand extends NetworkElementCommand { String vmIp6Address; String ip6Gateway; String duid; + private boolean isDefault; protected DhcpEntryCommand() { @@ -46,6 +47,7 @@ public class DhcpEntryCommand extends NetworkElementCommand { this.vmIpAddress = vmIpAddress; this.vmName = vmName; this.vmIp6Address = vmIp6Address; + this.setDefault(true); } public DhcpEntryCommand(String vmMac, String vmIpAddress, String vmName, String vmIp6Address, String dns, String gateway, String ip6Gateway) { @@ -129,4 +131,12 @@ public class DhcpEntryCommand extends NetworkElementCommand { public void setVmIp6Address(String ip6Address) { this.vmIp6Address = ip6Address; } + + public boolean isDefault() { + return isDefault; + } + + public void setDefault(boolean isDefault) { + this.isDefault = isDefault; + } } diff --git a/api/src/org/apache/cloudstack/api/command/admin/resource/ArchiveAlertsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/resource/ArchiveAlertsCmd.java new file mode 100644 index 00000000000..2a1a47a13ed --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/resource/ArchiveAlertsCmd.java @@ -0,0 +1,100 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command.admin.resource; + +import java.util.Date; +import java.util.List; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.AlertResponse; +import org.apache.cloudstack.api.response.ConditionResponse; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.log4j.Logger; + +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.user.Account; + +@APICommand(name = "archiveAlerts", description = "Archive one or more alerts.", responseObject = SuccessResponse.class) +public class ArchiveAlertsCmd extends BaseCmd { + + public static final Logger s_logger = Logger.getLogger(ArchiveAlertsCmd.class.getName()); + + private static final String s_name = "archivealertsresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = AlertResponse.class, + description = "the IDs of the alerts") + private List ids; + + @Parameter(name=ApiConstants.OLDER_THAN, type=CommandType.DATE, description="archive alerts older than this date (use format \"yyyy-MM-dd\")") + private Date olderThan; + + @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "archive by alert type") + private String type; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public List getIds() { + return ids; + } + + public Date getOlderThan() { + return olderThan; + } + + public String getType() { + return type; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute() { + if(ids == null && type == null && olderThan == null) { + throw new InvalidParameterValueException("either ids, type or olderthan must be specified"); + } + boolean result = _mgr.archiveAlerts(this); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Unable to archive Alerts, one or more parameters has invalid values"); + } + } +} diff --git a/api/src/org/apache/cloudstack/api/command/admin/resource/DeleteAlertsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/resource/DeleteAlertsCmd.java new file mode 100644 index 00000000000..f03793c4f6d --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/resource/DeleteAlertsCmd.java @@ -0,0 +1,99 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command.admin.resource; + +import java.util.Date; +import java.util.List; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.AlertResponse; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.log4j.Logger; + +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.user.Account; + +@APICommand(name = "deleteAlerts", description = "Delete one or more alerts.", responseObject = SuccessResponse.class) +public class DeleteAlertsCmd extends BaseCmd { + + public static final Logger s_logger = Logger.getLogger(DeleteAlertsCmd.class.getName()); + + private static final String s_name = "deletealertsresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = AlertResponse.class, + description = "the IDs of the alerts") + private List ids; + + @Parameter(name=ApiConstants.OLDER_THAN, type=CommandType.DATE, description="delete alerts older than (including) this date (use format \"yyyy-MM-dd\")") + private Date olderThan; + + @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "delete by alert type") + private String type; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public List getIds() { + return ids; + } + + public Date getOlderThan() { + return olderThan; + } + + public String getType() { + return type; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute() { + if(ids == null && type == null && olderThan == null) { + throw new InvalidParameterValueException("either ids, type or olderthan must be specified"); + } + boolean result = _mgr.deleteAlerts(this); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Unable to delete Alerts, one or more parameters has invalid values"); + } + } +} diff --git a/api/src/org/apache/cloudstack/api/command/user/event/ArchiveEventsCmd.java b/api/src/org/apache/cloudstack/api/command/user/event/ArchiveEventsCmd.java new file mode 100644 index 00000000000..481607c9f0b --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/user/event/ArchiveEventsCmd.java @@ -0,0 +1,105 @@ +//Licensed to the Apache Software Foundation (ASF) under one +//or more contributor license agreements. See the NOTICE file +//distributed with this work for additional information +//regarding copyright ownership. The ASF licenses this file +//to you under the Apache License, Version 2.0 (the +//"License"); you may not use this file except in compliance +//with the License. You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, +//software distributed under the License is distributed on an +//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +//KIND, either express or implied. See the License for the +//specific language governing permissions and limitations +//under the License. +package org.apache.cloudstack.api.command.user.event; + +import java.util.Date; +import java.util.List; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.AlertResponse; +import org.apache.cloudstack.api.response.EventResponse; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.log4j.Logger; + +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@APICommand(name = "archiveEvents", description = "Archive one or more events.", responseObject = SuccessResponse.class) +public class ArchiveEventsCmd extends BaseCmd { + + public static final Logger s_logger = Logger.getLogger(ArchiveEventsCmd.class.getName()); + + private static final String s_name = "archiveeventsresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = EventResponse.class, + description = "the IDs of the events") + private List ids; + + @Parameter(name=ApiConstants.OLDER_THAN, type=CommandType.DATE, description="archive events older than (including) this date (use format \"yyyy-MM-dd\" or the new format \"yyyy-MM-dd HH:mm:ss\")") + private Date olderThan; + + @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "archive by event type") + private String type; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public List getIds() { + return ids; + } + + public Date getOlderThan() { + return olderThan; + } + + public String getType() { + return type; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Account account = UserContext.current().getCaller(); + if (account != null) { + return account.getId(); + } + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute() { + if(ids == null && type == null && olderThan == null) { + throw new InvalidParameterValueException("either ids, type or olderthan must be specified"); + } + boolean result = _mgr.archiveEvents(this); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Unable to archive Events, one or more parameters has invalid values"); + } + } +} diff --git a/api/src/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java b/api/src/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java new file mode 100644 index 00000000000..55ca92a5dfe --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java @@ -0,0 +1,105 @@ +//Licensed to the Apache Software Foundation (ASF) under one +//or more contributor license agreements. See the NOTICE file +//distributed with this work for additional information +//regarding copyright ownership. The ASF licenses this file +//to you under the Apache License, Version 2.0 (the +//"License"); you may not use this file except in compliance +//with the License. You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, +//software distributed under the License is distributed on an +//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +//KIND, either express or implied. See the License for the +//specific language governing permissions and limitations +//under the License. +package org.apache.cloudstack.api.command.user.event; + +import java.util.Date; +import java.util.List; + +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.AlertResponse; +import org.apache.cloudstack.api.response.EventResponse; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.log4j.Logger; + +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.user.Account; +import com.cloud.user.UserContext; + +@APICommand(name = "deleteEvents", description = "Delete one or more events.", responseObject = SuccessResponse.class) +public class DeleteEventsCmd extends BaseCmd { + + public static final Logger s_logger = Logger.getLogger(DeleteEventsCmd.class.getName()); + + private static final String s_name = "deleteeventsresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.IDS, type = CommandType.LIST, collectionType = CommandType.UUID, entityType = EventResponse.class, + description = "the IDs of the events") + private List ids; + + @Parameter(name=ApiConstants.OLDER_THAN, type=CommandType.DATE, description="delete events older than (including) this date (use format \"yyyy-MM-dd\" or the new format \"yyyy-MM-dd HH:mm:ss\")") + private Date olderThan; + + @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "delete by event type") + private String type; + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public List getIds() { + return ids; + } + + public Date getOlderThan() { + return olderThan; + } + + public String getType() { + return type; + } + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + Account account = UserContext.current().getCaller(); + if (account != null) { + return account.getId(); + } + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute() { + if(ids == null && type == null && olderThan == null) { + throw new InvalidParameterValueException("either ids, type or enddate must be specified"); + } + boolean result = _mgr.deleteEvents(this); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Unable to delete Events, one or more parameters has invalid values"); + } + } +} diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java index 1824612ebb0..3219601156e 100644 --- a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java @@ -52,7 +52,7 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd { private String hypervisor; @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = TemplateResponse.class, - description="list all isos by id") + description="list ISO by id") private Long id; @Parameter(name=ApiConstants.IS_PUBLIC, type=CommandType.BOOLEAN, description="true if the ISO is publicly available to all users, false otherwise.") @@ -61,11 +61,14 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd { @Parameter(name=ApiConstants.IS_READY, type=CommandType.BOOLEAN, description="true if this ISO is ready to be deployed") private Boolean ready; - @Parameter(name=ApiConstants.ISO_FILTER, type=CommandType.STRING, description="possible values are \"featured\", \"self\", \"self-executable\",\"executable\", and \"community\". " + - "* featured-ISOs that are featured and are publicself-ISOs that have been registered/created by the owner. " + - "* selfexecutable-ISOs that have been registered/created by the owner that can be used to deploy a new VM. " + - "* executable-all ISOs that can be used to deploy a new VM " + - "* community-ISOs that are public.") + @Parameter(name=ApiConstants.ISO_FILTER, type=CommandType.STRING, description="possible values are \"featured\", \"self\", \"selfexecutable\",\"sharedexecutable\",\"executable\", and \"community\". " + + "* featured : templates that have been marked as featured and public. " + + "* self : templates that have been registered or created by the calling user. " + + "* selfexecutable : same as self, but only returns templates that can be used to deploy a new VM. " + + "* sharedexecutable : templates ready to be deployed that have been granted to the calling user by another user. " + + "* executable : templates that are owned by the calling user, or public templates, that can be used to deploy a VM. " + + "* community : templates that have been marked as public but not featured. " + + "* all : all templates (only usable by admins).") private String isoFilter = TemplateFilter.selfexecutable.toString(); @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="list all isos by name") diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index 9dd471d6efa..7148e0710ca 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -600,6 +600,10 @@ public class VirtualRoutingResource implements Manager { command.add("-6", cmd.getVmIp6Address()); command.add("-u", cmd.getDuid()); } + + if (!cmd.isDefault()) { + command.add("-z"); + } final String result = command.execute(); return new Answer(cmd, result==null, result); diff --git a/packaging/centos63/cloud.spec b/packaging/centos63/cloud.spec index 002fbbb4d56..e340dd08c60 100644 --- a/packaging/centos63/cloud.spec +++ b/packaging/centos63/cloud.spec @@ -323,7 +323,10 @@ fi # change cloud user's home to 4.1+ version if needed. Would do this via 'usermod', but it # requires that cloud user not be in use, so RPM could not be installed while management is running -getent passwd cloud | grep -q /var/lib/cloud && sed -i 's/\/var\/lib\/cloud\/management/\/var\/cloudstack\/management/g' /etc/passwd +if getent passwd cloud | grep -q /var/lib/cloud; then + sed -i 's/\/var\/lib\/cloud\/management/\/var\/cloudstack\/management/g' /etc/passwd +fi + %post awsapi if [ -d "%{_datadir}/%{name}-management" ] ; then 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 4fb0a9bcde6..877ab06009d 100755 --- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config +++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config @@ -425,7 +425,6 @@ setup_dnsmasq() { sed -r -i s/^[#]?domain=.*$/domain=$DOMAIN/ /etc/dnsmasq.conf #answer all local domain queries sed -i -e "s/^[#]*local=.*$/local=\/$DOMAIN\//" /etc/dnsmasq.conf - fi if [ -n "$DNS_SEARCH_ORDER" ] @@ -447,6 +446,9 @@ setup_dnsmasq() { if [ $DHCP_RANGE_IP6 ] then sed -i -e "s/^dhcp-range_ip6=.*$/dhcp-range=$DHCP_RANGE_IP6,static/" /etc/dnsmasq.conf + # For nondefault6 tagged host, don't send dns-server information + sed -i /nondefault6/d /etc/dnsmasq.conf + echo "dhcp-option=nondefault6,option6:dns-server" >> /etc/dnsmasq.conf else sed -i -e "s/^dhcp-range_ip6=.*$//" /etc/dnsmasq.conf fi diff --git a/patches/systemvm/debian/config/root/edithosts.sh b/patches/systemvm/debian/config/root/edithosts.sh index 257de926724..9f21f206172 100755 --- a/patches/systemvm/debian/config/root/edithosts.sh +++ b/patches/systemvm/debian/config/root/edithosts.sh @@ -27,7 +27,7 @@ # $6 : comma separated static routes usage() { - printf "Usage: %s: -m -4 -6 -h -d -n -s -u \n" $(basename $0) >&2 + printf "Usage: %s: -m -4 -6 -h -d -n -s -u [-N]\n" $(basename $0) >&2 } mac= @@ -38,8 +38,9 @@ dflt= dns= routes= duid= +nondefault= -while getopts 'm:4:h:d:n:s:6:u:' OPTION +while getopts 'm:4:h:d:n:s:6:u:N' OPTION do case $OPTION in m) mac="$OPTARG" @@ -58,6 +59,8 @@ do ;; s) routes="$OPTARG" ;; + N) nondefault=1 + ;; ?) usage exit 2 ;; @@ -120,7 +123,12 @@ then fi if [ $ipv6 ] then - echo "id:$duid,[$ipv6],$host,infinite" >>$DHCP_HOSTS + if [ $nondefault ] + then + echo "id:$duid,set:nondefault6,[$ipv6],$host,infinite" >>$DHCP_HOSTS + else + echo "id:$duid,[$ipv6],$host,infinite" >>$DHCP_HOSTS + fi fi #delete leases to supplied mac and ip addresses @@ -176,8 +184,8 @@ then if [ "$dflt" == "0.0.0.0" ] then logger -t cloud "$0: unset default router for $ipv4" + logger -t cloud "$0: unset dns server for $ipv4" echo "$tag,3" >> $DHCP_OPTS - logger -t cloud "$0: setting dns server for $ipv4 to $dns" echo "$tag,6" >> $DHCP_OPTS echo "$tag,15" >> $DHCP_OPTS fi diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 83226a41db4..155d6d9718f 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -1755,7 +1755,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += " -6 " + cmd.getVmIp6Address(); args += " -u " + cmd.getDuid(); } - + + if (!cmd.isDefault()) { + args += " -N"; + } + if (s_logger.isDebugEnabled()) { s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/edithosts.sh " + args); } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixHelper.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixHelper.java index 1b8496ff287..828a8279f9a 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixHelper.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixHelper.java @@ -576,13 +576,12 @@ public class CitrixHelper { _xenServer610GuestOsMap.put("CentOS 5.6 (64-bit)", "CentOS 5 (64-bit)"); _xenServer610GuestOsMap.put("CentOS 5.7 (32-bit)", "CentOS 5 (32-bit)"); _xenServer610GuestOsMap.put("CentOS 5.7 (64-bit)", "CentOS 5 (64-bit)"); - _xenServer610GuestOsMap.put("CentOS 6.0 (32-bit)", "CentOS 6.0 (32-bit)"); - _xenServer610GuestOsMap.put("CentOS 6.0 (64-bit)", "CentOS 6.0 (64-bit)"); - _xenServer610GuestOsMap.put("CentOS 6.1 (32-bit)", "CentOS 6.1 (32-bit)"); - _xenServer610GuestOsMap.put("CentOS 6.1 (64-bit)", "CentOS 6.1 (64-bit)"); - _xenServer610GuestOsMap.put("CentOS 6.2 (32-bit)", "CentOS 6.2 (32-bit)"); - _xenServer610GuestOsMap.put("CentOS 6.2 (64-bit)", "CentOS 6.2 (64-bit)"); - _xenServer610GuestOsMap.put("Debian GNU/Linux 5.0 (32-bit)", "Debian Lenny 5.0 (32-bit)"); + _xenServer610GuestOsMap.put("CentOS 6.0 (32-bit)", "CentOS 6 (32-bit)"); + _xenServer610GuestOsMap.put("CentOS 6.0 (64-bit)", "CentOS 6 (64-bit)"); + _xenServer610GuestOsMap.put("CentOS 6.1 (32-bit)", "CentOS 6 (32-bit)"); + _xenServer610GuestOsMap.put("CentOS 6.1 (64-bit)", "CentOS 6 (64-bit)"); + _xenServer610GuestOsMap.put("CentOS 6.2 (32-bit)", "CentOS 6 (32-bit)"); + _xenServer610GuestOsMap.put("CentOS 6.2 (64-bit)", "CentOS 6 (64-bit)"); _xenServer610GuestOsMap.put("Debian GNU/Linux 6(32-bit)", "Debian Squeeze 6.0 (32-bit)"); _xenServer610GuestOsMap.put("Debian GNU/Linux 6(64-bit)", "Debian Squeeze 6.0 (64-bit)"); _xenServer610GuestOsMap.put("Oracle Enterprise Linux 5.0 (32-bit)", "Oracle Enterprise Linux 5 (32-bit)"); @@ -601,12 +600,12 @@ public class CitrixHelper { _xenServer610GuestOsMap.put("Oracle Enterprise Linux 5.6 (64-bit)", "Oracle Enterprise Linux 5 (64-bit)"); _xenServer610GuestOsMap.put("Oracle Enterprise Linux 5.7 (32-bit)", "Oracle Enterprise Linux 5 (32-bit)"); _xenServer610GuestOsMap.put("Oracle Enterprise Linux 5.7 (64-bit)", "Oracle Enterprise Linux 5 (64-bit)"); - _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.0 (32-bit)", "Oracle Enterprise Linux 6.0 (32-bit)"); - _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.0 (64-bit)", "Oracle Enterprise Linux 6.0 (64-bit)"); - _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.1 (32-bit)", "Oracle Enterprise Linux 6.1 (32-bit)"); - _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.1 (64-bit)", "Oracle Enterprise Linux 6.1 (64-bit)"); - _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.2 (32-bit)", "Oracle Enterprise Linux 6.2 (32-bit)"); - _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.2 (64-bit)", "Oracle Enterprise Linux 6.2 (64-bit)"); + _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.0 (32-bit)", "Oracle Enterprise Linux 6 (32-bit)"); + _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.0 (64-bit)", "Oracle Enterprise Linux 6 (64-bit)"); + _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.1 (32-bit)", "Oracle Enterprise Linux 6 (32-bit)"); + _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.1 (64-bit)", "Oracle Enterprise Linux 6 (64-bit)"); + _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.2 (32-bit)", "Oracle Enterprise Linux 6 (32-bit)"); + _xenServer610GuestOsMap.put("Oracle Enterprise Linux 6.2 (64-bit)", "Oracle Enterprise Linux 6 (64-bit)"); _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 4.5 (32-bit)", "Red Hat Enterprise Linux 4.5 (32-bit)"); _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 4.6 (32-bit)", "Red Hat Enterprise Linux 4.6 (32-bit)"); _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 4.7 (32-bit)", "Red Hat Enterprise Linux 4.7 (32-bit)"); @@ -627,12 +626,12 @@ public class CitrixHelper { _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 5.6 (64-bit)", "Red Hat Enterprise Linux 5 (64-bit)"); _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 5.7 (32-bit)", "Red Hat Enterprise Linux 5 (32-bit)"); _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 5.7 (64-bit)", "Red Hat Enterprise Linux 5 (64-bit)"); - _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.0 (32-bit)", "Red Hat Enterprise Linux 6.0 (32-bit)"); - _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.0 (64-bit)", "Red Hat Enterprise Linux 6.0 (64-bit)"); - _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.1 (32-bit)", "Red Hat Enterprise Linux 6.1 (32-bit)"); - _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.1 (64-bit)", "Red Hat Enterprise Linux 6.1 (64-bit)"); - _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.2 (32-bit)", "Red Hat Enterprise Linux 6.2 (32-bit)"); - _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.2 (64-bit)", "Red Hat Enterprise Linux 6.2 (64-bit)"); + _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.0 (32-bit)", "Red Hat Enterprise Linux 6 (32-bit)"); + _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.0 (64-bit)", "Red Hat Enterprise Linux 6 (64-bit)"); + _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.1 (32-bit)", "Red Hat Enterprise Linux 6 (32-bit)"); + _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.1 (64-bit)", "Red Hat Enterprise Linux 6 (64-bit)"); + _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.2 (32-bit)", "Red Hat Enterprise Linux 6 (32-bit)"); + _xenServer610GuestOsMap.put("Red Hat Enterprise Linux 6.2 (64-bit)", "Red Hat Enterprise Linux 6 (64-bit)"); _xenServer610GuestOsMap.put("SUSE Linux Enterprise Server 9 SP4 (32-bit)", "SUSE Linux Enterprise Server 10 SP1 (32-bit)"); _xenServer610GuestOsMap.put("SUSE Linux Enterprise Server 10 SP1 (32-bit)", "SUSE Linux Enterprise Server 10 SP1 (32-bit)"); _xenServer610GuestOsMap.put("SUSE Linux Enterprise Server 10 SP1 (64-bit)", "SUSE Linux Enterprise Server 10 SP1 (64-bit)"); @@ -662,13 +661,15 @@ public class CitrixHelper { _xenServer610GuestOsMap.put("Windows Server 2008 (32-bit)", "Windows Server 2008 (32-bit)"); _xenServer610GuestOsMap.put("Windows Server 2008 (64-bit)", "Windows Server 2008 (64-bit)"); _xenServer610GuestOsMap.put("Windows Server 2008 R2 (64-bit)", "Windows Server 2008 R2 (64-bit)"); - _xenServer610GuestOsMap.put("Windows Server 8 (64-bit)", "Windows Server 8 (64-bit) (experimental)"); + _xenServer610GuestOsMap.put("Windows Server 8 (64-bit)", "Windows Server 2012 (64-bit) (experimental)"); _xenServer610GuestOsMap.put("Windows Vista (32-bit)", "Windows Vista (32-bit)"); _xenServer610GuestOsMap.put("Windows XP SP3 (32-bit)", "Windows XP SP3 (32-bit)"); _xenServer610GuestOsMap.put("Ubuntu 10.04 (32-bit)", "Ubuntu Lucid Lynx 10.04 (32-bit)"); _xenServer610GuestOsMap.put("Ubuntu 10.04 (64-bit)", "Ubuntu Lucid Lynx 10.04 (64-bit)"); _xenServer610GuestOsMap.put("Ubuntu 10.10 (32-bit)", "Ubuntu Maverick Meerkat 10.10 (32-bit) (experimental)"); _xenServer610GuestOsMap.put("Ubuntu 10.10 (64-bit)", "Ubuntu Maverick Meerkat 10.10 (64-bit) (experimental)"); + _xenServer610GuestOsMap.put("Ubuntu 12.04 (32-bit)", "Ubuntu Precise Pangolin 12.04 (32-bit)"); + _xenServer610GuestOsMap.put("Ubuntu 12.04 (64-bit)", "Ubuntu Precise Pangolin 12.04 (64-bit)"); _xenServer610GuestOsMap.put("Other Linux (32-bit)", "Other install media"); _xenServer610GuestOsMap.put("Other Linux (64-bit)", "Other install media"); _xenServer610GuestOsMap.put("Other (32-bit)", "Other install media"); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 4a89806a49f..886fc6f04fa 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -1890,6 +1890,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe args += " -u " + cmd.getDuid(); } + if (!cmd.isDefault()) { + args += " -z"; + } + String result = callHostPlugin(conn, "vmops", "saveDhcpEntry", "args", args); if (result == null || result.isEmpty()) { return new Answer(cmd, false, "DhcpEntry failed"); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java index 17ad3e62383..8d267b114fa 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java @@ -40,7 +40,7 @@ public class XenServer610Resource extends XenServer56FP1Resource { @Override protected String getGuestOsType(String stdType, boolean bootFromCD) { - return CitrixHelper.getXenServer602GuestOsType(stdType, bootFromCD); + return CitrixHelper.getXenServer610GuestOsType(stdType, bootFromCD); } @Override diff --git a/pom.xml b/pom.xml index 6b0a9ccfeac..86482d7a77b 100644 --- a/pom.xml +++ b/pom.xml @@ -381,6 +381,11 @@ tools/appliance/definitions/systemvmtemplate/definition.rb tools/appliance/definitions/systemvmtemplate/preseed.cfg tools/appliance/definitions/systemvmtemplate/zerodisk.sh + tools/appliance/definitions/systemvmtemplate64/base.sh + tools/appliance/definitions/systemvmtemplate64/cleanup.sh + tools/appliance/definitions/systemvmtemplate64/definition.rb + tools/appliance/definitions/systemvmtemplate64/preseed.cfg + tools/appliance/definitions/systemvmtemplate64/zerodisk.sh tools/cli/cloudmonkey.egg-info/* tools/devcloud/src/deps/boxes/basebox-build/definition.rb tools/devcloud/src/deps/boxes/basebox-build/preseed.cfg diff --git a/scripts/network/domr/dhcp_entry.sh b/scripts/network/domr/dhcp_entry.sh index e417f7273a2..fb5a1669e72 100755 --- a/scripts/network/domr/dhcp_entry.sh +++ b/scripts/network/domr/dhcp_entry.sh @@ -22,7 +22,7 @@ # @VERSION@ usage() { - printf "Usage: %s: -r -m -v -n -s -d -N -6 -u \n" $(basename $0) >&2 + printf "Usage: %s: -r -m -v -n -s -d -N -6 -u [-z]\n" $(basename $0) >&2 exit 2 } @@ -40,7 +40,7 @@ duid= opts= -while getopts 'r:m:v:n:d:s:N:6:u:' OPTION +while getopts 'r:m:v:n:d:s:N:6:u:z' OPTION do case $OPTION in r) domrIp="$OPTARG" @@ -69,6 +69,8 @@ do u) duid="$OPTARG" opts="$opts -u $duid" ;; + z) opts="$opts -N" + ;; ?) usage exit 1 ;; diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 35fe2f35275..951d09ed185 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -1518,7 +1518,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { // pagination _accountMgr.buildACLViewSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); - sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); + sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("volumeType", sb.entity().getVolumeType(), SearchCriteria.Op.LIKE); sb.and("instanceId", sb.entity().getVmId(), SearchCriteria.Op.EQ); @@ -1555,7 +1555,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } if (name != null) { - sc.setParameters("name", "%" + name + "%"); + sc.setParameters("name", name); } sc.setParameters("systemUse", 1); diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index b387ab5934c..3cbd51d4cc4 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -3116,9 +3116,9 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V if (guestOS.getDisplayName().startsWith(name)) { needGateway = true; break; + } } } - } if (!needGateway) { gatewayIp = "0.0.0.0"; } @@ -3126,6 +3126,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V dhcpCommand.setIp6Gateway(nic.getIp6Gateway()); dhcpCommand.setDefaultDns(findDefaultDnsIp(vm.getId())); dhcpCommand.setDuid(NetUtils.getDuidLL(nic.getMacAddress())); + dhcpCommand.setDefault(nic.isDefaultNic()); dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); dhcpCommand.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java index 45a9a242147..33feb5dd57e 100755 --- a/server/src/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/com/cloud/projects/ProjectManagerImpl.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.Properties; import java.util.Random; import java.util.TimeZone; +import java.util.UUID; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -204,7 +205,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { StringBuilder acctNm = new StringBuilder("PrjAcct-"); acctNm.append(name).append("-").append(owner.getDomainId()); - Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, "", 0); + Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null, UUID.randomUUID().toString(), 0); Project project = _projectDao.persist(new ProjectVO(name, displayText, owner.getDomainId(), projectAccount.getId())); diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index f0e60283067..4951975786f 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -813,6 +813,8 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { Long diskOfferingId = null; DiskOfferingVO diskOffering = null; Long size = null; + // Volume VO used for extracting the source template id + VolumeVO parentVolume = null; // validate input parameters before creating the volume if ((cmd.getSnapshotId() == null && cmd.getDiskOfferingId() == null) @@ -891,6 +893,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { + snapshotId + " is not in " + Snapshot.State.BackedUp + " state yet and can't be used for volume creation"); } + parentVolume = _volsDao.findByIdIncludingRemoved(snapshotCheck.getVolumeId()); diskOfferingId = snapshotCheck.getDiskOfferingId(); diskOffering = _diskOfferingDao.findById(diskOfferingId); @@ -947,6 +950,11 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { volume.setUpdated(new Date()); volume.setDomainId((caller == null) ? Domain.ROOT_DOMAIN : caller .getDomainId()); + if (parentVolume != null) { + volume.setTemplateId(parentVolume.getTemplateId()); + } else { + volume.setTemplateId(null); + } volume = _volsDao.persist(volume); if (cmd.getSnapshotId() == null) { diff --git a/server/src/com/cloud/user/DomainManagerImpl.java b/server/src/com/cloud/user/DomainManagerImpl.java index 9f0ad53c94b..babaed37494 100644 --- a/server/src/com/cloud/user/DomainManagerImpl.java +++ b/server/src/com/cloud/user/DomainManagerImpl.java @@ -365,7 +365,7 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom SearchBuilder sb = _domainDao.createSearchBuilder(); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); - sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); + sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); sb.and("level", sb.entity().getLevel(), SearchCriteria.Op.EQ); sb.and("path", sb.entity().getPath(), SearchCriteria.Op.LIKE); sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ); @@ -379,7 +379,7 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom } if (domainName != null) { - sc.setParameters("name", "%" + domainName + "%"); + sc.setParameters("name", domainName); } if (level != null) { @@ -492,7 +492,7 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom if (!domains.isEmpty() && !sameDomain) { InvalidParameterValueException ex = new InvalidParameterValueException("Failed to update specified domain id with name '" + domainName + "' since it already exists in the system"); - ex.addProxyObject(domain, domainId, "domainId"); + ex.addProxyObject(domain, domainId, "domainId"); throw ex; } } diff --git a/server/src/org/apache/cloudstack/region/RegionManagerImpl.java b/server/src/org/apache/cloudstack/region/RegionManagerImpl.java index b4b55fd5a90..cb0b1a69ad8 100755 --- a/server/src/org/apache/cloudstack/region/RegionManagerImpl.java +++ b/server/src/org/apache/cloudstack/region/RegionManagerImpl.java @@ -29,11 +29,11 @@ import com.cloud.user.DomainManager; import com.cloud.user.UserAccount; import com.cloud.user.UserVO; import com.cloud.user.dao.AccountDao; +import com.cloud.user.dao.UserAccountDao; import com.cloud.user.dao.UserDao; import com.cloud.utils.component.Manager; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.uuididentity.dao.IdentityDao; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd; import org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd; @@ -69,7 +69,7 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man @Inject private DomainManager _domainMgr; @Inject - private IdentityDao _identityDao; + private UserAccountDao _userAccountDao; private String _name; private int _id; @@ -251,7 +251,6 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man String command = "updateAccount"; List params = new ArrayList(); - params.add(new NameValuePair(ApiConstants.NEW_NAME, newAccountName)); params.add(new NameValuePair(ApiConstants.ID, account.getUuid())); params.add(new NameValuePair(ApiConstants.ACCOUNT, accountName)); params.add(new NameValuePair(ApiConstants.DOMAIN_ID, domain.getUuid())); @@ -266,14 +265,9 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man } else { //First update in the Region where account is created Region region = _regionDao.findById(regionId); - RegionAccount updatedAccount = RegionsApiUtil.makeAccountAPICall(region, command, params); - if (updatedAccount != null) { - Long id = _identityDao.getIdentityId("account", updatedAccount.getUuid()); - updatedAccount.setId(id); - Long domainID = _identityDao.getIdentityId("domain", updatedAccount.getDomainUuid()); - updatedAccount.setDomainId(domainID); + if (RegionsApiUtil.makeAPICall(region, command, params)) { s_logger.debug("Successfully updated account :"+account.getUuid()+" in source Region: "+region.getId()); - return updatedAccount; + return account; } else { throw new CloudRuntimeException("Error while updating account :"+account.getUuid()+" in source Region: "+region.getId()); } @@ -319,10 +313,9 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man } else { //First disable account in the Region where account is created Region region = _regionDao.findById(regionId); - Account retAccount = RegionsApiUtil.makeAccountAPICall(region, command, params); - if (retAccount != null) { + if (RegionsApiUtil.makeAPICall(region, command, params)) { s_logger.debug("Successfully disabled account :"+accountUUID+" in source Region: "+region.getId()); - return retAccount; + return account; } else { throw new CloudRuntimeException("Error while disabling account :"+accountUUID+" in source Region: "+region.getId()); } @@ -363,10 +356,9 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man } else { //First disable account in the Region where account is created Region region = _regionDao.findById(regionId); - Account retAccount = RegionsApiUtil.makeAccountAPICall(region, command, params); - if (retAccount != null) { + if (RegionsApiUtil.makeAPICall(region, command, params)) { s_logger.debug("Successfully enabled account :"+accountUUID+" in source Region: "+region.getId()); - return retAccount; + return account; } else { throw new CloudRuntimeException("Error while enabling account :"+accountUUID+" in source Region: "+region.getId()); } @@ -433,12 +425,9 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man } else { //First update in the Region where domain was created Region region = _regionDao.findById(regionId); - RegionDomain updatedDomain = RegionsApiUtil.makeDomainAPICall(region, command, params); - if (updatedDomain != null) { - Long parentId = _identityDao.getIdentityId("domain", updatedDomain.getParentUuid()); - updatedDomain.setParent(parentId); + if (RegionsApiUtil.makeAPICall(region, command, params)) { s_logger.debug("Successfully updated user :"+domainUUID+" in source Region: "+region.getId()); - return (DomainVO)updatedDomain; + return domain; } else { throw new CloudRuntimeException("Error while updating user :"+domainUUID+" in source Region: "+region.getId()); } @@ -510,10 +499,9 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man } else { //First update in the Region where user was created Region region = _regionDao.findById(regionId); - UserAccount updateUser = RegionsApiUtil.makeUserAccountAPICall(region, command, params); - if (updateUser != null) { + if (RegionsApiUtil.makeAPICall(region, command, params)) { s_logger.debug("Successfully updated user :"+userUUID+" in source Region: "+region.getId()); - return updateUser; + return _userAccountDao.findById(id); } else { throw new CloudRuntimeException("Error while updating user :"+userUUID+" in source Region: "+region.getId()); } @@ -541,10 +529,9 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man } else { //First disable in the Region where user was created Region region = _regionDao.findById(regionId); - UserAccount disabledUser = RegionsApiUtil.makeUserAccountAPICall(region, command, params); - if (disabledUser != null) { + if (RegionsApiUtil.makeAPICall(region, command, params)) { s_logger.debug("Successfully disabled user :"+user.getUuid()+" in source Region: "+region.getId()); - return disabledUser; + return _userAccountDao.findById(userId); } else { throw new CloudRuntimeException("Error while disabling user :"+user.getUuid()+" in source Region: "+region.getId()); } @@ -572,10 +559,9 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man } else { //First enable in the Region where user was created Region region = _regionDao.findById(regionId); - UserAccount enabledUser = RegionsApiUtil.makeUserAccountAPICall(region, command, params); - if (enabledUser != null) { + if (RegionsApiUtil.makeAPICall(region, command, params)) { s_logger.debug("Successfully enabled user :"+user.getUuid()+" in source Region: "+region.getId()); - return enabledUser; + return _userAccountDao.findById(userId); } else { throw new CloudRuntimeException("Error while enabling user :"+user.getUuid()+" in source Region: "+region.getId()); } diff --git a/server/test/com/cloud/alert/AlertControlsUnitTest.java b/server/test/com/cloud/alert/AlertControlsUnitTest.java new file mode 100644 index 00000000000..c1e4c5487f1 --- /dev/null +++ b/server/test/com/cloud/alert/AlertControlsUnitTest.java @@ -0,0 +1,83 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.alert; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyList; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; + +import java.util.Date; + +import junit.framework.TestCase; + +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; + +import com.cloud.alert.dao.AlertDao; +import com.cloud.server.ManagementServerImpl; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; + +public class AlertControlsUnitTest extends TestCase { + private static final Logger s_logger = Logger.getLogger(AlertControlsUnitTest.class); + + @Spy ManagementServerImpl _mgmtServer = new ManagementServerImpl(); + @Mock AccountManager _accountMgr; + @Mock AlertDao _alertDao; + @Override + @Before + protected void setUp() { + MockitoAnnotations.initMocks(this); + _mgmtServer._alertDao = _alertDao; + _mgmtServer._accountMgr = _accountMgr; + doReturn(3L).when(_accountMgr).checkAccessAndSpecifyAuthority(any(Account.class), anyLong()); + when(_alertDao.archiveAlert(anyList(), anyString(), any(Date.class), anyLong())).thenReturn(true); + when(_alertDao.deleteAlert(anyList(), anyString(), any(Date.class), anyLong())).thenReturn(true); + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testInjected() throws Exception { + s_logger.info("Starting test to archive and delete alerts"); + archiveAlerts(); + deleteAlerts(); + s_logger.info("archive/delete alerts: TEST PASSED"); + } + + protected void archiveAlerts() { + // archive alerts + String msg = "Archive Alerts: TEST FAILED"; + assertNotNull(msg, _mgmtServer._alertDao.archiveAlert(null, "system alert",null, 2L)); + } + + protected void deleteAlerts() { + // delete alerts + String msg = "Delete Alerts: TEST FAILED"; + assertNotNull(msg, _mgmtServer._alertDao.deleteAlert(null, "system alert",null, 2L)); + } +} diff --git a/server/test/com/cloud/event/EventControlsUnitTest.java b/server/test/com/cloud/event/EventControlsUnitTest.java new file mode 100644 index 00000000000..3c2527565c9 --- /dev/null +++ b/server/test/com/cloud/event/EventControlsUnitTest.java @@ -0,0 +1,84 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.event; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyList; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.when; + +import java.util.Date; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; + +import com.cloud.event.dao.EventDao; +import com.cloud.server.ManagementServerImpl; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; + +public class EventControlsUnitTest extends TestCase{ + private static final Logger s_logger = Logger.getLogger(EventControlsUnitTest.class); + + @Spy ManagementServerImpl _mgmtServer = new ManagementServerImpl(); + @Mock AccountManager _accountMgr; + @Mock EventDao _eventDao; + List _events = null; + + @Override + @Before + protected void setUp() { + MockitoAnnotations.initMocks(this); + _mgmtServer._eventDao = _eventDao; + _mgmtServer._accountMgr = _accountMgr; + doNothing().when(_accountMgr).checkAccess(any(Account.class), any(AccessType.class), any(Boolean.class), any(ControlledEntity.class)); + when(_eventDao.listToArchiveOrDeleteEvents(anyList(), anyString(), any(Date.class), anyLong())).thenReturn(_events); + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testInjected() throws Exception { + s_logger.info("Starting test to archive and delete events"); + archiveEvents(); + deleteEvents(); + s_logger.info("archive/delete events: TEST PASSED"); + } + + protected void archiveEvents() { + // archive alerts + doNothing().when(_eventDao).archiveEvents(_events); + } + + protected void deleteEvents() { + // delete alerts + } +} diff --git a/tools/appliance/README.md b/tools/appliance/README.md index 2f6f656212d..559f79c6adb 100644 --- a/tools/appliance/README.md +++ b/tools/appliance/README.md @@ -43,7 +43,7 @@ Note, gem may require gcc-4.2, make sure link exists: Just run build.sh, it will export archived appliances for KVM, Xen, VMWare and HyperV in `dist`: - sh build.sh + sh build.sh [systemvmtemplate|systemvmtemplate64] # Building SystemVM template appliance manually @@ -51,7 +51,7 @@ List available appliances one can build: veewee vbox list -Modify scripts in definitions/systemvmtemplate/ as per needs. +Modify scripts in definitions/*appliance*/ as per needs. Build systemvm template appliance: veewee vbox build 'systemvmtemplate' diff --git a/tools/appliance/build.sh b/tools/appliance/build.sh index 69e15d88ca7..d18faaf7ce6 100644 --- a/tools/appliance/build.sh +++ b/tools/appliance/build.sh @@ -18,7 +18,13 @@ set -x -appliance="systemvmtemplate" +if [ "$1"!="" ] +then + appliance="$1" +else + appliance="systemvmtemplate" +fi + build_date=`date +%Y-%m-%d` branch="master" rootdir=$PWD @@ -46,7 +52,7 @@ hdd_path=`vboxmanage list hdds | grep $appliance | grep vdi | cut -c 14-` shared_folders=`vboxmanage showvminfo $appliance | grep Name | grep Host` while [ "$shared_folders" != "" ] do - vboxmanage sharedfolder remove systemvmtemplate --name "`echo $shared_folders | head -1 | cut -c 8- | cut -d \' -f 1`" + vboxmanage sharedfolder remove $appliance --name "`echo $shared_folders | head -1 | cut -c 8- | cut -d \' -f 1`" shared_folders=`vboxmanage showvminfo $appliance | grep Name | grep Host` done diff --git a/tools/appliance/definitions/systemvmtemplate64/base.sh b/tools/appliance/definitions/systemvmtemplate64/base.sh new file mode 100644 index 00000000000..d6faea04b41 --- /dev/null +++ b/tools/appliance/definitions/systemvmtemplate64/base.sh @@ -0,0 +1,25 @@ +# Update the box +apt-get -y update +#apt-get -y install linux-headers-$(uname -r) build-essential +#apt-get -y install zlib1g-dev libssl-dev libreadline-gplv2-dev +apt-get -y install curl unzip + +# Set up sudo +echo 'vagrant ALL=NOPASSWD:ALL' > /etc/sudoers.d/vagrant + +# Tweak sshd to prevent DNS resolution (speed up logins) +echo 'UseDNS no' >> /etc/ssh/sshd_config + +# Remove 5s grub timeout to speed up booting +cat < /etc/default/grub +# If you change this file, run 'update-grub' afterwards to update +# /boot/grub/grub.cfg. + +GRUB_DEFAULT=0 +GRUB_TIMEOUT=0 +GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` +GRUB_CMDLINE_LINUX_DEFAULT="quiet" +GRUB_CMDLINE_LINUX="debian-installer=en_US" +EOF + +update-grub diff --git a/tools/appliance/definitions/systemvmtemplate64/cleanup.sh b/tools/appliance/definitions/systemvmtemplate64/cleanup.sh new file mode 100644 index 00000000000..9e98ab03531 --- /dev/null +++ b/tools/appliance/definitions/systemvmtemplate64/cleanup.sh @@ -0,0 +1,21 @@ +# Clean up +#apt-get -y remove linux-headers-$(uname -r) build-essential +apt-get -y remove dictionaries-common busybox +apt-get -y autoremove +apt-get autoclean +apt-get clean + +# Removing leftover leases and persistent rules +echo "cleaning up dhcp leases" +rm /var/lib/dhcp/* + +# Make sure Udev doesn't block our network +echo "cleaning up udev rules" +rm /etc/udev/rules.d/70-persistent-net.rules +mkdir /etc/udev/rules.d/70-persistent-net.rules +rm -rf /dev/.udev/ +rm /lib/udev/rules.d/75-persistent-net-generator.rules + +echo "Adding a 2 sec delay to the interface up, to make the dhclient happy" +echo "pre-up sleep 2" >> /etc/network/interfaces + diff --git a/tools/appliance/definitions/systemvmtemplate64/definition.rb b/tools/appliance/definitions/systemvmtemplate64/definition.rb new file mode 100644 index 00000000000..35ef878d35a --- /dev/null +++ b/tools/appliance/definitions/systemvmtemplate64/definition.rb @@ -0,0 +1,45 @@ +Veewee::Definition.declare({ + :cpu_count => '1', + :memory_size=> '256', + :disk_size => '2000', :disk_format => 'VDI', :hostiocache => 'off', + :os_type_id => 'Debian_64', + :iso_file => "debian-wheezy-DI-rc1-amd64-netinst.iso", + :iso_src => "http://cdimage.debian.org/cdimage/wheezy_di_rc1/amd64/iso-cd/debian-wheezy-DI-rc1-amd64-netinst.iso", + :iso_md5 => "412f77d4b98adf2a7d575745fd282d78", + :iso_download_timeout => "1000", + :boot_wait => "10", :boot_cmd_sequence => [ + '', + 'install ', + 'preseed/url=http://%IP%:%PORT%/preseed.cfg ', + 'debian-installer=en_US ', + 'auto ', + 'locale=en_US ', + 'kbd-chooser/method=us ', + 'netcfg/get_hostname=systemvm ', + 'netcfg/get_domain=apache.org ', + 'fb=false ', + 'debconf/frontend=noninteractive ', + 'console-setup/ask_detect=false ', + 'console-keymaps-at/keymap=us ', + 'keyboard-configuration/xkb-keymap=us ', + '' + ], + :kickstart_port => "7122", + :kickstart_timeout => "10000", + :kickstart_file => "preseed.cfg", + :ssh_login_timeout => "10000", + :ssh_user => "root", + :ssh_password => "password", + :ssh_key => "", + :ssh_host_port => "7222", + :ssh_guest_port => "22", + :sudo_cmd => "echo '%p'|sudo -S sh '%f'", + :shutdown_cmd => "halt -p", + :postinstall_files => [ + "base.sh", + "postinstall.sh", + "cleanup.sh", + "zerodisk.sh" + ], + :postinstall_timeout => "10000" +}) diff --git a/tools/appliance/definitions/systemvmtemplate64/postinstall.sh b/tools/appliance/definitions/systemvmtemplate64/postinstall.sh new file mode 100644 index 00000000000..8e745eb1ba9 --- /dev/null +++ b/tools/appliance/definitions/systemvmtemplate64/postinstall.sh @@ -0,0 +1,220 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +set -x + +ROOTPW=password +HOSTNAME=systemvm +CLOUDSTACK_RELEASE=4.2.0 + +install_packages() { + DEBIAN_FRONTEND=noninteractive + DEBIAN_PRIORITY=critical + + # Basic packages + apt-get --no-install-recommends -q -y --force-yes install rsyslog logrotate cron chkconfig insserv net-tools ifupdown vim-tiny netbase iptables + apt-get --no-install-recommends -q -y --force-yes install openssh-server openssl e2fsprogs dhcp3-client tcpdump socat wget + # apt-get --no-install-recommends -q -y --force-yes install grub-legacy + apt-get --no-install-recommends -q -y --force-yes install python bzip2 sed gawk diffutils grep gzip less tar telnet ftp rsync traceroute psmisc lsof procps monit inetutils-ping iputils-arping httping + apt-get --no-install-recommends -q -y --force-yes install dnsutils zip unzip ethtool uuid file iproute acpid virt-what sudo + + # sysstat + echo 'sysstat sysstat/enable boolean true' | debconf-set-selections + apt-get --no-install-recommends -q -y --force-yes install sysstat + # apache + apt-get --no-install-recommends -q -y --force-yes install apache2 ssl-cert + # haproxy + apt-get --no-install-recommends -q -y --force-yes install haproxy + # dnsmasq + apt-get --no-install-recommends -q -y --force-yes install dnsmasq + # nfs client + apt-get --no-install-recommends -q -y --force-yes install nfs-common + + # vpn stuff + apt-get --no-install-recommends -q -y --force-yes install xl2tpd bcrelay ppp ipsec-tools tdb-tools + echo "openswan openswan/install_x509_certificate boolean false" | debconf-set-selections + echo "openswan openswan/install_x509_certificate seen true" | debconf-set-selections + apt-get --no-install-recommends -q -y --force-yes install openswan + + # vmware tools + apt-get --no-install-recommends -q -y --force-yes install open-vm-tools + # xenstore utils + apt-get --no-install-recommends -q -y --force-yes install xenstore-utils libxenstore3.0 + # keepalived and conntrackd for redundant router + apt-get --no-install-recommends -q -y --force-yes install keepalived conntrackd ipvsadm libnetfilter-conntrack3 libnl1 + # ipcalc + apt-get --no-install-recommends -q -y --force-yes install ipcalc + # java + apt-get --no-install-recommends -q -y --force-yes install default-jre-headless + + echo "iptables-persistent iptables-persistent/autosave_v4 boolean true" | debconf-set-selections + echo "iptables-persistent iptables-persistent/autosave_v6 boolean true" | debconf-set-selections + apt-get --no-install-recommends -q -y --force-yes install iptables-persistent +} + +setup_accounts() { + # Setup sudo to allow no-password sudo for "admin" + groupadd -r admin + # Create a 'cloud' user if it's not there + id cloud + if [[ $? -ne 0 ]] + then + useradd -G admin cloud + else + usermod -a -G admin cloud + fi + echo "root:$ROOTPW" | chpasswd + echo "cloud:`openssl rand -base64 32`" | chpasswd + sed -i -e '/Defaults\s\+env_reset/a Defaults\texempt_group=admin' /etc/sudoers + sed -i -e 's/%admin ALL=(ALL) ALL/%admin ALL=NOPASSWD:ALL/g' /etc/sudoers + # Disable password based authentication via ssh, this will take effect on next reboot + sed -i -e 's/^.*PasswordAuthentication .*$/PasswordAuthentication no/g' /etc/ssh/sshd_config + # Secure ~/.ssh + mkdir -p /home/cloud/.ssh + chmod 700 /home/cloud/.ssh +} + +fix_nameserver() { + # Replace /etc/resolv.conf also + cat > /etc/resolv.conf << EOF +nameserver 8.8.8.8 +nameserver 4.4.4.4 +EOF +} + +fix_inittab() { + # Fix inittab + cat >> /etc/inittab << EOF + +vc:2345:respawn:/sbin/getty 38400 hvc0 +EOF +} + +fix_acpid() { + # Fix acpid + mkdir -p /etc/acpi/events + cat >> /etc/acpi/events/power << EOF +event=button/power.* +action=/usr/local/sbin/power.sh "%e" +EOF + cat >> /usr/local/sbin/power.sh << EOF +#!/bin/bash +/sbin/poweroff +EOF + chmod a+x /usr/local/sbin/power.sh +} + +fix_hostname() { + # Fix hostname in openssh-server generated keys + sed -i "s/root@\(.*\)$/root@$HOSTNAME/g" /etc/ssh/ssh_host_*.pub + # Fix hostname to override one provided by dhcp during vm build + echo "$HOSTNAME" > /etc/hostname + hostname $HOSTNAME + # Delete entry in /etc/hosts derived from dhcp + sed -i '/127.0.1.1/d' /etc/hosts +} + +fix_locale() { + cat >> /etc/default/locale << EOF +LANG=en_US.UTF-8 +LC_ALL=en_US.UTF-8 +EOF + cat >> /etc/locale.gen << EOF +en_US.UTF-8 UTF-8 +EOF + + locale-gen en_US.UTF-8 +} + +do_fixes() { + fix_nameserver + fix_inittab + fix_acpid + fix_hostname + fix_locale +} + +configure_apache2() { + # Enable ssl, rewrite and auth + a2enmod ssl rewrite auth_basic auth_digest + a2ensite default-ssl + # Backup stock apache configuration since we may modify it in Secondary Storage VM + cp /etc/apache2/sites-available/default /etc/apache2/sites-available/default.orig + cp /etc/apache2/sites-available/default-ssl /etc/apache2/sites-available/default-ssl.orig +} + +configure_services() { + mkdir -p /var/www/html + mkdir -p /opt/cloud/bin + mkdir -p /var/cache/cloud + mkdir -p /usr/share/cloud + mkdir -p /usr/local/cloud + mkdir -p /root/.ssh + # Fix haproxy directory issue + mkdir -p /var/lib/haproxy + + # Get config files from master + snapshot_url="https://git-wip-us.apache.org/repos/asf?p=incubator-cloudstack.git;a=snapshot;h=HEAD;sf=tgz" + snapshot_dir="/opt/incubator-cloudstack*" + cd /opt + wget $snapshot_url -O cloudstack.tar.gz + tar -zxvf cloudstack.tar.gz + cp -rv $snapshot_dir/patches/systemvm/debian/config/* / + cp -rv $snapshot_dir/patches/systemvm/debian/vpn/* / + mkdir -p /usr/share/cloud/ + cd $snapshot_dir/patches/systemvm/debian/config + tar -cvf /usr/share/cloud/cloud-scripts.tar * + cd $snapshot_dir/patches/systemvm/debian/vpn + tar -rvf /usr/share/cloud/cloud-scripts.tar * + cd /opt + rm -fr $snapshot_dir cloudstack.tar.gz + + chkconfig --add cloud-early-config + chkconfig cloud-early-config on + chkconfig --add cloud-passwd-srvr + chkconfig cloud-passwd-srvr off + chkconfig --add cloud + chkconfig cloud off + chkconfig monit off + chkconfig xl2tpd off +} + +do_signature() { + mkdir -p /var/cache/cloud/ + gzip -c /usr/share/cloud/cloud-scripts.tar > /usr/share/cloud/cloud-scripts.tgz + md5sum /usr/share/cloud/cloud-scripts.tgz | awk '{print $1}' > /var/cache/cloud/cloud-scripts-signature + echo "Cloudstack Release $CLOUDSTACK_RELEASE $(date)" > /etc/cloudstack-release +} + +begin=$(date +%s) + +echo "*************INSTALLING PACKAGES********************" +install_packages +echo "*************DONE INSTALLING PACKAGES********************" +setup_accounts +echo "*************DONE ACCOUNT SETUP********************" +configure_services +configure_apache2 +echo "*************DONE SETTING UP SERVICES********************" +do_fixes +echo "*************DONE FIXING CONFIGURATION********************" +do_signature + +fin=$(date +%s) +t=$((fin-begin)) + +echo "Signed systemvm build, finished building systemvm appliance in $t seconds" diff --git a/tools/appliance/definitions/systemvmtemplate64/preseed.cfg b/tools/appliance/definitions/systemvmtemplate64/preseed.cfg new file mode 100644 index 00000000000..ac9edd31213 --- /dev/null +++ b/tools/appliance/definitions/systemvmtemplate64/preseed.cfg @@ -0,0 +1,357 @@ +#### Contents of the preconfiguration file (for squeeze) +### Localization +# Locale sets language and country. +d-i debian-installer/locale string en_US + +# Keyboard selection. +#d-i console-tools/archs select at +d-i console-keymaps-at/keymap select us +# Example for a different keyboard architecture +#d-i console-keymaps-usb/keymap select mac-usb-us + +### Network configuration +# netcfg will choose an interface that has link if possible. This makes it +# skip displaying a list if there is more than one interface. +d-i netcfg/choose_interface select auto + +# To pick a particular interface instead: +#d-i netcfg/choose_interface select eth1 + +# If you have a slow dhcp server and the installer times out waiting for +# it, this might be useful. +#d-i netcfg/dhcp_timeout string 60 + +# If you prefer to configure the network manually, uncomment this line and +# the static network configuration below. +#d-i netcfg/disable_dhcp boolean true + +# If you want the preconfiguration file to work on systems both with and +# without a dhcp server, uncomment these lines and the static network +# configuration below. +#d-i netcfg/dhcp_failed note +#d-i netcfg/dhcp_options select Configure network manually + +# Static network configuration. +#d-i netcfg/get_nameservers string 192.168.1.1 +#d-i netcfg/get_ipaddress string 192.168.1.42 +#d-i netcfg/get_netmask string 255.255.255.0 +#d-i netcfg/get_gateway string 192.168.1.1 +#d-i netcfg/confirm_static boolean true + +# Any hostname and domain names assigned from dhcp take precedence over +# values set here. However, setting the values still prevents the questions +# from being shown, even if values come from dhcp. +d-i netcfg/get_hostname string systemvm +d-i netcfg/get_domain string cloudstack.org + +# Disable that annoying WEP key dialog. +d-i netcfg/wireless_wep string +# The wacky dhcp hostname that some ISPs use as a password of sorts. +#d-i netcfg/dhcp_hostname string radish + +# If non-free firmware is needed for the network or other hardware, you can +# configure the installer to always try to load it, without prompting. Or +# change to false to disable asking. +#d-i hw-detect/load_firmware boolean true + +### Network console +# Use the following settings if you wish to make use of the network-console +# component for remote installation over SSH. This only makes sense if you +# intend to perform the remainder of the installation manually. +#d-i anna/choose_modules string network-console +#d-i network-console/password password r00tme +#d-i network-console/password-again password r00tme + +### Mirror settings +# If you select ftp, the mirror/country string does not need to be set. +#d-i mirror/protocol string ftp +d-i mirror/country string manual +d-i mirror/http/hostname string http.us.debian.org +d-i mirror/http/directory string /debian +d-i mirror/http/proxy string + +# Suite to install. +#d-i mirror/suite string testing +# Suite to use for loading installer components (optional). +#d-i mirror/udeb/suite string testing + +### Clock and time zone setup +# Controls whether or not the hardware clock is set to UTC. +d-i clock-setup/utc boolean true + +# You may set this to any valid setting for $TZ; see the contents of +# /usr/share/zoneinfo/ for valid values. +d-i time/zone string UTC + +# Controls whether to use NTP to set the clock during the install +d-i clock-setup/ntp boolean true +# NTP server to use. The default is almost always fine here. +#d-i clock-setup/ntp-server string ntp.example.com + +### Partitioning +# If the system has free space you can choose to only partition that space. +#d-i partman-auto/init_automatically_partition select biggest_free + +# Alternatively, you can specify a disk to partition. The device name must +# be given in traditional non-devfs format. +# Note: A disk must be specified, unless the system has only one disk. +# For example, to use the first SCSI/SATA hard disk: +d-i partman-auto/disk string /dev/sda +# In addition, you'll need to specify the method to use. +# The presently available methods are: "regular", "lvm" and "crypto" +d-i partman-auto/method string regular + +# If one of the disks that are going to be automatically partitioned +# contains an old LVM configuration, the user will normally receive a +# warning. This can be preseeded away... +#d-i partman-lvm/device_remove_lvm boolean true +# The same applies to pre-existing software RAID array: +#d-i partman-md/device_remove_md boolean true + +# And the same goes for the confirmation to write the lvm partitions. +#d-i partman-lvm/confirm boolean true +#d-i partman-lvm/confirm_nooverwrite boolean true + +#d-i partman/choose_partition select finish +#d-i partman-auto-lvm/guided_size string max + +# You can choose one of the three predefined partitioning recipes: +# - atomic: all files in one partition +# - home: separate /home partition +# - multi: separate /home, /usr, /var, and /tmp partitions +d-i partman-auto/choose_recipe select atomic +#d-i partman/default_filesystem string ext3 + +# Or provide a recipe of your own... +# The recipe format is documented in the file devel/partman-auto-recipe.txt. +# If you have a way to get a recipe file into the d-i environment, you can +# just point at it. +#d-i partman-auto/expert_recipe_file string /hd-media/recipe + +d-i partman-auto/expert_recipe string \ + boot-root :: \ + 40 50 100 ext4 \ + $primary{ } $bootable{ } \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /boot } \ + . \ + 400 40 500 ext4 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ / } \ + . \ + 60 100 200 ext4 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /home } \ + . \ + 500 30 1000 ext4 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /usr } \ + . \ + 400 40 500 ext4 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /opt } \ + . \ + 500 60 1000 ext4 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /var } \ + . \ + 100 70 400 ext4 \ + method{ format } format{ } \ + use_filesystem{ } filesystem{ ext4 } \ + mountpoint{ /tmp } \ + . \ + 64 512 300% linux-swap \ + method{ swap } format{ } \ + . + +# If not, you can put an entire recipe into the preconfiguration file in one +# (logical) line. This example creates a small /boot partition, suitable +# swap, and uses the rest of the space for the root partition: +#d-i partman-auto/expert_recipe string \ +# boot-root :: \ +# 40 50 100 ext3 \ +# $primary{ } $bootable{ } \ +# method{ format } format{ } \ +# use_filesystem{ } filesystem{ ext3 } \ +# mountpoint{ /boot } \ +# . \ +# 500 10000 1000000000 ext3 \ +# method{ format } format{ } \ +# use_filesystem{ } filesystem{ ext3 } \ +# mountpoint{ / } \ +# . \ +# 64 512 300% linux-swap \ +# method{ swap } format{ } \ +# . + +#The preseed line that "selects finish" needs to be in a certain order in your preseed, the example-preseed does not follow this. +#http://ubuntuforums.org/archive/index.php/t-1504045.html + +# This makes partman automatically partition without confirmation, provided +# that you told it what to do using one of the methods above. +#d-i partman-partitioning/confirm_write_new_label boolean true +d-i partman/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true + +### Base system installation +# Select the initramfs generator used to generate the initrd for 2.6 kernels. +#d-i base-installer/kernel/linux/initramfs-generators string yaird + +# The kernel image (meta) package to be installed; "none" can be used if no +# kernel is to be installed. +#d-i base-installer/kernel/image string linux-image-2.6-486 + +### Account setup +# Skip creation of a root account (normal user account will be able to +# use sudo). +d-i passwd/root-login boolean true +# Alternatively, to skip creation of a normal user account. +#d-i passwd/make-user boolean false + +# Root password, either in clear text +d-i passwd/root-password password password +d-i passwd/root-password-again password password +# or encrypted using an MD5 hash. +#d-i passwd/root-password-crypted password [MD5 hash] + +# To create a normal user account. +d-i passwd/user-fullname string Cloud Stack +d-i passwd/username string cloud +# Normal user's password, either in clear text +d-i passwd/user-password password cloud +d-i passwd/user-password-again password cloud +# or encrypted using an MD5 hash. +#d-i passwd/user-password-crypted password [MD5 hash] +# Create the first user with the specified UID instead of the default. +#d-i passwd/user-uid string 1010 +d-i user-setup/encrypt-home boolean false +d-i user-setup/allow-password-weak boolean true + +# The user account will be added to some standard initial groups. To +# override that, use this. +d-i passwd/user-default-groups string audio cdrom video admin + +### Apt setup +# You can choose to install non-free and contrib software. +#d-i apt-setup/non-free boolean true +#d-i apt-setup/contrib boolean true +# Uncomment this if you don't want to use a network mirror. +#d-i apt-setup/use_mirror boolean false +# Select which update services to use; define the mirrors to be used. +# Values shown below are the normal defaults. +#d-i apt-setup/services-select multiselect security, volatile +#d-i apt-setup/security_host string security.debian.org +#d-i apt-setup/volatile_host string volatile.debian.org + + +# By default the installer requires that repositories be authenticated +# using a known gpg key. This setting can be used to disable that +# authentication. Warning: Insecure, not recommended. +#d-i debian-installer/allow_unauthenticated string true + +### Package selection +tasksel tasksel/first multiselect ssh-server +# If the desktop task is selected, install the kde and xfce desktops +# instead of the default gnome desktop. +#tasksel tasksel/desktop multiselect kde, xfce + +# Individual additional packages to install +d-i pkgsel/include string openssh-server ntp acpid sudo bzip2 + +# Whether to upgrade packages after debootstrap. +# Allowed values: none, safe-upgrade, full-upgrade +d-i pkgsel/upgrade select none + +# Some versions of the installer can report back on what software you have +# installed, and what software you use. The default is not to report back, +# but sending reports helps the project determine what software is most +# popular and include it on CDs. +popularity-contest popularity-contest/participate boolean false + +### Boot loader installation +# Grub is the default boot loader (for x86). If you want lilo installed +# instead, uncomment this: +#d-i grub-installer/skip boolean true +# To also skip installing lilo, and install no bootloader, uncomment this +# too: +#d-i lilo-installer/skip boolean true + +# This is fairly safe to set, it makes grub install automatically to the MBR +# if no other operating system is detected on the machine. +d-i grub-installer/only_debian boolean true + +# This one makes grub-installer install to the MBR if it also finds some other +# OS, which is less safe as it might not be able to boot that other OS. +#d-i grub-installer/with_other_os boolean true + +# Alternatively, if you want to install to a location other than the mbr, +# uncomment and edit these lines: +#d-i grub-installer/only_debian boolean false +#d-i grub-installer/with_other_os boolean false +#d-i grub-installer/bootdev string (hd0,0) +# To install grub to multiple disks: +#d-i grub-installer/bootdev string (hd0,0) (hd1,0) (hd2,0) + +# Optional password for grub, either in clear text +#d-i grub-installer/password password r00tme +#d-i grub-installer/password-again password r00tme +# or encrypted using an MD5 hash, see grub-md5-crypt(8). +#d-i grub-installer/password-crypted password [MD5 hash] + +### Finishing up the installation +# During installations from serial console, the regular virtual consoles +# (VT1-VT6) are normally disabled in /etc/inittab. Uncomment the next +# line to prevent this. +#d-i finish-install/keep-consoles boolean true + +# Avoid that last message about the install being complete. +d-i finish-install/reboot_in_progress note + +# This will prevent the installer from ejecting the CD during the reboot, +# which is useful in some situations. +#d-i cdrom-detect/eject boolean false + +# This is how to make the installer shutdown when finished, but not +# reboot into the installed system. +#d-i debian-installer/exit/halt boolean true +# This will power off the machine instead of just halting it. +#d-i debian-installer/exit/poweroff boolean true + +### Preseeding other packages +# Depending on what software you choose to install, or if things go wrong +# during the installation process, it's possible that other questions may +# be asked. You can preseed those too, of course. To get a list of every +# possible question that could be asked during an install, do an +# installation, and then run these commands: +# debconf-get-selections --installer > file +# debconf-get-selections >> file + + +#### Advanced options +### Running custom commands during the installation +# d-i preseeding is inherently not secure. Nothing in the installer checks +# for attempts at buffer overflows or other exploits of the values of a +# preconfiguration file like this one. Only use preconfiguration files from +# trusted locations! To drive that home, and because it's generally useful, +# here's a way to run any shell command you'd like inside the installer, +# automatically. + +# This first command is run as early as possible, just after +# preseeding is read. +# Prevent packaged version of VirtualBox Guest Additions being installed: +d-i preseed/early_command string sed -i \ + '/in-target/idiscover(){/sbin/discover|grep -v VirtualBox;}' \ + /usr/lib/pre-pkgsel.d/20install-hwpackages + +# This command is run just before the install finishes, but when there is +# still a usable /target directory. You can chroot to /target and use it +# directly, or use the apt-install and in-target commands to easily install +# packages and run commands in the target system. diff --git a/tools/appliance/definitions/systemvmtemplate64/zerodisk.sh b/tools/appliance/definitions/systemvmtemplate64/zerodisk.sh new file mode 100644 index 00000000000..25bd8c4af2d --- /dev/null +++ b/tools/appliance/definitions/systemvmtemplate64/zerodisk.sh @@ -0,0 +1,15 @@ +# Clean up stuff copied in by veewee +rm -fv /root/*.iso +rm -fv /root/base.sh /root/cleanup.sh /root/postinstall.sh /root/zerodisk.sh +rm -fv .veewee_version .veewee_params .vbox_version + +echo "Cleaning up" + +# Zero out the free space to save space in the final image: +for path in / /boot /usr /var /opt /tmp +do + dd if=/dev/zero of=$path/zero bs=1M + sync + rm -f $path/zero + echo "Completed zero-ing out disk on $path" +done