Statistics
| Branch: | Tag: | Revision:

root / snf-deploy / snfdeploy / __init__.py @ b570ce97

History | View | Annotate | Download (17.4 kB)

1 0ac84a9a Dimitris Aragiorgis
import json
2 0ac84a9a Dimitris Aragiorgis
import time
3 0ac84a9a Dimitris Aragiorgis
import ipaddr
4 0ac84a9a Dimitris Aragiorgis
import os
5 0ac84a9a Dimitris Aragiorgis
import signal
6 0ac84a9a Dimitris Aragiorgis
import time
7 0ac84a9a Dimitris Aragiorgis
import ConfigParser
8 0ac84a9a Dimitris Aragiorgis
import argparse
9 0ac84a9a Dimitris Aragiorgis
import sys
10 0ac84a9a Dimitris Aragiorgis
import re
11 0ac84a9a Dimitris Aragiorgis
import random
12 0ac84a9a Dimitris Aragiorgis
import subprocess
13 0ac84a9a Dimitris Aragiorgis
import imp
14 0ac84a9a Dimitris Aragiorgis
import ast
15 0ac84a9a Dimitris Aragiorgis
from snfdeploy.lib import *
16 0ac84a9a Dimitris Aragiorgis
17 0ac84a9a Dimitris Aragiorgis
def print_available_actions(command):
18 0ac84a9a Dimitris Aragiorgis
19 0ac84a9a Dimitris Aragiorgis
  if command == "vcluster":
20 0ac84a9a Dimitris Aragiorgis
    print """
21 0ac84a9a Dimitris Aragiorgis
Usage: snf-deploy vcluster
22 0ac84a9a Dimitris Aragiorgis

23 0ac84a9a Dimitris Aragiorgis
  Run the following actions concerning the local virtual cluster:
24 0ac84a9a Dimitris Aragiorgis

25 0ac84a9a Dimitris Aragiorgis
    - Download base image and create additional disk (if --create-extra-disk is passed)
26 0ac84a9a Dimitris Aragiorgis
    - Does all the network related actions (bridge, iptables, NAT)
27 0ac84a9a Dimitris Aragiorgis
    - Launches dnsmasq for dhcp server on bridge
28 0ac84a9a Dimitris Aragiorgis
    - Creates the virtual cluster (with kvm)
29 0ac84a9a Dimitris Aragiorgis

30 0ac84a9a Dimitris Aragiorgis
  """
31 0ac84a9a Dimitris Aragiorgis
32 0ac84a9a Dimitris Aragiorgis
  if command == "prepare":
33 0ac84a9a Dimitris Aragiorgis
    print """
34 0ac84a9a Dimitris Aragiorgis
Usage: snf-deploy prepare
35 0ac84a9a Dimitris Aragiorgis

36 0ac84a9a Dimitris Aragiorgis
  Run the following actions concerning deployment preparation:
37 0ac84a9a Dimitris Aragiorgis

38 0ac84a9a Dimitris Aragiorgis
    - Setup an internal Domain Name Server
39 0ac84a9a Dimitris Aragiorgis
    - Tweak hosts and add ssh keys
40 0ac84a9a Dimitris Aragiorgis
    - Check network setup
41 0ac84a9a Dimitris Aragiorgis
    - Setup apt repository and apt-get update
42 0ac84a9a Dimitris Aragiorgis
    - Setup the nfs server and clients among all nodes
43 0ac84a9a Dimitris Aragiorgis

44 0ac84a9a Dimitris Aragiorgis
  """
45 0ac84a9a Dimitris Aragiorgis
46 0ac84a9a Dimitris Aragiorgis
  if command == "backend":
47 0ac84a9a Dimitris Aragiorgis
    print """
48 0ac84a9a Dimitris Aragiorgis
Usage: snf-deploy backend [update]
49 0ac84a9a Dimitris Aragiorgis

50 0ac84a9a Dimitris Aragiorgis
  Run the following actions concerning a ganeti backend:
51 0ac84a9a Dimitris Aragiorgis

52 0ac84a9a Dimitris Aragiorgis
    - Create and add a backend to cyclades
53 0ac84a9a Dimitris Aragiorgis
    - Does all the net-infra specific actions in backend nodes
54 0ac84a9a Dimitris Aragiorgis
      (create/connect bridges, iptables..)
55 0ac84a9a Dimitris Aragiorgis
    - Does all the storage-infra specific actions in backend nodes
56 0ac84a9a Dimitris Aragiorgis
      depending on the --extra-disk option (create VG, enable lvm/drbd storage..)
57 0ac84a9a Dimitris Aragiorgis

58 0ac84a9a Dimitris Aragiorgis
    or
59 0ac84a9a Dimitris Aragiorgis

60 0ac84a9a Dimitris Aragiorgis
    - Update packages in an already registered backend in cyclades.
61 0ac84a9a Dimitris Aragiorgis

62 0ac84a9a Dimitris Aragiorgis
  """
63 0ac84a9a Dimitris Aragiorgis
64 0ac84a9a Dimitris Aragiorgis
  if command == "run":
65 0ac84a9a Dimitris Aragiorgis
    print """
66 0ac84a9a Dimitris Aragiorgis
Usage: snf-deploy run <action> [<action>...]
67 0ac84a9a Dimitris Aragiorgis

68 0ac84a9a Dimitris Aragiorgis
  Run any of the following fabric commands:
69 0ac84a9a Dimitris Aragiorgis

70 0ac84a9a Dimitris Aragiorgis

71 0ac84a9a Dimitris Aragiorgis
    Setup commands:        Init commands:                Admin commands:
72 0ac84a9a Dimitris Aragiorgis
      setup_apache           add_pools                     activate_user
73 0ac84a9a Dimitris Aragiorgis
      setup_apt              add_rapi_user                 add_backend
74 0ac84a9a Dimitris Aragiorgis
      setup_astakos          add_nodes                     add_image_locally
75 0ac84a9a Dimitris Aragiorgis
      setup_cms              astakos_loaddata              add_network
76 0ac84a9a Dimitris Aragiorgis
      setup_common           astakos_register_services     add_ns
77 0ac84a9a Dimitris Aragiorgis
      setup_cyclades         cms_loaddata                  add_user
78 0ac84a9a Dimitris Aragiorgis
      setup_db               cyclades_loaddata             connect_bridges
79 0ac84a9a Dimitris Aragiorgis
      setup_ganeti           enable_drbd                   create_bridges
80 0ac84a9a Dimitris Aragiorgis
      setup_gtools           init_cluster                  create_vlans
81 0ac84a9a Dimitris Aragiorgis
      setup_gunicorn         setup_nfs_clients             destroy_db
82 0ac84a9a Dimitris Aragiorgis
      setup_hosts            setup_nfs_server              get_auth_token_from_db
83 0ac84a9a Dimitris Aragiorgis
      setup_image_helper     update_ns_for_ganeti          get_service_details
84 0ac84a9a Dimitris Aragiorgis
      setup_image_host                                     gnt_instance_add
85 0ac84a9a Dimitris Aragiorgis
      setup_iptables                                       gnt_network_add
86 0ac84a9a Dimitris Aragiorgis
      setup_kamaki         Test commands:                  register_image
87 0ac84a9a Dimitris Aragiorgis
      setup_lvm              test                          restart_services
88 0ac84a9a Dimitris Aragiorgis
      setup_mq                                             setup_drbd_dparams
89 0ac84a9a Dimitris Aragiorgis
      setup_net_infra
90 0ac84a9a Dimitris Aragiorgis
      setup_network
91 0ac84a9a Dimitris Aragiorgis
      setup_ns
92 0ac84a9a Dimitris Aragiorgis
      setup_pithos
93 0ac84a9a Dimitris Aragiorgis
      setup_pithos_dir
94 0ac84a9a Dimitris Aragiorgis
      setup_router
95 0ac84a9a Dimitris Aragiorgis
      setup_vncauthproxy
96 0ac84a9a Dimitris Aragiorgis
      setup_webproject
97 0ac84a9a Dimitris Aragiorgis

98 0ac84a9a Dimitris Aragiorgis
  """
99 0ac84a9a Dimitris Aragiorgis
100 0ac84a9a Dimitris Aragiorgis
  sys.exit(1)
101 0ac84a9a Dimitris Aragiorgis
102 0ac84a9a Dimitris Aragiorgis
103 0ac84a9a Dimitris Aragiorgis
def create_dnsmasq_files(args, env):
104 0ac84a9a Dimitris Aragiorgis
105 0ac84a9a Dimitris Aragiorgis
  print("Customize dnsmasq..")
106 0ac84a9a Dimitris Aragiorgis
  out = env.dns
107 0ac84a9a Dimitris Aragiorgis
108 0ac84a9a Dimitris Aragiorgis
  hostsfile = open(out + "/dhcp-hostsfile", "w")
109 0ac84a9a Dimitris Aragiorgis
  optsfile = open(out + "/dhcp-optsfile", "w")
110 0ac84a9a Dimitris Aragiorgis
  conffile = open(out + "/conf-file", "w")
111 0ac84a9a Dimitris Aragiorgis
112 0ac84a9a Dimitris Aragiorgis
  for node, info in env.nodes_info.iteritems():
113 0ac84a9a Dimitris Aragiorgis
    # serve ip and hostname to nodes
114 0ac84a9a Dimitris Aragiorgis
    hostsfile.write("%s,%s,%s,2m\n" % (info.mac, info.ip, info.hostname))
115 0ac84a9a Dimitris Aragiorgis
116 0ac84a9a Dimitris Aragiorgis
  hostsfile.write("52:54:56:*:*:*,ignore\n")
117 0ac84a9a Dimitris Aragiorgis
118 0ac84a9a Dimitris Aragiorgis
  # Netmask
119 0ac84a9a Dimitris Aragiorgis
  optsfile.write("1,%s\n" % env.net.netmask)
120 0ac84a9a Dimitris Aragiorgis
  # Gateway
121 0ac84a9a Dimitris Aragiorgis
  optsfile.write("3,%s\n" % env.gateway)
122 0ac84a9a Dimitris Aragiorgis
  # Namesevers
123 0ac84a9a Dimitris Aragiorgis
  optsfile.write("6,%s\n" % "8.8.8.8")
124 0ac84a9a Dimitris Aragiorgis
125 0ac84a9a Dimitris Aragiorgis
  dnsconf = """
126 0ac84a9a Dimitris Aragiorgis
user=dnsmasq
127 0ac84a9a Dimitris Aragiorgis
bogus-priv
128 0ac84a9a Dimitris Aragiorgis
no-poll
129 0ac84a9a Dimitris Aragiorgis
no-negcache
130 0ac84a9a Dimitris Aragiorgis
leasefile-ro
131 0ac84a9a Dimitris Aragiorgis
bind-interfaces
132 0ac84a9a Dimitris Aragiorgis
except-interface=lo
133 0ac84a9a Dimitris Aragiorgis
dhcp-fqdn
134 0ac84a9a Dimitris Aragiorgis
no-resolv
135 0ac84a9a Dimitris Aragiorgis
# disable DNS
136 0ac84a9a Dimitris Aragiorgis
port=0
137 0ac84a9a Dimitris Aragiorgis
""".format(env.ns.ip)
138 0ac84a9a Dimitris Aragiorgis
139 0ac84a9a Dimitris Aragiorgis
  dnsconf += """
140 0ac84a9a Dimitris Aragiorgis
# serve domain and search domain for resolv.conf
141 0ac84a9a Dimitris Aragiorgis
domain={5}
142 0ac84a9a Dimitris Aragiorgis
interface={0}
143 0ac84a9a Dimitris Aragiorgis
dhcp-hostsfile={1}
144 0ac84a9a Dimitris Aragiorgis
dhcp-optsfile={2}
145 0ac84a9a Dimitris Aragiorgis
dhcp-range={0},{4},static,2m
146 0ac84a9a Dimitris Aragiorgis
""".format(env.bridge, hostsfile.name, optsfile.name,
147 0ac84a9a Dimitris Aragiorgis
           env.domain, env.net.network, env.domain)
148 0ac84a9a Dimitris Aragiorgis
149 0ac84a9a Dimitris Aragiorgis
  conffile.write(dnsconf)
150 0ac84a9a Dimitris Aragiorgis
151 0ac84a9a Dimitris Aragiorgis
  hostsfile.close()
152 0ac84a9a Dimitris Aragiorgis
  optsfile.close()
153 0ac84a9a Dimitris Aragiorgis
  conffile.close()
154 0ac84a9a Dimitris Aragiorgis
155 0ac84a9a Dimitris Aragiorgis
156 0ac84a9a Dimitris Aragiorgis
def cleanup(args, env):
157 0ac84a9a Dimitris Aragiorgis
  print("Cleaning up bridge, NAT, resolv.conf...")
158 0ac84a9a Dimitris Aragiorgis
159 0ac84a9a Dimitris Aragiorgis
  for f in os.listdir(env.run):
160 0ac84a9a Dimitris Aragiorgis
    if re.search(".pid$", f):
161 0ac84a9a Dimitris Aragiorgis
      check_pidfile(os.path.join(env.run, f))
162 0ac84a9a Dimitris Aragiorgis
163 0ac84a9a Dimitris Aragiorgis
  create_dir(env.run, True)
164 0ac84a9a Dimitris Aragiorgis
  # create_dir(env.cmd, True)
165 0ac84a9a Dimitris Aragiorgis
  cmd = """
166 0ac84a9a Dimitris Aragiorgis
  iptables -t nat -D POSTROUTING -s {0} -o {1} -j MASQUERADE
167 0ac84a9a Dimitris Aragiorgis
  echo 0 > /proc/sys/net/ipv4/ip_forward
168 0ac84a9a Dimitris Aragiorgis
  iptables -D INPUT -i {2} -j ACCEPT
169 0ac84a9a Dimitris Aragiorgis
  iptables -D FORWARD -i {2} -j ACCEPT
170 0ac84a9a Dimitris Aragiorgis
  iptables -D OUTPUT -o {2} -j ACCEPT
171 0ac84a9a Dimitris Aragiorgis
  """.format(env.subnet, get_default_route()[1], env.bridge)
172 0ac84a9a Dimitris Aragiorgis
  os.system(cmd)
173 0ac84a9a Dimitris Aragiorgis
174 0ac84a9a Dimitris Aragiorgis
  cmd = """
175 0ac84a9a Dimitris Aragiorgis
  ip link show {0} && ip addr del {1}/{2} dev {0}
176 0ac84a9a Dimitris Aragiorgis
  sleep 1
177 0ac84a9a Dimitris Aragiorgis
  ip link set {0} down
178 0ac84a9a Dimitris Aragiorgis
  sleep 1
179 0ac84a9a Dimitris Aragiorgis
  brctl delbr {0}
180 0ac84a9a Dimitris Aragiorgis
  """.format(env.bridge, env.gateway, env.net.prefixlen)
181 0ac84a9a Dimitris Aragiorgis
  os.system(cmd)
182 0ac84a9a Dimitris Aragiorgis
183 0ac84a9a Dimitris Aragiorgis
184 0ac84a9a Dimitris Aragiorgis
def network(args, env):
185 0ac84a9a Dimitris Aragiorgis
  print("Create bridge..Add gateway IP..Activate NAT..Append NS options to resolv.conf")
186 0ac84a9a Dimitris Aragiorgis
187 0ac84a9a Dimitris Aragiorgis
  cmd = """
188 0ac84a9a Dimitris Aragiorgis
  ! ip link show {0} && brctl addbr {0} && ip link set {0} up
189 0ac84a9a Dimitris Aragiorgis
  sleep 1
190 0ac84a9a Dimitris Aragiorgis
  ip link set promisc on dev {0}
191 0ac84a9a Dimitris Aragiorgis
  ip addr add {1}/{2} dev {0}
192 0ac84a9a Dimitris Aragiorgis
  """.format(env.bridge, env.gateway, env.net.prefixlen)
193 0ac84a9a Dimitris Aragiorgis
  os.system(cmd)
194 0ac84a9a Dimitris Aragiorgis
195 0ac84a9a Dimitris Aragiorgis
  cmd = """
196 0ac84a9a Dimitris Aragiorgis
  iptables -t nat -A POSTROUTING -s {0} -o {1} -j MASQUERADE
197 0ac84a9a Dimitris Aragiorgis
  echo 1 > /proc/sys/net/ipv4/ip_forward
198 0ac84a9a Dimitris Aragiorgis
  iptables -I INPUT 1 -i {2} -j ACCEPT
199 0ac84a9a Dimitris Aragiorgis
  iptables -I FORWARD 1 -i {2} -j ACCEPT
200 0ac84a9a Dimitris Aragiorgis
  iptables -I OUTPUT 1 -o {2} -j ACCEPT
201 0ac84a9a Dimitris Aragiorgis
  """.format(env.subnet, get_default_route()[1], env.bridge)
202 0ac84a9a Dimitris Aragiorgis
  os.system(cmd)
203 0ac84a9a Dimitris Aragiorgis
204 0ac84a9a Dimitris Aragiorgis
205 0ac84a9a Dimitris Aragiorgis
def image(args, env):
206 0ac84a9a Dimitris Aragiorgis
  if env.os == "ubuntu":
207 0ac84a9a Dimitris Aragiorgis
    url = env.ubuntu_image_url
208 0ac84a9a Dimitris Aragiorgis
  else:
209 0ac84a9a Dimitris Aragiorgis
    url = env.squeeze_image_url
210 0ac84a9a Dimitris Aragiorgis
211 0ac84a9a Dimitris Aragiorgis
  disk0 = "{0}/{1}.disk0".format(env.images, env.os)
212 0ac84a9a Dimitris Aragiorgis
  disk1 = "{0}/{1}.disk1".format(env.images, env.os)
213 0ac84a9a Dimitris Aragiorgis
214 0ac84a9a Dimitris Aragiorgis
  if url and not os.path.exists(disk0):
215 0ac84a9a Dimitris Aragiorgis
    cmd = "wget {0} -O {1}".format(url, disk0)
216 0ac84a9a Dimitris Aragiorgis
    os.system(cmd)
217 0ac84a9a Dimitris Aragiorgis
218 0ac84a9a Dimitris Aragiorgis
  if ast.literal_eval(env.create_extra_disk) and not os.path.exists(disk1):
219 0ac84a9a Dimitris Aragiorgis
    if env.lvg:
220 0ac84a9a Dimitris Aragiorgis
      cmd = "lvcreate -L30G -n{0}.disk1 {1}".format(env.os, env.lvg)
221 0ac84a9a Dimitris Aragiorgis
      os.system(cmd)
222 0ac84a9a Dimitris Aragiorgis
      cmd = "ln -s /dev/{0}/{1}.disk1 {2}".format(env.lvg, env.os, disk1)
223 0ac84a9a Dimitris Aragiorgis
      os.system(cmd)
224 0ac84a9a Dimitris Aragiorgis
    else:
225 0ac84a9a Dimitris Aragiorgis
      cmd = "dd if=/dev/zero of={0} bs=10M count=3000".format(disk1)
226 0ac84a9a Dimitris Aragiorgis
      os.system(cmd)
227 0ac84a9a Dimitris Aragiorgis
228 0ac84a9a Dimitris Aragiorgis
229 0ac84a9a Dimitris Aragiorgis
def fabcommand(args, env, actions, nodes=[]):
230 0ac84a9a Dimitris Aragiorgis
  levels = ["status", "aborts", "warnings", "running",
231 0ac84a9a Dimitris Aragiorgis
            "stdout", "stderr", "user", "debug"]
232 0ac84a9a Dimitris Aragiorgis
233 0ac84a9a Dimitris Aragiorgis
  level_aliases = {
234 0ac84a9a Dimitris Aragiorgis
    "output": ["stdout", "stderr"],
235 0ac84a9a Dimitris Aragiorgis
    "everything": ["warnings", "running", "user", "output"]
236 0ac84a9a Dimitris Aragiorgis
    }
237 0ac84a9a Dimitris Aragiorgis
238 0ac84a9a Dimitris Aragiorgis
  hide = ",".join(level_aliases["everything"])
239 0ac84a9a Dimitris Aragiorgis
  show = None
240 0ac84a9a Dimitris Aragiorgis
241 0ac84a9a Dimitris Aragiorgis
  if args.verbose == 1:
242 0ac84a9a Dimitris Aragiorgis
    show = ",".join(levels[:3])
243 0ac84a9a Dimitris Aragiorgis
    hide = ",".join(levels[3:])
244 0ac84a9a Dimitris Aragiorgis
  elif args.verbose == 2:
245 0ac84a9a Dimitris Aragiorgis
    show = ",".join(levels[:4])
246 0ac84a9a Dimitris Aragiorgis
    hide = ",".join(levels[4:])
247 0ac84a9a Dimitris Aragiorgis
  elif args.verbose >= 3 or args.debug:
248 0ac84a9a Dimitris Aragiorgis
    show = ",".join(levels)
249 0ac84a9a Dimitris Aragiorgis
    hide = None
250 0ac84a9a Dimitris Aragiorgis
251 0ac84a9a Dimitris Aragiorgis
  if args.ssh_key:
252 0ac84a9a Dimitris Aragiorgis
    fabcmd = "fab -i %s " % args.ssh_key
253 0ac84a9a Dimitris Aragiorgis
  else:
254 0ac84a9a Dimitris Aragiorgis
    fabcmd = "fab "
255 0ac84a9a Dimitris Aragiorgis
256 0ac84a9a Dimitris Aragiorgis
  fabcmd += " --fabfile {4}/fabfile.py \
257 1bc6d467 Dionysis Grigoropoulos
setup_env:confdir={0},packages={1},templates={2},cluster_name={3},\
258 1bc6d467 Dionysis Grigoropoulos
autoconf={5}, disable_colors={6} \
259 1bc6d467 Dionysis Grigoropoulos
".format(args.confdir, env.packages, env.templates, args.cluster_name,
260 1bc6d467 Dionysis Grigoropoulos
         env.lib, args.autoconf, args.disable_colors)
261 0ac84a9a Dimitris Aragiorgis
262 0ac84a9a Dimitris Aragiorgis
  if nodes:
263 0ac84a9a Dimitris Aragiorgis
    hosts = [env.nodes_info[n].hostname for n in nodes]
264 0ac84a9a Dimitris Aragiorgis
    actions = [a + ':hosts="%s"' % ";".join(hosts) for a in actions]
265 0ac84a9a Dimitris Aragiorgis
266 0ac84a9a Dimitris Aragiorgis
  extra = " ".join(actions)
267 0ac84a9a Dimitris Aragiorgis
268 0ac84a9a Dimitris Aragiorgis
  fabcmd += extra
269 0ac84a9a Dimitris Aragiorgis
270 0ac84a9a Dimitris Aragiorgis
  if show:
271 0ac84a9a Dimitris Aragiorgis
    fabcmd += " --show %s " % show
272 0ac84a9a Dimitris Aragiorgis
  if hide:
273 0ac84a9a Dimitris Aragiorgis
    fabcmd += " --hide %s " % hide
274 0ac84a9a Dimitris Aragiorgis
275 0ac84a9a Dimitris Aragiorgis
  # print("snf-deploy run " + " ".join(actions) + " -vvv")
276 0ac84a9a Dimitris Aragiorgis
  print(fabcmd)
277 0ac84a9a Dimitris Aragiorgis
278 0ac84a9a Dimitris Aragiorgis
  if not args.dry_run:
279 0ac84a9a Dimitris Aragiorgis
    os.system(fabcmd)
280 0ac84a9a Dimitris Aragiorgis
281 0ac84a9a Dimitris Aragiorgis
282 0ac84a9a Dimitris Aragiorgis
def cluster(args, env):
283 0ac84a9a Dimitris Aragiorgis
  for hostname, mac in env.node2mac.iteritems():
284 0ac84a9a Dimitris Aragiorgis
    launch_vm(args, env, hostname, mac)
285 0ac84a9a Dimitris Aragiorgis
286 0ac84a9a Dimitris Aragiorgis
  time.sleep(30)
287 0ac84a9a Dimitris Aragiorgis
  os.system("reset")
288 0ac84a9a Dimitris Aragiorgis
289 0ac84a9a Dimitris Aragiorgis
290 0ac84a9a Dimitris Aragiorgis
def launch_vm(args, env, hostname, mac):
291 0ac84a9a Dimitris Aragiorgis
  check_pidfile("%s/%s.pid" % (env.run, hostname))
292 0ac84a9a Dimitris Aragiorgis
293 0ac84a9a Dimitris Aragiorgis
  print("Launching cluster node {0}..".format(hostname))
294 0ac84a9a Dimitris Aragiorgis
  os.environ["BRIDGE"] = env.bridge
295 0ac84a9a Dimitris Aragiorgis
  if args.vnc:
296 0ac84a9a Dimitris Aragiorgis
    graphics = "-vnc :{0}".format(random.randint(1, 1000))
297 0ac84a9a Dimitris Aragiorgis
  else:
298 0ac84a9a Dimitris Aragiorgis
    graphics = "-nographic"
299 0ac84a9a Dimitris Aragiorgis
300 0ac84a9a Dimitris Aragiorgis
  disks = """ \
301 0ac84a9a Dimitris Aragiorgis
-drive file={0}/{1}.disk0,format=raw,if=none,id=drive0,snapshot=on \
302 0ac84a9a Dimitris Aragiorgis
-device virtio-blk-pci,drive=drive0,id=virtio-blk-pci.0 \
303 0ac84a9a Dimitris Aragiorgis
  """.format(env.images, env.os)
304 0ac84a9a Dimitris Aragiorgis
305 0ac84a9a Dimitris Aragiorgis
  if ast.literal_eval(env.create_extra_disk):
306 0ac84a9a Dimitris Aragiorgis
    disks += """ \
307 0ac84a9a Dimitris Aragiorgis
-drive file={0}/{1}.disk1,format=raw,if=none,id=drive1,snapshot=on \
308 0ac84a9a Dimitris Aragiorgis
-device virtio-blk-pci,drive=drive1,id=virtio-blk-pci.1 \
309 0ac84a9a Dimitris Aragiorgis
  """.format(env.images, env.os)
310 0ac84a9a Dimitris Aragiorgis
311 0ac84a9a Dimitris Aragiorgis
312 0ac84a9a Dimitris Aragiorgis
  ifup = env.lib + "/ifup"
313 0ac84a9a Dimitris Aragiorgis
  nics = """ \
314 0ac84a9a Dimitris Aragiorgis
-netdev tap,id=netdev0,script={0},downscript=no \
315 0ac84a9a Dimitris Aragiorgis
-device virtio-net-pci,mac={1},netdev=netdev0,id=virtio-net-pci.0 \
316 0ac84a9a Dimitris Aragiorgis
-netdev tap,id=netdev1,script={0},downscript=no \
317 0ac84a9a Dimitris Aragiorgis
-device virtio-net-pci,mac={2},netdev=netdev1,id=virtio-net-pci.1 \
318 0ac84a9a Dimitris Aragiorgis
-netdev tap,id=netdev2,script={0},downscript=no \
319 0ac84a9a Dimitris Aragiorgis
-device virtio-net-pci,mac={3},netdev=netdev2,id=virtio-net-pci.2 \
320 0ac84a9a Dimitris Aragiorgis
  """.format(ifup, mac, randomMAC(), randomMAC())
321 0ac84a9a Dimitris Aragiorgis
322 0ac84a9a Dimitris Aragiorgis
  cmd = """
323 0ac84a9a Dimitris Aragiorgis
/usr/bin/kvm -name {0} -pidfile {1}/{0}.pid -balloon virtio -daemonize \
324 0ac84a9a Dimitris Aragiorgis
-monitor unix:{1}/{0}.monitor,server,nowait -usbdevice tablet -boot c \
325 0ac84a9a Dimitris Aragiorgis
{2} \
326 0ac84a9a Dimitris Aragiorgis
{3} \
327 0ac84a9a Dimitris Aragiorgis
-m {4} -smp {5} {6} \
328 0ac84a9a Dimitris Aragiorgis
  """.format(hostname, env.run, disks, nics, args.mem, args.smp, graphics)
329 0ac84a9a Dimitris Aragiorgis
  print cmd
330 0ac84a9a Dimitris Aragiorgis
  os.system(cmd)
331 0ac84a9a Dimitris Aragiorgis
332 0ac84a9a Dimitris Aragiorgis
333 0ac84a9a Dimitris Aragiorgis
def dnsmasq(args, env):
334 0ac84a9a Dimitris Aragiorgis
  check_pidfile(env.run + "/dnsmasq.pid")
335 0ac84a9a Dimitris Aragiorgis
  cmd = "dnsmasq --pid-file={0}/dnsmasq.pid --conf-file={1}/conf-file".format(env.run, env.dns)
336 0ac84a9a Dimitris Aragiorgis
  os.system(cmd)
337 0ac84a9a Dimitris Aragiorgis
338 0ac84a9a Dimitris Aragiorgis
339 0ac84a9a Dimitris Aragiorgis
def get_packages(args, env):
340 0ac84a9a Dimitris Aragiorgis
  if env.package_url:
341 0ac84a9a Dimitris Aragiorgis
    os.system("rm {0}/*.deb".format(env.packages))
342 0ac84a9a Dimitris Aragiorgis
    os.system("wget -r --level=1 -nH --no-parent --cut-dirs=4 {0} -P {1}".format(env.package_url, env.packages))
343 0ac84a9a Dimitris Aragiorgis
344 0ac84a9a Dimitris Aragiorgis
345 0ac84a9a Dimitris Aragiorgis
def parse_options():
346 0ac84a9a Dimitris Aragiorgis
  parser = argparse.ArgumentParser()
347 0ac84a9a Dimitris Aragiorgis
348 0ac84a9a Dimitris Aragiorgis
  # Directories to load/store config
349 0ac84a9a Dimitris Aragiorgis
  parser.add_argument("-c", dest="confdir",
350 0ac84a9a Dimitris Aragiorgis
                      default="/etc/snf-deploy",
351 0ac84a9a Dimitris Aragiorgis
                      help="Directory to find default configuration")
352 0ac84a9a Dimitris Aragiorgis
  parser.add_argument("--dry-run", dest="dry_run",
353 0ac84a9a Dimitris Aragiorgis
                      default=False, action="store_true",
354 0ac84a9a Dimitris Aragiorgis
                      help="Do not execute or write anything.")
355 0ac84a9a Dimitris Aragiorgis
  parser.add_argument("-v", dest="verbose",
356 0ac84a9a Dimitris Aragiorgis
                      default=0, action="count",
357 0ac84a9a Dimitris Aragiorgis
                      help="Increase verbosity.")
358 0ac84a9a Dimitris Aragiorgis
  parser.add_argument("-d", dest="debug",
359 0ac84a9a Dimitris Aragiorgis
                      default=False, action="store_true",
360 0ac84a9a Dimitris Aragiorgis
                      help="Debug mode")
361 0ac84a9a Dimitris Aragiorgis
  parser.add_argument("--autoconf", dest="autoconf",
362 0ac84a9a Dimitris Aragiorgis
                      default=False, action="store_true",
363 0ac84a9a Dimitris Aragiorgis
                      help="In case of all in one auto conf setup")
364 0ac84a9a Dimitris Aragiorgis
365 0ac84a9a Dimitris Aragiorgis
  # virtual cluster related options
366 0ac84a9a Dimitris Aragiorgis
  parser.add_argument("--mem", dest="mem",
367 0ac84a9a Dimitris Aragiorgis
                      default=2024,
368 0ac84a9a Dimitris Aragiorgis
                      help="Memory for every virutal node")
369 0ac84a9a Dimitris Aragiorgis
  parser.add_argument("--smp", dest="smp",
370 0ac84a9a Dimitris Aragiorgis
                      default=1,
371 0ac84a9a Dimitris Aragiorgis
                      help="Virtual CPUs for every virtual node")
372 0ac84a9a Dimitris Aragiorgis
  parser.add_argument("--vnc", dest="vnc",
373 0ac84a9a Dimitris Aragiorgis
                      default=False, action="store_true",
374 0ac84a9a Dimitris Aragiorgis
                      help="Wheter virtual nodes will have a vnc console or not")
375 0ac84a9a Dimitris Aragiorgis
  parser.add_argument("-k", "--keygen", dest="keygen",
376 0ac84a9a Dimitris Aragiorgis
                      default=False, action="store_true",
377 0ac84a9a Dimitris Aragiorgis
                      help="Whether to create new ssh key pairs")
378 0ac84a9a Dimitris Aragiorgis
379 0ac84a9a Dimitris Aragiorgis
  parser.add_argument("-i", "--ssh-key", dest="ssh_key",
380 0ac84a9a Dimitris Aragiorgis
                      default=None,
381 0ac84a9a Dimitris Aragiorgis
                      help="Path of an existing ssh key to use")
382 0ac84a9a Dimitris Aragiorgis
383 0ac84a9a Dimitris Aragiorgis
  # backend related options
384 0ac84a9a Dimitris Aragiorgis
  parser.add_argument("--cluster-name", dest="cluster_name",
385 0ac84a9a Dimitris Aragiorgis
                      default="ganeti1",
386 0ac84a9a Dimitris Aragiorgis
                      help="The cluster name in ganeti.conf")
387 0ac84a9a Dimitris Aragiorgis
388 0ac84a9a Dimitris Aragiorgis
  # backend related options
389 0ac84a9a Dimitris Aragiorgis
  parser.add_argument("--cluster-node", dest="cluster_node",
390 0ac84a9a Dimitris Aragiorgis
                      default=None,
391 0ac84a9a Dimitris Aragiorgis
                      help="The node to add to the existing cluster")
392 0ac84a9a Dimitris Aragiorgis
393 0ac84a9a Dimitris Aragiorgis
  # available commands
394 0ac84a9a Dimitris Aragiorgis
  parser.add_argument("command", type=str,
395 0ac84a9a Dimitris Aragiorgis
                      choices=["packages", "vcluster", "prepare",
396 0ac84a9a Dimitris Aragiorgis
                               "synnefo", "backend", "ganeti",
397 0ac84a9a Dimitris Aragiorgis
                               "run", "cleanup", "test",
398 0ac84a9a Dimitris Aragiorgis
                               "all", "add"],
399 0ac84a9a Dimitris Aragiorgis
                      help="Run on of the supported deployment commands")
400 0ac84a9a Dimitris Aragiorgis
401 0ac84a9a Dimitris Aragiorgis
  # available actions for the run command
402 0ac84a9a Dimitris Aragiorgis
  parser.add_argument("actions", type=str, nargs="*",
403 0ac84a9a Dimitris Aragiorgis
                      help="Run one or more of the supported subcommands")
404 0ac84a9a Dimitris Aragiorgis
405 1bc6d467 Dionysis Grigoropoulos
  # disable colors in terminal
406 1bc6d467 Dionysis Grigoropoulos
  parser.add_argument("--disable-colors", dest="disable_colors", default=False,
407 1bc6d467 Dionysis Grigoropoulos
                      action="store_true", help="Disable colors in terminal")
408 1bc6d467 Dionysis Grigoropoulos
409 0ac84a9a Dimitris Aragiorgis
  return parser.parse_args()
410 0ac84a9a Dimitris Aragiorgis
411 1bc6d467 Dionysis Grigoropoulos
412 0ac84a9a Dimitris Aragiorgis
def get_actions(*args):
413 0ac84a9a Dimitris Aragiorgis
    actions = {
414 0ac84a9a Dimitris Aragiorgis
      # prepare actions
415 0ac84a9a Dimitris Aragiorgis
      "ns":  ["setup_ns", "setup_resolv_conf"],
416 0ac84a9a Dimitris Aragiorgis
      "hosts": ["setup_hosts", "add_keys"],
417 0ac84a9a Dimitris Aragiorgis
      "check": ["check_dhcp", "check_dns", "check_connectivity", "check_ssh"],
418 0ac84a9a Dimitris Aragiorgis
      "apt": ["apt_get_update", "setup_apt"],
419 0ac84a9a Dimitris Aragiorgis
      "nfs": ["setup_nfs_server", "setup_nfs_clients"],
420 0ac84a9a Dimitris Aragiorgis
      "prepare":  [
421 0ac84a9a Dimitris Aragiorgis
        "setup_hosts", "add_keys",
422 0ac84a9a Dimitris Aragiorgis
        "setup_ns", "setup_resolv_conf",
423 0ac84a9a Dimitris Aragiorgis
        "check_dhcp", "check_dns", "check_connectivity", "check_ssh",
424 0ac84a9a Dimitris Aragiorgis
        "apt_get_update", "setup_apt",
425 0ac84a9a Dimitris Aragiorgis
        "setup_nfs_server", "setup_nfs_clients"
426 0ac84a9a Dimitris Aragiorgis
        ],
427 0ac84a9a Dimitris Aragiorgis
      # synnefo actions
428 0ac84a9a Dimitris Aragiorgis
      "synnefo": [
429 0ac84a9a Dimitris Aragiorgis
        "setup_mq", "setup_db",
430 0ac84a9a Dimitris Aragiorgis
        "setup_astakos",
431 0ac84a9a Dimitris Aragiorgis
        #TODO: astakos-quota fails if no user is added.
432 0ac84a9a Dimitris Aragiorgis
        #      add_user fails if no groups found
433 0ac84a9a Dimitris Aragiorgis
        "astakos_loaddata", "add_user", "activate_user", "astakos_register_services",
434 0ac84a9a Dimitris Aragiorgis
        "setup_cms", "cms_loaddata",
435 0ac84a9a Dimitris Aragiorgis
        "setup_pithos",
436 0ac84a9a Dimitris Aragiorgis
        "setup_cyclades", "cyclades_loaddata", "add_pools", "setup_vncauthproxy",
437 0ac84a9a Dimitris Aragiorgis
        "setup_kamaki", "upload_image", "register_image",
438 0ac84a9a Dimitris Aragiorgis
        "setup_burnin"
439 0ac84a9a Dimitris Aragiorgis
        ],
440 0ac84a9a Dimitris Aragiorgis
      "supdate": [
441 0ac84a9a Dimitris Aragiorgis
        "apt_get_update", "setup_astakos",
442 0ac84a9a Dimitris Aragiorgis
        "setup_cms", "setup_pithos", "setup_cyclades"
443 0ac84a9a Dimitris Aragiorgis
        ],
444 0ac84a9a Dimitris Aragiorgis
      # backend actions
445 0ac84a9a Dimitris Aragiorgis
      "backend": [
446 0ac84a9a Dimitris Aragiorgis
        "update_ns_for_ganeti",
447 0ac84a9a Dimitris Aragiorgis
        "setup_ganeti", "init_cluster",
448 0ac84a9a Dimitris Aragiorgis
        "add_rapi_user", "add_nodes",
449 0ac84a9a Dimitris Aragiorgis
        "setup_image_host", "setup_image_helper",
450 0ac84a9a Dimitris Aragiorgis
        "setup_network",
451 0ac84a9a Dimitris Aragiorgis
        "setup_gtools", "add_backend", "add_network",
452 0ac84a9a Dimitris Aragiorgis
        "setup_lvm", "enable_lvm",
453 0ac84a9a Dimitris Aragiorgis
        "enable_drbd", "setup_drbd_dparams",
454 0ac84a9a Dimitris Aragiorgis
        "setup_net_infra", "setup_iptables", "setup_router",
455 0ac84a9a Dimitris Aragiorgis
        ],
456 0ac84a9a Dimitris Aragiorgis
      "bstorage": [
457 0ac84a9a Dimitris Aragiorgis
        "setup_lvm", "enable_lvm",
458 0ac84a9a Dimitris Aragiorgis
        "enable_drbd", "setup_drbd_dparams"
459 0ac84a9a Dimitris Aragiorgis
        ],
460 0ac84a9a Dimitris Aragiorgis
      "bnetwork": ["setup_net_infra", "setup_iptables", "setup_router"],
461 0ac84a9a Dimitris Aragiorgis
      "bupdate": [
462 0ac84a9a Dimitris Aragiorgis
        "apt_get_update", "setup_ganeti", "setup_image_host", "setup_image_helper",
463 0ac84a9a Dimitris Aragiorgis
        "setup_network", "setup_gtools"
464 0ac84a9a Dimitris Aragiorgis
        ],
465 0ac84a9a Dimitris Aragiorgis
      # ganeti actions
466 0ac84a9a Dimitris Aragiorgis
      "ganeti": [
467 0ac84a9a Dimitris Aragiorgis
        "update_ns_for_ganeti",
468 0ac84a9a Dimitris Aragiorgis
        "setup_ganeti", "init_cluster", "add_nodes",
469 0ac84a9a Dimitris Aragiorgis
        "setup_image_host", "setup_image_helper", "add_image_locally",
470 0ac84a9a Dimitris Aragiorgis
        "debootstrap", "setup_net_infra",
471 0ac84a9a Dimitris Aragiorgis
        "setup_lvm", "enable_lvm", "enable_drbd", "setup_drbd_dparams",
472 0ac84a9a Dimitris Aragiorgis
        ],
473 0ac84a9a Dimitris Aragiorgis
      "gupdate": ["setup_apt", "setup_ganeti"],
474 0ac84a9a Dimitris Aragiorgis
      "gdestroy": ["destroy_cluster"],
475 0ac84a9a Dimitris Aragiorgis
      }
476 0ac84a9a Dimitris Aragiorgis
477 0ac84a9a Dimitris Aragiorgis
    ret = []
478 0ac84a9a Dimitris Aragiorgis
    for x in args:
479 0ac84a9a Dimitris Aragiorgis
      ret += actions[x]
480 0ac84a9a Dimitris Aragiorgis
481 0ac84a9a Dimitris Aragiorgis
    return ret
482 0ac84a9a Dimitris Aragiorgis
483 0ac84a9a Dimitris Aragiorgis
484 0ac84a9a Dimitris Aragiorgis
def create_keys(args, env):
485 0ac84a9a Dimitris Aragiorgis
  d = os.path.join(env.templates, "root/.ssh")
486 0ac84a9a Dimitris Aragiorgis
  a = os.path.join(d, "authorized_keys")
487 0ac84a9a Dimitris Aragiorgis
  for t in ("dsa", "rsa"):
488 0ac84a9a Dimitris Aragiorgis
    f = os.path.join(d, "id_" + t)
489 0ac84a9a Dimitris Aragiorgis
    cmd = 'ssh-keygen -q -t {0} -f {1} -N ""'.format(t, f)
490 0ac84a9a Dimitris Aragiorgis
    os.system(cmd)
491 0ac84a9a Dimitris Aragiorgis
    cmd = 'cat {0}.pub >> {1}'.format(f, a)
492 0ac84a9a Dimitris Aragiorgis
    os.system(cmd)
493 0ac84a9a Dimitris Aragiorgis
494 0ac84a9a Dimitris Aragiorgis
def add_node(args, env):
495 0ac84a9a Dimitris Aragiorgis
    actions = [
496 0ac84a9a Dimitris Aragiorgis
      "update_ns_for_node:" + args.cluster_node,
497 0ac84a9a Dimitris Aragiorgis
      ]
498 0ac84a9a Dimitris Aragiorgis
    fabcommand(args, env, actions)
499 0ac84a9a Dimitris Aragiorgis
    actions = [
500 0ac84a9a Dimitris Aragiorgis
      "setup_resolv_conf",
501 0ac84a9a Dimitris Aragiorgis
      "apt_get_update",
502 0ac84a9a Dimitris Aragiorgis
      "setup_apt",
503 0ac84a9a Dimitris Aragiorgis
      "setup_hosts",
504 0ac84a9a Dimitris Aragiorgis
      "add_keys",
505 0ac84a9a Dimitris Aragiorgis
      ]
506 0ac84a9a Dimitris Aragiorgis
    fabcommand(args, env, actions, [args.cluster_node])
507 0ac84a9a Dimitris Aragiorgis
508 0ac84a9a Dimitris Aragiorgis
    actions = get_actions("check")
509 0ac84a9a Dimitris Aragiorgis
    fabcommand(args, env, actions)
510 0ac84a9a Dimitris Aragiorgis
511 0ac84a9a Dimitris Aragiorgis
    actions = [
512 0ac84a9a Dimitris Aragiorgis
      "setup_nfs_clients",
513 0ac84a9a Dimitris Aragiorgis
      "setup_ganeti",
514 0ac84a9a Dimitris Aragiorgis
      "setup_image_host", "setup_image_helper", "setup_network", "setup_gtools",
515 0ac84a9a Dimitris Aragiorgis
      ]
516 0ac84a9a Dimitris Aragiorgis
    fabcommand(args, env, actions, [args.cluster_node])
517 0ac84a9a Dimitris Aragiorgis
518 0ac84a9a Dimitris Aragiorgis
    actions = [
519 0ac84a9a Dimitris Aragiorgis
      "add_node:" + args.cluster_node,
520 0ac84a9a Dimitris Aragiorgis
      ]
521 0ac84a9a Dimitris Aragiorgis
    fabcommand(args, env, actions)
522 0ac84a9a Dimitris Aragiorgis
523 0ac84a9a Dimitris Aragiorgis
    actions = [
524 0ac84a9a Dimitris Aragiorgis
      "setup_lvm", "enable_drbd",
525 0ac84a9a Dimitris Aragiorgis
      "setup_net_infra", "setup_iptables",
526 0ac84a9a Dimitris Aragiorgis
      ]
527 0ac84a9a Dimitris Aragiorgis
    fabcommand(args, env, actions, [args.cluster_node])
528 0ac84a9a Dimitris Aragiorgis
529 0ac84a9a Dimitris Aragiorgis
def main():
530 0ac84a9a Dimitris Aragiorgis
  args = parse_options()
531 0ac84a9a Dimitris Aragiorgis
532 0ac84a9a Dimitris Aragiorgis
  conf = Conf.configure(args.confdir, args.cluster_name, args, args.autoconf)
533 0ac84a9a Dimitris Aragiorgis
  env = Env(conf)
534 0ac84a9a Dimitris Aragiorgis
535 0ac84a9a Dimitris Aragiorgis
  create_dir(env.run, False)
536 0ac84a9a Dimitris Aragiorgis
  create_dir(env.dns, False)
537 0ac84a9a Dimitris Aragiorgis
538 0ac84a9a Dimitris Aragiorgis
  if args.command == "test":
539 0ac84a9a Dimitris Aragiorgis
    conf.print_config()
540 0ac84a9a Dimitris Aragiorgis
541 0ac84a9a Dimitris Aragiorgis
  if args.command == "cleanup":
542 0ac84a9a Dimitris Aragiorgis
    cleanup(args, env)
543 0ac84a9a Dimitris Aragiorgis
544 0ac84a9a Dimitris Aragiorgis
  if args.keygen:
545 0ac84a9a Dimitris Aragiorgis
    create_keys(args, env)
546 0ac84a9a Dimitris Aragiorgis
547 0ac84a9a Dimitris Aragiorgis
  if args.command == "packages":
548 0ac84a9a Dimitris Aragiorgis
    create_dir(env.packages, True)
549 0ac84a9a Dimitris Aragiorgis
    get_packages(args, env)
550 0ac84a9a Dimitris Aragiorgis
551 0ac84a9a Dimitris Aragiorgis
  if args.command == "vcluster":
552 0ac84a9a Dimitris Aragiorgis
    image(args, env)
553 0ac84a9a Dimitris Aragiorgis
    network(args, env)
554 0ac84a9a Dimitris Aragiorgis
    create_dnsmasq_files(args, env)
555 0ac84a9a Dimitris Aragiorgis
    dnsmasq(args, env)
556 0ac84a9a Dimitris Aragiorgis
    cluster(args, env)
557 0ac84a9a Dimitris Aragiorgis
558 0ac84a9a Dimitris Aragiorgis
  if args.command == "prepare":
559 0ac84a9a Dimitris Aragiorgis
    actions = get_actions("prepare")
560 0ac84a9a Dimitris Aragiorgis
    fabcommand(args, env, actions)
561 0ac84a9a Dimitris Aragiorgis
562 0ac84a9a Dimitris Aragiorgis
  if args.command == "synnefo":
563 0ac84a9a Dimitris Aragiorgis
    actions = get_actions("synnefo")
564 0ac84a9a Dimitris Aragiorgis
    fabcommand(args, env, actions)
565 0ac84a9a Dimitris Aragiorgis
566 0ac84a9a Dimitris Aragiorgis
  if args.command == "backend":
567 0ac84a9a Dimitris Aragiorgis
    actions = get_actions("backend")
568 0ac84a9a Dimitris Aragiorgis
    fabcommand(args, env, actions)
569 0ac84a9a Dimitris Aragiorgis
570 0ac84a9a Dimitris Aragiorgis
  if args.command == "ganeti":
571 0ac84a9a Dimitris Aragiorgis
    actions += get_actions("ganeti")
572 0ac84a9a Dimitris Aragiorgis
    fabcommand(args, env, actions)
573 0ac84a9a Dimitris Aragiorgis
574 0ac84a9a Dimitris Aragiorgis
575 0ac84a9a Dimitris Aragiorgis
576 0ac84a9a Dimitris Aragiorgis
577 0ac84a9a Dimitris Aragiorgis
  if args.command == "all":
578 0ac84a9a Dimitris Aragiorgis
    actions = get_actions("prepare", "synnefo", "backend")
579 0ac84a9a Dimitris Aragiorgis
    fabcommand(args, env, actions)
580 0ac84a9a Dimitris Aragiorgis
581 0ac84a9a Dimitris Aragiorgis
  if args.command == "add":
582 0ac84a9a Dimitris Aragiorgis
    if args.cluster_node:
583 0ac84a9a Dimitris Aragiorgis
      add_node(args, env)
584 0ac84a9a Dimitris Aragiorgis
    else:
585 0ac84a9a Dimitris Aragiorgis
      actions = get_actions("backend")
586 0ac84a9a Dimitris Aragiorgis
      fabcommand(args, env, actions)
587 0ac84a9a Dimitris Aragiorgis
588 0ac84a9a Dimitris Aragiorgis
589 0ac84a9a Dimitris Aragiorgis
  if args.command == "run":
590 0ac84a9a Dimitris Aragiorgis
    if not args.actions:
591 0ac84a9a Dimitris Aragiorgis
      print_available_actions(args.command)
592 0ac84a9a Dimitris Aragiorgis
    else:
593 0ac84a9a Dimitris Aragiorgis
      fabcommand(args, env, args.actions)
594 0ac84a9a Dimitris Aragiorgis
595 0ac84a9a Dimitris Aragiorgis
596 0ac84a9a Dimitris Aragiorgis
if __name__ == "__main__":
597 0ac84a9a Dimitris Aragiorgis
  sys.exit(main())