-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaegir_6.x-1.1_install.py
221 lines (179 loc) · 9.83 KB
/
aegir_6.x-1.1_install.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#! /usr/bin/env python
#
# Libcloud tool to build Rackspace VPS, install Aegir and build makefile-based Drupal projects
# Designed for use as a Jenkins project, works from CLI just fine though
# Dependencies: libcloud, fabric
#
# Written by Miguel Jacq (mig5) of Green Bee Digital and the Aegir project
# http://greenbeedigital.com.au
#
from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver
from libcloud.compute.ssh import SSHClient, ParamikoSSHClient
import libcloud.security
import os, sys, string, ConfigParser, socket, time, random, traceback
import fabric.api as fabric
libcloud.security.VERIFY_SSL_CERT = True
# Fetch some values from the config file
config = ConfigParser.RawConfigParser()
config.read(os.path.expanduser("~/aegir_ci/aegir_ci_config.ini"))
# Try to abstract the provider here, as we may end up supporting others
# Theoretically since we are using libcloud, it should support any
# provider that supports the deploy_node function (Amazon EC2 doesn't)
provider = config.get('Aegir', 'provider')
provider_driver = config.get(provider, 'driver')
# API credentials
user = config.get(provider, 'user')
key = config.get(provider, 'key')
# Preferred image and size
config_distro = config.get(provider, 'distro')
config_size = config.get(provider, 'size')
# These are used as options to Aegir during install
email = config.get('Aegir', 'email')
# A trusted IP to grant access to in the firewall
trusted_ip = config.get('Aegir', 'trusted_ip')
# Where our build files are
builds_repo = config.get('Aegir', 'builds_repo')
hostname = 'aegirjenkins-%d' % random.randrange(0, 10001, 2)
# Some basic dependency tests for this job itself
def dependency_check():
try:
import fabric
except ImportError:
print "You need Fabric installed (apt-get install fabric)"
sys.exit(1)
# Helper script to generate a random password
def gen_passwd():
N=8
return ''.join(random.choice(string.ascii_letters + string.digits) for x in range(N))
# Install dependencies for Aegir
def fab_install_dependencies(newpass):
fabric.run("apt-get update", pty=True)
fabric.run("echo 'postfix postfix/main_mailer_type select Internet Site' | debconf-set-selections", pty=True)
fabric.run("echo 'postfix postfix/mailname string $HOSTNAME' | debconf-set-selections", pty=True)
fabric.run("echo 'postfix postfix/destinations string localhost.localdomain, localhost' | debconf-set-selections", pty=True)
fabric.run("echo mysql-server mysql-server/root_password select %s | debconf-set-selections" % newpass, pty=True)
fabric.run("echo mysql-server mysql-server/root_password_again select %s | debconf-set-selections" % newpass, pty=True)
fabric.run("apt-get -y install apache2 php5 php5-cli php5-gd php5-mysql postfix mysql-server sudo rsync git-core unzip", pty=True)
# Prepare a basic firewall
def fab_prepare_firewall():
print "===> Setting a little firewall"
fabric.run("iptables -I INPUT -s %s -p tcp --dport 22 -j ACCEPT; iptables -I INPUT -s %s -p tcp --dport 80 -j ACCEPT; iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT; iptables --policy INPUT DROP" % (trusted_ip, trusted_ip), pty=True)
# Fabric command to set some Apache requirements
def fab_prepare_apache():
print "===> Preparing Apache"
fabric.run("a2enmod rewrite", pty=True)
fabric.run("ln -s /var/aegir/config/apache.conf /etc/apache2/conf.d/aegir.conf", pty=True)
# Fabric command to raise PHP CLI memory limit (for Drupal 7 / OpenAtrum)
def fab_prepare_php():
print "===> Preparing PHP"
fabric.run("sed -i s/'memory_limit = 32M'/'memory_limit = 256M'/ /etc/php5/cli/php.ini", pty=True)
# Fabric command to add the aegir user and to sudoers also
def fab_prepare_user():
print "===> Preparing the Aegir user"
fabric.run("useradd -r -U -d /var/aegir -m -G www-data aegir", pty=True)
fabric.run("echo 'aegir ALL=NOPASSWD: /usr/sbin/apache2ctl' >> /etc/sudoers", pty=True)
# Fabric command to fetch Drush
def fab_fetch_drush():
print "===> Fetching Drush"
fabric.run("su - -s /bin/sh aegir -c 'wget http://ftp.drupal.org/files/projects/drush-7.x-4.4.tar.gz'", pty=True)
fabric.run("su - -s /bin/sh aegir -c' gunzip -c drush-7.x-4.4.tar.gz | tar -xf - '", pty=True)
fabric.run("su - -s /bin/sh aegir -c 'rm /var/aegir/drush-7.x-4.4.tar.gz'", pty=True)
# Fabric command to fetch Provision
def fab_fetch_provision():
print "===> Fetching Provision"
fabric.run("su - -s /bin/sh aegir -c 'php /var/aegir/drush/drush.php dl -y --destination=/var/aegir/.drush provision-6.x-1.1'", pty=True)
# Fabric command to run the install.sh aegir script
def fab_hostmaster_install(domain, email, newpass):
print "===> Running hostmaster-install"
fabric.run("su - -s /bin/sh aegir -c 'php /var/aegir/drush/drush.php hostmaster-install %s --client_email=%s --aegir_db_pass=%s --yes'" % (domain, email, newpass), pty=True)
fabric.run("su - -s /bin/sh aegir -c 'php /var/aegir/drush/drush.php -y @hostmaster vset hosting_queue_tasks_frequency 1'", pty=True)
fab_run_dispatch()
# Download, import and verify platforms
def fab_install_platform(platform_name):
fabric.run("su - -s /bin/sh aegir -c 'php /var/aegir/drush/drush.php make %s/%s.build /var/aegir/platforms/%s'" % (builds_repo, platform_name, platform_name), pty=True)
fabric.run("su - -s /bin/sh aegir -c 'php /var/aegir/drush/drush.php --root=\'/var/aegir/platforms/%s\' provision-save \'@platform_%s\' --context_type=\'platform\''" % (platform_name, platform_name), pty=True)
fabric.run("su - -s /bin/sh aegir -c 'php /var/aegir/drush/drush.php @hostmaster hosting-import \'@platform_%s\''" % platform_name, pty=True)
fab_run_dispatch()
# Install a site
def fab_install_site(platform_name, profile):
fabric.run("su - -s /bin/sh aegir -c '/var/aegir/drush/drush.php --uri=\'%s.mig5.net\' provision-save \'@%s.mig5.net\' --context_type=\'site\' --platform=\'@platform_%s\' --profile=\'%s\' --db_server=\'@server_localhost\''" % (platform_name, platform_name, platform_name, profile), pty=True)
fabric.run("su - -s /bin/sh aegir -c '/var/aegir/drush/drush.php @%s.mig5.net provision-install'" % platform_name, pty=True)
fabric.run("su - -s /bin/sh aegir -c '/var/aegir/drush/drush.php @hostmaster hosting-task @platform_%s verify'" % platform_name, pty=True)
fab_run_dispatch()
# Force the dispatcher
def fab_run_dispatch():
fabric.run("su - -s /bin/sh aegir -c 'php /var/aegir/drush/drush.php @hostmaster hosting-dispatch'", pty=True)
def run_platform_tests():
print "===> Installing some common platforms"
fab_install_platform('drupal6')
fab_install_platform('drupal7')
fab_install_platform('openatrium')
def run_site_tests():
print "===> Installing some sites"
fab_install_site('drupal6', 'default')
fab_install_site('drupal7', 'standard')
fab_install_site('openatrium', 'openatrium')
def main():
# Run some tests
dependency_check()
# Set a random password for the MySQL root user.
newpass = gen_passwd()
# Make a new connection
Driver = get_driver( getattr(Provider, provider_driver) )
conn = Driver(user, key)
# Get a list of the available images and sizes
images = conn.list_images()
sizes = conn.list_sizes()
# We'll use the distro and size from the config ini
preferred_image = [image for image in images if config_distro in image.name]
preferred_size = [size for size in sizes if config_size in size.name]
# Create and deploy a new server now, and run the deployment steps defined above
print "Provisioning server and running deployment processes"
try:
node = conn.create_node(name=hostname, image=preferred_image[0], size=preferred_size[0])
except:
print "Error provisioning new node"
traceback.print_exc()
sys.exit(1)
print "Provisioning complete, you can ssh as root to %s" % node.public_ip[0]
if node.extra.get('password'):
print "The root user's password is %s" % node.extra.get('password')
password = node.extra.get('password')
# VPS aren't immediately available after provisioning sometimes
# Let's try and loop until the node state is 'Running'.
var = 1
while var == 1:
nodes = conn.list_nodes()
for node in nodes:
if hostname in node.name:
if node.state == 0:
# Setting some parameters for fabric
domain = socket.getfqdn(node.public_ip[0])
fabric.env.host_string = domain
fabric.env.user = 'root'
fabric.env.password = password
try:
fab_prepare_firewall()
fab_install_dependencies(newpass)
fab_prepare_apache()
fab_prepare_php()
fab_prepare_user()
fab_fetch_drush()
fab_fetch_provision()
fab_hostmaster_install(domain, email, newpass)
run_platform_tests()
run_site_tests()
print "===> Destroying this node"
conn.destroy_node(node)
var = 2
break
except:
traceback.print_exc()
sys.exit(1)
else:
print "New host doesn't seem booted yet. Sleeping and will try again in 20 secs..."
time.sleep(20)
continue
if __name__ == "__main__":
main()