From e138596aa72c2ccb577600ac9766520ca721c5e5 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Sat, 2 Feb 2013 13:55:38 +0100 Subject: [PATCH] Remove the last remnants of the old build system --- build.xml | 49 --- build/.gitignore | 18 - build/build-aws-api.properties | 28 -- build/build-aws-api.xml | 478 -------------------- build/build-cloud-plugins.xml | 328 -------------- build/build-cloud.properties | 26 -- build/build-cloud.xml | 595 ------------------------- build/build-common.xml | 100 ----- build/build-devcloud.xml | 98 ----- build/build-docs.xml | 82 ---- build/build-marvin.xml | 71 --- build/build-tests.xml | 319 -------------- build/build-usage.xml | 69 --- build/cloud.properties | 29 -- build/developer.xml | 431 ------------------ build/overview.html | 35 -- build/package.xml | 305 ------------- build/release-notes | 328 -------------- cloud.spec | 647 --------------------------- waf | Bin 92487 -> 0 bytes waf.bat | 44 -- wscript | 782 --------------------------------- wscript_build | 457 ------------------- wscript_configure | 408 ----------------- 24 files changed, 5727 deletions(-) delete mode 100755 build.xml delete mode 100644 build/.gitignore delete mode 100644 build/build-aws-api.properties delete mode 100644 build/build-aws-api.xml delete mode 100755 build/build-cloud-plugins.xml delete mode 100755 build/build-cloud.properties delete mode 100755 build/build-cloud.xml delete mode 100755 build/build-common.xml delete mode 100644 build/build-devcloud.xml delete mode 100755 build/build-docs.xml delete mode 100644 build/build-marvin.xml delete mode 100755 build/build-tests.xml delete mode 100644 build/build-usage.xml delete mode 100755 build/cloud.properties delete mode 100755 build/developer.xml delete mode 100755 build/overview.html delete mode 100755 build/package.xml delete mode 100644 build/release-notes delete mode 100644 cloud.spec delete mode 100755 waf delete mode 100755 waf.bat delete mode 100644 wscript delete mode 100644 wscript_build delete mode 100644 wscript_configure diff --git a/build.xml b/build.xml deleted file mode 100755 index b013518ac72..00000000000 --- a/build.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - This is the overall dispatch file. It includes other build - files but doesnot provide targets of its own. Do not modify - this file. If you need to create your own targets, modify the - developer.xml. - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/.gitignore b/build/.gitignore deleted file mode 100644 index d11410db1a5..00000000000 --- a/build/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -# 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. - -/override diff --git a/build/build-aws-api.properties b/build/build-aws-api.properties deleted file mode 100644 index 0a02d1b5579..00000000000 --- a/build/build-aws-api.properties +++ /dev/null @@ -1,28 +0,0 @@ -# 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. - -company.major.version=1 -company.minor.version=0 -company.patch.version=8 - -target.compat.version=1.6 -source.compat.version=1.6 - -debug=true -build.type=developer -debuglevel=lines,source,vars -deprecation=off diff --git a/build/build-aws-api.xml b/build/build-aws-api.xml deleted file mode 100644 index 40ad22c2679..00000000000 --- a/build/build-aws-api.xml +++ /dev/null @@ -1,478 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/build-cloud-plugins.xml b/build/build-cloud-plugins.xml deleted file mode 100755 index 207ef7113c8..00000000000 --- a/build/build-cloud-plugins.xml +++ /dev/null @@ -1,328 +0,0 @@ - - - - - - - - - - - - - Cloud Stack ant build file for building all the plugins - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/build-cloud.properties b/build/build-cloud.properties deleted file mode 100755 index be67a368fc0..00000000000 --- a/build/build-cloud.properties +++ /dev/null @@ -1,26 +0,0 @@ -# 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. - -debug=true -debuglevel=lines,source,vars -debug.jvmarg=-Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n -deprecation=off -build.type=developer -target.compat.version=1.6 -source.compat.version=1.6 -branding.name=default -ssvm.include.vmware.jar=true diff --git a/build/build-cloud.xml b/build/build-cloud.xml deleted file mode 100755 index c31d00da220..00000000000 --- a/build/build-cloud.xml +++ /dev/null @@ -1,595 +0,0 @@ - - - - - - - Cloud Stack ant build file - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/build-common.xml b/build/build-common.xml deleted file mode 100755 index 7240f5323c3..00000000000 --- a/build/build-common.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/build-devcloud.xml b/build/build-devcloud.xml deleted file mode 100644 index a001dc2dd9c..00000000000 --- a/build/build-devcloud.xml +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/build-docs.xml b/build/build-docs.xml deleted file mode 100755 index c38b986ed5f..00000000000 --- a/build/build-docs.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - Cloud Stack ant build file - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/build-marvin.xml b/build/build-marvin.xml deleted file mode 100644 index 6daac03f2ce..00000000000 --- a/build/build-marvin.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - This build file contains simple targets that - - build - - package - - distribute - the Marvin test client written in python - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/build-tests.xml b/build/build-tests.xml deleted file mode 100755 index 5f41ba278ff..00000000000 --- a/build/build-tests.xml +++ /dev/null @@ -1,319 +0,0 @@ - - - - - - - Cloud Stack ant build file - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - diff --git a/build/build-usage.xml b/build/build-usage.xml deleted file mode 100644 index 9940f46edb3..00000000000 --- a/build/build-usage.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - Cloud Stack Usage server build - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/cloud.properties b/build/cloud.properties deleted file mode 100755 index e3cddf7770d..00000000000 --- a/build/cloud.properties +++ /dev/null @@ -1,29 +0,0 @@ -# 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. - -# major.minor.patch versioning scheme for CloudStack -company.major.version=4 -company.minor.version=0 -company.patch.version=0 - -svn.revision=2 - -# copyright year -company.copyright.year=2012 -company.url=http://cloudstack.org -company.license.name=Apache License, Version 2.0 -company.name=CloudStack diff --git a/build/developer.xml b/build/developer.xml deleted file mode 100755 index fdda171aff6..00000000000 --- a/build/developer.xml +++ /dev/null @@ -1,431 +0,0 @@ - - - - - - - This is a developer.xml with tools to start and stop tomcat and - generally developer targets that has nothing to do with compiling. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - password - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/overview.html b/build/overview.html deleted file mode 100755 index 22f349fe10b..00000000000 --- a/build/overview.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - -

- -VMOps source javadoc. - -

-Javadoc for JUnit tests -is also available. -

- - - diff --git a/build/package.xml b/build/package.xml deleted file mode 100755 index 3efdd7dda05..00000000000 --- a/build/package.xml +++ /dev/null @@ -1,305 +0,0 @@ - - - - - - - This is a package.xml with tools to package the cloud stack distribution - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/release-notes b/build/release-notes deleted file mode 100644 index 34b20803a00..00000000000 --- a/build/release-notes +++ /dev/null @@ -1,328 +0,0 @@ -******************************************************************************** - VMOps Cloud Stack Version 0.4 - Release Notes -******************************************************************************** - -================================= -WHAT'S NEW : -================================= - -* NIC bonding support for the Computing, Routing, and Storage nodes to take -advantage of the multiple NICS installed on the server. -* Maintenance Mode support for physical servers. Administrators now have the -option to enable or disable maintenance mode on any physical servers. Enabling -maintenance mode on a Routing or Computing node will result in the seamless live -migration of guest virtual machines into other physical servers within the same -zone before making the server available for maintenance. -* Introduction of a new user web interface for allowing user accounts to manage -their own virtual machines. This new interface has a brand new look and feel, -allows for easier branding and customization, and is easier to incorporate into -existing web interfaces. -* Added support for the creation of Reseller Domains. The Reseller Domain -feature allows host providers to create resellers complete with their own -user base and administrators while using the same global computing resources -provided by the host provider. -* Added a new email alerting system that will now inform administrators of -events such as when physical servers are down or computing resources are -passing a pre-configured threshold. -* Massive improvements to the existing Developer and Integration API. Error -codes have now been added and existing API method names and parameters have been -made more consistent. A JSON format can also now be optionally -returned in addition to the existing XML format. Please read the new API -Reference documentation for more details on the changes. -* Billing records have now been changed to Usage records to provide data for -both billing integration and usage metering. Price has been completely removed -from VMOps. Instead we added ability to set your own display text for both -service offering and templates. You can now use this to set any text for the UI -to display. -* New virtual machines deployed will now generate a random password. A reset -password is also now available both in the web user interface as well as the -API. We support both Linux and Windows OS based templates. -* Storage server is now a bare-bone installation and uses the new COMSTAR iSCSI -stack for improved performance. We recognized that while running the storage -server as a virtual machine does allows for more hardware support, it severely -impacts performance. The list of compatible hardware can be found in the Open -Solaris website. -* Added clustering support for the VMOps Management Server. -* Added the ability to configure an additional storage ip address (separate -subnet) for both Routing and Computing servers. If a server is configured with -an additional storage ip, all storage traffic will route through this subnet and -all network/internet traffic will route through the existing private network. -* Added concept of a user account. VMOps supports multiple username for a -single user account. -* Created new installers for the VMOps MultiTenant Hypervisor and the VMOps -Storage. - -================================= -KNOWN ISSUES : -================================= - -* DomR is still counting internal network activities as part of the usage that -is being returned by the API. -* The reset password for virtual machine feature does not return an error if it -fails to successfully reset the password. -* VMOps installation scripts to not validate bad network configuration values. -* VNX Proxy Server does not handle rapid refreshes of web console proxy well. -* VNC Proxy Server at times do not return a thumbnail image. -* Rebooting a DomR instance will cause network traffic to not be collected. -* Associating new IP addresses should clean out existing LB or PF rules before -assigning it to a DomR instance. -* The Usage parse engine needs to be split out from the VMOps Management Server -so that only a single instance of this can be running and does not affect -normal operations. -* Templates needs a way of specifying the minimum CPU and Memory requirements. -* createUser API method currently allows you to assign users to admin accounts. -* Installations of servers with more than 3 NIC sometimes duplicates the MAC -address on the ifcfg configuration files. -* Additional admin only API methods are missing (ie. Domain management, router -management). -* Usage parse engine could go OOM in the event it has not been run recently -and there are a large (2 million+ records). -* Problem with domU when both e1000 and e1000e used as a NIC drivers for a -Computing Server. The installer needs to blacklist one of the drivers. -* vnet failures and xen crashes currently do not generate an alert to the administrator. -* The current limit for domU instances created on a Computing Server is 64 and -the currently limit for domR instances created is 59 on a Routing Server. -* No current way of allowing different subnets for different pods within the -same zone. -* limit the number of usage and event records returned by the API. A large -enough of the query could cause the Management Server to go oom. - -================================= -BUG FIXES : -================================= - -* Improved transactions across both database calls and calls across agents. -* Fixed an issue where duplicate IP or LB rules could be sent to the DomR -instance during a DomR restart. -* Removed requirement of the reverse DNS lookup for the Storage Server. -* Massive improvements to the HA process. -* Fixed an issue where the it would take too long for the management server -to detect a TCP disconnect. -* Fixed an issue where the the agent would *think* it has connected to the -management server but in reality, it is just stuck waiting for a response that -will never come. -* Generic DB lock wait timeout fixes. -* Improvements to the general state management of the servers. -* Fixed issue where where physical servers with the same IP attempts to connect -to the Management Server. The second server is now prevented from registering. -* Fixed an issue where deleting a user from an account would result in all the -virtual machines to be cleaned up. This can only happen if the last user for -an account has been deleted. -* Fixed an issue where the source NAT ip address of a DomR instance is being -released back into the public pool even though the DomR instance was not -successfully destroyed. -* Fixed an issue where a guest virtual machine cannot be destroyed while in HA -state. -* Removed requirement to specify the storage type when installing a new tempate. -* Fixed an issue where the console proxy from different zones are all starting -in the same zone. -* Fixed an issue where the listing of virtual machines would hang if the console -proxy is not even started. -* Massive improvements to our installer scripts. -* Massive improvements to the general stability of the Cloud Stack. -* Fixed an issue where the Hypervisor installer is unable to install onto -machines with a IPMI card. -* As usual, there are too many bug fixes to list... - -******************************************************************************** - VMOps Cloud Stack Version 0.3.xxxx - Release Notes -******************************************************************************** - -================================= -WHAT'S NEW : -================================= - -* Introduction of VMOps Developer API. This allows users of the VMOps Cloud - Stack to manage their virtual machines through a set of REST-like API. -* Improved collection of user usage data that can be used for both billing - aggregation and metric collection. -* High availability support for user virtual machines. -* Support for automatic hypervisor agent software update. -* VNC console proxy servers can now run as managed VMOps system VMs. The new - implementation provides features such as on-demand VM startup, standby - capacity pre-allocation and console proxy load monitoring. -* Much Improved VMOps Cloud Stack installation process. VMOps Cloud Stack can - now be installed with a minimum of two physical servers. -* VMOps Cloud Stack installation DVD now comes in two flavors. VMOps Cloud Stack - Management Server Installation DVD and VMOps Cloud Stack Multitenant - Hypervisor Installation DVD. - -================================= -KNOWN ISSUES : -================================= - -* PV drivers for Windows 2003 and Windows 2003 x86_64 (Incomplete Feature) -* GUI panel for allowing administrators to set various system configurations - - i.e. zones, pods, ip addresses (Incomplete Feature) -* Support for multiple NIC cards on computing, routing, and storage servers - (Disabled Feature) -* Support for resellers (Incomplete Feature) -* Allow admins/users to specify the root password for their new instance. It - cannot default to root/password (Bug 134) -* Admin/User Dashboard (Bug 154 and 155) -* Dynamically refresh server and vm instance status in GUI without a manual - refresh (Bug 389) -* Need transaction semantics across DB and agent. Without this, it is possible - to timeout db calls that first lock a record and relies on an agent response - before releasing that record. (Bug 408) -* All Server Roles (Mgmt, Computing, Routing, and Storage) require a functioning - eth0 NIC in order to install correctly. (Bug 470) -* Unable to handle HA when an entire Pod is unreachable (Bug 620) -* Improved network traffic reporting (Bug 642) -* Multiple login support a single user account (Bug 589) -* DomR instances continue to run even though all VMs associated with the DomR - are no longer even running. (Bug 617) -* HA fails when VM and Router for the same user go down at the same time - (Bug 603) - -================================= -BUG FIXES : -================================= - -* Improved Billing data generation (Bug 482) -* Able to create new admins through the admin console UI. (Bug 492) -* Able to create new Service Offerings through the admin console UI (Bug 500) -* Significantly improved the imaging speed when installing VMOps Cloud Stack - (Bug 476) -* Harden DomR Template to prevent unauthorized access -* No longer require eth0 during installation process of the hosts (Bug 490) -* Fixed issue where having multiple NIC cards caused issues (Bug 489) -* Installation UI will now allow you to select to the disk for storage - (Bug 556) -* Installation UI will now allow you to select NIC to use as private, public, - or simply disabled -* Mgmt server will now reflect the status of user vms if the storage server that - hosts the vm's volumes is no longer accessible. (Bug 521) -* Routing and Console Proxy VM will now be HA-enabled by default (Bug 614) -* Console Proxy VM are now automatically managed by the Mgmt Server (Bug 110) -* Template Management from the console admin UI should be improved -* Too many to list... - -******************************************************************************** - VMOps Cloud Stack Version 0.2.6297 - Release Notes -******************************************************************************** - -================================= -WHAT'S NEW : -================================= - -* VMOps Server - - Introduction of VMOps Integration API. This API allows service providers - to provision users and to retrieve billing info and events. It is a simple - query language written on top of HTTP that simply returns results in XML - format. - - Improved VMOps Server installation process. - -* VMOps Multitenant Hypervisor - - Improved VMOps Multitenant Hypervisor installation process. - -================================= -KNOWN ISSUES : -================================= - -* PV drivers for Windows 2003 and Windows 2003 x86_64 (Incomplete Feature) -* Developer, Billing, and Provisioning API (Incomplete Feature) -* Mirroring of disk images on storage servers across pods (Incomplete Feature) -* HA Enabled VMs (Disabled Feature) -* Firewall integration API (Incomplete Feature) -* GUI panel for allowing administrators to set various system configurations - - i.e. zones, pods, ip addresses (Incomplete Feature) -* Support for multiple NIC cards on computing, routing, and storage servers - (Disabled Feature) -* Ability to deploy agent upgrade on VMOps server and have the upgrade - automatically propagated to storage, routing, and computing servers. - (Bug 386) -* Detailed IO stats for storage servers (Bug 94) -* Admin/User Dashboard (Bug 154 and 155) -* OpenSolaris kernel panic (Bug 413) -* Dynamically refresh server and vm instance status in GUI without a manual - refresh (Bug 389) -* Need transaction semantics across DB and agent. Without this, it is possible - to timeout db calls that first lock a record and relies on an agent response - before releasing that record. (Bug 408) -* All Server Roles (Mgmt, Computing, Routing, and Storage) require a functioning - eth0 NIC in order to install correctly. (Bug 470) -* Admin Console UI Templates Tab needs improvement. (Bug 469) -* Unable to create new admins through the admin console UI. (Bug 492) -* Unable to create new Service Offerings through the admin console UI (Bug 500) - -================================= -BUG FIXES : -================================= - -* Added a new XML (server-setup.xml) to configure initial VMOps Server data. - (Bug 430) -* Made installation of the router template easier (Bug 434) -* Deleting a user through the admin UI will now show a progress bar (Bug 428) -* You can no longer any drop down boxes in the search left panel of the console - UI (Bug 439) -* Configured dom0 and domR to no longer do any reverse DNS lookup (Bug 459) -* Fixed installer to handle multiple NIC (Bug 457) -* Missing SDL module in all templates (Bug 449) - -******************************************************************************** - VMOps Cloud Stack Version 0.1.6053 - Release Notes -******************************************************************************** - -================================= -WHAT'S NEW : -================================= - -* VMOps Server - - Complete web UI for both administrators and users to manage VMOps Cloud - Stack. - - Allows administrators to manage the creation of service offerings and set - its pricing along with pricing for network bandwidth, additional public - ips, and vm templates. - - Allows administrators to retrieve billing records and user usages. - - VM Sync - coordinates, manages, and maintains the life cycle of VMOps agents - running on attached computing, routing, and storage hosts. - - VM Template Management - allows administrators to manage and upload hosted - vm templates into VMOps Cloud Stack. - -* VMOps Multitenant Hypervisor - - Designed to allow for the complete isolation of CPU, memory, storage, and - network resources for each user. - • Hypervisor Attached Storage (HAS) – The storage solution that is - integrated within the hypervisor and does not rely on centralized SAN or NAS - to implement storage virtualization. It provides a high performance and - ultra-reliable block storage for virtual machine images - - Hypervisor Aware Network (HAN) – The network solution for VMOps Cloud Stack - that implements the necessary IP address translation and tunneling for the - guest OS running inside the virtual machine. It does not rely on VLAN to - implement any network virtualization and isolation. - -================================= -KNOWN ISSUES : -================================= - -* PV drivers for Windows 2003 and Windows 2003 x86_64 (Incomplete Feature) -* Developer, Billing, and Provisioning API (Incomplete Feature) -* Mirroring of disk images on storage servers across pods (Incomplete Feature) -* HA Enabled VMs (Disabled Feature) -* Firewall integration API (Incomplete Feature) -* GUI panel for allowing administrators to set various system configurations - - i.e. zones, pods, ip addresses (Incomplete Feature) -* Support for multiple NIC cards on computing, routing, and storage servers - (Disabled Feature) -* Ability to deploy agent upgrade on VMOps server and have the upgrade - automatically propagated to storage, routing, and computing servers. - (Bug 386) -* Detailed IO stats for storage servers (Bug 94) -* Admin/User Dashboard (Bug 154 and 155) -* OpenSolaris kernel panic (Bug 413) -* Dynamically refresh server and vm instance status in GUI without a manual - refresh (Bug 389) -* Need transaction semantics across DB and agent. Without this, it is possible - to timeout db calls that first lock a record and relies on an agent response - before releasing that record. (Bug 408) - -================================= -BUG FIXES : -================================= - -* N/A \ No newline at end of file diff --git a/cloud.spec b/cloud.spec deleted file mode 100644 index bde3958d0be..00000000000 --- a/cloud.spec +++ /dev/null @@ -1,647 +0,0 @@ -# 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. - -%define __os_install_post %{nil} -%global debug_package %{nil} - -# DISABLE the post-percentinstall java repacking and line number stripping -# we need to find a way to just disable the java repacking and line number stripping, but not the autodeps - -Name: cloud -Summary: CloudStack IaaS Platform -Version: %{_ver} -#http://fedoraproject.org/wiki/PackageNamingGuidelines#Pre-Release_packages -%if "%{?_prerelease}" != "" -Release: 0.%{_build_number}%{dist}.%{_prerelease} -%else -Release: %{_rel}%{dist} -%endif -License: Apache License 2.0 -Vendor: CloudStack -Packager: CloudStack -Group: System Environment/Libraries -# FIXME do groups for every single one of the subpackages -Source0: %{name}-%{_ver}.tar.bz2 -BuildRoot: %{_tmppath}/%{name}-%{_ver}-%{release}-build - -%if 0%{?fedora} >= 17 -BuildRequires: java-1.7.0-openjdk-devel -%else -BuildRequires: java-1.6.0-openjdk-devel -%endif -BuildRequires: tomcat6 -BuildRequires: ws-commons-util -BuildRequires: jpackage-utils -BuildRequires: gcc -BuildRequires: glibc-devel -BuildRequires: /usr/bin/mkisofs -BuildRequires: MySQL-python - -%description -CloudStack is a highly-scalable elastic, open source, -intelligent IaaS cloud implementation. - -%package utils -Summary: CloudStack utility library -Requires: java >= 1.6.0 -Requires: python -Group: System Environment/Libraries -Obsoletes: vmops-utils < %{version}-%{release} -%description utils -Utility libraries and set of Java classes used -by CloudStack. - -%package client-ui -Summary: CloudStack management server UI -Requires: %{name}-client -Group: System Environment/Libraries -Obsoletes: vmops-client-ui < %{version}-%{release} -%description client-ui -The CloudStack management server is the central point of coordination, -management, and intelligence in CloudStack. This package -is a requirement of the %{name}-client package, which installs the -CloudStack management server. - -%package server -Summary: CloudStack server library -Requires: java >= 1.6.0 -Obsoletes: vmops-server < %{version}-%{release} -Requires: %{name}-utils = %{version}, %{name}-core = %{version}, %{name}-deps = %{version}, %{name}-scripts = %{version}, tomcat6-servlet-2.5-api -Group: System Environment/Libraries -%description server -The CloudStack server libraries provide a set of Java classes for CloudStack. - -%package scripts -Summary: CloudStack scripts -# FIXME nuke the archdependency -Requires: python -Requires: bash -Requires: bzip2 -Requires: gzip -Requires: unzip -Requires: /sbin/mount.nfs -Requires: openssh-clients -Requires: nfs-utils -Requires: wget -# there is a fsimage.so in the source code, which adds xen-libs as a dependence, needs to supress it, as rhel doesn't have this pacakge -AutoReqProv: no -Provides: cloud-agent-scripts = %{version}-%{release} -Obsoletes: cloud-agent-scripts < %{version}-%{release} -Group: System Environment/Libraries -%description scripts -This package contains common scripts used by the Agent and Management server - -%package python -Summary: CloudStack Python library -# FIXME nuke the archdependency -Requires: python -Group: System Environment/Libraries -%description python -The CloudStack Python library contains a few Python modules that the -CloudStack uses. - -%package deps -Summary: CloudStack library dependencies -Requires: java >= 1.6.0 -Requires: mysql-connector-java -Obsoletes: vmops-deps < %{version}-%{release} -Group: System Environment/Libraries -%description deps -This package contains a number of third-party dependencies -not shipped by distributions, required to run CloudStack - - -%package core -Summary: CloudStack core library -Requires: java >= 1.6.0 -Requires: %{name}-utils = %{version}, %{name}-deps = %{version} -Group: System Environment/Libraries -Obsoletes: vmops-core < %{version}-%{release} -%description core -The CloudStack core libraries provide a set of Java classes used -in CloudStack. - -%package client -Summary: CloudStack management server -# If GCJ is present, a setPerformanceSomething method fails to load Catalina -Conflicts: java-1.5.0-gcj-devel -Obsoletes: vmops-client < %{version}-%{release} -Obsoletes: cloud-premium < %{version}-%{release} -Requires: java >= 1.6.0 -Requires: %{name}-deps = %{version}, %{name}-utils = %{version}, %{name}-server = %{version} -Requires: %{name}-client-ui = %{version} -Requires: %{name}-setup = %{version} -Requires: %{name}-scripts = %{version} -Requires: %{name}-python = %{version} -Requires: %{name}-aws-api = %{version} -# for consoleproxy -# Requires: %{name}-agent -Requires: tomcat6 -Requires: ws-commons-util -Requires: jpackage-utils -Requires: sudo -Requires: /sbin/service -Requires: /sbin/chkconfig -Requires: /usr/bin/ssh-keygen -Requires: mkisofs -Requires: MySQL-python -Requires: python-paramiko -Requires: ipmitool -Requires: %{name}-utils = %{version} -%if 0%{?fedora} > 14 -Requires: apache-commons-dbcp -Requires: apache-commons-collections -Requires: jakarta-commons-httpclient -Requires: jakarta-taglibs-standard -Requires: mysql-connector-java -%endif - -Group: System Environment/Libraries -%description client -The CloudStack management server is the central point of coordination, -management, and intelligence in CloudStack and installs the management server. - -%package setup -Summary: CloudStack setup tools -Obsoletes: vmops-setup < %{version}-%{release} -Requires: java >= 1.6.0 -Requires: python -Requires: MySQL-python -Requires: %{name}-utils = %{version} -Requires: %{name}-server = %{version} -Requires: %{name}-deps = %{version} -Requires: %{name}-python = %{version} -Group: System Environment/Libraries -%description setup -The CloudStack setup tools let you set up your Management Server and Usage Server. - -%package agent-libs -Summary: CloudStack agent libraries -Requires: java >= 1.6.0 -Requires: %{name}-utils = %{version}, %{name}-core = %{version}, %{name}-deps = %{version} -Requires: commons-httpclient -Requires: jakarta-commons-logging -Requires: jpackage-utils -Group: System Environment/Libraries -%description agent-libs -The CloudStack agent libraries are used by the KVM Agent - -%package agent -Summary: CloudStack agent -Obsoletes: vmops-agent < %{version}-%{release} -Obsoletes: vmops-console < %{version}-%{release} -Obsoletes: cloud-console < %{version}-%{release} -Obsoletes: cloud-vnet < %{version}-%{release} -Obsoletes: cloud-premium-agent < %{version}-%{release} -Requires: java >= 1.6.0 -Requires: %{name}-utils = %{version}, %{name}-core = %{version}, %{name}-deps = %{version} -Requires: %{name}-agent-libs = %{version} -Requires: %{name}-scripts = %{version} -Requires: python -Requires: %{name}-python = %{version} -Requires: commons-httpclient -Requires: jakarta-commons-logging -Requires: libvirt -Requires: /usr/sbin/libvirtd -Requires: jpackage-utils -Requires: /sbin/service -Requires: /sbin/chkconfig -Requires: jna -Requires: ebtables -Requires: jsvc -Requires: jakarta-commons-daemon -Requires: bridge-utils -Group: System Environment/Libraries - -Requires: kvm - -%if 0%{?fedora} >= 14 && 0%{?fedora} != 16 -Requires: cloud-qemu-kvm -Requires: cloud-qemu-img -%endif - -%if 0%{?rhel} >= 5 -Requires: qemu-img -%endif - -Requires: libcgroup -%if 0%{?fedora} >= 16 -Requires: libcgroup-tools -%endif -Requires: /usr/bin/uuidgen -Requires: rsync -Requires: /bin/egrep -Requires: /sbin/ip -Requires: vconfig -Group: System Environment/Libraries -%description agent -The CloudStack agent is in charge of managing KVM shared computing resources in -a CloudStack-powered cloud. Install this package if this computer -will participate in your cloud. - -%package baremetal-agent -Summary: CloudStack baremetal agent -Requires: PING -Requires: tftp-server -Requires: xinetd -Requires: syslinux -Requires: chkconfig -Requires: dhcp -Group: System Environment/Libraries -%description baremetal-agent -The CloudStack baremetal agent - -%package cli -Summary: CloudStack command line tools -Requires: python -Group: System Environment/Libraries -%description cli -The CloudStack command line tools contain a few Python modules that can call cloudStack APIs. - -%package usage -Summary: CloudStack usage monitor -Obsoletes: vmops-usage < %{version}-%{release} -Requires: java >= 1.6.0 -Requires: %{name}-utils = %{version}, %{name}-core = %{version}, %{name}-deps = %{version}, %{name}-server = %{version} -Requires: %{name}-setup = %{version} -Requires: %{name}-client = %{version} -Requires: jsvc -License: Apache License 2.0 -Group: System Environment/Libraries -%description usage -The CloudStack usage monitor provides usage accounting across the entire cloud for -cloud operators to charge based on usage parameters. - -%package aws-api -Summary: CloudStack CloudBridge -Group: System Environment/Libraries -Requires: java >= 1.6.0 -Requires: tomcat6 -Requires: %{name}-deps = %{version} -%if 0%{?fedora} > 15 -Requires: apache-commons-lang -%endif -%if 0%{?rhel} >= 5 -Requires: jakarta-commons-lang -%endif -Obsoletes: cloud-bridge < %{version}-%{release} -%description aws-api -This is the CloudStack CloudBridge - -%prep - -echo Doing CloudStack build - -%setup -q -n %{name}-%{_ver} - -%build - -# this fixes the /usr/com bug on centos5 -%define _localstatedir /var -%define _sharedstatedir /var/lib -./waf configure --prefix=%{_prefix} --libdir=%{_libdir} --bindir=%{_bindir} --javadir=%{_javadir} --sharedstatedir=%{_sharedstatedir} --localstatedir=%{_localstatedir} --sysconfdir=%{_sysconfdir} --mandir=%{_mandir} --docdir=%{_docdir}/%{name}-%{version} --with-tomcat=%{_datadir}/tomcat6 --tomcat-user=%{name} --fast --build-number=%{_ver}-%{release} --package-version=%{_ver} -./waf build --build-number=%{?_build_number} --package-version=%{_ver} - -%install -[ ${RPM_BUILD_ROOT} != "/" ] && rm -rf ${RPM_BUILD_ROOT} -# we put the build number again here, otherwise state checking will cause an almost-full recompile -./waf install --destdir=$RPM_BUILD_ROOT --nochown --build-number=%{?_build_number} -rm $RPM_BUILD_ROOT/etc/rc.d/init.d/cloud-console-proxy -rm $RPM_BUILD_ROOT/usr/bin/cloud-setup-console-proxy -rm $RPM_BUILD_ROOT/usr/libexec/console-proxy-runner -ant deploy-rpm-install -Drpm.install.dir=$RPM_BUILD_ROOT - -%clean - -[ ${RPM_BUILD_ROOT} != "/" ] && rm -rf ${RPM_BUILD_ROOT} - - -%preun client -/sbin/service %{name}-management stop || true -if [ "$1" == "0" ] ; then - /sbin/chkconfig --del %{name}-management > /dev/null 2>&1 || true - /sbin/service %{name}-management stop > /dev/null 2>&1 || true -fi - -%pre aws-api -id %{name} > /dev/null 2>&1 || /usr/sbin/useradd -M -c "CloudStack unprivileged user" \ - -r -s /bin/sh -d %{_sharedstatedir}/%{name}/management %{name}|| true - -rm -rf %{_localstatedir}/cache/%{name} -# user harcoded here, also hardcoded on wscript - -%pre client-ui -if [ -d %{_datadir}/%{name}/management/webapps/client/ ]; then - pushd /tmp &>/dev/null - file=cloud-ui-backup-%(date +%%F).tar.bz2 - cp -r %{_datadir}/%{name}/management/webapps/client/ . - tar cjf "$file" client/ - rm -rf client/ - mkdir -p /usr/share/cloud/ui-backup/ - mv "$file" /usr/share/cloud/ui-backup/ - popd &>/dev/null -fi - -%preun usage -if [ "$1" == "0" ] ; then - /sbin/chkconfig --del %{name}-usage > /dev/null 2>&1 || true - /sbin/service %{name}-usage stop > /dev/null 2>&1 || true -fi - -%pre usage -id %{name} > /dev/null 2>&1 || /usr/sbin/useradd -M -c "CloudStack unprivileged user" \ - -r -s /bin/sh -d %{_sharedstatedir}/%{name}/management %{name}|| true -# user harcoded here, also hardcoded on wscript - -%post usage -if [ "$1" == "1" ] ; then - /sbin/chkconfig --add %{name}-usage > /dev/null 2>&1 || true - /sbin/chkconfig --level 345 %{name}-usage on > /dev/null 2>&1 || true -else - /sbin/service %{name}-usage condrestart >/dev/null 2>&1 || true -fi - -%preun agent -if [ "$1" == "0" ] ; then - /sbin/chkconfig --del %{name}-agent > /dev/null 2>&1 || true - /sbin/service %{name}-agent stop > /dev/null 2>&1 || true -fi - -%post agent -if [ "$1" == "1" ] ; then - /sbin/chkconfig --add %{name}-agent > /dev/null 2>&1 || true - /sbin/chkconfig --level 345 %{name}-agent on > /dev/null 2>&1 || true -else - /sbin/service %{name}-agent condrestart >/dev/null 2>&1 || true -fi - -if [ -x /etc/sysconfig/modules/kvm.modules ] ; then - /bin/sh /etc/sysconfig/modules/kvm.modules -fi - -%post client - /sbin/chkconfig --add %{name}-management > /dev/null 2>&1 || true - /sbin/chkconfig --level 345 %{name}-management on > /dev/null 2>&1 || true - - root=/usr/share/cloud/bridge - target=/usr/share/cloud/management - - mkdir -p $target/webapps7080 - if [ ! -h $target/webapps7080/awsapi ]; then - ln -sf $root/webapps7080/awsapi $target/webapps7080/awsapi - fi - -# jars=`ls $root/lib` -# for j in $jars -# do -# cp -f $root/lib/$j $root/webapps/awsapi/WEB-INF/lib/ -# done - - confs="cloud-bridge.properties ec2-service.properties" - for c in $confs - do - cp -f $root/conf/$c $target/conf - done - -%files utils -%defattr(0644,root,root,0755) -%{_javadir}/%{name}-utils.jar -%{_javadir}/%{name}-api.jar -%attr(0755,root,root) %{_bindir}/cloud-sccs -%attr(0755,root,root) %{_bindir}/cloud-gitrevs -%doc %{_docdir}/%{name}-%{version}/version-info -%doc LICENSE -%doc NOTICE - -%files client-ui -%defattr(0644,root,root,0755) -%{_datadir}/%{name}/management/webapps/client/* -%doc LICENSE -%doc NOTICE - -%files server -%defattr(0644,root,root,0755) -%{_javadir}/%{name}-server.jar -%{_javadir}/%{name}-ovm.jar -%{_javadir}/%{name}-dp-user-concentrated-pod.jar -%{_javadir}/%{name}-dp-user-dispersing.jar -%{_javadir}/%{name}-host-allocator-random.jar -%{_javadir}/%{name}-plugin-ovs.jar -%{_javadir}/%{name}-storage-allocator-random.jar -%{_javadir}/%{name}-user-authenticator-ldap.jar -%{_javadir}/%{name}-user-authenticator-md5.jar -%{_javadir}/%{name}-user-authenticator-plaintext.jar -%{_javadir}/%{name}-plugin-hypervisor-xen.jar -%{_javadir}/%{name}-plugin-elb.jar -%{_javadir}/%{name}-plugin-nicira-nvp.jar -%{_javadir}/%{name}-plugin-bigswitch-vns.jar -%config(noreplace) %{_sysconfdir}/%{name}/server/* -%doc LICENSE -%doc NOTICE - -%files scripts -%defattr(-,root,root,-) -%{_libdir}/%{name}/common/scripts/* -# maintain the following list in sync with files scripts -%{_libdir}/%{name}/common/vms/systemvm.zip -%{_libdir}/%{name}/common/vms/systemvm.iso -%doc LICENSE -%doc NOTICE - -%files deps -%defattr(0644,root,root,0755) -%{_javadir}/axiom-*.jar -%{_javadir}/axis2-*.jar -%{_javadir}/antlr*.jar -%{_javadir}/XmlSchema-*.jar -%{_javadir}/json-simple*.jar -%{_javadir}/neethi*.jar -%{_javadir}/woden*.jar -%{_javadir}/xercesImpl*.jar -%{_javadir}/xml-apis*.jar -%{_javadir}/dom4j*.jar -%{_javadir}/javassist*.jar -%{_javadir}/commons-fileupload*.jar -%{_javadir}/commons-codec-1.6.jar -%{_javadir}/commons-dbcp-1.4.jar -%{_javadir}/commons-pool-1.6.jar -%{_javadir}/gson-1.7.1.jar -%{_javadir}/CAStorSDK-*.jar -%{_javadir}/backport-util-concurrent-3.1.jar -%{_javadir}/ehcache-1.5.0.jar -%{_javadir}/httpcore-4.0.jar -%{_javadir}/mail-1.4.jar -%{_javadir}/activation-1.1.jar -%{_javadir}/xapi-5.6.100-1-SNAPSHOT.jar -%{_javadir}/log4j-*.jar -%{_javadir}/apache-log4j-extras-1.1.jar -%{_javadir}/trilead-ssh2-build213-svnkit-1.3-patch.jar -%{_javadir}/cglib-nodep-2.2.2.jar -%{_javadir}/xmlrpc-common-3.*.jar -%{_javadir}/xmlrpc-client-3.*.jar -%{_javadir}/wsdl4j-1.6.2.jar -%{_javadir}/jsch-0.1.42.jar -%{_javadir}/jasypt-1.*.jar -%{_javadir}/commons-configuration-1.8.jar -%{_javadir}/ejb-api-3.0.jar -%{_javadir}/axis2-1.5.1.jar -%{_javadir}/commons-discovery-0.5.jar -%{_javadir}/jstl-1.2.jar -%{_javadir}/javax.persistence-2.0.0.jar -%{_javadir}/bcprov-jdk16-1.45.jar -%doc LICENSE -%doc NOTICE - -%files core -%defattr(0644,root,root,0755) -%{_javadir}/%{name}-core.jar -%doc LICENSE -%doc NOTICE - -%files python -%defattr(0644,root,root,0755) -%{_prefix}/lib*/python*/site-packages/%{name}* -%attr(0755,root,root) %{_bindir}/cloud-external-ipallocator.py -%attr(0755,root,root) %{_initrddir}/cloud-ipallocator -%dir %attr(0770,root,root) %{_localstatedir}/log/%{name}/ipallocator -%doc LICENSE -%doc NOTICE - -%files setup -%attr(0755,root,root) %{_bindir}/%{name}-setup-databases -%attr(0755,root,root) %{_bindir}/%{name}-migrate-databases -%attr(0755,root,root) %{_bindir}/%{name}-set-guest-password -%attr(0755,root,root) %{_bindir}/%{name}-set-guest-sshkey -%attr(0755,root,root) %{_bindir}/%{name}-sysvmadm -%attr(0755,root,root) %{_bindir}/%{name}-setup-encryption -%dir %{_datadir}/%{name}/setup -%{_datadir}/%{name}/setup/*.sql -%{_datadir}/%{name}/setup/db/*.sql -%{_datadir}/%{name}/setup/*.sh -%{_datadir}/%{name}/setup/server-setup.xml -%doc LICENSE -%doc NOTICE - -%files client -%defattr(0644,root,root,0775) -%config(noreplace) %{_sysconfdir}/%{name}/management -%config(noreplace) %attr(0640,root,%{name}) %{_sysconfdir}/%{name}/management/db.properties -%config(noreplace) %{_sysconfdir}/%{name}/management/log4j-%{name}.xml -%config(noreplace) %{_sysconfdir}/%{name}/management/tomcat6.conf -%dir %attr(0770,root,%{name}) %{_sysconfdir}/%{name}/management/Catalina -%dir %attr(0770,root,%{name}) %{_sysconfdir}/%{name}/management/Catalina/localhost -%dir %attr(0770,root,%{name}) %{_sysconfdir}/%{name}/management/Catalina/localhost/client -%config(noreplace) %{_sysconfdir}/sysconfig/%{name}-management -%attr(0755,root,root) %{_initrddir}/%{name}-management -%dir %{_datadir}/%{name}/management -%{_datadir}/%{name}/management/* -%attr(0755,root,root) %{_bindir}/%{name}-setup-management -%attr(0755,root,root) %{_bindir}/%{name}-update-xenserver-licenses -%dir %attr(0770,root,%{name}) %{_sharedstatedir}/%{name}/mnt -%dir %attr(0770,%{name},%{name}) %{_sharedstatedir}/%{name}/management -%dir %attr(0770,root,%{name}) %{_localstatedir}/cache/%{name}/management -%dir %attr(0770,root,%{name}) %{_localstatedir}/cache/%{name}/management/work -%dir %attr(0770,root,%{name}) %{_localstatedir}/cache/%{name}/management/temp -%dir %attr(0770,root,%{name}) %{_localstatedir}/log/%{name}/management -%dir %attr(0770,root,%{name}) %{_localstatedir}/log/%{name}/agent -%doc LICENSE -%doc NOTICE - -%files agent-libs -%defattr(0644,root,root,0755) -%{_javadir}/%{name}-agent.jar -%{_javadir}/%{name}-plugin-hypervisor-kvm.jar -%{_javadir}/libvirt-0.4.9.jar -%doc LICENSE -%doc NOTICE - -%files agent -%defattr(0644,root,root,0755) -%config(noreplace) %{_sysconfdir}/%{name}/agent/agent.properties -%config(noreplace) %{_sysconfdir}/%{name}/agent/developer.properties.template -%config(noreplace) %{_sysconfdir}/%{name}/agent/environment.properties -%config(noreplace) %{_sysconfdir}/%{name}/agent/log4j-%{name}.xml -%attr(0755,root,root) %{_initrddir}/%{name}-agent -%attr(0755,root,root) %{_bindir}/%{name}-setup-agent -%attr(0755,root,root) %{_bindir}/%{name}-ssh -%dir %attr(0770,root,root) %{_localstatedir}/log/%{name}/agent -%doc LICENSE -%doc NOTICE - -%files cli -%{_bindir}/%{name}-tool -%{_bindir}/cloudvoladm -%{_bindir}/cloud-grab-dependent-library-versions -%config(noreplace) %{_sysconfdir}/%{name}/cli/commands.xml -%dir %{_prefix}/lib*/python*/site-packages/%{name}tool -%{_prefix}/lib*/python*/site-packages/%{name}tool/* -%{_prefix}/lib*/python*/site-packages/%{name}apis.py -%doc LICENSE -%doc NOTICE - -%files baremetal-agent -%attr(0755,root,root) %{_bindir}/cloud-setup-baremetal -%doc LICENSE -%doc NOTICE - -%files usage -%defattr(0644,root,root,0775) -%{_javadir}/%{name}-usage.jar -%attr(0755,root,root) %{_initrddir}/%{name}-usage -%dir %attr(0770,root,%{name}) %{_localstatedir}/log/%{name}/usage -%config(noreplace) %{_sysconfdir}/%{name}/usage/usage-components.xml -%config(noreplace) %{_sysconfdir}/%{name}/usage/log4j-%{name}_usage.xml -%config(noreplace) %attr(0640,root,%{name}) %{_sysconfdir}/%{name}/usage/db.properties -%doc LICENSE -%doc NOTICE - -%files aws-api -%defattr(0644,cloud,cloud,0755) -%{_datadir}/cloud/bridge/conf/* -%{_datadir}/cloud/bridge/webapps7080/* -%attr(0644,root,root) %{_datadir}/cloud/setup/bridge/db/* -%attr(0755,root,root) %{_bindir}/cloudstack-aws-api-register -%attr(0755,root,root) %{_bindir}/cloud-setup-bridge -%doc LICENSE -%doc NOTICE - -%changelog -* Mon Nov 19 2012 Satoshi Kobayashi 4.0.1 -- adding dependency bridge-utils to fix a system requirement - -* Fri Sep 14 2012 Marcus Sorensen 4.0.1 -- adding dependency jakarta-commons-daemon to fix "cannot find daemon loader" - -* Thu Aug 16 2012 Marcus Sorensen 4.0 -- rearranged files sections to match currently built files - -* Mon May 3 2010 Manuel Amador (Rudd-O) 1.9.12 -- Bump version for RC4 release - -* Fri Apr 30 2010 Manuel Amador (Rudd-O) 1.9.11 -- Rename to CloudStack everywhere - -* Wed Apr 28 2010 Manuel Amador (Rudd-O) 1.9.10 -- FOSS release - -* Mon Apr 05 2010 Manuel Amador (Rudd-O) 1.9.8 -- RC3 branched - -* Wed Feb 17 2010 Manuel Amador (Rudd-O) 1.9.7 -- First initial broken-up release - - diff --git a/waf b/waf deleted file mode 100755 index a2c413830968cc38aac27252c6014d9c9fa4c516..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92487 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

Loo{C)N460eIH=WSchIeO^$b=_T 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 diff --git a/waf.bat b/waf.bat deleted file mode 100755 index afc94cd12bd..00000000000 --- a/waf.bat +++ /dev/null @@ -1,44 +0,0 @@ -@echo off -rem Licensed to the Apache Software Foundation (ASF) under one -rem or more contributor license agreements. See the NOTICE file -rem distributed with this work for additional information -rem regarding copyright ownership. The ASF licenses this file -rem to you under the Apache License, Version 2.0 (the -rem "License"); you may not use this file except in compliance -rem with the License. You may obtain a copy of the License at -rem -rem http://www.apache.org/licenses/LICENSE-2.0 -rem -rem Unless required by applicable law or agreed to in writing, -rem software distributed under the License is distributed on an -rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -rem KIND, either express or implied. See the License for the -rem specific language governing permissions and limitations -rem under the License. - -if exist jython.jar goto runjython -if exist C:\Python26\Python.exe goto runpython -goto helprun - -:helprun -echo To run waf with Python -echo 1. Download Python 2.6 for Windows from http://www.python.org/ -echo 2. Install it in C:\Python2.6 (the default path) -echo 3. Use this batch file to run waf -echo "" -echo To run waf without installing Python -echo 1. Download the Jython installer from http://wiki.python.org/jython/ -echo 2. Install it to this directory in standalone mode -echo 3. Ensure the java command is on your PATH variable -echo 3. Use this batch file to run waf -goto end - -:runjython -java -jar jython.jar waf %* -goto end - -:runpython -C:\Python26\Python.exe waf %* -goto end - -:end diff --git a/wscript b/wscript deleted file mode 100644 index 077fc713686..00000000000 --- a/wscript +++ /dev/null @@ -1,782 +0,0 @@ -#! /usr/bin/env python -# -*- coding: utf-8 -*- -# 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. - - -# the following variables are used by the target "waf dist" -# if you change APPNAME here, you need to change 'Name' also -# in cloud.spec, add a %changelog entry there, and add an -# entry in debian/changelog. SHORTVERSION is used in package -# naming for deb/rpm, VERSION is used for tarball and bin -VERSION = '4.0.0.2012-08-15T18:03:12Z' -SHORTVERSION = '4.0.0' -APPNAME = 'cloud' - -import shutil,os -import email,time -import optparse -import Utils,Node,Options,Logs,Scripting,Environment,Build,Configure -from subprocess import Popen as _Popen,PIPE -import os -import sys -from os import unlink as _unlink, makedirs as _makedirs, getcwd as _getcwd, chdir as _chdir -from os.path import abspath as _abspath, basename as _basename, dirname as _dirname, exists as _exists, isdir as _isdir, split as _split, join as _join, sep, pathsep, pardir, curdir -from glob import glob as _glob -import zipfile,tarfile -try: - from os import chmod as _chmod,chown as _chown - import pwd,stat,grp -except ImportError: - _chmod,_chown,pwd,stat,grp = (None,None,None,None,None) -import xml.dom.minidom -import re - -# these variables are mandatory ('/' are converted automatically) -srcdir = '.' -blddir = 'artifacts' - -Configure.autoconfig = True - -# things not to include in the source tarball -# exclude by file name or by _glob (wildcard matching) -for _globber in [ - ["dist", # does not belong in the source tarball - "system", # for windows - "override", # not needed - "eclipse", # only there to please eclipse - "repomanagement", # internal management stuff - "client-api", # obsolete - "cloud-bridge", # not compiled and packaged yet - "target", # eclipse workdir - "apache-log4j-1.2.16", - "apache-log4j-extras-1.1", - "cglib", - "gson", - "ehcache", - "vhd-tools", - "xmlrpc", - "PreviousDatabaseSchema", - "mockito", - "gcc", - "junit" ], - _glob("./*.disabledblahxml"), - ]: - for f in _globber: Scripting.excludes.append(_basename(f)) # _basename() only the filename - -# things never to consider when building or installing -for pattern in ["**/.project","**/.classpath","**/.pydevproject"]: Node.exclude_regs += "\n%s"%pattern - -# Support functions - -def distclean(ctx): - """Clear the build artifacts""" - for root, folder, files in os.walk(blddir): - for f in files: - path = os.path.join(root, f) - print "Removing artifact %s"%path - os.remove(path) - -def inspectobj(x): - """Look inside an object""" - for m in dir(x): print m,": ",getattr(x,m) -Utils.inspectobj = inspectobj - -def _trm(x,y): - if len(x) > y: return x[:y] + "..." - return x - -def getrpmdeps(): - def rpmdeps(fileset): - for f in fileset: - lines = file(f).readlines() - lines = [ x[len("BuildRequires: "):] for x in lines if x.startswith("BuildRequires") ] - for l in lines: - deps = [ x.strip() for x in l.split(",") ] - for d in deps: - if "%s-"%APPNAME in d: continue - yield d - yield "rpm-build" - - deps = set(rpmdeps(_glob("./*.spec"))) - deps.add("ant") - return deps - -# CENTOS does not have this -- we have to put this here -try: - from subprocess import check_call as _check_call - from subprocess import CalledProcessError -except ImportError: - def _check_call(*popenargs, **kwargs): - import subprocess - retcode = subprocess.call(*popenargs, **kwargs) - cmd = kwargs.get("args") - if cmd is None: cmd = popenargs[0] - if retcode: raise CalledProcessError(retcode, cmd) - return retcode - - class CalledProcessError(Exception): - def __init__(self, returncode, cmd): - self.returncode = returncode ; self.cmd = cmd - def __str__(self): return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode) -def throws_command_errors(f): - def g(*args,**kwargs): - try: return f(*args,**kwargs) - except CalledProcessError,e: - raise Utils.WafError("system command %s failed with error value %s"%(e.cmd[0],e.returncode)) - except IOError,e: - if e.errno is 32: - raise Utils.WafError("system command %s terminated abruptly, closing communications with parent's pipe"%e.cmd[0]) - raise - return g - -def c(cmdlist,cwd=None): - # Run a command with _check_call, pretty-printing the cmd list - Utils.pprint("BLUE"," ".join(cmdlist)) - return _check_call(cmdlist,cwd=cwd) - -def svninfo(*args): - try: p = _Popen(['svn','info']+list(args),stdin=PIPE,stdout=PIPE,stderr=PIPE) - except OSError,e: - if e.errno == 2: return '' # svn command is not installed - raise - stdout,stderr = p.communicate('') - retcode = p.wait() - # If the guess fails, just return nothing. - if retcode: return - # SVN available - rev = [ x for x in stdout.splitlines() if x.startswith('Revision') ] - if not rev: rev = '' - else: rev = "SVN " + rev[0].strip() - url = [ x for x in stdout.splitlines() if x.startswith('URL') ] - if not url: url = '' - else: url = "SVN " + url[0].strip() - return rev + "\n" + url - -def gitinfo(dir=None): - if dir and not _isdir(dir): return '' - try: p = _Popen(['git','remote','show','-n','origin'],stdin=PIPE,stdout=PIPE,stderr=PIPE,cwd=dir) - except OSError,e: - if e.errno == 2: return '' # svn command is not installed - raise - stdout,stderr = p.communicate('') - retcode = p.wait() - # If the guess fails, just return nothing. - if retcode: return - stdout = [ s.strip() for s in stdout.splitlines() ] - try: url = [ s[11:] for s in stdout if s.startswith("Fetch URL") ][0] - except IndexError: url = [ s[5:] for s in stdout if s.startswith("URL") ][0] - assert url - - p = _Popen(['git','log','-1'],stdin=PIPE,stdout=PIPE,stderr=PIPE,cwd=dir) - stdout,stderr = p.communicate('') - retcode = p.wait() - if retcode: return - # If the guess fails, just return nothing. - stdout = [ s.strip() for s in stdout.splitlines() ] - commitid = [ s.split()[1] for s in stdout if s.startswith("commit") ][0] - assert commitid - - return "Git Revision: %s"%commitid + "\n" + "Git URL: %s"%url - -def allgitinfo(): - t = gitinfo() - if not t: return t - - u = gitinfo(_join(pardir,"cloudstack-proprietary")) - if not u: return t - - return t + "\n\ncloustack-proprietary:\n" + u - -def _getbuildnumber(): # FIXME implement for git - n = Options.options.BUILDNUMBER - if n: - # luntbuild prepends "build-" to the build number. we work around this here: - if n.startswith("build-"): n = n[6:] - # SVN identifiers prepend "$Revision:" to the build number. we work around this here: - if n.startswith("$Revision:"): n = n[11:-2].strip() - return n - else: - # Try to guess the SVN revision number by calling SVN info. - stdout = svninfo() - if not stdout: return '' - # Filter lines. - rev = [ x for x in stdout.splitlines() if x.startswith('SVN Revision') ] - if not rev: return '' - # Parse revision number. - rev = rev[0][14:].strip() - return rev -Utils.getbuildnumber = _getbuildnumber - -def mkdir_p(directory): - if not _isdir(directory): - Utils.pprint("GREEN","Creating directory %s and necessary parents"%directory) - _makedirs(directory) - -def relpath(path, start="."): - if not path: raise ValueError("no path specified") - - start_list = os.path.abspath(start).split(sep) - path_list = os.path.abspath(path).split(sep) - - # Work out how much of the filepath is shared by start and path. - i = len(os.path.commonprefix([start_list, path_list])) - - rel_list = [pardir] * (len(start_list)-i) + path_list[i:] - if not rel_list: - return curdir - return os.path.join(*rel_list) -Utils.relpath = relpath - -def dev_override(pathname): - p,e = _split(pathname) - overridden = _join(p,"override",e) - if _exists(overridden): return overridden - return pathname - -def discover_ant_targets_and_properties(files): - doms = [ xml.dom.minidom.parseString(file(f).read(-1)) for f in files if f.endswith(".xml") ] - targets = dict( [ (target.getAttribute("name"),target) for dom in doms for target in dom.getElementsByTagName("target") if target.getElementsByTagName("compile-java") ] ) - propsinxml = [ (prop.getAttribute("name"),prop.getAttribute("value") or prop.getAttribute("location")) for dom in doms for prop in dom.getElementsByTagName("property") ] - propsinpropfiles = [ l.strip().split("=",1) for f in files if f.endswith(".properties") for l in file(f).readlines() if "=" in l and not l.startswith("#") ] - props = dict( propsinxml + propsinpropfiles ) - props["base.dir"] = '.' - props["p.base.dir"] = '.' - - result = [] - for name,target in targets.items(): - sourcedir = target.getElementsByTagName("compile-java")[0].getAttribute("top.dir") + "/src" - classdir = "${classes.dir}/" + target.getElementsByTagName("compile-java")[0].getAttribute("jar.name") - jarpath = "${jar.dir}/" + target.getElementsByTagName("compile-java")[0].getAttribute("jar.name") - def lookup(matchobject): return props[matchobject.group(1)] - while "$" in sourcedir: sourcedir = re.sub("\${(.+?)}",lookup,sourcedir) - while "$" in classdir: classdir = re.sub("\${(.+?)}",lookup,classdir) - while "$" in jarpath: jarpath= re.sub("\${(.+?)}",lookup,jarpath) - dependencies = [ dep.strip() for dep in target.getAttribute("depends").split(",") if dep.strip() in targets ] - result.append([str(name),str(relpath(sourcedir)),str(relpath(classdir)),str(relpath(jarpath)),[str(s) for s in dependencies]]) - # hardcoded here because the discovery process does not get it - result.append( ["build-console-viewer","console-viewer/src", "target/classes/console-viewer", "target/jar/VMOpsConsoleApplet.jar", ["compile-utils","compile-console-common"] ] ) - return result,props -Utils.discover_ant_targets_and_properties = discover_ant_targets_and_properties - -# this snippet of code runs a list of ant targets -# then it expects a certain set of JAR files to be output in the artifacts/default/ant/jar directory -# this set of jar files is defined here in the variable jartgts, and must match the definitions at the bottom of -# build/package.xml and build/premium/package-premium.xml -# this is NOT a task for a task generator -- it is a plain function. -# If you want to use it as a task function in a task generator, use a lambda x: runant("targetname") -def runant(tsk): - - environ = dict(os.environ) - environ["CATALINA_HOME"] = tsk.env.TOMCATHOME - if tsk.generator.env.DISTRO == "Windows": - stanzas = [ - "ant", - "-Dthirdparty.classpath=\"%s\""%(tsk.env.CLASSPATH.replace(os.pathsep,",")), - ] - else: - stanzas = [ - "ant", - "-Dthirdparty.classpath=%s"%(tsk.env.CLASSPATH.replace(os.pathsep,",")), - ] - stanzas += tsk.generator.antargs - ret = Utils.exec_command(" ".join(stanzas),cwd=tsk.generator.bld.srcnode.abspath(),env=environ,log=True) - if ret != 0: raise Utils.WafError("Ant command %s failed with error value %s"%(stanzas,ret)) - return ret -Utils.runant = runant - -@throws_command_errors -def run_java(classname,classpath,options=None,arguments=None): - if not options: options = [] - if not arguments: arguments = [] - if type(classpath) in [list,tuple]: classpath = pathsep.join(classpath) - - Utils.pprint("BLUE","Run-time CLASSPATH:") - for v in classpath.split(pathsep): Utils.pprint("BLUE"," %s"%v) - - cmd = ["java","-classpath",classpath] + options + [classname] + arguments - Utils.pprint("BLUE"," ".join([ _trm(x,32) for x in cmd ])) - _check_call(cmd) - -# this will enforce the after= ordering constraints in the javac task generators -from TaskGen import after, feature -@feature('*') -@after('apply_core', 'apply_java', 'apply_subst') -def process_after(self): - lst = self.to_list(getattr(self, 'after', [])) - for x in lst: - obj = self.bld.name_to_obj(x,self.bld.env) - if not obj: break - obj.post() - for a in obj.tasks: - for b in self.tasks: - b.set_run_after(a) - -Build.BuildContext.process_after = staticmethod(process_after) - -def _getbuildcontext(): - ctx = Build.BuildContext() - ctx.load_dirs(_abspath(srcdir),_abspath(blddir)) - ctx.load_envs() - return ctx - -def _install_files_filtered(self,destdir,listoffiles,**kwargs): - if "cwd" in kwargs: cwd = kwargs["cwd"] - else: cwd = self.path - if isinstance(listoffiles,str) and '**' in listoffiles: - listoffiles = cwd.ant_glob(listoffiles,flat=True) - elif isinstance(listoffiles,str) and '*' in listoffiles: - listoffiles = [ n for x in listoffiles.split() for n in _glob(cwd.abspath() + os.sep + x.replace("/",os.sep)) ] - listoffiles = Utils.to_list(listoffiles)[:] - listoffiles = [ x for x in listoffiles if not ( x.endswith("~") or x == "override" or "%soverride"%os.sep in x ) ] - for n,f in enumerate(listoffiles): - f = os.path.abspath(f) - f = dev_override(f) - if _isdir(f): continue - if f.endswith(".in"): - source = f ; target = f[:-3] - tgen = self(features='subst', source=source[len(self.path.abspath())+1:], target=target[len(self.path.abspath())+1:], name="filtered_%s"%source) - tgen.dict = self.env.get_merged_dict() - else: - source = f ; target = f - listoffiles[n] = target[len(cwd.abspath())+1:] - if "postpone" not in kwargs: kwargs["postpone"] = True - ret = self.install_files(destdir,listoffiles,**kwargs) - return ret -Build.BuildContext.install_files_filtered = _install_files_filtered - -def _substitute(self,listoffiles,install_to=None,cwd=None,dict=None,name=None,**kwargs): - if cwd is None: cwd = self.path - tgenkwargs = {} - if name is not None: tgenkwargs["name"] = name - if isinstance(listoffiles,str) and '**' in listoffiles: - listoffiles = cwd.ant_glob(listoffiles,flat=True) - elif isinstance(listoffiles,str) and '*' in listoffiles: - listoffiles = [ n for x in listoffiles.split() for n in _glob(cwd.abspath() + os.sep + x.replace("/",os.sep)) ] - for src in Utils.to_list(listoffiles): - tgt = src + ".subst" - inst = src # Utils.relpath(src,relative_to) <- disabled - - # Use cwd path when creating task and shift back later - tmp = self.path - self.path = cwd - tgen = self(features='subst', source=src, target=tgt, **tgenkwargs) - self.path = tmp - - if dict is not None: tgen.dict = dict - else: tgen.dict = self.env.get_merged_dict() - self.path.find_or_declare(tgt) - if install_to is not None: self.install_as("%s/%s"%(install_to,inst), tgt, cwd=cwd, **kwargs) -Build.BuildContext.substitute = _substitute - -def set_options(opt): - """Register command line options""" - opt.tool_options('gnu_dirs') - opt.tool_options('python') - opt.tool_options('tar',tooldir='tools/waf') - opt.tool_options('mkisofs',tooldir='tools/waf') - if Options.platform not in ['darwin','win32']: opt.tool_options('usermgmt',tooldir='tools/waf') - if Options.platform not in ['darwin','win32']: opt.tool_options('javadir',tooldir='tools/waf') - opt.tool_options('tomcat',tooldir='tools/waf') - if Options.platform not in ['darwin',"win32"]: opt.tool_options('compiler_cc') - - inst_dir = opt.get_option_group('--srcdir') - inst_dir.add_option('--with-db-host', - help = 'Database host to use for waf deploydb [Default: 127.0.0.1]', - default = '127.0.0.1', - dest = 'DBHOST') - inst_dir.add_option('--with-db-user', - help = 'Database user to use for waf deploydb [Default: root]', - default = 'root', - dest = 'DBUSER') - inst_dir.add_option('--with-db-pw', - help = 'Database password to use for waf deploydb [Default: ""]', - default = '', - dest = 'DBPW') - inst_dir.add_option('--tomcat-user', - help = 'UNIX user that the management server initscript will switch to [Default: ]', - default = '', - dest = 'MSUSER') - inst_dir.add_option('--no-dep-check', - action='store_true', - help = 'Skip dependency check and assume JARs already exist', - default = False, - dest = 'NODEPCHECK') - inst_dir.add_option('--fast', - action='store_true', - help = 'does ---no-dep-check', - default = False, - dest = 'NODEPCHECK') - inst_dir = opt.get_option_group('--force') - inst_dir.add_option('--preserve-config', - action='store_true', - help = 'do not install configuration files', - default = False, - dest = 'PRESERVECONFIG') - - debugopts = optparse.OptionGroup(opt.parser,'run/debug options') - opt.add_option_group(debugopts) - debugopts.add_option('--debug-port', - help = 'Port on which the debugger will listen when running waf debug [Default: 8787]', - default = '8787', - dest = 'DEBUGPORT') - debugopts.add_option('--debug-suspend', - action='store_true', - help = 'Suspend the process upon startup so that a debugger can attach and set breakpoints', - default = False, - dest = 'DEBUGSUSPEND') - debugopts.add_option('--run-verbose', - action='store_true', - help = 'Run Tomcat in verbose mode (java option -verbose)', - default = False, - dest = 'RUNVERBOSE') - - rpmopts = optparse.OptionGroup(opt.parser,'RPM/DEB build options') - opt.add_option_group(rpmopts) - rpmopts.add_option('--build-number', - help = 'Build number [Default: SVN revision number for builds from checkouts, or empty for builds from source releases]', - default = '', - dest = 'BUILDNUMBER') - rpmopts.add_option('--package-version', - help = 'package version', - default = '', - dest = 'VERNUM') - rpmopts.add_option('--release-version', - help = 'release version', - default = '', - dest = 'RELEASENUM') - rpmopts.add_option('--prerelease', - help = 'Branch name to append to the release number (if specified, alter release number to be a prerelease); this option requires --build-number=X [Default: nothing]', - default = '', - dest = 'PRERELEASE') - rpmopts.add_option('--skip-dist', - action='store_true', - help = 'Normally, dist() is called during package build. This makes the package build assume that a distribution tarball has already been made, and use that. This option is also valid during distcheck and dist.', - default = False, - dest = 'DONTDIST') - - distopts = optparse.OptionGroup(opt.parser,'dist options') - opt.add_option_group(distopts) - distopts.add_option('--oss', - help = 'Only include open source components', - action = 'store_true', - default = False, - dest = 'OSS') - -def showconfig(conf): - """prints out the current configure environment configuration""" - conf = _getbuildcontext() - - Utils.pprint("WHITE","Build environment:") - for key,val in sorted(conf.env.get_merged_dict().items()): - if "CLASSPATH" in key: - Utils.pprint("BLUE"," %s:"%key) - for v in val.split(pathsep): - Utils.pprint("BLUE"," %s"%v) - continue - Utils.pprint("BLUE"," %s: %s"%(key,val)) - -def _getconfig(self): - lines = [] - for key,val in sorted(self.env.get_merged_dict().items()): - if "CLASSPATH" in key: - lines.append(" %s:"%key) - for v in val.split(pathsep): - lines.append(" %s"%v) - continue - lines.append(" %s: %s"%(key,val)) - return "\n".join(lines) -Build.BuildContext.getconfig = _getconfig - -def list_targets(ctx): - """return the list of buildable and installable targets""" - - bld = Build.BuildContext() - proj = Environment.Environment(Options.lockfile) - bld.load_dirs(proj['srcdir'], proj['blddir']) - bld.load_envs() - - bld.add_subdirs([os.path.split(Utils.g_module.root_path)[0]]) - - names = set([]) - for x in bld.all_task_gen: - try: - names.add(x.name or x.target) - except AttributeError: - pass - - lst = list(names) - lst.sort() - for name in lst: - print(name) - -def decorate_dist(f): - def dist(appname='',version=''): - '''makes a tarball for redistributing the sources -- if --skip-dist is specified, does nothing''' - if Options.options.DONTDIST: - if not appname: appname=Utils.g_module.APPNAME - if not version: version=Utils.g_module.VERSION - tmp_folder=appname+'-'+version - if Scripting.g_gz in['gz','bz2']: - arch_name=tmp_folder+'.tar.'+Scripting.g_gz - else: - arch_name=tmp_folder+'.'+'zip' - Logs.info('New archive skipped: %s'%(arch_name)) - return arch_name - else: - return f(appname,version) - return dist -Scripting.dist = decorate_dist(Scripting.dist) - -def dist_hook(): - # Clean the GARBAGE that clogs our repo to the tune of 300 MB - # so downloaders won't have to cry every time they download a "source" - # package over 90 MB in size - [ shutil.rmtree(f) for f in _glob(_join("*","bin")) if _isdir(f) ] - [ shutil.rmtree(f) for f in _glob(_join("cloudstack-proprietary","thirdparty","*")) if _isdir(f) ] - [ shutil.rmtree(f) for f in [ _join("cloudstack-proprietary","tools") ] if _isdir(f) ] - - if Options.options.OSS: - [ shutil.rmtree(f) for f in "cloudstack-proprietary".split() if _exists(f) ] - - stdout = svninfo("..") or allgitinfo() - if stdout: - f = file("sccs-info","w") - f.write(stdout) - f.flush() - f.close() - else: - # No SVN available - if _exists("sccs-info"): - # If the file already existed, we preserve it - return - else: - f = file("sccs-info","w") - f.write("No revision control information could be detected when the source distribution was built.") - f.flush() - f.close() - -def bindist(ctx): - """creates a binary distribution that, when unzipped in the root directory of a machine, deploys the entire stack""" - ctx = _getbuildcontext() - - if Options.options.VERNUM: - VERSION = Options.options.VERNUM - - tarball = "%s-bindist-%s.tar.%s"%(APPNAME,VERSION,Scripting.g_gz) - zf = _join(ctx.bldnode.abspath(),tarball) - Options.options.destdir = _join(ctx.bldnode.abspath(),"bindist-destdir") - Scripting.install(ctx) - - if _exists(zf): _unlink(zf) - Utils.pprint("GREEN","Creating %s"%(zf)) - z = tarfile.open(zf,"w:bz2") - cwd = _getcwd() - _chdir(Options.options.destdir) - z.add(".") - z.close() - _chdir(cwd) - -@throws_command_errors -def deb(context): - raise Utils.WafError("Debian packages are no longer build with waf. Use dpkg-buildpackage instead.") - -@throws_command_errors -def rpm(context): - buildnumber = Utils.getbuildnumber() - if buildnumber: buildnumber = ["--define","_build_number %s"%buildnumber] - else: buildnumber = [] - - if Options.options.PRERELEASE: - if not buildnumber: - raise Utils.WafError("Please specify a build number to go along with --prerelease") - prerelease = ["--define","_prerelease %s"%Options.options.PRERELEASE] - else: prerelease = [] - - if Options.options.RELEASENUM: - release = Options.options.RELEASENUM - else: release = "1" - - releasever = ["--define", "_rel %s" % release] - - if Options.options.VERNUM: - ver = Options.options.VERNUM - else: ver = SHORTVERSION - - packagever = ["--define", "_ver %s" % ver] - - # FIXME wrap the source tarball in POSIX locking! - if not Options.options.blddir: outputdir = _join(context.curdir,blddir,"rpmbuild") - else: outputdir = _join(_abspath(Options.options.blddir),"rpmbuild") - Utils.pprint("GREEN","Building RPMs") - - tarball = Scripting.dist('', ver) - sourcedir = _join(outputdir,"SOURCES") - - if _exists(sourcedir): shutil.rmtree(sourcedir) - for a in ["RPMS/noarch","SRPMS","BUILD","SPECS","SOURCES"]: mkdir_p(_join(outputdir,a)) - shutil.move(tarball,_join(sourcedir,tarball)) - - specfile = "%s.spec"%APPNAME - checkdeps = lambda: c(["rpmbuild","--define","_topdir %s"%outputdir,"--nobuild",specfile]+packagever+releasever) - dorpm = lambda: c(["rpmbuild","--define","_topdir %s"%outputdir,"-bb",specfile]+buildnumber+prerelease+packagever+releasever) - try: checkdeps() - except (CalledProcessError,OSError),e: - Utils.pprint("YELLOW","Dependencies might be missing. Trying to auto-install them...") - installrpmdeps(context) - dorpm() - -def uninstallrpms(context): - """uninstalls any Cloud Stack RPMs on this system""" - Utils.pprint("GREEN","Uninstalling any installed RPMs") - cmd = "rpm -qa | grep %s- | xargs -r sudo rpm -e"%APPNAME - Utils.pprint("BLUE",cmd) - system(cmd) - -def viewrpmdeps(context): - """shows all the necessary dependencies to build the RPM packages of the stack""" - for dep in getrpmdeps(): print dep - -@throws_command_errors -def installrpmdeps(context): - """installs all the necessary dependencies to build the RPM packages of the stack""" - runnable = ["sudo","yum","install","-y"]+list(getrpmdeps()) - Utils.pprint("GREEN","Installing RPM build dependencies") - Utils.pprint("BLUE"," ".join(runnable)) - _check_call(runnable) - -@throws_command_errors -def deploydb(ctx,virttech=None): - if not virttech: raise Utils.WafError('use deploydb_xenserver, deploydb_vmware or deploydb_kvm rather than deploydb') - - ctx = _getbuildcontext() - setupdatabases = _join(ctx.env.BINDIR,"cloud-setup-databases") - serversetup = _join(ctx.env.SETUPDATADIR,"server-setup.xml") - - if not _exists(setupdatabases): # Needs install! - Scripting.install(ctx) - - cmd = [ - ctx.env.PYTHON, - setupdatabases, - "cloud@%s"%ctx.env.DBHOST, - virttech, - "--auto=%s"%serversetup, - "--deploy-as=%s:%s"%(ctx.env.DBUSER,ctx.env.DBPW), - ] - - Utils.pprint("BLUE"," ".join(cmd)) - retcode = Utils.exec_command(cmd,shell=False,stdout=None,stderr=None,log=True) - if retcode: raise CalledProcessError(retcode,cmd) - -def deploydb_xenserver(ctx): - """re-deploys the database using the MySQL connection information and the XenServer templates.sql""" - return deploydb(ctx,"xenserver") -def deploydb_kvm(ctx): - """re-deploys the database using the MySQL connection information and the KVM templates.sql""" - return deploydb(ctx,"kvm") -def deploydb_vmware(ctx): - """re-deploys the database using the MySQL connection information and the KVM templates.sql""" - return deploydb(ctx,"vmware") - -def run(args): - """runs the management server""" - conf = _getbuildcontext() - - runverbose = [] - if Options.options.RUNVERBOSE: runverbose = ['-verbose'] - if args == "debug": - suspend = "n" - if Options.options.DEBUGSUSPEND: suspend = "y" - debugargs = [ - "-Xdebug","-Xrunjdwp:transport=dt_socket,address=%s,server=y,suspend=%s"%( - Options.options.DEBUGPORT,suspend), - "-ea"] - Utils.pprint("GREEN","Starting Tomcat in debug mode") - else: - Utils.pprint("GREEN","Starting Tomcat in foreground mode") - debugargs = [] - - options = runverbose + debugargs + [ - "-Dcatalina.base=" + conf.env.MSENVIRON, - "-Dcatalina.home=" + conf.env.MSENVIRON, - "-Djava.io.tmpdir="+_join(conf.env.MSENVIRON,"temp"), ] - - if not _exists(_join(conf.env.BINDIR,"cloud-setup-databases")): Scripting.install(conf) - - cp = [conf.env.MSCONF] - cp += _glob(_join(conf.env.MSENVIRON,'bin',"*.jar")) - cp += _glob(_join(conf.env.MSENVIRON,'lib',"*.jar")) - cp += _glob( _join ( conf.env.PREMIUMJAVADIR , "*" ) ) - cp += [conf.env.SYSTEMCLASSPATH] - cp += [conf.env.DEPSCLASSPATH] - cp += [conf.env.MSCLASSPATH] - - # FIXME Make selectable at runtime - #plugins = _glob( _join(conf.env.PLUGINJAVADIR,"*") ) - #if plugins: cp = plugins + cp - #vendorconfs = _glob( _join(conf.env.MSCONF,"vendor","*") ) - #if vendorconfs: cp = plugins + cp - - run_java("org.apache.catalina.startup.Bootstrap",cp,options,["start"]) - -def debug(ctx): - """runs the management server in debug mode""" - run("debug") - -@throws_command_errors -def run_agent(args): - """runs the agent""" # FIXME: make this use the run/debug options - conf = _getbuildcontext() - if not _exists(_join(conf.env.LIBEXECDIR,"agent-runner")): Scripting.install(conf) - _check_call("sudo",[_join(conf.env.LIBEXECDIR,"agent-runner")]) - -@throws_command_errors -#def run_console_proxy(args): -# """runs the console proxy""" # FIXME: make this use the run/debug options -# conf = _getbuildcontext() -# if not _exists(_join(conf.env.LIBEXECDIR,"console-proxy-runner")): Scripting.install(conf) -# _check_call("sudo",[_join(conf.env.LIBEXECDIR,"console-proxy-runner")]) - -def simulate_agent(args): - """runs the agent simulator, compiling and installing files as needed - - Any parameter specified after the simulate_agent is appended to - the java command line. To inhibit waf from interpreting the - command-line options that you specify to the agent, put a -- - (double-dash) between the waf simulate_agent and the options, like this: - - python waf simulate_agent -- -z KY -p KY -""" - - # to get this to work smoothly from the configure onwards, you need to - # create an override directory in java/agent/conf, then add an agent.properties - # there, with the correct configuration that you desire - # that is it -- you are now ready to simulate_agent - conf = _getbuildcontext() - args = sys.argv[sys.argv.index("simulate_agent")+1:] - if '--' in args: args.remove('--') - - cp = [conf.env.AGENTSYSCONFDIR] - cp += _glob( _join ( conf.env.PREMIUMJAVADIR , "*" ) ) - cp += [conf.env.SYSTEMCLASSPATH] - cp += [conf.env.DEPSCLASSPATH] - cp += [conf.env.AGENTSIMULATORCLASSPATH] - - if not _exists(_join(conf.env.LIBEXECDIR,"agent-runner")): Scripting.install(conf) - - run_java("com.cloud.agent.AgentSimulator",cp,arguments=args) - diff --git a/wscript_build b/wscript_build deleted file mode 100644 index 1c12c612912..00000000000 --- a/wscript_build +++ /dev/null @@ -1,457 +0,0 @@ -#!/usr/bin/env python -# 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. - -"""builds the entire stack""" -#For every matching build change here, that produces new installable -#files, the cloud.spec file and the Debian control files must be -#revised and tested. - -import shutil,os -import Utils,Node,Options,Logs,Scripting,Environment,Build,Configure -from os import unlink as _unlink, makedirs as _makedirs, getcwd as _getcwd, chdir as _chdir -from os.path import abspath as _abspath, basename as _basename, dirname as _dirname, exists as _exists, isdir as _isdir, split as _split, join as _join, sep, pathsep, pardir, curdir -from glob import glob as _glob -from subprocess import Popen as _Popen,PIPE -try: set([1,2,3]) -except Exception: from Sets import set -import re -import zipfile,tarfile -import time -try: - from os import chmod as _chmod,chown as _chown - import pwd,stat,grp -except ImportError: - _chmod,_chown,pwd,stat,grp = (None,None,None,None,None) - - -# Global variables setup -sourcedir = bld.srcnode.abspath() -builddir = bld.path.abspath(bld.env) -#buildpremium = _exists(_join(sourcedir,"cloudstack-proprietary")) -buildpremium = False -filelist = bld.path.ant_glob -distdir = Utils.relpath(_join(sourcedir,"dist")) -targetdir = Utils.relpath(_join(sourcedir,"target")) - -def gitinfo(dir=None): - if dir and not _isdir(dir): return '' - try: p = _Popen(['git','remote','show','-n','origin'],stdin=PIPE,stdout=PIPE,stderr=PIPE,cwd=dir) - except OSError,e: - if e.errno == 2: return '' # svn command is not installed - raise - stdout,stderr = p.communicate('') - retcode = p.wait() - # If the guess fails, just return nothing. - if retcode: return - stdout = [ s.strip() for s in stdout.splitlines() ] - try: url = [ s[11:] for s in stdout if s.startswith("Fetch URL") ][0] - except IndexError: url = [ s[5:] for s in stdout if s.startswith("URL") ][0] - assert url - - p = _Popen(['git','log','-1'],stdin=PIPE,stdout=PIPE,stderr=PIPE,cwd=dir) - stdout,stderr = p.communicate('') - retcode = p.wait() - if retcode: return - # If the guess fails, just return nothing. - stdout = [ s.strip() for s in stdout.splitlines() ] - commitid = [ s.split()[1] for s in stdout if s.startswith("commit") ][0] - assert commitid - - return "Git Revision: %s"%commitid + "\n" + "Git URL: %s"%url + "\n" - -def build_utils_docs (): - stdout = gitinfo() - if stdout: - f = file("sccs-info","w") - f.write(stdout) - f.flush() - f.close() - else: - if _exists("sccs-info"): - # If the file already existed, we preserve it - return - else: - f = file("sccs-info","w") - f.write("No revision control information could be detected when the source distribution was built.") - f.flush() - f.close() - - sccsinfo = _join(sourcedir,"sccs-info") - if _exists(sccsinfo): bld.install_files("${DOCDIR}","sccs-info") - - tgen = bld(features='subst', name='configure-info', source="configure-info.in", target="configure-info") - tgen.dict = {"CONFIGUREVARS":bld.getconfig()} - bld.install_files("${DOCDIR}","configure-info") - -# compile jar files using ant -# ant only needs to be reinvoked if the version with build number changes -# we here trim all the depended targets from the target list: -def build_jars (): - Implementation_Version = bld.env.VERSION - - # this is to trigger recompilation / cache avoidance if the relevant environment for ant changes - ant_args = [ - "build-all", - "-Dimpl.version=%s" % Implementation_Version, - "-Dtarget.dir=%s" % targetdir, - "-Ddist.dir=%s" % distdir, - "-Dbase.dir=%s" % sourcedir, - "-f %s" % Utils.relpath (_join(sourcedir, "build.xml")), - ] - - if buildpremium: - ant_args.append("-Dbuild.premium=true") - - tgen = bld(features='subst', name='version-info', source="version-info.in", target="version-info") - tgen.dict = { "Implementation_Version":Implementation_Version,"ant_args":ant_args } - bld.install_files("${DOCDIR}","version-info") - - bld.srcnode.ensure_dir_node_from_path("target/jar") - bld.srcnode.ensure_dir_node_from_path("dist") - - tgen = bld.new_task_gen (rule = Utils.runant, - name = "runant", - antargs = ant_args) - - jarnode = bld.srcnode.find_dir ('target/jar') - jars_str = jarnode.ant_glob ('*.jar').split () - ant_jars = [] - excludes = ["cloud-xstream-1.3.1.jar", "cloud-commons-dbcp-1.2.2.jar", - "cloud-commons-httpclient-3.1.jar", "cloud-commons-pool-1.4.jar", - "cloud-servlet-api.jar", "cloud-commons-logging-1.1.1.jar", - "cloud-ws-commons-util-1.0.2.jar", - "cloud-commons-collections-3.2.1.jar", "vmware*.jar", "cloud-secstorage-extras.jar", - "cloud-agent-simulator.jar", "cloud-awsapi.jar", "cloud-test.jar", "cloud-wsdl4j.jar", "cloud-console-proxy.jar"] - - for a in jars_str: - if _basename (a).startswith ("cloud-") \ - and not _basename (a) in excludes: - a = jarnode.abspath () + os.sep + a - ant_jars.append (a) - - bld.install_files ('${JAVADIR}', ant_jars) - - -def build_premium (): - if buildpremium: bld.recurse(["cloudstack-proprietary/"],'build') - -def build_thirdparty_dir (): - start_path = bld.path.find_dir ("thirdparty") - bld.install_files('${PREMIUMJAVADIR}','*.jar', cwd = start_path) - Utils.pprint ("GREEN", "Installed files of thirdparty/") - -def build_dependences (): - excludes = ["cloud-xstream-1.3.1.jar", "cloud-servlet-api.jar", "cloud-commons-logging-1.1.1.jar", - "cloud-ws-commons-util-1.0.2.jar", - "cloud-commons-collections-3.2.1.jar", "cloud-wsdl4j.jar"] - - start_path = bld.path.find_dir ("deps") - - bld.install_files('${JAVADIR}',start_path.ant_glob(["CAStorSDK-*.jar", "javax.persistence-2.0.0.jar", "apache-log4j-extras-1.1.jar", "libvirt-0.4.9.jar", "axis2-1.5.1.jar", "jstl-1.2.jar", "commons-discovery-0.5.jar", "commons-codec-1.6.jar", "ejb-api-3.0.jar", "xmlrpc-client-3.1.3.jar", "commons-dbcp-1.4.jar", "commons-pool-1.6.jar", "gson-1.7.1.jar", - "netscaler-1.0.jar", "netscaler-sdx-1.0.jar", "backport-util-concurrent-3.1.jar", "ehcache-1.5.0.jar", "httpcore-4.0.jar", "log4j-1.2.16.jar", "trilead-ssh2-build213-svnkit-1.3-patch.jar", "cglib-nodep-2.2.2.jar", "xmlrpc-common-3.*.jar", - "axiom*.jar", "axis2*.jar", "antlr*.jar", "XmlSchema*.jar", "json-simple*.jar", "neethi*.jar", "woden*.jar", "xercesImpl*.jar", "xml-apis*.jar", "dom4j*.jar", "javassist*.jar", "commons-fileupload*.jar", - "xmlrpc-client-3.*.jar", "wsdl4j-1.6.2.jar", "bcprov-jdk16-1.45.jar", "jsch-0.1.42.jar", "jasypt-1.9.0.jar", "commons-configuration-1.8.jar", "mail-1.4.jar", "activation-1.1.jar", "xapi-5.6.100-1-SNAPSHOT.jar"], excl = excludes), cwd=start_path) - -#def build_console_proxy (): - # binary unsubstitutable files: -# start_path = bld.path.find_dir ("console-proxy") -# bld.install_files("${CPLIBDIR}",start_path.ant_glob("images/**",src=True,bld=False,dir=False,flat=True),cwd=start_path,relative_trick=True) - - # text substitutable files (substitute with tokens from the environment bld.env): -# bld.substitute('css/** js/** ui/** scripts/**',install_to="${CPLIBDIR}", cwd=start_path) - - # config files (do not replace them if preserve config option is true) -# if not Options.options.PRESERVECONFIG: bld.install_files_filtered("${CPSYSCONFDIR}","conf.dom0/*", cwd=start_path) - -def build_patches (): - # done here because the patches require substituted files - start_path = bld.path.find_dir ("patches") - bld.substitute("*/**",name="patchsubst", cwd = start_path) - - for virttech in Utils.to_list(start_path.ant_glob("*",dir=True)): - if virttech in ["shared"]: continue - patchfiles = start_path.ant_glob('shared/** %s/debian/config/**'%virttech,src=False,bld=True,dir=False,flat=True) - tmp = bld.path - bld.path = start_path - tgen = bld( - features = 'tar',#Utils.tar_up, - source = patchfiles, - target = 'cloud-scripts.tgz', - name = 'cloud-scripts_tgz', - root = os.path.join("patches", virttech + "/debian/config"), - rename = lambda x: re.sub(".subst$","",x), - ) - bld.path = tmp - - -def build_systemvm_patch (): - if bld.env.DISTRO not in ["Windows","Mac"]: - # patch creation - bld.install_files ("${COMMONLIBDIR}/vms", "%s/systemvm.zip" % distdir) - # ISO creation - bld.install_as("${COMMONLIBDIR}/vms/systemvm.iso", "%s/systemvm.iso" % distdir) - -def build_systemvm_iso (): - if buildpremium: - bld.install_as("${AGENTLIBDIR}/vms/systemvm-premium.iso", "%s/systemvm-premium.iso" % distdir) - -# =================== Empty directory / symlink creation on install target ==================== - -def build_dirs_symlinks (): - bld.createuser(bld.env.MSUSER,bld.env.MSENVIRON,'/bin/sh') - - # 7. make log and cache dirs (this actually runs first) - if bld.env.DISTRO in 'Windows Mac': pass - else: - x = ("root",bld.env.MSUSER) - directories = [ - ("${MSLOGDIR}",0770,x), - ("${AGENTLOGDIR}",0770,x), - ("${USAGELOGDIR}",0770,x), -# ("${CPLOGDIR}",0770,x), - ("${IPALLOCATORLOGDIR}",0770,x), - ("${LOCALSTATEDIR}/cache/${MSPATH}",0770,x), - ("${LOCALSTATEDIR}/cache/${MSPATH}/temp",0770,x), - ("${LOCALSTATEDIR}/cache/${MSPATH}/work",0770,x), - ("${SHAREDSTATEDIR}/${MSPATH}",0770,x), - ("${MSMNTDIR}",0770,x), - ("${MSCONF}/Catalina",0770,x), - ("${MSCONF}/Catalina/localhost",0770,x), - ("${MSCONF}/Catalina/localhost/client",0770,x), - ("${PIDDIR}",0755,("root","root")), - ("${LOCKDIR}",0755,("root","root")), - ] - - for a,mode,owner in directories: - s = bld.subst_add_destdir(a,bld) - if Options.is_install: - bld.install_dir(a) - bld.setownership(a,owner[0],owner[1],mode) - - # 8. create environment symlinks - symlinks = [ - ('${MSENVIRON}/bin', '${TOMCATHOME}/bin'), - ('${MSENVIRON}/lib', '${TOMCATHOME}/lib'), - ('${MSENVIRON}/logs', "${MSLOGDIR}"), - ('${MSENVIRON}/temp', '${LOCALSTATEDIR}/cache/${MSPATH}/temp'), - ('${MSENVIRON}/work','${LOCALSTATEDIR}/cache/${MSPATH}/work'), - ('${MSENVIRON}/conf', '${SYSCONFDIR}/${MSPATH}'), -# ("${AGENTLIBDIR}/css", '${CPLIBDIR}/css'), -# ("${AGENTLIBDIR}/images", '${CPLIBDIR}/images'), -# ("${AGENTLIBDIR}/js", '${CPLIBDIR}/js'), -# ("${AGENTLIBDIR}/ui", '${CPLIBDIR}/ui'), - ("${MSCONF}/server.xml", '${MSCONF}/server-nonssl.xml'), - ("${MSCONF}/tomcat6.conf", '${MSCONF}/tomcat6-nonssl.conf'), - ] - - for lnk,dst in symlinks: bld.symlink_as(lnk,Utils.subst_vars(dst,bld.env)) - - -def build_scripts (): - start_path = bld.path.find_dir ("scripts") - bld.substitute('**',"${COMMONLIBDIR}/scripts",chmod=0755, cwd=start_path) - -def build_bin_exec_dirs (): - #bld.install_files_filtered("${LIBEXECDIR}","*/libexec/* cloudstack-proprietary/*/libexec/*",chmod=0755) - #bld.install_files_filtered("${BINDIR}","*/bindir/* cloudstack-proprietary/*/bindir/*",chmod=0755) - #bld.install_files_filtered("${SBINDIR}","*/sbindir/* cloudstack-proprietary/*/sbindir/*",chmod=0755) - - bld.install_files_filtered("${LIBEXECDIR}","*/libexec/*",chmod=0755) - bld.install_files_filtered("${BINDIR}","*/bindir/*",chmod=0755) - bld.install_files_filtered("${SBINDIR}","*/sbindir/*",chmod=0755) - -def build_server_client (): - start_path = bld.path.find_dir("client/WEB-INF") - bld.install_files('${MSENVIRON}/webapps/client/WEB-INF', - start_path.ant_glob("**",src=True,bld=False,dir=False,flat=True), - cwd=start_path,relative_trick=True) - - start_path = bld.path.find_dir("client") - bld.install_files("${MSCONF}/resources",'WEB-INF/classes/resources/*.properties',chmod=0640, cwd=start_path) - - if not Options.options.PRESERVECONFIG: - bld.install_files_filtered("${MSCONF}","tomcatconf/*", cwd=start_path) - bld.install_files("${MSCONF}",'tomcatconf/db.properties',chmod=0640, cwd=start_path) - bld.setownership("${MSCONF}/db.properties","root",bld.env.MSUSER) - - start_path = bld.path.find_dir("server") - if not Options.options.PRESERVECONFIG: - bld.install_files_filtered("${SERVERSYSCONFDIR}","conf/*", cwd=start_path) - -def build_agent (): - start_path = bld.path.find_dir ("agent") - bld.install_files("${AGENTLIBDIR}", - start_path.ant_glob("storagepatch/**",src=True,bld=False,dir=False,flat=True), - cwd=start_path,relative_trick=True) - if not Options.options.PRESERVECONFIG: - bld.install_files_filtered("${AGENTSYSCONFDIR}","conf/*", cwd = start_path) - -def build_ui (): - # binary unsubstitutable files: - start_path = bld.path.find_dir ("ui") - bld.install_files ("${MSENVIRON}/webapps/client",start_path.ant_glob("*.ico **/*png **/*jpg **/*gif",src=True,bld=False,dir=False,flat=True),cwd=start_path,relative_trick=True) - - # text substitutable files (substitute with tokens from the environment bld.env): - bld.substitute ("*html **/*html **/*js **/*css **/*properties **/*jsp *jsp",install_to="${MSENVIRON}/webapps/client", cwd=start_path) - -def build_conf_files (): - # apply distro-specific config on top of the 'all' generic cloud-management config - globspec = _join("*","distro",bld.env.DISTRO.lower(),"*") # matches premium/distro/centos/SYSCONFDIR - #distrospecificdirs=_glob(globspec) + _glob(_join("cloudstack-proprietary",globspec)) - distrospecificdirs=_glob(globspec) - for dsdir in distrospecificdirs: - start_path = bld.srcnode.find_dir(dsdir) - subpath,varname = _split(dsdir) - dsdirwithvar = _join("${%s}"%varname) - files = filelist('%s/**'%dsdir,src=True,bld=False,dir=False,flat=True) - mode = 0644 - if "SYSCONFDIR" in dsdir: - mode = 0755 - if Options.options.PRESERVECONFIG: continue - bld.install_files_filtered(dsdirwithvar, files, cwd=start_path, relative_trick=True,chmod=mode) - -# cloudstack-proprietary still has db files for usage -def build_db_files (): - #bld.install_files_filtered("${SETUPDATADIR}",filelist("*/db/* cloudstack-proprietary/*/db/*",excl=Node.exclude_regs + "\ncloud-gate\ncloud-bridge")) - start_path = bld.path.find_dir ("setup/db") - bld.substitute('**',"${SETUPDATADIR}", cwd=start_path) - if buildpremium: - start_path = bld.path.find_dir ("cloudstack-proprietary/premium/db") - bld.substitute('**',"${SETUPDATADIR}", cwd=start_path) - - -def build_plugins (): - # ====================== Feature-specific plugins ======================== - - for plugin in _glob(_join("plugins","*")) + _glob(_join("cloudstack-proprietary","plugins","*")): - if not _exists(_join(plugin,"build.xml")): continue - pluginname = _basename(plugin) - target = 'target/jar/cloud-%s.jar' % pluginname - sources = filelist( '%s/**/*.java' % plugin.replace(sep,"/") , src=True, bld=False, dir=False ) - tgen = bld(rule=lambda x: runant("compile-%s"%pluginname), name='compile_%s'%pluginname, source=sources, target=target, after='runant') - bld.install_files('${PLUGINJAVADIR}',target) - - # ====================== End feature-specific plugins ==================== - - - # ====================== Vendor-specific plugins ======================== - - for vendor in _glob(_join("vendor","*")) + _glob(_join("cloudstack-proprietary","vendor","*")): - if not Options.options.PRESERVECONFIG: - bld.install_files_filtered("${MSCONF}/%s"%vendor,filelist("%s/tomcatconf/*"%vendor)) - - # ====================== End vendor-specific plugins ==================== - -def build_xml_api_description (): - def generate_xml_api_description(task): - relationship = Utils.relpath(sourcedir,os.getcwd()) - cp = [ _join(relationship,x) for x in task.generator.env.CLASSPATH.split(pathsep) ] - - jarnames = ['utils','server','core', 'api', 'server-extras'] - props = ["client/tomcatconf/commands.properties.in"] - - sources = [] - for i in jarnames: - str = 'target/jar/cloud-%s.jar' % i - sources.append (str) - sources.append ("client/tomcatconf/commands.properties.in") - if buildpremium: - sources.append("client/tomcatconf/commands-ext.properties.in") - - buildproducts = [] - for i in sources: - path = bld.path.abspath() + os.sep + i - buildproducts.append (path) - - jars = [ x for x in buildproducts if x.endswith("jar") ] - properties = [ x for x in buildproducts if x.endswith("properties.in") ] - cp += jars - cp = pathsep.join(cp) - arguments = ["-f",",".join(properties),"-d",builddir] - ret = Utils.exec_command(["java","-cp",cp,"com.cloud.api.doc.ApiXmlDocWriter"]+arguments,log=True) - return ret - - #TODO: We can't use 'source' token here because task_gen check if sources - # exist before all task_gen. This bring a problem that 'runant' task doesn't - # run when the check happen, which results in no source found at target/jar. - # Ask waf community to fix that - tgen = bld.new_task_gen ( - rule = generate_xml_api_description, - target = 'commands.xml', - name = 'xmlapi', - after = 'runant', - install_path="${CLIDIR}" - ) - - bld.install_as("${PYTHONDIR}/cloud_utils.py", 'python/lib/cloud_utils.py') - bld.install_files("${PYTHONDIR}/cloudtool", 'cloud-cli/cloudtool/*') - bld.install_files("${PYTHONDIR}/cloudutils", 'python/lib/cloudutils/*') - bld.install_as("${PYTHONDIR}/cloudapis.py", 'cloud-cli/cloudapis/cloud.py') - -def build_ovm(): - start_path = bld.path.find_dir("plugins/hypervisors/ovm/scripts") - bld.substitute('**',"${COMMONLIBDIR}/scripts",chmod=0755, cwd=start_path) - -def build_test(): - start_path = bld.path.find_dir("test/scripts") - bld.install_files('${LIBDIR}/${PACKAGE}/test', \ - start_path.ant_glob("**",src=True,bld=False,dir=False,flat=True), \ - cwd=start_path,relative_trick=True) - - start_path = bld.path.find_dir("test/metadata") - bld.install_files('${SHAREDSTATEDIR}/${PACKAGE}/test', \ - start_path.ant_glob("**",src=True,bld=False,dir=False,flat=True), \ - cwd=start_path,relative_trick=True) - - if not Options.options.PRESERVECONFIG: - start_path = bld.path.find_dir("test") - bld.install_files('${SYSCONFDIR}/${PACKAGE}/test','conf/*', cwd = start_path) - Utils.pprint ("GREEN", "Installed files of test/") - -def build_usage_dir (): - start_path = bld.path.find_dir ("usage") - bld.install_files_filtered("${USAGESYSCONFDIR}","conf/*", cwd = start_path) - bld.symlink_as("${USAGESYSCONFDIR}/db.properties", \ - Utils.subst_vars("${MSCONF}/db.properties",bld.env)) - Utils.pprint ("GREEN", "Installed files of usage/") - - -# Get started to execute here -#build_utils_docs () -build_jars () -build_premium () -#build_thirdparty_dir() -build_dependences () -#build_patches () -build_systemvm_patch () -build_dirs_symlinks () -build_scripts () -build_bin_exec_dirs () -build_server_client () -build_agent () -build_ui () -build_conf_files () -build_db_files () -build_plugins () -build_xml_api_description () -build_ovm () -#build_test() -build_usage_dir() - -# ====================== Magic! ========================================= -bld.use_the_magic() diff --git a/wscript_configure b/wscript_configure deleted file mode 100644 index d586c9e56fb..00000000000 --- a/wscript_configure +++ /dev/null @@ -1,408 +0,0 @@ -#!/usr/bin/env python -# 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. - -"""examines environment, then: - - configures classpath as per environment or command-line options - - detects Tomcat (on Windows) - - detects or configures directories according to command-line options""" - -import Utils,Node,Options,Logs,Scripting,Environment,Build,Configure -from os import unlink as _unlink, makedirs as _makedirs, getcwd as _getcwd, chdir as _chdir -try: from os import getuid as _getuid -except ImportError: pass -from os.path import abspath as _abspath, basename as _basename, dirname as _dirname, exists as _exists, isdir as _isdir, split as _split, join as _join, expanduser as _expanduser, sep, pathsep, pardir -from glob import glob as _glob -import time - - -# list of JARs that provide the build dependencies -# "j" generally means /usr/share/java -# when adding a new system JAR file: -# 1. check the hard_deps variable at the bottom and add the appropriate packaging information, -# 2. add the RPM package that contains the jarfile into the cloud.spec file, and the DEB package into the debian/control file -# 3. (the jars specified here will be looked up at runtime with build-classpath, on linux installs) -systemjars = { - 'common': - ( - "commons-collections.jar", - # "commons-daemon.jar", - #"commons-dbcp.jar", - "commons-codec.jar", - "commons-logging.jar", - "commons-logging-api.jar", - #"commons-pool.jar", - "commons-httpclient.jar", - "ws-commons-util.jar", - "mysql-connector-java.jar", - ), - 'Fedora': - ( - "tomcat6-servlet-2.5-api.jar", - "tomcat6-el-2.1-api-6.0.26.jar", - "tomcat6-jsp-2.1-api-6.0.26.jar", - #"tomcat6/catalina.jar", # all supported distros put the file there - ), - 'RHEL': - ( - "tomcat6-servlet-2.5-api.jar", - "tomcat6-el-2.1-api-6.0.24.jar", - "tomcat6-jsp-2.1-api-6.0.24.jar", - "jakarta-taglibs-core-1.1.1.jar", - "jakarta-taglibs-standard-1.1.1.jar", - "tomcat6/jasper.jar", - "tomcat6/jasper-el.jar", - "tomcat6/jasper-jdt.jar", - - ), - 'CentOS': - ( - "tomcat6-servlet-2.5-api.jar", - "tomcat6-jsp-2.1-api-6.0.24.jar", - "tomcat6-el-2.1-api-6.0.24.jar", - "jakarta-taglibs-core-1.1.1.jar", - "jakarta-taglibs-standard-1.1.1.jar", - "tomcat6/jasper.jar", - "tomcat6/jasper-el.jar", - "tomcat6/jasper-jdt.jar", - #"tomcat6/catalina.jar", # all supported distros put the file there - ), - 'Ubuntu': - ( - "servlet-api-2.5.jar", - "jsp-api-2.1.jar", - "jasper.jar", - "el-api-2.1.jar", - "jasper-el.jar", - "ecj.jar", - "cglib.jar", - "asm3.jar", - "jsch.jar", - "backport-util-concurrent.jar", - "jetty.jar", - "jetty-util.jar", - "jetty-start-daemon.jar", - "jetty-sslengine.jar", - "jetty-start.jar", - "jna.jar", - "log4j-1.2.jar", - ), - 'Windows': - ( - "servlet-api.jar", # this ships with Tomcat in lib/ - #"catalina.jar", - ), - 'Mac': - ( - "servlet-api.jar", - ), - 'openSUSE': - ( - "tomcat6-servlet-2.5-api.jar", - "tomcat6-jsp-2.1-api-6.0.24.jar", - "tomcat6-el-1.0-api.jar" - ), - 'SLES': - ( - "tomcat6-servlet-2.5-api.jar", - "tomcat6-jsp-2.1-api-6.0.24.jar", - "tomcat6-el-1.0-api.jar" - ) -} - -#A JAR dependency may be: - -#- required during compile-time -#- required during run-time - -#A JAR file can be available: - -#- in Tomcat lib/ -#- as a Linux system package -#- in the cloud-deps package -#- in the cloud-premium package - -# servlet-api: - -#- is required during compile-time -#- is required during management server run-time -#- is available in Tomcat lib/ (Windows/Mac) AND as a system package (Linux) -# -> ERGO, we do not need to include it -# but it should be named on the SYSTEMJARS (which is then used in the tomcat6.conf to build the MS classpath), -# and it should also be in the compile-time CLASSPATH - -# ===================================== - -# list of dependencies for configure check -# (classname,fedora package name,ubuntu package name) -# when adding a package name here, also add to the spec or debian control file -hard_deps = [ - ('java.io.FileOutputStream',"java-devel","openjdk-6-jdk"), - ('javax.servlet.http.Cookie',"tomcat6-servlet-2.5-api","libservlet2.5-java","(if on Windows,did you set TOMCAT_HOME to point to your Tomcat setup?)"), - ('org.apache.naming.resources.Constants',"tomcat6-lib","libtomcat6-java","(if on Windows,did you set TOMCAT_HOME to point to your Tomcat setup?)"), -] - - -if Options.options.VERNUM: - Version = Options.options.VERNUM -else: - Version = "2.2" -builddate = time.strftime("%Y.%m.%d.%H.%M.%S", time.localtime()).replace('.','') -conf.env.VERSION = Version + "." + builddate - -conf.check_message_1('Detecting distribution') -if Options.platform == 'win32': conf.env.DISTRO = "Windows" -elif Options.platform == 'darwin': conf.env.DISTRO = "Mac" -elif _exists("/etc/network"): conf.env.DISTRO = "Ubuntu" -elif _exists("/etc/fedora-release"): conf.env.DISTRO = "Fedora" -elif _exists("/etc/centos-release"): conf.env.DISTRO = "CentOS" -elif _exists("/etc/redhat-release"): - version = file("/etc/redhat-release").readline() - if version.find("Red Hat Enterprise Linux Server release 6") != -1: - conf.env.DISTRO = "RHEL" - elif version.find("CentOS release") != -1: - conf.env.DISTRO = "CentOS" -elif _exists("/etc/SuSE-release"): - content = file("/etc/SuSE-release").readlines() - supportedVersion = None - if content[0].find("SUSE Linux Enterprise Server 11") != -1: - spLevel = eval(content[-1].split()[-1]) - if spLevel >= 2: - conf.env.DISTRO = "SLES" - supportedVersion = 1 - elif content[0].find("openSUSE") != -1: - version = eval(content[1].split()[-1]) - if version >= 12.1: - conf.env.DISTRO = "openSUSE" - supportedVersion = 1 - if not supportedVersion: - conf.env.DISTRO = "unknown" -else: conf.env.DISTRO = "unknown" -if conf.env.DISTRO == "unknown": c = "YELLOW" -else: c = "GREEN" -conf.check_message_2(conf.env.DISTRO,c) -conf.check_message_1('Detecting installation prefix') -if Options.options.prefix == Options.default_prefix: - if conf.env.DISTRO == 'Windows': - conf.env.PREFIX = 'C:\\CloudStack' - elif _getuid() != 0: # not root - conf.env.PREFIX = _join(_expanduser("~"),"cloudstack") -conf.check_message_2("%s"%conf.env.PREFIX,"GREEN") - -conf.check_tool('misc') - -conf.check_tool("gnu_dirs") -if conf.env.DISTRO == 'Windows': - # waf uses slashes somewhere along the line in some paths. we fix them on windows. - for pth in [ x for x in conf.env.get_merged_dict().keys() if x.endswith("DIR") ]: - if not pth: continue - if not conf.env[pth]: continue - conf.env[pth] = conf.env[pth].replace("/","\\") - -conf.check_tool('tar') -try: conf.check_tool('mkisofs') -except Configure.ConfigurationError,e: - raise Configure.ConfigurationError, "The program genisoimage (or mkisofs) could not be found.\nOn Linux: ./waf installrpmdeps or ./waf installdebdeps according to your distro's package format.\nOn Windows: Use cygwin to install the mkisofs package, then ensure that the program is in your PATH." -conf.check_tool('java') - -conf.check_tool("python") -conf.check_python_version((2,4,0)) - -conf.check_message_1('Detecting Python MySQL module') -try: import MySQLdb -except ImportError,e: - raise Configure.ConfigurationError, "The Python MySQLdb module could not be found.\nOn Linux: ./waf installrpmdeps or ./waf installdebdeps according to your distro's package format.\nOn Windows: Install MySQL 5.1 on your machine, then install the Python MySQLdb module for Python %s.\nThe module for Python 2.6 / win32 / MySQL 5.1 is available here: http://soemin.googlecode.com/files/MySQL-python-1.2.3c1.win32-py2.6.exe"%conf.env.PYTHON_VERSION -conf.check_message_2('MySQLdb','GREEN') -conf.check_message_1('Database info for developer setup') -for a in "DBHOST DBUSER DBPW".split(): conf.env[a] = getattr(Options.options, a, '') -conf.check_message_2("user: %r, password: %r, host: %r"%(conf.env.DBUSER,conf.env.DBPW,conf.env.DBHOST),'GREEN') - -try: conf.check_tool("tomcat") -except Configure.ConfigurationError,e: - conf.fatal("Tomcat directory %r not found. Either install Tomcat using ./waf installrpmdeps or ./waf installdebdeps, or manually install Tomcat to a directory in your system and set the environment variable TOMCAT_HOME to point to it."%conf.env.TOMCATHOME) - -conf.env.COMMONPATH = _join(conf.env.PACKAGE,"common") -conf.env.AGENTPATH = _join(conf.env.PACKAGE,"agent") -conf.env.CPPATH = _join(conf.env.PACKAGE,"console-proxy") -conf.env.IPALLOCATORPATH = _join(conf.env.PACKAGE,"ipallocator") -conf.env.MSPATH = _join(conf.env.PACKAGE,"management") -conf.env.USAGEPATH = _join(conf.env.PACKAGE,"usage") -conf.env.SETUPPATH = _join(conf.env.PACKAGE,"setup") -conf.env.SERVERPATH = _join(conf.env.PACKAGE,"server") - -if conf.env.DISTRO in ['Windows','Mac']: - conf.env.MSENVIRON = conf.env.TOMCATHOME - conf.env.MSCONF = _join(conf.env.TOMCATHOME,"conf") - conf.env.MSLOGDIR = _join(conf.env.TOMCATHOME,"logs") - conf.env.MSMNTDIR = _join(conf.env.TOMCATHOME,"mnt") - conf.env.JAVADIR = _join(conf.env.MSENVIRON,"lib") - conf.env.PREMIUMJAVADIR = conf.env.JAVADIR - conf.env.PLUGINJAVADIR = conf.env.JAVADIR - conf.env.SYSTEMJAVADIR = conf.env.JAVADIR -else: - conf.env.MSENVIRON = _join(conf.env.DATADIR,conf.env.MSPATH) - conf.env.MSCONF = _join(conf.env.SYSCONFDIR,conf.env.MSPATH) - conf.env.MSLOGDIR = _join(conf.env.LOCALSTATEDIR,"log",conf.env.MSPATH) - conf.env.MSMNTDIR = _join(conf.env.SHAREDSTATEDIR,conf.env.PACKAGE,"mnt") - conf.check_tool('compiler_cc') - conf.check_cc(lib='dl') - conf.check_tool('usermgmt') - conf.check_message_1('Determining management server user name') - msuser = getattr(Options.options, 'MSUSER', '') - if msuser: - conf.env.MSUSER = msuser - conf.check_message_2("%s (forced through --tomcat-user)"%conf.env.MSUSER,"GREEN") - else: - conf.env.MSUSER = conf.env.PACKAGE - conf.check_message_2("%s (Linux default)"%conf.env.MSUSER,"GREEN") - conf.check_tool("javadir") - conf.env.PREMIUMJAVADIR = _join(conf.env.JAVADIR,"%s-premium"%conf.env.PACKAGE) - conf.env.PLUGINJAVADIR = _join(conf.env.JAVADIR,"%s-plugins"%conf.env.PACKAGE) - conf.env.SYSTEMJAVADIR = "/usr/share/java" - -in_javadir = lambda name: _join(conf.env.JAVADIR,_basename(name)) # $PREFIX/share/java -in_system_javadir = lambda name: _join(conf.env.SYSTEMJAVADIR,name) # /usr/share/java -in_premiumjavadir = lambda name: _join(conf.env.PREMIUMJAVADIR,name) # $PREFIX/share/java/cloud-premium - -conf.env.COMMONLIBDIR = Utils.subst_vars(_join("${LIBDIR}","${COMMONPATH}"),conf.env) - -conf.env.AGENTLIBDIR = Utils.subst_vars(_join("${LIBDIR}","${AGENTPATH}"),conf.env) -conf.env.AGENTSYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${AGENTPATH}"),conf.env) -conf.env.AGENTLOGDIR = Utils.subst_vars(_join("${LOCALSTATEDIR}","log","${AGENTPATH}"),conf.env) - -conf.env.USAGELOGDIR = Utils.subst_vars(_join("${LOCALSTATEDIR}","log","${USAGEPATH}"),conf.env) -conf.env.USAGESYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${USAGEPATH}"),conf.env) - -conf.env.CPLIBDIR = Utils.subst_vars(_join("${LIBDIR}","${CPPATH}"),conf.env) -conf.env.CPSYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${CPPATH}"),conf.env) -conf.env.CPLOGDIR = Utils.subst_vars(_join("${LOCALSTATEDIR}","log","${CPPATH}"),conf.env) - -conf.env.MSLOG = _join(conf.env.MSLOGDIR,"management-server.log") -conf.env.AWSAPILOG = _join(conf.env.MSLOGDIR,"awsapi.log") -conf.env.APISERVERLOG = _join(conf.env.MSLOGDIR,"api-server.log") -conf.env.AGENTLOG = _join(conf.env.AGENTLOGDIR,"agent.log") -conf.env.USAGELOG = _join(conf.env.USAGELOGDIR,"usage.log") -conf.env.CPLOG = _join(conf.env.CPLOGDIR,"console-proxy.log") - -conf.env.SETUPDATADIR = Utils.subst_vars(_join("${DATADIR}","${SETUPPATH}"),conf.env) - -conf.env.SERVERSYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${SERVERPATH}"),conf.env) -conf.env.PIDDIR = _join(conf.env.LOCALSTATEDIR,"run") -conf.env.LOCKDIR = _join(conf.env.LOCALSTATEDIR,"lock","subsys") - - -conf.check_message_1('Building classpaths') - -# == Here we build the run-time classpaths == - -# The system classpath points to JARs we expect the user has installed using distro packages -# not used for Windows and Mac (except for servlet-api.jar) because we install them from the thirdparty/ directory -sysjars = list(systemjars['common']) -if conf.env.DISTRO in systemjars.keys(): sysjars = sysjars + list(systemjars[conf.env.DISTRO]) -conf.env.SYSTEMJARS = " ".join(sysjars) # used by build-classpath in the initscripts -conf.env.SYSTEMCLASSPATH = pathsep.join([ in_system_javadir(x) for x in sysjars ]) # used for compile, waf run and simulate_agent - -# the deps classpath points to JARs that are installed in the cloud-deps package -# these will install on Tomcat6's lib/ directory on Windows and Mac -depsclasspath = [ in_javadir(_basename(x)) for x in _glob(_join(conf.srcdir,"deps","*.jar")) ] -conf.env.DEPSCLASSPATH = pathsep.join(depsclasspath) - -# the MS classpath points to JARs required to run the management server -msclasspath = [ in_javadir("%s-%s.jar"%(conf.env.PACKAGE,x)) for x in "utils api core server server-extras core-extras vmware-base ovm dp-user-concentrated-pod dp-user-dispersing host-allocator-random plugin-f5 plugin-netscaler plugin-ovs plugin-srx storage-allocator-random user-authenticator-ldap user-authenticator-md5 user-authenticator-plaintext vmware plugin-hypervisor-xen plugin-nicira-nvp plugin-elb plugin-netapp plugin-bigswitch-vns".split() ] -conf.env.MSCLASSPATH = pathsep.join(msclasspath) - -# the agent and simulator classpaths point to JARs required to run these two applications -agentclasspath = [ in_javadir("%s-%s.jar"%(conf.env.PACKAGE,x)) for x in "utils api core server server-extras agent console-common console-proxy core-extras agent-extras plugin-hypervisor-kvm".split() ] -agentclasspath.append(in_javadir("jna.jar")) -conf.env.AGENTCLASSPATH = pathsep.join(agentclasspath) -conf.env.AGENTSIMULATORCLASSPATH = pathsep.join(agentclasspath+[in_javadir("%s-agent-simulator.jar"%conf.env.PACKAGE)]) - -usageclasspath = [ in_javadir("%s-%s.jar"%(conf.env.PACKAGE,x)) for x in "utils api core server server-extras usage core-extras".split() ] -conf.env.USAGECLASSPATH = pathsep.join(usageclasspath) - -# the premium classpath was ELIMINATED -# CloudStack now detects the premium classpath at runtime by iterating through the JAR files in @PREMIUMJAVADIR@ -# premium JARs will install on Tomcat6's lib/ directory on Windows and Mac - -# The compile path is composed of the -# 1. source directories (without including the JARs) -# JARs are not included because in case of parallel compilation (IOW, all the time), javac picks up half-written JARs and die -compilecp = []# list(srcdirs) -# 2.b) the deps/ directory in the source if on Linux -# 2.a) the thirdparty/ directory if available -if conf.env.DISTRO in ["Windows","Mac"]: - pass -else: - compilecp+= _glob(_join("deps","*.jar")) -compilecp+= _glob(_join("cloudstack-proprietary","thirdparty","*.jar")) -# 3. the system classpath (system-installed JARs) -compilecp+= [ conf.env.SYSTEMCLASSPATH ] -compilecp+= _glob(_join(conf.env.TOMCATHOME,'bin',"*.jar")) -compilecp+= _glob(_join(conf.env.TOMCATHOME,'lib',"*.jar")) -conf.env.CLASSPATH = pathsep.join(compilecp) -conf.check_message_2('Done','GREEN') - -# log4j config and property config files require backslash escapes on Windows - -conf.env.COMMONLIBDIR = Utils.subst_vars(_join("${LIBDIR}","${COMMONPATH}"),conf.env) - -conf.env.AGENTLIBDIR = Utils.subst_vars(_join("${LIBDIR}","${AGENTPATH}"),conf.env) -conf.env.AGENTSYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${AGENTPATH}"),conf.env) -conf.env.AGENTLOGDIR = Utils.subst_vars(_join("${LOCALSTATEDIR}","log","${AGENTPATH}"),conf.env) - -conf.env.USAGELOGDIR = Utils.subst_vars(_join("${LOCALSTATEDIR}","log","${USAGEPATH}"),conf.env) -conf.env.USAGESYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${USAGEPATH}"),conf.env) - -conf.env.CPLIBDIR = Utils.subst_vars(_join("${LIBDIR}","${CPPATH}"),conf.env) -conf.env.CPSYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${CPPATH}"),conf.env) -conf.env.CPLOGDIR = Utils.subst_vars(_join("${LOCALSTATEDIR}","log","${CPPATH}"),conf.env) - -conf.env.CLIPATH = _join(conf.env.PACKAGE,"cli") - -conf.env.IPALLOCATORLIBDIR = Utils.subst_vars(_join("${LIBDIR}","${IPALLOCATORPATH}"),conf.env) -conf.env.IPALLOCATORSYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${IPALLOCATORPATH}"),conf.env) -conf.env.IPALLOCATORLOGDIR = Utils.subst_vars(_join("${LOCALSTATEDIR}","log","${IPALLOCATORPATH}"),conf.env) - -conf.env.MSLOG = _join(conf.env.MSLOGDIR,"management-server.log") -conf.env.APISERVERLOG = _join(conf.env.MSLOGDIR,"api-server.log") -conf.env.AGENTLOG = _join(conf.env.AGENTLOGDIR,"agent.log") -conf.env.USAGELOG = _join(conf.env.USAGELOGDIR,"usage.log") -conf.env.CPLOG = _join(conf.env.CPLOGDIR,"console-proxy.log") -conf.env.IPALOCATORLOG = _join(conf.env.IPALLOCATORLOGDIR,"ipallocator.log") - -conf.env.SETUPDATADIR = Utils.subst_vars(_join("${DATADIR}","${SETUPPATH}"),conf.env) - -conf.env.CLIDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${CLIPATH}"),conf.env) - -conf.env.SERVERSYSCONFDIR = Utils.subst_vars(_join("${SYSCONFDIR}","${SERVERPATH}"),conf.env) - -if conf.env.DISTRO in ["Windows"]: - for log in "MSLOG APISERVERLOG AGENTLIBDIR USAGELOG AGENTLOG".split(): conf.env[log] = conf.env[log].replace("\\","\\\\") - -no_java_class = lambda x: conf.check_java_class(x,with_classpath=conf.env.CLASSPATH) != 0 -def require_dependency(javacls,packagenames): - if no_java_class(javacls): - conf.fatal("Cannot find the Java class %s (available in the distro packages: %s)"%( - javacls, ", ".join(packagenames))) -def check_dependencies(deps): - for d in deps: - cls,pkgs = d[0],d[1:] - require_dependency(cls,pkgs) - -if not getattr(Options.options, 'NODEPCHECK', ''): check_dependencies(hard_deps) - -Utils.pprint("WHITE","Configure finished. Use 'python waf showconfig' to show the configure-time environment.")