Revision ca1de37b

b/snf-deploy/setup.py
38 38
import os
39 39
import sys
40 40

  
41
from distutils.util import convert_path
42
from fnmatch import fnmatchcase
43 41
from setuptools import setup, find_packages
44 42
HERE = os.path.abspath(os.path.normpath(os.path.dirname(__file__)))
45 43

  
......
65 63
]
66 64

  
67 65
setup(
68
    name = 'snf-deploy',
69
    version = VERSION,
70
    license = 'BSD',
71
    url = 'http://code.grnet.gr/',
72
    description = SHORT_DESCRIPTION,
73
    long_description = SHORT_DESCRIPTION,
74
    classifiers = CLASSIFIERS,
66
    name='snf-deploy',
67
    version=VERSION,
68
    license='BSD',
69
    url='http://code.grnet.gr/',
70
    description=SHORT_DESCRIPTION,
71
    long_description=SHORT_DESCRIPTION,
72
    classifiers=CLASSIFIERS,
75 73

  
76 74
    author='Synnefo development team',
77 75
    author_email='synnefo-devel@googlegroups.com',
78 76
    maintainer='Synnefo development team',
79 77
    maintainer_email='synnefo-devel@googlegroups.com',
80 78

  
81
    packages = PACKAGES,
82
    package_dir= {'': PACKAGES_ROOT},
83
    include_package_data = True,
84
    zip_safe = False,
79
    packages=PACKAGES,
80
    package_dir={'': PACKAGES_ROOT},
81
    include_package_data=True,
82
    zip_safe=False,
85 83

  
86
    install_requires = INSTALL_REQUIRES,
84
    install_requires=INSTALL_REQUIRES,
87 85

  
88
    dependency_links = ['http://docs.dev.grnet.gr/pypi'],
86
    dependency_links=['http://docs.dev.grnet.gr/pypi'],
89 87
    entry_points={
90
     'console_scripts': [
91
         'snf-deploy=snfdeploy:main',
92
         ],
93
      },
88
        'console_scripts': [
89
            'snf-deploy=snfdeploy:main',
90
            ],
91
        },
94 92
)
b/snf-deploy/snfdeploy/__init__.py
1
import json
2 1
import time
3
import ipaddr
4 2
import os
5
import signal
6
import time
7
import ConfigParser
8 3
import argparse
9 4
import sys
10 5
import re
11 6
import random
12
import subprocess
13
import imp
14 7
import ast
15
from snfdeploy.lib import *
8
from snfdeploy.lib import check_pidfile, create_dir, get_default_route, \
9
    random_mac, Conf, Env
16 10
from snfdeploy import fabfile
17
from fabric.api import hide, env, settings, local, roles, execute, show
11
from fabric.api import hide, settings, execute, show
12

  
18 13

  
19 14
def print_available_actions(command):
20 15

  
21
  if command == "keygen":
22
    print """
16
    if command == "keygen":
17
        print """
23 18
Usage: snf-deploy keygen [--force]
24 19

  
25 20
  Generate new ssh keys (both rsa and dsa keypairs)
26 21

  
27 22
  """
28 23

  
29
  if command == "vcluster":
30
    print """
24
    if command == "vcluster":
25
        print """
31 26
Usage: snf-deploy vcluster
32 27

  
33 28
  Run the following actions concerning the local virtual cluster:
34 29

  
35
    - Download base image and create additional disk (if --create-extra-disk is passed)
30
    - Download base image and create additional disk \
31
(if --create-extra-disk is passed)
36 32
    - Does all the network related actions (bridge, iptables, NAT)
37 33
    - Launches dnsmasq for dhcp server on bridge
38 34
    - Creates the virtual cluster (with kvm)
39 35

  
40 36
  """
41 37

  
42
  if command == "prepare":
43
    print """
38
    if command == "prepare":
39
        print """
44 40
Usage: snf-deploy prepare
45 41

  
46 42
  Run the following actions concerning deployment preparation:
......
53 49

  
54 50
  """
55 51

  
56
  if command == "backend":
57
    print """
52
    if command == "backend":
53
        print """
58 54
Usage: snf-deploy backend [update]
59 55

  
60 56
  Run the following actions concerning a ganeti backend:
......
63 59
    - Does all the net-infra specific actions in backend nodes
64 60
      (create/connect bridges, iptables..)
65 61
    - Does all the storage-infra specific actions in backend nodes
66
      depending on the --extra-disk option (create VG, enable lvm/drbd storage..)
62
      depending on the --extra-disk option \
63
(create VG, enable lvm/drbd storage..)
67 64

  
68 65
    or
69 66

  
......
71 68

  
72 69
  """
73 70

  
74
  if command == "run":
75
    print """
71
    if command == "run":
72
        print """
76 73
Usage: snf-deploy run <action> [<action>...]
77 74

  
78 75
  Run any of the following fabric commands:
......
89 86
      setup_ganeti           enable_drbd                   create_bridges
90 87
      setup_gtools           init_cluster                  create_vlans
91 88
      setup_gunicorn         setup_nfs_clients             destroy_db
92
      setup_hosts            setup_nfs_server              get_auth_token_from_db
89
      setup_hosts            setup_nfs_server              \
90
get_auth_token_from_db
93 91
      setup_image_helper     update_ns_for_ganeti          get_service_details
94 92
      setup_image_host                                     gnt_instance_add
95 93
      setup_iptables                                       gnt_network_add
......
107 105

  
108 106
  """
109 107

  
110
  sys.exit(1)
108
    sys.exit(1)
111 109

  
112 110

  
113 111
def create_dnsmasq_files(args, env):
114 112

  
115
  print("Customize dnsmasq..")
116
  out = env.dns
113
    print("Customize dnsmasq..")
114
    out = env.dns
117 115

  
118
  hostsfile = open(out + "/dhcp-hostsfile", "w")
119
  optsfile = open(out + "/dhcp-optsfile", "w")
120
  conffile = open(out + "/conf-file", "w")
116
    hostsfile = open(out + "/dhcp-hostsfile", "w")
117
    optsfile = open(out + "/dhcp-optsfile", "w")
118
    conffile = open(out + "/conf-file", "w")
121 119

  
122
  for node, info in env.nodes_info.iteritems():
123
    # serve ip and hostname to nodes
124
    hostsfile.write("%s,%s,%s,2m\n" % (info.mac, info.ip, info.hostname))
120
    for node, info in env.nodes_info.iteritems():
121
        # serve ip and hostname to nodes
122
        hostsfile.write("%s,%s,%s,2m\n" % (info.mac, info.ip, info.hostname))
125 123

  
126
  hostsfile.write("52:54:56:*:*:*,ignore\n")
124
    hostsfile.write("52:54:56:*:*:*,ignore\n")
127 125

  
128
  # Netmask
129
  optsfile.write("1,%s\n" % env.net.netmask)
130
  # Gateway
131
  optsfile.write("3,%s\n" % env.gateway)
132
  # Namesevers
133
  optsfile.write("6,%s\n" % "8.8.8.8")
126
    # Netmask
127
    optsfile.write("1,%s\n" % env.net.netmask)
128
    # Gateway
129
    optsfile.write("3,%s\n" % env.gateway)
130
    # Namesevers
131
    optsfile.write("6,%s\n" % "8.8.8.8")
134 132

  
135
  dnsconf = """
133
    dnsconf = """
136 134
user=dnsmasq
137 135
bogus-priv
138 136
no-poll
......
146 144
port=0
147 145
""".format(env.ns.ip)
148 146

  
149
  dnsconf += """
147
    dnsconf += """
150 148
# serve domain and search domain for resolv.conf
151 149
domain={5}
152 150
interface={0}
......
156 154
""".format(env.bridge, hostsfile.name, optsfile.name,
157 155
           env.domain, env.net.network, env.domain)
158 156

  
159
  conffile.write(dnsconf)
157
    conffile.write(dnsconf)
160 158

  
161
  hostsfile.close()
162
  optsfile.close()
163
  conffile.close()
159
    hostsfile.close()
160
    optsfile.close()
161
    conffile.close()
164 162

  
165 163

  
166 164
def cleanup(args, env):
167
  print("Cleaning up bridge, NAT, resolv.conf...")
168

  
169
  for f in os.listdir(env.run):
170
    if re.search(".pid$", f):
171
      check_pidfile(os.path.join(env.run, f))
172

  
173
  create_dir(env.run, True)
174
  # create_dir(env.cmd, True)
175
  cmd = """
176
  iptables -t nat -D POSTROUTING -s {0} -o {1} -j MASQUERADE
177
  echo 0 > /proc/sys/net/ipv4/ip_forward
178
  iptables -D INPUT -i {2} -j ACCEPT
179
  iptables -D FORWARD -i {2} -j ACCEPT
180
  iptables -D OUTPUT -o {2} -j ACCEPT
181
  """.format(env.subnet, get_default_route()[1], env.bridge)
182
  os.system(cmd)
183

  
184
  cmd = """
185
  ip link show {0} && ip addr del {1}/{2} dev {0}
186
  sleep 1
187
  ip link set {0} down
188
  sleep 1
189
  brctl delbr {0}
190
  """.format(env.bridge, env.gateway, env.net.prefixlen)
191
  os.system(cmd)
165
    print("Cleaning up bridge, NAT, resolv.conf...")
166

  
167
    for f in os.listdir(env.run):
168
        if re.search(".pid$", f):
169
            check_pidfile(os.path.join(env.run, f))
170

  
171
    create_dir(env.run, True)
172
    # create_dir(env.cmd, True)
173
    cmd = """
174
    iptables -t nat -D POSTROUTING -s {0} -o {1} -j MASQUERADE
175
    echo 0 > /proc/sys/net/ipv4/ip_forward
176
    iptables -D INPUT -i {2} -j ACCEPT
177
    iptables -D FORWARD -i {2} -j ACCEPT
178
    iptables -D OUTPUT -o {2} -j ACCEPT
179
    """.format(env.subnet, get_default_route()[1], env.bridge)
180
    os.system(cmd)
181

  
182
    cmd = """
183
    ip link show {0} && ip addr del {1}/{2} dev {0}
184
    sleep 1
185
    ip link set {0} down
186
    sleep 1
187
    brctl delbr {0}
188
    """.format(env.bridge, env.gateway, env.net.prefixlen)
189
    os.system(cmd)
192 190

  
193 191

  
194 192
def network(args, env):
195
  print("Create bridge..Add gateway IP..Activate NAT..Append NS options to resolv.conf")
196

  
197
  cmd = """
198
  ! ip link show {0} && brctl addbr {0} && ip link set {0} up
199
  sleep 1
200
  ip link set promisc on dev {0}
201
  ip addr add {1}/{2} dev {0}
202
  """.format(env.bridge, env.gateway, env.net.prefixlen)
203
  os.system(cmd)
204

  
205
  cmd = """
206
  iptables -t nat -A POSTROUTING -s {0} -o {1} -j MASQUERADE
207
  echo 1 > /proc/sys/net/ipv4/ip_forward
208
  iptables -I INPUT 1 -i {2} -j ACCEPT
209
  iptables -I FORWARD 1 -i {2} -j ACCEPT
210
  iptables -I OUTPUT 1 -o {2} -j ACCEPT
211
  """.format(env.subnet, get_default_route()[1], env.bridge)
212
  os.system(cmd)
193
    print("Create bridge..Add gateway IP..Activate NAT.."
194
          "Append NS options to resolv.conf")
195

  
196
    cmd = """
197
    ! ip link show {0} && brctl addbr {0} && ip link set {0} up
198
    sleep 1
199
    ip link set promisc on dev {0}
200
    ip addr add {1}/{2} dev {0}
201
    """.format(env.bridge, env.gateway, env.net.prefixlen)
202
    os.system(cmd)
203

  
204
    cmd = """
205
    iptables -t nat -A POSTROUTING -s {0} -o {1} -j MASQUERADE
206
    echo 1 > /proc/sys/net/ipv4/ip_forward
207
    iptables -I INPUT 1 -i {2} -j ACCEPT
208
    iptables -I FORWARD 1 -i {2} -j ACCEPT
209
    iptables -I OUTPUT 1 -o {2} -j ACCEPT
210
    """.format(env.subnet, get_default_route()[1], env.bridge)
211
    os.system(cmd)
213 212

  
214 213

  
215 214
def image(args, env):
216
  if env.os == "ubuntu":
217
    url = env.ubuntu_image_url
218
  else:
219
    url = env.squeeze_image_url
215
    if env.os == "ubuntu":
216
        url = env.ubuntu_image_url
217
    else:
218
        url = env.squeeze_image_url
220 219

  
221
  disk0 = "{0}/{1}.disk0".format(env.images, env.os)
222
  disk1 = "{0}/{1}.disk1".format(env.images, env.os)
220
    disk0 = "{0}/{1}.disk0".format(env.images, env.os)
221
    disk1 = "{0}/{1}.disk1".format(env.images, env.os)
223 222

  
224
  if url and not os.path.exists(disk0):
225
    cmd = "wget {0} -O {1}".format(url, disk0)
226
    os.system(cmd)
223
    if url and not os.path.exists(disk0):
224
        cmd = "wget {0} -O {1}".format(url, disk0)
225
        os.system(cmd)
227 226

  
228
  if ast.literal_eval(env.create_extra_disk) and not os.path.exists(disk1):
229
    if env.lvg:
230
      cmd = "lvcreate -L30G -n{0}.disk1 {1}".format(env.os, env.lvg)
231
      os.system(cmd)
232
      cmd = "ln -s /dev/{0}/{1}.disk1 {2}".format(env.lvg, env.os, disk1)
233
      os.system(cmd)
234
    else:
235
      cmd = "dd if=/dev/zero of={0} bs=10M count=3000".format(disk1)
236
      os.system(cmd)
227
    if ast.literal_eval(env.create_extra_disk) and not os.path.exists(disk1):
228
        if env.lvg:
229
            cmd = "lvcreate -L30G -n{0}.disk1 {1}".format(env.os, env.lvg)
230
            os.system(cmd)
231
            cmd = "ln -s /dev/{0}/{1}.disk1 {2}".format(env.lvg, env.os, disk1)
232
            os.system(cmd)
233
        else:
234
            cmd = "dd if=/dev/zero of={0} bs=10M count=3000".format(disk1)
235
            os.system(cmd)
237 236

  
238 237

  
239 238
def fabcommand(args, env, actions, nodes=[]):
240
  levels = ["status", "aborts", "warnings", "running",
241
            "stdout", "stderr", "user", "debug"]
239
    levels = ["status", "aborts", "warnings", "running",
240
              "stdout", "stderr", "user", "debug"]
242 241

  
243
  level_aliases = {
244
    "output": ["stdout", "stderr"],
245
    "everything": ["warnings", "running", "user", "output"]
242
    level_aliases = {
243
        "output": ["stdout", "stderr"],
244
        "everything": ["warnings", "running", "user", "output"]
246 245
    }
247 246

  
248
  lhide = level_aliases["everything"]
249
  lshow = []
247
    lhide = level_aliases["everything"]
248
    lshow = []
250 249

  
251
  if args.verbose == 1:
252
    lshow = levels[:3]
253
    lhide = levels[3:]
254
  elif args.verbose == 2:
255
    lshow = levels[:4]
256
    lhide = levels[4:]
257
  elif args.verbose >= 3 or args.debug:
258
    lshow = levels
259
    lhide = []
250
    if args.verbose == 1:
251
        lshow = levels[:3]
252
        lhide = levels[3:]
253
    elif args.verbose == 2:
254
        lshow = levels[:4]
255
        lhide = levels[4:]
256
    elif args.verbose >= 3 or args.debug:
257
        lshow = levels
258
        lhide = []
260 259

  
261 260
#   fabcmd += " --fabfile {4}/fabfile.py \
262 261
# setup_env:confdir={0},packages={1},templates={2},cluster_name={3},\
......
264 263
# ".format(args.confdir, env.packages, env.templates, args.cluster_name,
265 264
#          env.lib, args.autoconf, args.disable_colors, args.key_inject)
266 265

  
267
  if nodes:
268
    ips = [env.nodes_info[n].ip for n in nodes]
266
    if nodes:
267
        ips = [env.nodes_info[n].ip for n in nodes]
269 268

  
270
  fabfile.setup_env(args)
271
  with settings(hide(*lhide), show(*lshow)):
272
      print " ".join(actions)
273
      for a in actions:
274
        fn = getattr(fabfile, a)
275
        if not args.dry_run:
276
          if nodes:
277
             execute(fn, hosts=ips)
278
          else:
279
             execute(fn)
269
    fabfile.setup_env(args)
270
    with settings(hide(*lhide), show(*lshow)):
271
        print " ".join(actions)
272
        for a in actions:
273
            fn = getattr(fabfile, a)
274
            if not args.dry_run:
275
                if nodes:
276
                    execute(fn, hosts=ips)
277
                else:
278
                    execute(fn)
280 279

  
281 280

  
282 281
def cluster(args, env):
283
  for hostname, mac in env.node2mac.iteritems():
284
    launch_vm(args, env, hostname, mac)
282
    for hostname, mac in env.node2mac.iteritems():
283
        launch_vm(args, env, hostname, mac)
285 284

  
286
  time.sleep(30)
287
  os.system("reset")
285
    time.sleep(30)
286
    os.system("reset")
288 287

  
289 288

  
290 289
def launch_vm(args, env, hostname, mac):
291
  check_pidfile("%s/%s.pid" % (env.run, hostname))
290
    check_pidfile("%s/%s.pid" % (env.run, hostname))
292 291

  
293
  print("Launching cluster node {0}..".format(hostname))
294
  os.environ["BRIDGE"] = env.bridge
295
  if args.vnc:
296
    graphics = "-vnc :{0}".format(random.randint(1, 1000))
297
  else:
298
    graphics = "-nographic"
292
    print("Launching cluster node {0}..".format(hostname))
293
    os.environ["BRIDGE"] = env.bridge
294
    if args.vnc:
295
        graphics = "-vnc :{0}".format(random.randint(1, 1000))
296
    else:
297
        graphics = "-nographic"
299 298

  
300
  disks = """ \
299
    disks = """ \
301 300
-drive file={0}/{1}.disk0,format=raw,if=none,id=drive0,snapshot=on \
302 301
-device virtio-blk-pci,drive=drive0,id=virtio-blk-pci.0 \
303
  """.format(env.images, env.os)
302
""".format(env.images, env.os)
304 303

  
305
  if ast.literal_eval(env.create_extra_disk):
306
    disks += """ \
304
    if ast.literal_eval(env.create_extra_disk):
305
        disks += """ \
307 306
-drive file={0}/{1}.disk1,format=raw,if=none,id=drive1,snapshot=on \
308 307
-device virtio-blk-pci,drive=drive1,id=virtio-blk-pci.1 \
309
  """.format(env.images, env.os)
308
""".format(env.images, env.os)
310 309

  
311

  
312
  ifup = env.lib + "/ifup"
313
  nics = """ \
310
    ifup = env.lib + "/ifup"
311
    nics = """ \
314 312
-netdev tap,id=netdev0,script={0},downscript=no \
315 313
-device virtio-net-pci,mac={1},netdev=netdev0,id=virtio-net-pci.0 \
316 314
-netdev tap,id=netdev1,script={0},downscript=no \
317 315
-device virtio-net-pci,mac={2},netdev=netdev1,id=virtio-net-pci.1 \
318 316
-netdev tap,id=netdev2,script={0},downscript=no \
319 317
-device virtio-net-pci,mac={3},netdev=netdev2,id=virtio-net-pci.2 \
320
  """.format(ifup, mac, randomMAC(), randomMAC())
318
""".format(ifup, mac, random_mac(), random_mac())
321 319

  
322
  cmd = """
320
    cmd = """
323 321
/usr/bin/kvm -name {0} -pidfile {1}/{0}.pid -balloon virtio -daemonize \
324 322
-monitor unix:{1}/{0}.monitor,server,nowait -usbdevice tablet -boot c \
325 323
{2} \
326 324
{3} \
327 325
-m {4} -smp {5} {6} \
328
  """.format(hostname, env.run, disks, nics, args.mem, args.smp, graphics)
329
  print cmd
330
  os.system(cmd)
326
""".format(hostname, env.run, disks, nics, args.mem, args.smp, graphics)
327
    print cmd
328
    os.system(cmd)
331 329

  
332 330

  
333 331
def dnsmasq(args, env):
334
  check_pidfile(env.run + "/dnsmasq.pid")
335
  cmd = "dnsmasq --pid-file={0}/dnsmasq.pid --conf-file={1}/conf-file".format(env.run, env.dns)
336
  os.system(cmd)
332
    check_pidfile(env.run + "/dnsmasq.pid")
333
    cmd = "dnsmasq --pid-file={0}/dnsmasq.pid --conf-file={1}/conf-file"\
334
        .format(env.run, env.dns)
335
    os.system(cmd)
337 336

  
338 337

  
339 338
def get_packages(args, env):
340
  if env.package_url:
341
    os.system("rm {0}/*.deb".format(env.packages))
342
    os.system("wget -r --level=1 -nH --no-parent --cut-dirs=4 {0} -P {1}".format(env.package_url, env.packages))
339
    if env.package_url:
340
        os.system("rm {0}/*.deb".format(env.packages))
341
        os.system("wget -r --level=1 -nH --no-parent --cut-dirs=4 {0} -P {1}"
342
                  .format(env.package_url, env.packages))
343 343

  
344 344

  
345 345
def parse_options():
346
  parser = argparse.ArgumentParser()
347

  
348
  # Directories to load/store config
349
  parser.add_argument("-c", dest="confdir",
350
                      default="/etc/snf-deploy",
351
                      help="Directory to find default configuration")
352
  parser.add_argument("--dry-run", dest="dry_run",
353
                      default=False, action="store_true",
354
                      help="Do not execute or write anything.")
355
  parser.add_argument("-v", dest="verbose",
356
                      default=0, action="count",
357
                      help="Increase verbosity.")
358
  parser.add_argument("-d", dest="debug",
359
                      default=False, action="store_true",
360
                      help="Debug mode")
361
  parser.add_argument("--autoconf", dest="autoconf",
362
                      default=False, action="store_true",
363
                      help="In case of all in one auto conf setup")
364

  
365
  # virtual cluster related options
366
  parser.add_argument("--mem", dest="mem",
367
                      default=2024,
368
                      help="Memory for every virutal node")
369
  parser.add_argument("--smp", dest="smp",
370
                      default=1,
371
                      help="Virtual CPUs for every virtual node")
372
  parser.add_argument("--vnc", dest="vnc",
373
                      default=False, action="store_true",
374
                      help="Wheter virtual nodes will have a vnc console or not")
375
  parser.add_argument("--force", dest="force",
376
                      default=False, action="store_true",
377
                      help="Force the creation of new ssh key pairs")
378

  
379
  parser.add_argument("-i", "--ssh-key", dest="ssh_key",
380
                      default=None,
381
                      help="Path of an existing ssh key to use")
382

  
383
  parser.add_argument("--no-key-inject", dest="key_inject",
384
                      default=True, action="store_false",
385
                      help="Whether to inject ssh key pairs to hosts")
386

  
387
  # backend related options
388
  parser.add_argument("--cluster-name", dest="cluster_name",
389
                      default="ganeti1",
390
                      help="The cluster name in ganeti.conf")
391

  
392
  # backend related options
393
  parser.add_argument("--cluster-node", dest="cluster_node",
394
                      default=None,
395
                      help="The node to add to the existing cluster")
396

  
397
  # available commands
398
  parser.add_argument("command", type=str,
399
                      choices=["packages", "vcluster", "prepare",
400
                               "synnefo", "backend", "ganeti",
401
                               "run", "cleanup", "test",
402
                               "all", "add", "keygen"],
403
                      help="Run on of the supported deployment commands")
404

  
405
  # available actions for the run command
406
  parser.add_argument("actions", type=str, nargs="*",
407
                      help="Run one or more of the supported subcommands")
408

  
409
  # disable colors in terminal
410
  parser.add_argument("--disable-colors", dest="disable_colors", default=False,
411
                      action="store_true", help="Disable colors in terminal")
412

  
413
  return parser.parse_args()
346
    parser = argparse.ArgumentParser()
347

  
348
    # Directories to load/store config
349
    parser.add_argument("-c", dest="confdir",
350
                        default="/etc/snf-deploy",
351
                        help="Directory to find default configuration")
352
    parser.add_argument("--dry-run", dest="dry_run",
353
                        default=False, action="store_true",
354
                        help="Do not execute or write anything.")
355
    parser.add_argument("-v", dest="verbose",
356
                        default=0, action="count",
357
                        help="Increase verbosity.")
358
    parser.add_argument("-d", dest="debug",
359
                        default=False, action="store_true",
360
                        help="Debug mode")
361
    parser.add_argument("--autoconf", dest="autoconf",
362
                        default=False, action="store_true",
363
                        help="In case of all in one auto conf setup")
364

  
365
    # virtual cluster related options
366
    parser.add_argument("--mem", dest="mem",
367
                        default=2024,
368
                        help="Memory for every virutal node")
369
    parser.add_argument("--smp", dest="smp",
370
                        default=1,
371
                        help="Virtual CPUs for every virtual node")
372
    parser.add_argument("--vnc", dest="vnc",
373
                        default=False, action="store_true",
374
                        help="Wheter virtual nodes will have a vnc "
375
                             "console or not")
376
    parser.add_argument("--force", dest="force",
377
                        default=False, action="store_true",
378
                        help="Force the creation of new ssh key pairs")
379

  
380
    parser.add_argument("-i", "--ssh-key", dest="ssh_key",
381
                        default=None,
382
                        help="Path of an existing ssh key to use")
383

  
384
    parser.add_argument("--no-key-inject", dest="key_inject",
385
                        default=True, action="store_false",
386
                        help="Whether to inject ssh key pairs to hosts")
387

  
388
    # backend related options
389
    parser.add_argument("--cluster-name", dest="cluster_name",
390
                        default="ganeti1",
391
                        help="The cluster name in ganeti.conf")
392

  
393
    # backend related options
394
    parser.add_argument("--cluster-node", dest="cluster_node",
395
                        default=None,
396
                        help="The node to add to the existing cluster")
397

  
398
    # available commands
399
    parser.add_argument("command", type=str,
400
                        choices=["packages", "vcluster", "prepare",
401
                                 "synnefo", "backend", "ganeti",
402
                                 "run", "cleanup", "test",
403
                                 "all", "add", "keygen"],
404
                        help="Run on of the supported deployment commands")
405

  
406
    # available actions for the run command
407
    parser.add_argument("actions", type=str, nargs="*",
408
                        help="Run one or more of the supported subcommands")
409

  
410
    # disable colors in terminal
411
    parser.add_argument("--disable-colors", dest="disable_colors",
412
                        default=False, action="store_true",
413
                        help="Disable colors in terminal")
414

  
415
    return parser.parse_args()
414 416

  
415 417

  
416 418
def get_actions(*args):
417 419
    actions = {
418
      # prepare actions
419
      "ns":  ["setup_ns", "setup_resolv_conf"],
420
      "hosts": ["setup_hosts", "add_keys"],
421
      "check": ["check_dhcp", "check_dns", "check_connectivity", "check_ssh"],
422
      "apt": ["apt_get_update", "setup_apt"],
423
      "nfs": ["setup_nfs_server", "setup_nfs_clients"],
424
      "prepare":  [
425
        "setup_hosts", "add_keys",
426
        "setup_ns", "setup_resolv_conf",
427
        "check_dhcp", "check_dns", "check_connectivity", "check_ssh",
428
        "apt_get_update", "setup_apt",
429
        "setup_nfs_server", "setup_nfs_clients"
420
        # prepare actions
421
        "ns":  ["setup_ns", "setup_resolv_conf"],
422
        "hosts": ["setup_hosts", "add_keys"],
423
        "check": ["check_dhcp", "check_dns",
424
                  "check_connectivity", "check_ssh"],
425
        "apt": ["apt_get_update", "setup_apt"],
426
        "nfs": ["setup_nfs_server", "setup_nfs_clients"],
427
        "prepare":  [
428
            "setup_hosts", "add_keys",
429
            "setup_ns", "setup_resolv_conf",
430
            "check_dhcp", "check_dns", "check_connectivity", "check_ssh",
431
            "apt_get_update", "setup_apt",
432
            "setup_nfs_server", "setup_nfs_clients"
430 433
        ],
431
      # synnefo actions
432
      "synnefo": [
433
        "setup_mq", "setup_db",
434
        "setup_astakos",
435
        #TODO: astakos-quota fails if no user is added.
436
        #      add_user fails if no groups found
437
        "astakos_loaddata", "add_user", "activate_user",
438
        "astakos_register_components",
439
        "setup_cms", "cms_loaddata",
440
        "setup_pithos",
441
        "setup_cyclades", "cyclades_loaddata", "add_pools",
442
        "export_services", "import_services", "setup_vncauthproxy",
443
        "setup_kamaki", "upload_image", "register_image",
444
        "setup_burnin"
434
        # synnefo actions
435
        "synnefo": [
436
            "setup_mq", "setup_db",
437
            "setup_astakos",
438
            #TODO: astakos-quota fails if no user is added.
439
            #      add_user fails if no groups found
440
            "astakos_loaddata", "add_user", "activate_user",
441
            "astakos_register_components",
442
            "setup_cms", "cms_loaddata",
443
            "setup_pithos",
444
            "setup_cyclades", "cyclades_loaddata", "add_pools",
445
            "export_services", "import_services", "setup_vncauthproxy",
446
            "setup_kamaki", "upload_image", "register_image",
447
            "setup_burnin"
445 448
        ],
446
      "supdate": [
447
        "apt_get_update", "setup_astakos",
448
        "setup_cms", "setup_pithos", "setup_cyclades"
449
        "supdate": [
450
            "apt_get_update", "setup_astakos",
451
            "setup_cms", "setup_pithos", "setup_cyclades"
449 452
        ],
450
      # backend actions
451
      "backend": [
452
        "setup_hosts",
453
        "update_ns_for_ganeti",
454
        "setup_ganeti", "init_cluster",
455
        "add_rapi_user", "add_nodes",
456
        "setup_image_host", "setup_image_helper",
457
        "setup_network",
458
        "setup_gtools", "add_backend", "add_network",
459
        "setup_lvm", "enable_lvm",
460
        "enable_drbd", "setup_drbd_dparams",
461
        "setup_net_infra", "setup_iptables", "setup_router",
453
        # backend actions
454
        "backend": [
455
            "setup_hosts",
456
            "update_ns_for_ganeti",
457
            "setup_ganeti", "init_cluster",
458
            "add_rapi_user", "add_nodes",
459
            "setup_image_host", "setup_image_helper",
460
            "setup_network",
461
            "setup_gtools", "add_backend", "add_network",
462
            "setup_lvm", "enable_lvm",
463
            "enable_drbd", "setup_drbd_dparams",
464
            "setup_net_infra", "setup_iptables", "setup_router",
462 465
        ],
463
      "bstorage": [
464
        "setup_lvm", "enable_lvm",
465
        "enable_drbd", "setup_drbd_dparams"
466
        "bstorage": [
467
            "setup_lvm", "enable_lvm",
468
            "enable_drbd", "setup_drbd_dparams"
466 469
        ],
467
      "bnetwork": ["setup_net_infra", "setup_iptables", "setup_router"],
468
      "bupdate": [
469
        "apt_get_update", "setup_ganeti", "setup_image_host", "setup_image_helper",
470
        "setup_network", "setup_gtools"
470
        "bnetwork": ["setup_net_infra", "setup_iptables", "setup_router"],
471
        "bupdate": [
472
            "apt_get_update", "setup_ganeti", "setup_image_host",
473
            "setup_image_helper", "setup_network", "setup_gtools"
471 474
        ],
472
      # ganeti actions
473
      "ganeti": [
474
        "update_ns_for_ganeti",
475
        "setup_ganeti", "init_cluster", "add_nodes",
476
        "setup_image_host", "setup_image_helper", "add_image_locally",
477
        "debootstrap", "setup_net_infra",
478
        "setup_lvm", "enable_lvm", "enable_drbd", "setup_drbd_dparams",
475
        # ganeti actions
476
        "ganeti": [
477
            "update_ns_for_ganeti",
478
            "setup_ganeti", "init_cluster", "add_nodes",
479
            "setup_image_host", "setup_image_helper", "add_image_locally",
480
            "debootstrap", "setup_net_infra",
481
            "setup_lvm", "enable_lvm", "enable_drbd", "setup_drbd_dparams",
479 482
        ],
480
      "gupdate": ["setup_apt", "setup_ganeti"],
481
      "gdestroy": ["destroy_cluster"],
482
      }
483
        "gupdate": ["setup_apt", "setup_ganeti"],
484
        "gdestroy": ["destroy_cluster"],
485
    }
483 486

  
484 487
    ret = []
485 488
    for x in args:
486
      ret += actions[x]
489
        ret += actions[x]
487 490

  
488 491
    return ret
489 492

  
......
510 513

  
511 514

  
512 515
def do_create_keys(args, env):
513
  d = os.path.join(env.templates, "root/.ssh")
514
  a = os.path.join(d, "authorized_keys")
515
  # Delete old keys
516
  for filename in os.listdir(d):
517
      os.remove(os.path.join(d, filename))
518
  # Generate new keys
519
  for t in ("dsa", "rsa"):
520
    f = os.path.join(d, "id_" + t)
521
    cmd = 'ssh-keygen -q -t {0} -f {1} -N ""'.format(t, f)
522
    os.system(cmd)
523
    cmd = 'cat {0}.pub >> {1}'.format(f, a)
524
    os.system(cmd)
516
    d = os.path.join(env.templates, "root/.ssh")
517
    a = os.path.join(d, "authorized_keys")
518
    # Delete old keys
519
    for filename in os.listdir(d):
520
        os.remove(os.path.join(d, filename))
521
    # Generate new keys
522
    for t in ("dsa", "rsa"):
523
        f = os.path.join(d, "id_" + t)
524
        cmd = 'ssh-keygen -q -t {0} -f {1} -N ""'.format(t, f)
525
        os.system(cmd)
526
        cmd = 'cat {0}.pub >> {1}'.format(f, a)
527
        os.system(cmd)
528

  
525 529

  
526 530
def add_node(args, env):
527 531
    actions = [
528
      "update_ns_for_node:" + args.cluster_node,
529
      ]
532
        "update_ns_for_node:" + args.cluster_node,
533
    ]
530 534
    fabcommand(args, env, actions)
531 535
    actions = [
532
      "setup_resolv_conf",
533
      "apt_get_update",
534
      "setup_apt",
535
      "setup_hosts",
536
      "add_keys",
537
      ]
536
        "setup_resolv_conf",
537
        "apt_get_update",
538
        "setup_apt",
539
        "setup_hosts",
540
        "add_keys",
541
    ]
538 542
    fabcommand(args, env, actions, [args.cluster_node])
539 543

  
540 544
    actions = get_actions("check")
541 545
    fabcommand(args, env, actions)
542 546

  
543 547
    actions = [
544
      "setup_nfs_clients",
545
      "setup_ganeti",
546
      "setup_image_host", "setup_image_helper", "setup_network", "setup_gtools",
547
      ]
548
        "setup_nfs_clients",
549
        "setup_ganeti",
550
        "setup_image_host", "setup_image_helper",
551
        "setup_network", "setup_gtools",
552
    ]
548 553
    fabcommand(args, env, actions, [args.cluster_node])
549 554

  
550 555
    actions = [
551
      "add_node:" + args.cluster_node,
552
      ]
556
        "add_node:" + args.cluster_node,
557
    ]
553 558
    fabcommand(args, env, actions)
554 559

  
555 560
    actions = [
556
      "setup_lvm", "enable_drbd",
557
      "setup_net_infra", "setup_iptables",
558
      ]
561
        "setup_lvm", "enable_drbd",
562
        "setup_net_infra", "setup_iptables",
563
    ]
559 564
    fabcommand(args, env, actions, [args.cluster_node])
560 565

  
561
def main():
562
  args = parse_options()
563

  
564
  conf = Conf(args)
565
  env = Env(conf)
566

  
567
  create_dir(env.run, False)
568
  create_dir(env.dns, False)
569

  
570
  # Check if there are keys to use
571
  if args.command == "keygen":
572
    if must_create_keys(args.force, env):
573
      do_create_keys(args, env)
574
      return 0
575
    else:
576
      print "Keys already existed.. aborting"
577
      return 1
578
  else:
579
    if (args.key_inject and (args.ssh_key is None)
580
        and must_create_keys(False, env)):
581
      print "No ssh keys to use. Run `snf-deploy keygen' first."
582
      return 1
583

  
584
  if args.command == "test":
585
    conf.print_config()
586

  
587
  if args.command == "cleanup":
588
    cleanup(args, env)
589

  
590
  if args.command == "packages":
591
    create_dir(env.packages, True)
592
    get_packages(args, env)
593

  
594
  if args.command == "vcluster":
595
    image(args, env)
596
    network(args, env)
597
    create_dnsmasq_files(args, env)
598
    dnsmasq(args, env)
599
    cluster(args, env)
600

  
601
  if args.command == "prepare":
602
    actions = get_actions("prepare")
603
    fabcommand(args, env, actions)
604

  
605
  if args.command == "synnefo":
606
    actions = get_actions("synnefo")
607
    fabcommand(args, env, actions)
608

  
609
  if args.command == "backend":
610
    actions = get_actions("backend")
611
    fabcommand(args, env, actions)
612

  
613
  if args.command == "ganeti":
614
    actions = get_actions("ganeti")
615
    fabcommand(args, env, actions)
616

  
617 566

  
618

  
619

  
620
  if args.command == "all":
621
    actions = get_actions("prepare", "synnefo", "backend")
622
    fabcommand(args, env, actions)
623

  
624
  if args.command == "add":
625
    if args.cluster_node:
626
      add_node(args, env)
627
    else:
628
      actions = get_actions("backend")
629
      fabcommand(args, env, actions)
630

  
631

  
632
  if args.command == "run":
633
    if not args.actions:
634
      print_available_actions(args.command)
567
def main():
568
    args = parse_options()
569

  
570
    conf = Conf(args)
571
    env = Env(conf)
572

  
573
    create_dir(env.run, False)
574
    create_dir(env.dns, False)
575

  
576
    # Check if there are keys to use
577
    if args.command == "keygen":
578
        if must_create_keys(args.force, env):
579
            do_create_keys(args, env)
580
            return 0
581
        else:
582
            print "Keys already existed.. aborting"
583
            return 1
635 584
    else:
636
      fabcommand(args, env, args.actions)
585
        if (args.key_inject and (args.ssh_key is None)
586
                and must_create_keys(False, env)):
587
            print "No ssh keys to use. Run `snf-deploy keygen' first."
588
            return 1
589

  
590
    if args.command == "test":
591
        conf.print_config()
592

  
593
    if args.command == "cleanup":
594
        cleanup(args, env)
595

  
596
    if args.command == "packages":
597
        create_dir(env.packages, True)
598
        get_packages(args, env)
599

  
600
    if args.command == "vcluster":
601
        image(args, env)
602
        network(args, env)
603
        create_dnsmasq_files(args, env)
604
        dnsmasq(args, env)
605
        cluster(args, env)
606

  
607
    if args.command == "prepare":
608
        actions = get_actions("prepare")
609
        fabcommand(args, env, actions)
610

  
611
    if args.command == "synnefo":
612
        actions = get_actions("synnefo")
613
        fabcommand(args, env, actions)
614

  
615
    if args.command == "backend":
616
        actions = get_actions("backend")
617
        fabcommand(args, env, actions)
618

  
619
    if args.command == "ganeti":
620
        actions = get_actions("ganeti")
621
        fabcommand(args, env, actions)
622

  
623
    if args.command == "all":
624
        actions = get_actions("prepare", "synnefo", "backend")
625
        fabcommand(args, env, actions)
626

  
627
    if args.command == "add":
628
        if args.cluster_node:
629
            add_node(args, env)
630
        else:
631
            actions = get_actions("backend")
632
            fabcommand(args, env, actions)
633

  
634
    if args.command == "run":
635
        if not args.actions:
636
            print_available_actions(args.command)
637
        else:
638
            fabcommand(args, env, args.actions)
637 639

  
638 640

  
639 641
if __name__ == "__main__":
640
  sys.exit(main())
642
    sys.exit(main())
b/snf-deploy/snfdeploy/lib.py
1 1
#!/usr/bin/python
2 2

  
3
import json
4 3
import time
5 4
import ipaddr
6 5
import os
......
10 9
import re
11 10
import random
12 11
import subprocess
13
import shutil
14 12
import imp
15
import tempfile
16
from snfdeploy import massedit
17 13

  
18 14

  
19 15
HEADER = '\033[95m'
......
85 81

  
86 82
    def update_packages(self, os):
87 83
        for section in self.conf.files[os]:
88
          self.evaluate(os, section)
84
            self.evaluate(os, section)
89 85

  
90 86
    def evaluate(self, filename, section):
91 87
        for k, v in self.conf.get_section(filename, section):
......
152 148
    def get_ganeti(self, cluster_name):
153 149
        self.files["ganeti"] = [cluster_name]
154 150

  
155

  
156 151
    def __init__(self, args):
157 152
        self.confdir = args.confdir
158 153
        self.get_ganeti(args.cluster_name)
......
220 215
        pass
221 216

  
222 217

  
223
def randomMAC():
218
def random_mac():
224 219
    mac = [0x52, 0x54, 0x56,
225 220
           random.randint(0x00, 0xff),
226 221
           random.randint(0x00, 0xff),

Also available in: Unified diff