From 9aaaab0ebed00d28bf578aa20a7100ac6ce223d8 Mon Sep 17 00:00:00 2001 From: prachi Date: Fri, 25 May 2012 14:30:37 -0700 Subject: [PATCH] Merging awsapi-setup to master --- .../db/mysql/cloudbridge_bucketpolicy.sql | 27 ++ awsapi-setup/db/mysql/cloudbridge_db.sql | 12 + awsapi-setup/db/mysql/cloudbridge_index.sql | 47 +++ .../db/mysql/cloudbridge_multipart.sql | 60 ++++ .../db/mysql/cloudbridge_multipart_alter.sql | 5 + .../db/mysql/cloudbridge_offering.sql | 22 ++ .../db/mysql/cloudbridge_offering_alter.sql | 3 + .../db/mysql/cloudbridge_policy_alter.sql | 3 + awsapi-setup/db/mysql/cloudbridge_schema.sql | 144 +++++++++ awsapi-setup/db/mysql/deploy-db-bridge.sh | 59 ++++ awsapi-setup/db/mysql/init_db.bat | 9 + awsapi-setup/init/debian/cloud-bridge | 228 ++++++++++++++ awsapi-setup/init/rpm/cloud-bridge | 283 ++++++++++++++++++ awsapi-setup/setup/cloud-setup-bridge | 126 ++++++++ .../setup/cloudstack-aws-api-register | 76 +++++ 15 files changed, 1104 insertions(+) create mode 100644 awsapi-setup/db/mysql/cloudbridge_bucketpolicy.sql create mode 100644 awsapi-setup/db/mysql/cloudbridge_db.sql create mode 100644 awsapi-setup/db/mysql/cloudbridge_index.sql create mode 100644 awsapi-setup/db/mysql/cloudbridge_multipart.sql create mode 100644 awsapi-setup/db/mysql/cloudbridge_multipart_alter.sql create mode 100644 awsapi-setup/db/mysql/cloudbridge_offering.sql create mode 100644 awsapi-setup/db/mysql/cloudbridge_offering_alter.sql create mode 100644 awsapi-setup/db/mysql/cloudbridge_policy_alter.sql create mode 100644 awsapi-setup/db/mysql/cloudbridge_schema.sql create mode 100644 awsapi-setup/db/mysql/deploy-db-bridge.sh create mode 100644 awsapi-setup/db/mysql/init_db.bat create mode 100644 awsapi-setup/init/debian/cloud-bridge create mode 100644 awsapi-setup/init/rpm/cloud-bridge create mode 100644 awsapi-setup/setup/cloud-setup-bridge create mode 100644 awsapi-setup/setup/cloudstack-aws-api-register diff --git a/awsapi-setup/db/mysql/cloudbridge_bucketpolicy.sql b/awsapi-setup/db/mysql/cloudbridge_bucketpolicy.sql new file mode 100644 index 00000000000..9d6a650b09e --- /dev/null +++ b/awsapi-setup/db/mysql/cloudbridge_bucketpolicy.sql @@ -0,0 +1,27 @@ +USE cloudbridge; + +-- This file (and cloudbridge_policy_alter.sql) can be applied to an existing cloudbridge +-- database. It is used to manage defined bucket access policies. +-- +SET foreign_key_checks = 0; + +DROP TABLE IF EXISTS bucket_policies; + +-- 1) Amazon S3 only allows one policy to be defined for a bucket. +-- 2) The maximum size of a policy is 20 KB. +-- 3) A bucket policy has to be able to exist even before the bucket itself (e.g., to +-- support "CreateBucket" actions). +-- +CREATE TABLE bucket_policies ( + ID BIGINT NOT NULL AUTO_INCREMENT, + + BucketName VARCHAR(64) NOT NULL, + OwnerCanonicalID VARCHAR(150) NOT NULL, + + Policy VARCHAR(20000) NOT NULL, -- policies are written in JSON + + PRIMARY KEY(ID) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +SET foreign_key_checks = 1; + diff --git a/awsapi-setup/db/mysql/cloudbridge_db.sql b/awsapi-setup/db/mysql/cloudbridge_db.sql new file mode 100644 index 00000000000..04ea41a75b9 --- /dev/null +++ b/awsapi-setup/db/mysql/cloudbridge_db.sql @@ -0,0 +1,12 @@ +SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ANSI'; + +DROP DATABASE IF EXISTS cloudbridge; +CREATE DATABASE cloudbridge; + +GRANT ALL ON cloudbridge.* to cloud@`localhost` identified by 'cloud'; +GRANT ALL ON cloudbridge.* to cloud@`%` identified by 'cloud'; + +GRANT process ON *.* TO `cloud`@`localhost`; +GRANT process ON *.* TO `cloud`@`%`; + +COMMIT; diff --git a/awsapi-setup/db/mysql/cloudbridge_index.sql b/awsapi-setup/db/mysql/cloudbridge_index.sql new file mode 100644 index 00000000000..d00e5d87acb --- /dev/null +++ b/awsapi-setup/db/mysql/cloudbridge_index.sql @@ -0,0 +1,47 @@ +USE cloudbridge; + +ALTER TABLE shost ADD UNIQUE shost_uq_host(Host, HostType, ExportRoot); +ALTER TABLE shost ADD CONSTRAINT FOREIGN KEY shost_fk_mhost_id(MHostID) REFERENCES mhost(ID); +ALTER TABLE shost ADD INDEX shost_idx_mhost_id(MHostID); + +ALTER TABLE sbucket ADD UNIQUE sbucket_uq_name(Name); +ALTER TABLE sbucket ADD CONSTRAINT FOREIGN KEY sbucket_fk_shost_id(SHostID) REFERENCES shost(ID); +ALTER TABLE sbucket ADD INDEX sbucket_idx_shost_id(SHostID); +ALTER TABLE sbucket ADD INDEX sbucket_idx_owner_cid(OwnerCanonicalID); +ALTER TABLE sbucket ADD INDEX sbucket_idx_create_time(CreateTime); + +ALTER TABLE sobject ADD CONSTRAINT FOREIGN KEY sobject_fk_sbuckt_id(SBucketID) REFERENCES sbucket(ID) ON DELETE CASCADE; +ALTER TABLE sobject ADD INDEX sobject_idx_bucket_id(SBucketID); +ALTER TABLE sobject ADD INDEX sobject_idx_owner_cid(OwnerCanonicalID); +ALTER TABLE sobject ADD UNIQUE sobject_uq_sbucket_id_name_key(SBucketID, NameKey); +ALTER TABLE sobject ADD INDEX sobject_idx_create_time(CreateTime); + +ALTER TABLE sobject_item ADD CONSTRAINT FOREIGN KEY sobject_item_fk_object_id(SObjectID) REFERENCES sobject(ID) ON DELETE CASCADE; +ALTER TABLE sobject_item ADD INDEX sobject_item_idx_object_id(SObjectID); +ALTER TABLE sobject_item ADD UNIQUE sobject_item_uq_sobject_id_version(SObjectID, Version); +ALTER TABLE sobject_item ADD INDEX sobject_item_idx_create_time(CreateTime); +ALTER TABLE sobject_item ADD INDEX sobject_item_idx_modify_time(LastModifiedTime); +ALTER TABLE sobject_item ADD INDEX sobject_item_idx_access_time(LastAccessTime); +ALTER TABLE sobject_item ADD INDEX sobject_item_idx_stored_size(StoredSize); + +ALTER TABLE meta ADD UNIQUE meta_uq_target_name(Target, TargetID, Name); +ALTER TABLE meta ADD INDEX meta_idx_target(Target, TargetID); + +ALTER TABLE usercredentials ADD UNIQUE usercredentials_mappings1(AccessKey); +ALTER TABLE usercredentials ADD UNIQUE usercredentials_mappings2(CertUniqueId); +ALTER TABLE usercredentials ADD INDEX usercredentials_idx_access(AccessKey); +ALTER TABLE usercredentials ADD INDEX usercredentials_idx_cert(CertUniqueId); + +ALTER TABLE acl ADD INDEX acl_idx_target(Target, TargetID); +ALTER TABLE acl ADD INDEX acl_idx_modify_time(LastModifiedTime); + +ALTER TABLE mhost ADD UNIQUE mhost_uq_host(Host); +ALTER TABLE mhost ADD INDEX mhost_idx_mhost_key(MHostKey); +ALTER TABLE mhost ADD INDEX mhost_idx_heartbeat_time(LastHeartbeatTime); + +ALTER TABLE mhost_mount ADD UNIQUE mhost_mnt_uq_mhost_shost(MHostID, SHostID); +ALTER TABLE mhost_mount ADD CONSTRAINT FOREIGN KEY mhost_mnt_fk_mhost_id(MHostID) REFERENCES mhost(ID) ON DELETE CASCADE; +ALTER TABLE mhost_mount ADD CONSTRAINT FOREIGN KEY mhost_mnt_fk_shost_id(SHostID) REFERENCES shost(ID) ON DELETE CASCADE; +ALTER TABLE mhost_mount ADD INDEX mhost_mnt_idx_mhost_id(MHostID); +ALTER TABLE mhost_mount ADD INDEX mhost_mnt_idx_shost_id(SHostID); +ALTER TABLE mhost_mount ADD INDEX mhost_mnt_idx_mount_time(LastMountTime); diff --git a/awsapi-setup/db/mysql/cloudbridge_multipart.sql b/awsapi-setup/db/mysql/cloudbridge_multipart.sql new file mode 100644 index 00000000000..27456c4f41b --- /dev/null +++ b/awsapi-setup/db/mysql/cloudbridge_multipart.sql @@ -0,0 +1,60 @@ +USE cloudbridge; + +-- This file can be applied to an existing cloudbridge database. It is used +-- to keep track of in progress multipart file uploads. +-- +SET foreign_key_checks = 0; + +DROP TABLE IF EXISTS multipart_uploads; +DROP TABLE IF EXISTS multipart_meta; +DROP TABLE IF EXISTS multipart_parts; + +-- We need to keep track of the multipart uploads and all the parts of each upload until they +-- are completed or aborted. +-- The AccessKey is where we store the AWS account id +-- +CREATE TABLE multipart_uploads ( + ID BIGINT NOT NULL AUTO_INCREMENT, + + AccessKey VARCHAR(150) NOT NULL, -- this is the initiator of the request + BucketName VARCHAR(64) NOT NULL, + NameKey VARCHAR(255) NOT NULL, + x_amz_acl VARCHAR(64) NULL, + + CreateTime DATETIME, + + PRIMARY KEY(ID) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- We need to store all the meta data for an object being mutlipart uploaded +-- UploadID is a foreign key to an entry in the mutipart_uploads table +-- +CREATE TABLE multipart_meta ( + ID BIGINT NOT NULL AUTO_INCREMENT, + + UploadID BIGINT NOT NULL, + Name VARCHAR(64) NOT NULL, + Value VARCHAR(256), + + PRIMARY KEY(ID) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Each part of a multipart upload gets a row in this table +-- UploadId is a foreign key to an entry in the mutipart_uploads table +-- +CREATE TABLE multipart_parts ( + ID BIGINT NOT NULL AUTO_INCREMENT, + + UploadID BIGINT NOT NULL, + partNumber INT NOT NULL, + MD5 VARCHAR(128), + StoredPath VARCHAR(256), -- relative to mount point of the root + StoredSize BIGINT NOT NULL DEFAULT 0, + + CreateTime DATETIME, + + PRIMARY KEY(ID) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +SET foreign_key_checks = 1; + diff --git a/awsapi-setup/db/mysql/cloudbridge_multipart_alter.sql b/awsapi-setup/db/mysql/cloudbridge_multipart_alter.sql new file mode 100644 index 00000000000..203bf3aa9c8 --- /dev/null +++ b/awsapi-setup/db/mysql/cloudbridge_multipart_alter.sql @@ -0,0 +1,5 @@ +USE cloudbridge; + +ALTER TABLE multipart_meta ADD CONSTRAINT FOREIGN KEY meta_uploads_id(UploadID) REFERENCES multipart_uploads(ID) ON DELETE CASCADE; +ALTER TABLE multipart_parts ADD CONSTRAINT FOREIGN KEY part_uploads_id(UploadID) REFERENCES multipart_uploads(ID) ON DELETE CASCADE; +ALTER TABLE multipart_parts ADD UNIQUE part_uploads_number(UploadId, partNumber); diff --git a/awsapi-setup/db/mysql/cloudbridge_offering.sql b/awsapi-setup/db/mysql/cloudbridge_offering.sql new file mode 100644 index 00000000000..064fd93fe7f --- /dev/null +++ b/awsapi-setup/db/mysql/cloudbridge_offering.sql @@ -0,0 +1,22 @@ +USE cloudbridge; + +-- This file (and cloudbridge_offering_alter.sql) can be applied to an existing cloudbridge +-- database. It is used to manage the mappings from the Amazon EC2 offering strings to +-- cloudstack service offering identifers. +-- +SET foreign_key_checks = 0; + +DROP TABLE IF EXISTS offering_bundle; + +-- AmazonEC2Offering - string name of an EC2 AMI capability (e.g. "m1.small") +-- CloudStackOffering - string name of the cloud stack service offering identifer (e.g. "1" ) +-- +CREATE TABLE offering_bundle ( + ID INTEGER NOT NULL AUTO_INCREMENT, + AmazonEC2Offering VARCHAR(100) NOT NULL, + CloudStackOffering VARCHAR(20) NOT NULL, + PRIMARY KEY(ID) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +SET foreign_key_checks = 1; + diff --git a/awsapi-setup/db/mysql/cloudbridge_offering_alter.sql b/awsapi-setup/db/mysql/cloudbridge_offering_alter.sql new file mode 100644 index 00000000000..c44df79f479 --- /dev/null +++ b/awsapi-setup/db/mysql/cloudbridge_offering_alter.sql @@ -0,0 +1,3 @@ +USE cloudbridge; + +ALTER TABLE offering_bundle ADD UNIQUE one_offering (AmazonEC2Offering); diff --git a/awsapi-setup/db/mysql/cloudbridge_policy_alter.sql b/awsapi-setup/db/mysql/cloudbridge_policy_alter.sql new file mode 100644 index 00000000000..311a86528e7 --- /dev/null +++ b/awsapi-setup/db/mysql/cloudbridge_policy_alter.sql @@ -0,0 +1,3 @@ +USE cloudbridge; + +ALTER TABLE bucket_policies ADD UNIQUE one_policy_per_bucket(BucketName); diff --git a/awsapi-setup/db/mysql/cloudbridge_schema.sql b/awsapi-setup/db/mysql/cloudbridge_schema.sql new file mode 100644 index 00000000000..f4b21a04376 --- /dev/null +++ b/awsapi-setup/db/mysql/cloudbridge_schema.sql @@ -0,0 +1,144 @@ +USE cloudbridge; + +SET foreign_key_checks = 0; + +DROP TABLE IF EXISTS shost; +DROP TABLE IF EXISTS mhost; +DROP TABLE IF EXISTS mhost_mount; +DROP TABLE IF EXISTS sbucket; +DROP TABLE IF EXISTS sobject; +DROP TABLE IF EXISTS sobject_item; +DROP TABLE IF EXISTS meta; +DROP TABLE IF EXISTS acl; +DROP TABLE IF EXISTS usercredentials; + +-- storage host +CREATE TABLE shost ( + ID BIGINT NOT NULL AUTO_INCREMENT, + + Host VARCHAR(128) NOT NULL, + HostType INT NOT NULL DEFAULT 0, -- 0 : local, 1 : nfs + ExportRoot VARCHAR(128) NOT NULL, + + MHostID BIGINT, -- when host type is local, MHostID points to its owner management host + + UserOnHost VARCHAR(64), + UserPassword VARCHAR(128), + PRIMARY KEY(ID) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- management host +CREATE TABLE mhost ( + ID BIGINT NOT NULL AUTO_INCREMENT, + + MHostKey VARCHAR(128) NOT NULL, -- host key could be derived from MAC address or named configuration value + Host VARCHAR(128), -- public host address for redirecting request from/to + + Version VARCHAR(64), + LastHeartbeatTime DATETIME, + + PRIMARY KEY(ID) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE mhost_mount ( + ID BIGINT NOT NULL AUTO_INCREMENT, + MHostID BIGINT NOT NULL, + SHostID BIGINT NOT NULL, + + MountPath VARCHAR(256), -- local mount path + LastMountTime DATETIME, -- null : unmounted, otherwise the mount location + + PRIMARY KEY(ID) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE sbucket ( + ID BIGINT NOT NULL AUTO_INCREMENT, + + Name VARCHAR(64) NOT NULL, + OwnerCanonicalID VARCHAR(150) NOT NULL, + + SHostID BIGINT, + + CreateTime DATETIME, + + VersioningStatus INT NOT NULL DEFAULT 0, -- 0 : initial not set, 1 : enabled, 2 : suspended + + PRIMARY KEY(ID) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE sobject ( + ID BIGINT NOT NULL AUTO_INCREMENT, + + SBucketID BIGINT NOT NULL, + NameKey VARCHAR(255) NOT NULL, + + OwnerCanonicalID VARCHAR(150) NOT NULL, + NextSequence INT NOT NULL DEFAULT 1, + DeletionMark VARCHAR (150), + + CreateTime DATETIME, + + PRIMARY KEY(ID) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE sobject_item ( + ID BIGINT NOT NULL AUTO_INCREMENT, + + SObjectID BIGINT NOT NULL, + Version VARCHAR(64), + + MD5 VARCHAR(128), + StoredPath VARCHAR(256), -- relative to mount point of the root + StoredSize BIGINT NOT NULL DEFAULT 0, + + CreateTime DATETIME, + LastModifiedTime DATETIME, + LastAccessTime DATETIME, + + PRIMARY KEY(ID) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE meta ( + ID BIGINT NOT NULL AUTO_INCREMENT, + + Target VARCHAR(64) NOT NULL, + TargetID BIGINT NOT NULL, + + Name VARCHAR(64) NOT NULL, + Value VARCHAR(256), + + PRIMARY KEY(ID) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE acl ( + ID BIGINT NOT NULL AUTO_INCREMENT, + + Target VARCHAR(64) NOT NULL, + TargetID BIGINT NOT NULL, + + GranteeType INT NOT NULL DEFAULT 0, -- 0 : Cloud service user, 1 : Cloud user community, 2: Public user community + GranteeCanonicalID VARCHAR(150), -- make it big enought to hold a Cloud API access key + + Permission INT NOT NULL DEFAULT 0, -- 0 : no permission, 1 : read, 2 : write, 4 : read_acl, 8 : write_acl + GrantOrder INT NOT NULL DEFAULT 0, + + CreateTime DATETIME, + LastModifiedTime DATETIME, + + PRIMARY KEY(ID) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- each account has to have a separate +-- each account has to have a separate mappings +CREATE TABLE usercredentials ( + ID BIGINT NOT NULL AUTO_INCREMENT, + + AccessKey VARCHAR(150) NOT NULL, + SecretKey VARCHAR(150) NOT NULL, + CertUniqueId VARCHAR(200), + + PRIMARY KEY(ID) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +SET foreign_key_checks = 1; + diff --git a/awsapi-setup/db/mysql/deploy-db-bridge.sh b/awsapi-setup/db/mysql/deploy-db-bridge.sh new file mode 100644 index 00000000000..abaa19b9a0a --- /dev/null +++ b/awsapi-setup/db/mysql/deploy-db-bridge.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +# deploy-db-bridge.sh -- deploys the cloudbridge database configuration. +# +# set -x + +if [ ! -f cloudbridge_db.sql ]; then + printf "Error: Unable to find cloudbridge_db.sql\n" + exit 4 +fi + +if [ ! -f cloudbridge_schema.sql ]; then + printf "Error: Unable to find cloudbridge_schema.sql\n" + exit 5 +fi + +if [ ! -f cloudbridge_index.sql ]; then + printf "Error: Unable to find cloudbridge_index.sql\n" + exit 6; +fi + +echo "Recreating Database." +mysql --user=root --password=$1 < cloudbridge_db.sql > /dev/null 2>/dev/null +mysqlout=$? +if [ $mysqlout -eq 1 ]; then + printf "Please enter root password for MySQL.\n" + mysql --user=root --password < cloudbridge_db.sql + if [ $? -ne 0 ]; then + printf "Error: Cannot execute cloudbridge_db.sql\n" + exit 10 + fi +elif [ $mysqlout -ne 0 ]; then + printf "Error: Cannot execute cloudbridge_db.sql\n" + exit 11 +fi + +mysql --user=cloud --password=cloud < cloudbridge_schema.sql +if [ $? -ne 0 ]; then + printf "Error: Cannot execute cloudbridge_schema.sql\n" + exit 11 +fi + +mysql --user=cloud --password=cloud < cloudbridge_multipart.sql +if [ $? -ne 0 ] +then + exit 1 +fi + +echo "Creating Indice and Foreign Keys" +mysql --user=cloud --password=cloud < cloudbridge_index.sql +if [ $? -ne 0 ]; then + printf "Error: Cannot execute cloudbridge_index.sql\n" + exit 13 +fi + +mysql --user=cloud --password=cloud < cloudbridge_multipart_alter.sql +mysql --user=cloud --password=cloud < cloudbridge_bucketpolicy.sql +mysql --user=cloud --password=cloud < cloudbridge_policy_alter.sql +mysql --user=cloud --password=cloud < cloudbridge_offering.sql +mysql --user=cloud --password=cloud < cloudbridge_offering_alter.sql diff --git a/awsapi-setup/db/mysql/init_db.bat b/awsapi-setup/db/mysql/init_db.bat new file mode 100644 index 00000000000..b7296a6dd2f --- /dev/null +++ b/awsapi-setup/db/mysql/init_db.bat @@ -0,0 +1,9 @@ +mysql --user=root --password < cloudbridge_db.sql +mysql --user=root --password < cloudbridge_schema.sql +mysql --user=root --password < cloudbridge_multipart.sql +mysql --user=root --password < cloudbridge_index.sql +mysql --user=root --password < cloudbridge_multipart_alter.sql +mysql --user=root --password < cloudbridge_bucketpolicy.sql +mysql --user=root --password < cloudbridge_policy_alter.sql +mysql --user=root --password < cloudbridge_offering.sql +mysql --user=root --password < cloudbridge_offering_alter.sql diff --git a/awsapi-setup/init/debian/cloud-bridge b/awsapi-setup/init/debian/cloud-bridge new file mode 100644 index 00000000000..8fb0fbf659c --- /dev/null +++ b/awsapi-setup/init/debian/cloud-bridge @@ -0,0 +1,228 @@ +#!/bin/sh +# +# /etc/init.d/tomcat6 -- startup script for the Tomcat 6 servlet engine +# +# Written by Miquel van Smoorenburg . +# Modified for Debian GNU/Linux by Ian Murdock . +# Modified for Tomcat by Stefan Gybas . +# Modified for Tomcat6 by Thierry Carrez . +# Modified for VMOps by Manuel Amador (Rudd-O) +# +### BEGIN INIT INFO +# Provides: tomcat-vmops +# Required-Start: $local_fs $remote_fs $network +# Required-Stop: $local_fs $remote_fs $network +# Should-Start: $named +# Should-Stop: $named +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start Tomcat (CloudStack). +# Description: Start the Tomcat servlet engine that runs the CloudStack Management Server. +### END INIT INFO + +PATH=/bin:/usr/bin:/sbin:/usr/sbin +NAME=cloud-bridge +DESC="CloudStack-specific Tomcat servlet engine" +DAEMON=/usr/bin/jsvc +CATALINA_BASE=/usr/share/cloud/bridge +CATALINA_HOME=/usr/share/tomcat6 +DEFAULT=$CATALINA_BASE/conf/tomcat6.conf +JVM_TMP=/tmp/$NAME-temp + +if [ `id -u` -ne 0 ]; then + echo "You need root privileges to run this script" + exit 1 +fi + +# Make sure tomcat is started with system locale +if [ -r /etc/default/locale ]; then + . /etc/default/locale + export LANG +fi + +. /lib/lsb/init-functions +. /etc/default/rcS + + +# The following variables can be overwritten in $DEFAULT + +# Run Tomcat 6 as this user ID +TOMCAT6_USER=tomcat6 + +# The first existing directory is used for JAVA_HOME (if JAVA_HOME is not +# defined in $DEFAULT) +JDK_DIRS="/usr/lib/jvm/java-6-openjdk /usr/lib/jvm/java-6-sun /usr/lib/jvm/java-1.5.0-sun /usr/lib/j2sdk1.5-sun /usr/lib/j2sdk1.5-ibm" + +# Look for the right JVM to use +for jdir in $JDK_DIRS; do + if [ -r "$jdir/bin/java" -a -z "${JAVA_HOME}" ]; then + JAVA_HOME="$jdir" + fi +done +export JAVA_HOME + + +# Use the Java security manager? (yes/no) +TOMCAT6_SECURITY=no + +# Default Java options +# Set java.awt.headless=true if JAVA_OPTS is not set so the +# Xalan XSL transformer can work without X11 display on JDK 1.4+ +# It also looks like the default heap size of 64M is not enough for most cases +# so the maximum heap size is set to 128M +if [ -z "$JAVA_OPTS" ]; then + JAVA_OPTS="-Djava.awt.headless=true -Xmx128M" +fi + +# End of variables that can be overwritten in $DEFAULT + +# overwrite settings from default file +if [ -f "$DEFAULT" ]; then + . "$DEFAULT" +fi + +if [ ! -f "$CATALINA_HOME/bin/bootstrap.jar" ]; then + log_failure_msg "$NAME is not installed" + exit 1 +fi + +[ -f "$DAEMON" ] || exit 0 + +POLICY_CACHE="$CATALINA_BASE/work/catalina.policy" + +JAVA_OPTS="$JAVA_OPTS -Djava.endorsed.dirs=$CATALINA_HOME/endorsed -Dcatalina.base=$CATALINA_BASE -Dcatalina.home=$CATALINA_HOME -Djava.io.tmpdir=$JVM_TMP" + +# Set the JSP compiler if set in the tomcat6.default file +if [ -n "$JSP_COMPILER" ]; then + JAVA_OPTS="$JAVA_OPTS -Dbuild.compiler=$JSP_COMPILER" +fi + +if [ "$TOMCAT6_SECURITY" = "yes" ]; then + JAVA_OPTS="$JAVA_OPTS -Djava.security.manager -Djava.security.policy=$POLICY_CACHE" +fi + +# Set juli LogManager if logging.properties is provided +if [ -r "$CATALINA_BASE"/conf/logging.properties ]; then + JAVA_OPTS="$JAVA_OPTS "-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager" "-Djava.util.logging.config.file="$CATALINA_BASE/conf/logging.properties" +fi + +# Define other required variables +CATALINA_PID="/var/run/$NAME.pid" +BOOTSTRAP_CLASS=org.apache.catalina.startup.Bootstrap +JSVC_CLASSPATH="/usr/share/java/commons-daemon.jar:$CATALINA_HOME/bin/bootstrap.jar" +JSVC_CLASSPATH=$CLASSPATH:$JSVC_CLASSPATH + +# Look for Java Secure Sockets Extension (JSSE) JARs +if [ -z "${JSSE_HOME}" -a -r "${JAVA_HOME}/jre/lib/jsse.jar" ]; then + JSSE_HOME="${JAVA_HOME}/jre/" +fi +export JSSE_HOME + +case "$1" in + start) + if [ -z "$JAVA_HOME" ]; then + log_failure_msg "no JDK found - please set JAVA_HOME" + exit 1 + fi + + if [ ! -d "$CATALINA_BASE/conf" ]; then + log_failure_msg "invalid CATALINA_BASE: $CATALINA_BASE" + exit 1 + fi + + log_daemon_msg "Starting $DESC" "$NAME" + if start-stop-daemon --test --start --pidfile "$CATALINA_PID" \ + --user $TOMCAT6_USER --startas "$JAVA_HOME/bin/java" \ + >/dev/null; then + + # Regenerate POLICY_CACHE file + umask 022 + echo "// AUTO-GENERATED FILE from /etc/tomcat6/policy.d/" \ + > "$POLICY_CACHE" + echo "" >> "$POLICY_CACHE" + if ls $CATALINA_BASE/conf/policy.d/*.policy > /dev/null 2>&1 ; then + cat $CATALINA_BASE/conf/policy.d/*.policy \ + >> "$POLICY_CACHE" + fi + + # Remove / recreate JVM_TMP directory + rm -rf "$JVM_TMP" + mkdir "$JVM_TMP" || { + log_failure_msg "could not create JVM temporary directory" + exit 1 + } + chown $TOMCAT6_USER "$JVM_TMP" + cd "$JVM_TMP" + + + # fix storage issues on nfs mounts + umask 000 + $DAEMON -user "$TOMCAT6_USER" -cp "$JSVC_CLASSPATH" \ + -outfile SYSLOG -errfile SYSLOG \ + -pidfile "$CATALINA_PID" $JAVA_OPTS "$BOOTSTRAP_CLASS" + + sleep 5 + if start-stop-daemon --test --start --pidfile "$CATALINA_PID" \ + --user $TOMCAT6_USER --startas "$JAVA_HOME/bin/java" \ + >/dev/null; then + log_end_msg 1 + else + log_end_msg 0 + fi + else + log_progress_msg "(already running)" + log_end_msg 0 + fi + ;; + stop) + log_daemon_msg "Stopping $DESC" "$NAME" + if start-stop-daemon --test --start --pidfile "$CATALINA_PID" \ + --user "$TOMCAT6_USER" --startas "$JAVA_HOME/bin/java" \ + >/dev/null; then + log_progress_msg "(not running)" + else + $DAEMON -cp "$JSVC_CLASSPATH" -pidfile "$CATALINA_PID" \ + -stop "$BOOTSTRAP_CLASS" + fi + rm -rf "$JVM_TMP" + log_end_msg 0 + ;; + status) + if start-stop-daemon --test --start --pidfile "$CATALINA_PID" \ + --user $TOMCAT6_USER --startas "$JAVA_HOME/bin/java" \ + >/dev/null; then + + if [ -f "$CATALINA_PID" ]; then + log_success_msg "$DESC is not running, but pid file exists." + exit 1 + else + log_success_msg "$DESC is not running." + exit 3 + fi + else + log_success_msg "$DESC is running with pid `cat $CATALINA_PID`" + fi + ;; + restart|force-reload) + if start-stop-daemon --test --stop --pidfile "$CATALINA_PID" \ + --user $TOMCAT6_USER --startas "$JAVA_HOME/bin/java" \ + >/dev/null; then + $0 stop + sleep 1 + fi + $0 start + ;; + try-restart) + if start-stop-daemon --test --start --pidfile "$CATALINA_PID" \ + --user $TOMCAT6_USER --startas "$JAVA_HOME/bin/java" \ + >/dev/null; then + $0 start + fi + ;; + *) + log_success_msg "Usage: $0 {start|stop|restart|try-restart|force-reload|status}" + exit 1 + ;; +esac + +exit 0 diff --git a/awsapi-setup/init/rpm/cloud-bridge b/awsapi-setup/init/rpm/cloud-bridge new file mode 100644 index 00000000000..ee9bd5138ee --- /dev/null +++ b/awsapi-setup/init/rpm/cloud-bridge @@ -0,0 +1,283 @@ +#!/bin/bash +# +# tomcat6 This shell script takes care of starting and stopping Tomcat +# +# chkconfig: - 80 20 +# +### BEGIN INIT INFO +# Provides: tomcat6 +# Required-Start: $network $syslog +# Required-Stop: $network $syslog +# Default-Start: +# Default-Stop: +# Description: Release implementation for Servlet 2.5 and JSP 2.1 +# Short-Description: start and stop tomcat +### END INIT INFO +# +# - originally written by Henri Gomez, Keith Irwin, and Nicolas Mailhot +# - heavily rewritten by Deepak Bhole and Jason Corley +# + +## Source function library. +#. /etc/rc.d/init.d/functions +# Source LSB function library. +export NAME=cloud-bridge +DESC="CloudStack-specific Tomcat servlet engine" +export CATALINA_BASE=/usr/share/cloud/bridge +DEFAULT=$CATALINA_BASE/conf/tomcat6.conf +TOMCAT_USER="cloud" +export TOMCAT_LOG="${TOMCAT_LOG:-/var/log/tomcat6/catalina.out}" +export TOMCAT_CFG=$DEFAULT +if [ -r "$TOMCAT_CFG" ]; then + . $TOMCAT_CFG +fi + +if [ -r /lib/lsb/init-functions ]; then + . /lib/lsb/init-functions +else + exit 1 +fi + +DISTRIB_ID=`lsb_release -i -s 2>/dev/null` + +# For SELinux we need to use 'runuser' not 'su' +if [ -x "/sbin/runuser" ]; then + SU="/sbin/runuser -m" +else + SU="/bin/su -m" +fi + + +# Get instance specific config file +if [ -r "/etc/sysconfig/${NAME}" ]; then + . /etc/sysconfig/${NAME} +fi + + +# Path to the tomcat launch script +TOMCAT_SCRIPT="/usr/sbin/tomcat6" + +# Tomcat program name +TOMCAT_PROG="${NAME}" + + +RETVAL="0" + +# Look for open ports, as the function name might imply +function findFreePorts() { + local isSet1="false" + local isSet2="false" + local isSet3="false" + local lower="8000" + randomPort1="0" + randomPort2="0" + randomPort3="0" + local -a listeners="( $( + netstat -ntl | \ + awk '/^tcp/ {gsub("(.)*:", "", $4); print $4}' + ) )" + while [ "$isSet1" = "false" ] || \ + [ "$isSet2" = "false" ] || \ + [ "$isSet3" = "false" ]; do + let port="${lower}+${RANDOM:0:4}" + if [ -z `expr " ${listeners[*]} " : ".*\( $port \).*"` ]; then + if [ "$isSet1" = "false" ]; then + export randomPort1="$port" + isSet1="true" + elif [ "$isSet2" = "false" ]; then + export randomPort2="$port" + isSet2="true" + elif [ "$isSet3" = "false" ]; then + export randomPort3="$port" + isSet3="true" + fi + fi + done +} + +function makeHomeDir() { + if [ ! -d "$CATALINA_HOME" ]; then + echo "$CATALINA_HOME does not exist, creating" + if [ ! -d "/usr/share/${NAME}" ]; then + mkdir /usr/share/${NAME} + cp -pLR /usr/share/tomcat6/* /usr/share/${NAME} + fi + mkdir -p /var/log/${NAME} \ + /var/cache/${NAME} \ + /var/tmp/${NAME} + ln -fs /var/cache/${NAME} ${CATALINA_HOME}/work + ln -fs /var/tmp/${NAME} ${CATALINA_HOME}/temp + cp -pLR /usr/share/${NAME}/bin $CATALINA_HOME + cp -pLR /usr/share/${NAME}/conf $CATALINA_HOME + ln -fs /usr/share/java/tomcat6 ${CATALINA_HOME}/lib + ln -fs /usr/share/tomcat6/webapps ${CATALINA_HOME}/webapps + chown ${TOMCAT_USER}:${TOMCAT_USER} /var/log/${NAME} + fi +} + +function parseOptions() { + options="" + options="$options $( + awk '!/^#/ && !/^$/ { ORS=" "; print "export ", $0, ";" }' \ + $TOMCAT_CFG + )" + if [ -r "/etc/sysconfig/${NAME}" ]; then + options="$options $( + awk '!/^#/ && !/^$/ { ORS=" "; + print "export ", $0, ";" }' \ + /etc/sysconfig/${NAME} + )" + fi + TOMCAT_SCRIPT="$options ${TOMCAT_SCRIPT}" +} + +# See how we were called. +function start() { + echo -n "Starting ${TOMCAT_PROG}: " + if [ -f "/var/lock/subsys/${NAME}" ] ; then + if [ -f "/var/run/${NAME}.pid" ]; then + read kpid < /var/run/${NAME}.pid +# if checkpid $kpid 2>&1; then + if [ -d "/proc/${kpid}" ]; then + log_success_msg + if [ "$DISTRIB_ID" = "MandrivaLinux" ]; then + echo + fi + return 0 + fi + fi + fi + # fix permissions on the log and pid files + export CATALINA_PID="/var/run/${NAME}.pid" + touch $CATALINA_PID + chown ${TOMCAT_USER}:${TOMCAT_USER} $CATALINA_PID + touch $TOMCAT_LOG + chown ${TOMCAT_USER}:${TOMCAT_USER} $TOMCAT_LOG + if [ "$CATALINA_HOME" != "/usr/share/tomcat6" ]; then + # Create a tomcat directory if it doesn't exist + makeHomeDir + # If CATALINA_HOME doesn't exist modify port number so that + # multiple instances don't interfere with each other + findFreePorts + sed -i -e "s/8005/${randomPort1}/g" -e "s/8080/${CONNECTOR_PORT}/g" \ + -e "s/8009/${randomPort2}/g" -e "s/8443/${randomPort3}/g" \ + ${CATALINA_HOME}/conf/server.xml + fi + parseOptions + if [ "$SECURITY_MANAGER" = "true" ]; then + $SU $TOMCAT_USER -c "${TOMCAT_SCRIPT} start-security" \ + >> $TOMCAT_LOG 2>&1 + else + $SU $TOMCAT_USER -c "${TOMCAT_SCRIPT} start" >> $TOMCAT_LOG 2>&1 + fi + RETVAL="$?" + if [ "$RETVAL" -eq 0 ]; then + log_success_msg + touch /var/lock/subsys/${NAME} + else + log_failure_msg + fi + if [ "$DISTRIB_ID" = "MandrivaLinux" ]; then + echo + fi + return $RETVAL +} + +function stop() { + RETVAL="0" + echo -n "Stopping ${TOMCAT_PROG}: " + if [ -f "/var/lock/subsys/${NAME}" ]; then + parseOptions + $SU $TOMCAT_USER -c "${TOMCAT_SCRIPT} stop" >> $TOMCAT_LOG 2>&1 + RETVAL="$?" + if [ "$RETVAL" -eq "0" ]; then + count="0" + if [ -f "/var/run/${NAME}.pid" ]; then + read kpid < /var/run/${NAME}.pid + until [ "$(ps --pid $kpid | grep -c $kpid)" -eq "0" ] || \ + [ "$count" -gt "$SHUTDOWN_WAIT" ]; do + if [ "$SHUTDOWN_VERBOSE" = "true" ]; then + echo "waiting for processes $kpid to exit" + fi + sleep 1 + let count="${count}+1" + done + if [ "$count" -gt "$SHUTDOWN_WAIT" ]; then + if [ "$SHUTDOWN_VERBOSE" = "true" ]; then + echo "killing processes which didn't stop after $SHUTDOWN_WAIT seconds" + fi + kill -9 $kpid + fi + log_success_msg + fi + rm -f /var/lock/subsys/${NAME} /var/run/${NAME}.pid + else + log_failure_msg + fi + else + log_success_msg + fi + if [ "$DISTRIB_ID" = "MandrivaLinux" ]; then + echo + fi + return $RETVAL +} + +# See how we were called. +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + condrestart|try-restart) + if [ -f "/var/run/${NAME}.pid" ]; then + stop + start + fi + ;; + reload) + RETVAL="3" + ;; + force-reload) + if [ -f "/var/run/${NAME}.pid" ]; then + stop + start + fi + ;; + status) + if [ -f "/var/run/${NAME}.pid" ]; then +# status ${NAME} +# RETVAL="$?" + read kpid < /var/run/${NAME}.pid + if [ -d "/proc/${kpid}" ]; then + echo "${NAME} (pid ${kpid}) is running..." + RETVAL="0" + fi + else + pid="$(/usr/bin/pgrep -d , -u ${TOMCAT_USER} -G ${TOMCAT_USER} java)" + if [ -z "$pid" ]; then +# status ${NAME} +# RETVAL="$?" + echo "${NAME} is stopped" + RETVAL="3" + else + echo "${NAME} (pid $pid) is running..." + RETVAL="0" + fi + fi + ;; + version) + ${TOMCAT_SCRIPT} version + ;; + *) + echo "Usage: $0 {start|stop|restart|condrestart|try-restart|reload|force-reload|status|version}" + RETVAL="2" +esac + +exit $RETVAL diff --git a/awsapi-setup/setup/cloud-setup-bridge b/awsapi-setup/setup/cloud-setup-bridge new file mode 100644 index 00000000000..ea3fa1faf22 --- /dev/null +++ b/awsapi-setup/setup/cloud-setup-bridge @@ -0,0 +1,126 @@ +#!/bin/bash +# +# Cloud.com Bridge setup script. +# + +settingsFile="/usr/share/cloud/bridge/conf/ec2-service.properties" + +function readCurrentSettings () { + readVar managementServer + readVar cloudAPIPort + readVar cloudstackVersion + readVar WSDLVersion + readVar keystore + readVar keystorePass + readVar m1.small.serviceId + readVar m1.large.serviceId + readVar m1.xlarge.serviceId + readVar c1.medium.serviceId + readVar c1.xlarge.serviceId + readVar m2.xlarge.serviceId + readVar m2.2xlarge.serviceId + readVar m2.4xlarge.serviceId + readVar cc1.4xlarge.serviceId + readVar dbHost + readVar dbName + readVar dbUser + readVar dbPassword +} + +function readVar () { + local _pointer=$(sub "$1") + local _tmp="`cat $settingsFile|grep \"$1=\"|awk -F= '{print $2}'|tr -d '\r'`" + eval $_pointer="$_tmp" +} + +function readValue () { + local _value + local _tmp + local _pointer=$(sub "$2") + eval _value="\$$_pointer" + printf "%s [%s]: " "$1" "$_value" + read -e _tmp + + if [ "$_tmp" != "" ] + then + eval $_pointer="$_tmp" + fi +} + +function getNewValues () { + readValue "Management server hostname or IP" managementServer + readValue "Management server port" cloudAPIPort + + readValue "Service offering ID for m1.small" m1.small.serviceId + readValue "Service offering ID for m1.large" m1.large.serviceId + readValue "Service offering ID for m1.xlarge" m1.xlarge.serviceId + + readValue "Service offering ID for c1.medium" c1.medium.serviceId + readValue "Service offering ID for c1.xlarge" c1.xlarge.serviceId + + readValue "Service offering ID for m2.xlarge" m2.xlarge.serviceId + readValue "Service offering ID for m2.2xlarge" m2.2xlarge.serviceId + readValue "Service offering ID for m2.4xlarge" m2.4xlarge.serviceId + readValue "Service offering ID for cc1.4xlarge" cc1.4xlarge.serviceId +} + +function sub () { + echo "$1" | awk '{gsub(/\./, "_", $0); print $0}' +} + +function saveValue () { + local _pointer=$(sub "$1") + local _value + eval _value="\$$_pointer" + echo "$1=$_value" >> $settingsFile +} + +function saveValues () { + cat /dev/null > $settingsFile + saveValue managementServer + saveValue cloudAPIPort + saveValue cloudstackVersion + saveValue WSDLVersion + saveValue keystore + saveValue keystorePass + saveValue m1.small.serviceId + saveValue m1.large.serviceId + saveValue m1.xlarge.serviceId + saveValue c1.medium.serviceId + saveValue c1.xlarge.serviceId + saveValue m2.xlarge.serviceId + saveValue m2.2xlarge.serviceId + saveValue m2.4xlarge.serviceId + saveValue cc1.4xlarge.serviceId + saveValue dbHost + saveValue dbName + saveValue dbUser + saveValue dbPassword +} + +echo "Welcome to the CloudBridge setup." + + +if [ ! -e $settingsFile ] +then + settingsFile=$1 + if [ ! -e $settingsFile ] + then + echo "Error: Settings file not found." + exit 1 + fi +fi +if [ ! -w $settingsFile ] +then + echo "Error: Insufficient permissions. Run as super-user." + exit 1 +fi + +readCurrentSettings + +printf "Enter suitable values or press enter for default. \n\n" + +getNewValues +saveValues + +printf "\nValues saved. Restart the cloud-bridge service for the changes to become active.\n\n" diff --git a/awsapi-setup/setup/cloudstack-aws-api-register b/awsapi-setup/setup/cloudstack-aws-api-register new file mode 100644 index 00000000000..859a57188fc --- /dev/null +++ b/awsapi-setup/setup/cloudstack-aws-api-register @@ -0,0 +1,76 @@ +#!/cygdrive/c/python26/python + +import base64 +import hmac +import os +import sys +import urllib2 +import urllib +import httplib +from datetime import datetime +from optparse import OptionParser +from urlparse import urlparse + +try: + from hashlib import sha1 as sha +except ImportError: + import sha + +def get_signature(key, url, query): + netloc, path = urlparse(url)[1:3] + return urllib.quote_plus(base64.b64encode( + hmac.new(key, '\n'.join(['GET', netloc, path, query]), sha).digest())) + +def get_url(url, api_key, secret_key, action, query): + amzn_string = 'AWSAccessKeyId=' + api_key + '&Action=' + action + '&SignatureMethod=HmacSHA1' + amzn_string += '&SignatureVersion=2&Timestamp='+ datetime.now().isoformat()[:19] +'Z&Version=2010-11-15' + query = amzn_string + '&' + query + url = url + '?' + query + '&Signature=' + get_signature(secret_key, url, query) + try: + urllib2.urlopen(url) + if action == 'SetCertificate': + print 'User registration is successful!' + return True + except urllib2.HTTPError, e: + print 'User registration failed with http error code:' , e.code + return False + except urllib2.URLError, e: + print 'User registration failed with error: ' , e.reason + return False + + +def register(url, api_key, secret_key, cert): + # Register API keys + query = 'accesskey=' + api_key + '&secretkey=' + secret_key + result = get_url(url, api_key, secret_key, 'SetUserKeys', query) + + if result == True: + # Tie Certifcate to API keys + query = 'cert=' + urllib.quote_plus(cert) + get_url(url, api_key, secret_key, 'SetCertificate', query) + + +def get_opts(): + parser = OptionParser() + parser.add_option('-a', '--apikey') + parser.add_option('-s', '--secretkey') + parser.add_option('-c', '--cert', help='Name of a file containing an X.509 certificate') + parser.add_option('-u', '--url', help='CloudStack AWSAPI URL, eg. http://cloudstack.host:8080/awsapi') + (options, args) = parser.parse_args() + if None in [options.apikey, options.secretkey, options.cert, options.url]: + print 'Error: Missing argument\n' + parser.print_help() + sys.exit(1) + return options + +def validate_opts(options): + if not os.path.isfile(options.cert): + print 'Error reading file: ' + options.cert + sys.exit(1) + f = open(options.cert) + options.cert = f.read() + return options + +if __name__ == '__main__': + opts = validate_opts(get_opts()) + register(opts.url, opts.apikey, opts.secretkey, opts.cert)