Commit b79be2cf authored by Julien Muchembled's avatar Julien Muchembled

Merge remote-tracking branch 'origin/master' into erp5-cluster

parents 5dfaff54 9eeac11b
Changes Changes
======= =======
0.80 (2013-08-06)
----------------
* Add a simple readline recipe. [f4fce7e]
0.79 (2013-08-06)
-----------------
* KVM SR: Add support for NAT based networking (User Mode Network). [627895fe35]
* KVM SR: add virtual-hard-drive-url support. [aeb5df40cd, 8ce5a9aa1d0, a5034801aa9]
* Fix regression in GenericBaseRecipe.generatePassword. [3333b07d33c]
0.78.5 (2013-08-06) 0.78.5 (2013-08-06)
----------------------- -------------------
* check_url_available: add option to check secure links [6cbce4d8231] * check_url_available: add option to check secure links [6cbce4d8231]
0.78.4 (2013-08-06) 0.78.4 (2013-08-06)
----------------------- -------------------
* slapos.cookbook:slaprunner: Update to use https. [Cedric Le Ninivin] * slapos.cookbook:slaprunner: Update to use https. [Cedric Le Ninivin]
......
...@@ -28,7 +28,7 @@ from setuptools import setup, find_packages ...@@ -28,7 +28,7 @@ from setuptools import setup, find_packages
import glob import glob
import os import os
version = '0.78.5' version = '0.81-dev'
name = 'slapos.cookbook' name = 'slapos.cookbook'
long_description = open("README.txt").read() + "\n" + \ long_description = open("README.txt").read() + "\n" + \
open("CHANGES.txt").read() + "\n" open("CHANGES.txt").read() + "\n"
...@@ -165,6 +165,7 @@ setup(name=name, ...@@ -165,6 +165,7 @@ setup(name=name,
'publish.serialised = slapos.recipe.publish:Serialised', 'publish.serialised = slapos.recipe.publish:Serialised',
'publishsection = slapos.recipe.publish:PublishSection', 'publishsection = slapos.recipe.publish:PublishSection',
'publishurl = slapos.recipe.publishurl:Recipe', 'publishurl = slapos.recipe.publishurl:Recipe',
'readline = slapos.recipe.readline:Recipe',
'redis.server = slapos.recipe.redis:Recipe', 'redis.server = slapos.recipe.redis:Recipe',
'request = slapos.recipe.request:Recipe', 'request = slapos.recipe.request:Recipe',
'request.serialised = slapos.recipe.request:Serialised', 'request.serialised = slapos.recipe.request:Serialised',
......
...@@ -26,7 +26,11 @@ ...@@ -26,7 +26,11 @@
############################################################################## ##############################################################################
import os import os
from slapos.recipe.librecipe import GenericBaseRecipe if __name__ == '__main__': # Hack to easily run test below.
GenericBaseRecipe = object
else:
from slapos.recipe.librecipe import GenericBaseRecipe
from zc.buildout import UserError
class Recipe(GenericBaseRecipe): class Recipe(GenericBaseRecipe):
...@@ -51,18 +55,111 @@ class Recipe(GenericBaseRecipe): ...@@ -51,18 +55,111 @@ class Recipe(GenericBaseRecipe):
return [script] return [script]
class Part(GenericBaseRecipe): class Part(GenericBaseRecipe):
def install(self): def install(self):
try:
periodicity = self.options['frequency']
except KeyError:
periodicity = self.options['time']
try:
periodicity = systemd_to_cron(periodicity)
except Exception:
raise UserError("Invalid systemd calendar spec %r" % periodicity)
cron_d = self.options['cron-entries'] cron_d = self.options['cron-entries']
name = self.options['name'] name = self.options['name']
filename = os.path.join(cron_d, name) filename = os.path.join(cron_d, name)
with open(filename, 'w') as part: with open(filename, 'w') as part:
part.write('%(frequency)s %(command)s\n' % { part.write('%s %s\n' % (periodicity, self.options['command']))
'frequency': self.options['frequency'],
'command': self.options['command'],
})
return [filename] return [filename]
day_of_week_dict = dict((name, dow) for dow, name in enumerate(
"sunday monday tuesday wednesday thursday friday saturday".split())
for name in (name, name[:3]))
def systemd_to_cron(spec):
"""Convert from systemd.time(7) calendar spec to crontab spec"""
if spec in ("hourly", "daily", "monthly", "weekly"):
return '@' + spec
if not spec.strip():
raise ValueError
spec = spec.split(' ')
try:
dow = ','.join(sorted('-'.join(str(day_of_week_dict[x.lower()])
for x in x.split('-', 1))
for x in spec[0].split(',')
if x))
del spec[0]
except KeyError:
dow = '*'
day = spec.pop(0) if spec else '*-*'
if spec:
time, = spec
elif ':' in day:
time = day
day = '*-*'
else:
time = '0:0'
day = day.split('-')
time = time.split(':')
if (# years not supported
len(day) > 2 and day.pop(0) != '*' or
# some crons ignore day of month if day of week is given, and dcron
# treats day of month in a way that is not compatible with systemd
dow != '*' != day[1] or
# seconds not supported
len(time) > 2 and int(time.pop())):
raise ValueError
month, day = day
hour, minute = time
spec = minute, hour, day, month, dow
for x, (y, z) in zip(spec, ((0, 60), (0, 24), (1, 31), (1, 12))):
if x != '*':
for x in x.split(','):
x = map(int, x.split('/', 1))
x[0] -= y
if x[0] < 0 or len(x) > 1 and x[0] >= x[1] or z <= sum(x):
raise ValueError
return ' '.join(spec)
def test(self):
def _(systemd, cron):
self.assertEqual(systemd_to_cron(systemd), cron)
_("Sat,Mon-Thu,Sun", "0 0 * * 0,1-4,6")
_("mon,sun *-* 2,1:23", "23 2,1 * * 0,1")
_("Wed, 17:48", "48 17 * * 3")
_("Wed-Sat,Tue 10-* 1:2", "2 1 * 10 2,3-6")
_("*-*-7 0:0:0", "0 0 7 * *")
_("10-15", "0 0 15 10 *")
_("monday *-12-* 17:00", "00 17 * 12 1")
_("12,14,13,12:20,10,30", "20,10,30 12,14,13,12 * * *") # TODO: sort
_("*-1/2-1,3 *:30", "30 * 1,3 1/2 *")
_("03-05 08:05", "05 08 05 03 *")
_("08:05:00", "05 08 * * *")
_("05:40", "40 05 * * *")
_("Sat,Sun 12-* 08:05", "05 08 * 12 0,6")
_("Sat,Sun 08:05", "05 08 * * 0,6")
def _(systemd):
self.assertRaises(Exception, systemd_to_cron, systemd)
_("test")
_("")
_("7")
_("121212:1:2")
_("Wed *-1")
_("08:05:40")
_("2003-03-05")
_("0-1"); _("13-1"); _("6/4-1"); _("5/8-1")
_("1-0"); _("1-32"); _("1-4/3"); _("1-14/18")
_("24:0");_("9/9:0"); _("8/16:0")
_("0:60"); _("0:22/22"); _("0:15/45")
if __name__ == '__main__':
import unittest
unittest.TextTestRunner().run(type('', (unittest.TestCase,), {
'runTest': test})())
...@@ -41,40 +41,40 @@ class Recipe(GenericBaseRecipe): ...@@ -41,40 +41,40 @@ class Recipe(GenericBaseRecipe):
'"virtio" value.' '"virtio" value.'
self.options['disk-type'] = 'virtio' self.options['disk-type'] = 'virtio'
config = dict( self.options['python-path'] = sys.executable
tap_interface=self.options['tap'],
vnc_ip=self.options['vnc-ip'], path_list = []
vnc_port=self.options['vnc-port'],
nbd_ip=self.options['nbd-host'], if not self.isTrueValue(self.options.get('use-tap')):
nbd_port=self.options['nbd-port'], # XXX This could be done using Jinja.
nbd2_ip=self.options.get('nbd2-host', ''), for port in self.options['nat-rules'].split():
nbd2_port=self.options.get('nbd2-port', 1024), ipv6_port = int(port) + 10000
disk_path=self.options['disk-path'], tunnel_path = self.createExecutable(
disk_size=self.options['disk-size'], '%s-%sto%s' % (self.options['6tunnel-wrapper-path'], port, ipv6_port),
disk_type=self.options['disk-type'], self.substituteTemplate(
mac_address=self.options['mac-address'], self.getTemplateFilename('6to4.in'),
smp_count=self.options['smp-count'], {
ram_size=self.options['ram-size'], 'ipv6': self.options['ipv6'],
socket_path=self.options['socket-path'], 'ipv6_port': ipv6_port,
pid_file_path=self.options['pid-path'], 'ipv4': self.options['ipv4'],
python_path=sys.executable, 'ipv4_port': port,
shell_path=self.options['shell-path'], 'shell_path': self.options['shell-path'],
qemu_path=self.options['qemu-path'], '6tunnel_path': self.options['6tunnel-path'],
qemu_img_path=self.options['qemu-img-path'], },
vnc_passwd=self.options['passwd'], ),
default_disk_image=self.options['default-disk-image'],
) )
path_list.append(tunnel_path)
# Runners
runner_path = self.createExecutable( runner_path = self.createExecutable(
self.options['runner-path'], self.options['runner-path'],
self.substituteTemplate(self.getTemplateFilename('kvm_run.in'), self.substituteTemplate(self.getTemplateFilename('kvm_run.in'),
config)) self.options))
path_list.append(runner_path)
controller_path = self.createExecutable( controller_path = self.createExecutable(
self.options['controller-path'], self.options['controller-path'],
self.substituteTemplate(self.getTemplateFilename('kvm_controller_run.in'), self.substituteTemplate(self.getTemplateFilename('kvm_controller_run.in'),
config)) self.options))
return [runner_path, controller_path] return path_list
#!%(shell_path)s
# BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically
exec %(6tunnel_path)s -6 -4 -d -l %(ipv6)s %(ipv6_port)s %(ipv4)s %(ipv4_port)s
#!%(python_path)s #!%(python-path)s
# BEWARE: This file is operated by slapgrid # BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically # BEWARE: It will be overwritten automatically
...@@ -6,12 +6,15 @@ ...@@ -6,12 +6,15 @@
import socket import socket
import time import time
socket_path = '%(socket-path)s'
vnc_password = '%(vnc-passwd)s'
# Connect to KVM qmp socket # Connect to KVM qmp socket
so = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) so = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
connected = False connected = False
while not connected: while not connected:
try: try:
so.connect('%(socket_path)s') so.connect(socket_path)
except socket.error: except socket.error:
time.sleep(1) time.sleep(1)
else: else:
...@@ -25,7 +28,7 @@ data = so.recv(1024) ...@@ -25,7 +28,7 @@ data = so.recv(1024)
# Set VNC password # Set VNC password
so.send('{ "execute": "change", ' \ so.send('{ "execute": "change", ' \
'"arguments": { "device": "vnc", "target": "password", ' \ '"arguments": { "device": "vnc", "target": "password", ' \
' "arg": "%(vnc_passwd)s" } }') ' "arg": "' + vnc_password + '" } }')
data = so.recv(1024) data = so.recv(1024)
# Finish # Finish
......
#!%(python_path)s #!%(python-path)s
# BEWARE: This file is operated by slapgrid # BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically # BEWARE: It will be overwritten automatically
# Echo client program import hashlib
import os import os
import socket import socket
import subprocess import subprocess
import urllib
# XXX: give all of this through parameter, don't use this as template # XXX: give all of this through parameter, don't use this as template, but as module
default_disk_image = '%(default_disk_image)s' qemu_img_path = '%(qemu-img-path)s'
qemu_path = '%(qemu-path)s'
disk_size = '%(disk-size)s'
disk_type = '%(disk-type)s'
socket_path = '%(socket-path)s'
nbd_list = (('%(nbd-host)s', %(nbd-port)s), ('%(nbd2-host)s', %(nbd2-port)s))
default_disk_image = '%(default-disk-image)s'
disk_path = '%(disk-path)s'
virtual_hard_drive_url = '%(virtual-hard-drive-url)s'.strip()
virtual_hard_drive_md5_url = '%(virtual-hard-drive-md5-url)s'.strip()
nat_rules = '%(nat-rules)s'.strip()
use_tap = '%(use-tap)s'
tap_interface = '%(tap-interface)s'
listen_ip = '%(ipv4)s'
mac_address = '%(mac-address)s'
smp_count = '%(smp-count)s'
ram_size = '%(ram-size)s'
pid_file_path = '%(pid-file-path)s'
def md5Checksum(file_path):
with open(file_path, 'rb') as fh:
m = hashlib.md5()
while True:
data = fh.read(8192)
if not data:
break
m.update(data)
return m.hexdigest()
def getSocketStatus(host, port): def getSocketStatus(host, port):
s = None s = None
...@@ -29,28 +57,44 @@ def getSocketStatus(host, port): ...@@ -29,28 +57,44 @@ def getSocketStatus(host, port):
break break
return s return s
# Download existing hard drive if needed at first boot
if not os.path.exists(disk_path) and virtual_hard_drive_url != '':
urllib.urlretrieve(virtual_hard_drive_url, disk_path)
local_md5sum = md5Checksum(disk_path)
md5sum = urllib.urlopen(virtual_hard_drive_md5_url).read().strip()
if local_md5sum != md5sum:
os.remove(disk_path)
raise Exception('MD5 mismatch.')
# Create disk if doesn't exist # Create disk if doesn't exist
# XXX: move to Buildout profile # XXX: move to Buildout profile
disk_path = '%(disk_path)s'
if not os.path.exists(disk_path): if not os.path.exists(disk_path):
subprocess.Popen(['%(qemu_img_path)s', 'create' ,'-f', 'qcow2', subprocess.Popen([qemu_img_path, 'create' ,'-f', 'qcow2',
disk_path, '%(disk_size)sG']) disk_path, '%%sG' %% disk_size])
kvm_argument_list = ['%(qemu_path)s', # Generate network parameters
'-enable-kvm', '-net', 'nic,macaddr=%(mac_address)s', # XXX: use_tap should be a boolean
'-net', 'tap,ifname=%(tap_interface)s,script=no,downscript=no', if use_tap == 'True':
'-smp', '%(smp_count)s', qemu_network_parameter = 'tap,ifname=%%s,script=no,downscript=no' %% tap_interface
'-m', '%(ram_size)s', else:
'-drive', 'file=%(disk_path)s,if=%(disk_type)s', qemu_network_parameter = 'user,' + ','.join('hostfwd=tcp:%%s:%%s-:%%s' %% (listen_ip, int(port) + 10000, port) for port in nat_rules.split())
'-vnc', '%(vnc_ip)s:1,ipv4,password',
kvm_argument_list = [qemu_path,
'-enable-kvm', '-net', 'nic,macaddr=%%s' %% mac_address,
'-net', qemu_network_parameter,
'-smp', smp_count,
'-m', ram_size,
'-drive', 'file=%%s,if=%%s' %% (disk_path, disk_type),
'-vnc', '%%s:1,ipv4,password' %% listen_ip,
'-boot', 'menu=on', '-boot', 'menu=on',
'-qmp', 'unix:%(socket_path)s,server', '-qmp', 'unix:%%s,server' %% socket_path,
'-pidfile', '%(pid_file_path)s', '-pidfile', pid_file_path,
] ]
# Try to connect to NBD server (and second nbd if defined) # Try to connect to NBD server (and second nbd if defined).
for nbd_ip, nbd_port in ( # If not available, don't even specify it in qemu command line parameters.
('%(nbd_ip)s', %(nbd_port)s), ('%(nbd2_ip)s', %(nbd2_port)s)): # Reason: if qemu starts with unavailable NBD drive, it will just crash.
for nbd_ip, nbd_port in nbd_list:
if nbd_ip and nbd_port: if nbd_ip and nbd_port:
s = getSocketStatus(nbd_ip, nbd_port) s = getSocketStatus(nbd_ip, nbd_port)
if s is None: if s is None:
...@@ -61,11 +105,10 @@ for nbd_ip, nbd_port in ( ...@@ -61,11 +105,10 @@ for nbd_ip, nbd_port in (
kvm_argument_list.extend([ kvm_argument_list.extend([
'-drive', '-drive',
'file=nbd:[%%s]:%%s,media=cdrom' %% (nbd_ip, nbd_port)]) 'file=nbd:[%%s]:%%s,media=cdrom' %% (nbd_ip, nbd_port)])
# If no NBD is specified/available: use internal disk image # If no NBD is specified/available: use internal disk image
else: else:
kvm_argument_list.extend([ kvm_argument_list.extend([
'-drive', 'file=%%s,media=cdrom' %% default_disk_image '-drive', 'file=%%s,media=cdrom' %% default_disk_image
]) ])
os.execv('%(qemu_path)s', kvm_argument_list) os.execv(qemu_path, kvm_argument_list)
# vim: set et sts=2:
##############################################################################
#
# Copyright (c) 2013 Vifib SARL and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import errno
class Recipe(object):
"""Read the first line of a file.
As the result has to be provided as an options, it is mandatory that the
buildout profile fills the file content (if needed) before trying to read it.
Options:
- storage-path: file to read
Result set in options:
- readline: first line of the file
"""
def __init__(self, buildout, name, options):
storage_path = options['storage-path']
try:
with open(storage_path) as f:
readline = f.readline()
except IOError, e:
if e.errno != errno.ENOENT:
raise
readline = None
self.readline = readline
options['readline'] = readline
def install(self):
if self.readline is None:
raise ValueError('Unable to read the file content.')
return ()
def update(self):
return ()
...@@ -76,27 +76,21 @@ type = rsa ...@@ -76,27 +76,21 @@ type = rsa
[{{ slave_reference }}-backup-public_key] [{{ slave_reference }}-backup-public_key]
recipe = plone.recipe.command recipe = plone.recipe.command
stop-on-error = true stop-on-error = true
update-command = $${:command}
command = ${coreutils-output:rm} -f $${:key} && ${dropbear-output:keygen} -y -f {{ '$${' ~ slave_reference }}-backup-private_key:key} | ${grep-output:grep} {{ '$${' ~ slave_reference }}-backup-private_key:type} > $${:key} command = ${coreutils-output:rm} -f $${:key} && ${dropbear-output:keygen} -y -f {{ '$${' ~ slave_reference }}-backup-private_key:key} | ${grep-output:grep} {{ '$${' ~ slave_reference }}-backup-private_key:type} > $${:key}
key = {{ '$${' ~ slave_reference }}-backup-private_key:key}.pub key = {{ '$${' ~ slave_reference }}-backup-private_key:key}.pub
location = $${:key} location = $${:key}
# Insert as a beginning part, to ensure that all public keys are generated before trying to publish. This will reduce the number of slapgrid-cp run.
[{{ slave_reference }}-backup-check-public_key] {% do part_list.insert(0, "%s-backup-public_key" % slave_reference) -%}
recipe = plone.recipe.command
stop-on-error = true
update-command = $${:command}
command = grep ssh-{{ '$${' ~ slave_reference }}-backup-private_key:type} {{ '$${' ~ slave_reference }}-backup-public_key:key}
[{{ slave_reference }}-backup-read-public_key] [{{ slave_reference }}-backup-read-public_key]
recipe = slapos.cookbook:generate.password recipe = slapos.cookbook:readline
storage-path = {{ '$${' ~ slave_reference }}-backup-public_key:key} storage-path = {{ '$${' ~ slave_reference }}-backup-public_key:key}
bytes = 8
# Publish slave {{ slave_reference }} information # Publish slave {{ slave_reference }} information
[{{ slave_reference }}-backup-publish] [{{ slave_reference }}-backup-publish]
recipe = slapos.cookbook:publish recipe = slapos.cookbook:publish
-slave-reference = {{ slave_reference }} -slave-reference = {{ slave_reference }}
authorized_key = {{ '$${' ~ slave_reference }}-backup-read-public_key:passwd} authorized_key = {{ '$${' ~ slave_reference }}-backup-read-public_key:readline}
{% do part_list.append("%s-backup-publish" % slave_reference) -%} {% do part_list.append("%s-backup-publish" % slave_reference) -%}
[{{ slave_reference }}-backup-script] [{{ slave_reference }}-backup-script]
...@@ -133,7 +127,6 @@ frequency = {{ frequency }} ...@@ -133,7 +127,6 @@ frequency = {{ frequency }}
# XXX File is never removed # XXX File is never removed
recipe = plone.recipe.command recipe = plone.recipe.command
stop-on-error = true stop-on-error = true
update-command = $${:command}
command = ${coreutils-output:cat} ${template-crontab:output} {{ crontab_line_list_string }} | ${dcron-output:crontab} -c $${directory:crontabs} - command = ${coreutils-output:cat} ${template-crontab:output} {{ crontab_line_list_string }} | ${dcron-output:crontab} -c $${directory:crontabs} -
......
...@@ -197,7 +197,7 @@ mode = 0644 ...@@ -197,7 +197,7 @@ mode = 0644
[template-pullrdiffbackup] [template-pullrdiffbackup]
recipe = slapos.recipe.template recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance-pullrdiffbackup.cfg.in url = ${:_profile_base_location_}/instance-pullrdiffbackup.cfg.in
md5sum = 62c236773dadecac11eb9a47dbca9351 md5sum = 213256229360f57c778308825b161321
output = ${buildout:directory}/template-pullrdiffbackup.cfg output = ${buildout:directory}/template-pullrdiffbackup.cfg
mode = 0644 mode = 0644
...@@ -218,7 +218,7 @@ gunicorn = 17.5 ...@@ -218,7 +218,7 @@ gunicorn = 17.5
itsdangerous = 0.22 itsdangerous = 0.22
meld3 = 0.6.10 meld3 = 0.6.10
plone.recipe.command = 1.1 plone.recipe.command = 1.1
slapos.cookbook = 0.78.3 slapos.cookbook = 0.80
slapos.recipe.build = 0.11.6 slapos.recipe.build = 0.11.6
slapos.recipe.cmmi = 0.1.1 slapos.recipe.cmmi = 0.1.1
slapos.recipe.template = 2.4.2 slapos.recipe.template = 2.4.2
......
[buildout] [buildout]
extends = extends =
../../component/6tunnel/buildout.cfg
../../component/curl/buildout.cfg ../../component/curl/buildout.cfg
../../component/dash/buildout.cfg ../../component/dash/buildout.cfg
../../component/dcron/buildout.cfg ../../component/dcron/buildout.cfg
...@@ -84,7 +85,7 @@ mode = 0644 ...@@ -84,7 +85,7 @@ mode = 0644
[template-kvm] [template-kvm]
recipe = slapos.recipe.template recipe = slapos.recipe.template
url = ${:_profile_base_location_}/instance-kvm.cfg.in url = ${:_profile_base_location_}/instance-kvm.cfg.in
md5sum = f7c0e2172dac4ee70daae50f38d610ef #md5sum = c3c888c78bbff334135be9e8ad5885a9
output = ${buildout:directory}/template-kvm.cfg output = ${buildout:directory}/template-kvm.cfg
mode = 0644 mode = 0644
......
{ {
"name": "Input Parameters", "type": "object",
"$schema": "http://json-schema.org/draft-04/schema",
"title": "Input Parameters",
"properties": { "properties": {
"ram-size": { "ram-size": {
"title": "RAM size", "title": "RAM size",
...@@ -7,7 +10,7 @@ ...@@ -7,7 +10,7 @@
"type": "integer", "type": "integer",
"default": 1024, "default": 1024,
"minimum": 128, "minimum": 128,
"divisibleBy": 128, "multipleOf": 128,
"maximum": 16384 "maximum": 16384
}, },
"disk-size": { "disk-size": {
...@@ -34,7 +37,6 @@ ...@@ -34,7 +37,6 @@
"maximum": 8 "maximum": 8
}, },
"nbd-host": { "nbd-host": {
"title": "NBD hostname", "title": "NBD hostname",
"description": "hostname (or IP) of the NBD server containing the boot image.", "description": "hostname (or IP) of the NBD server containing the boot image.",
...@@ -65,6 +67,25 @@ ...@@ -65,6 +67,25 @@
"maximum": 65535 "maximum": 65535
}, },
"virtual-hard-drive-url": {
"title": "Existing disk image URL",
"description": "If specified, will download an existing disk image (qcow2, raw, ...), and will use it as main virtual hard drive. Can be used to download and use an already installed and customized virtual hard drive.",
"format": "uri",
"type": "string",
},
"use-tap": {
"title": "Use QEMU TAP network interface",
"description": "Use QEMU TAP network interface, requires a bridge on SlapOS Node. If false, use user-mode network stack (NAT).",
"type": "boolean",
"default": false
},
"nat-rules": {
"title": "List of rules for NAT of QEMU user mode network stack.",
"description": "List of rules for NAT of QEMU user mode network stack, as comma-separated list of ports. For each port specified, it will redirect port x of the VM (example: 80) to the port x + 10000 of the public IPv6 (example: 10080). Defaults to \"22 80 443\". Ignored if \"use-tap\" parameter is enabled.",
"type": "string",
},
"frontend-instance-guid": { "frontend-instance-guid": {
"title": "Frontend Instance ID", "title": "Frontend Instance ID",
......
...@@ -13,13 +13,6 @@ ...@@ -13,13 +13,6 @@
"description": "URL used to connect to the service.", "description": "URL used to connect to the service.",
"type": "uri", "type": "uri",
"required": false "required": false
},
"password": {
"title": "Password",
"description": "Password used to authenticate in the service webpage.",
"type": "uri",
"required": true
} }
} }
} }
...@@ -45,32 +45,56 @@ recipe = slapos.cookbook:generate.password ...@@ -45,32 +45,56 @@ recipe = slapos.cookbook:generate.password
storage-path = $${directory:srv}/passwd storage-path = $${directory:srv}/passwd
bytes = 8 bytes = 8
[kvm-instance] [kvm-instance]
# XXX-Cedric: change "KVM" recipe to simple "create wrappers". No need for this # XXX-Cedric: change "KVM" recipe to simple "create wrappers". No need for this
# Specific code # Specific code. It needs Jinja.
recipe = slapos.cookbook:kvm recipe = slapos.cookbook:kvm
vnc-ip = $${slap-network-information:local-ipv4}
vnc-passwd = $${gen-passwd:passwd}
ipv4 = $${slap-network-information:local-ipv4}
ipv6 = $${slap-network-information:global-ipv6}
vnc-ip = $${:ipv4}
vnc-port = 5901 vnc-port = 5901
# XXX-Cedric: should be named "default-cdrom-iso"
default-disk-image = ${debian-amd64-netinst.iso:location}/${debian-amd64-netinst.iso:filename} default-disk-image = ${debian-amd64-netinst.iso:location}/${debian-amd64-netinst.iso:filename}
nbd-host = $${slap-parameter:nbd-host} nbd-host = $${slap-parameter:nbd-host}
nbd-port = $${slap-parameter:nbd-port} nbd-port = $${slap-parameter:nbd-port}
nbd2-host = $${slap-parameter:nbd2-host} nbd2-host = $${slap-parameter:nbd2-host}
nbd2-port = $${slap-parameter:nbd2-port} nbd2-port = $${slap-parameter:nbd2-port}
tap = $${slap-network-information:network-interface}
tap-interface = $${slap-network-information:network-interface}
disk-path = $${directory:srv}/virtual.qcow2 disk-path = $${directory:srv}/virtual.qcow2
disk-size = $${slap-parameter:disk-size} disk-size = $${slap-parameter:disk-size}
disk-type = $${slap-parameter:disk-type} disk-type = $${slap-parameter:disk-type}
socket-path = $${directory:var}/qmp_socket socket-path = $${directory:var}/qmp_socket
pid-path = $${directory:run}/pid_file pid-file-path = $${directory:run}/pid_file
smp-count = $${slap-parameter:cpu-count} smp-count = $${slap-parameter:cpu-count}
ram-size = $${slap-parameter:ram-size} ram-size = $${slap-parameter:ram-size}
mac-address = $${create-mac:mac-address} mac-address = $${create-mac:mac-address}
# XXX-Cedric: should be named runner-wrapper-path and controller-wrapper-path
runner-path = $${directory:services}/kvm runner-path = $${directory:services}/kvm
controller-path = $${directory:scripts}/kvm_controller controller-path = $${directory:scripts}/kvm_controller
use-tap = $${slap-parameter:use-tap}
nat-rules = $${slap-parameter:nat-rules}
6tunnel-wrapper-path = $${directory:services}/6tunnel
virtual-hard-drive-url = $${slap-parameter:virtual-hard-drive-url}
virtual-hard-drive-md5-url = $${slap-parameter:virtual-hard-drive-md5-url}
shell-path = ${dash:location}/bin/dash shell-path = ${dash:location}/bin/dash
qemu-path = ${kvm:location}/bin/qemu-system-x86_64 qemu-path = ${kvm:location}/bin/qemu-system-x86_64
qemu-img-path = ${kvm:location}/bin/qemu-img qemu-img-path = ${kvm:location}/bin/qemu-img
passwd = $${gen-passwd:passwd} 6tunnel-path = ${6tunnel:location}/bin/6tunnel
[kvm-promise] [kvm-promise]
recipe = slapos.cookbook:check_port_listening recipe = slapos.cookbook:check_port_listening
...@@ -188,8 +212,8 @@ sla-instance_guid = $${slap-parameter:frontend-instance-guid} ...@@ -188,8 +212,8 @@ sla-instance_guid = $${slap-parameter:frontend-instance-guid}
[publish-connection-information] [publish-connection-information]
recipe = slapos.cookbook:publish recipe = slapos.cookbook:publish
backend-url = https://[$${novnc-instance:ip}]:$${novnc-instance:port}/vnc_auto.html?host=[$${novnc-instance:ip}]&port=$${novnc-instance:port}&encrypt=1&password=$${kvm-instance:passwd} backend-url = https://[$${novnc-instance:ip}]:$${novnc-instance:port}/vnc_auto.html?host=[$${novnc-instance:ip}]&port=$${novnc-instance:port}&encrypt=1&password=$${kvm-instance:vnc-passwd}
url = $${request-slave-frontend:connection-url}/vnc_auto.html?host=$${request-slave-frontend:connection-domainname}&port=$${request-slave-frontend:connection-port}&encrypt=1&path=$${request-slave-frontend:connection-resource}&password=$${kvm-instance:passwd} url = $${request-slave-frontend:connection-url}/vnc_auto.html?host=$${request-slave-frontend:connection-domainname}&port=$${request-slave-frontend:connection-port}&encrypt=1&path=$${request-slave-frontend:connection-resource}&password=$${kvm-instance:vnc-passwd}
[frontend-promise] [frontend-promise]
...@@ -214,3 +238,9 @@ disk-size = 10 ...@@ -214,3 +238,9 @@ disk-size = 10
disk-type = virtio disk-type = virtio
cpu-count = 1 cpu-count = 1
nat-rules = 22 80 443
use-tap = False
virtual-hard-drive-url =
virtual-hard-drive-md5-url =
...@@ -59,7 +59,7 @@ meld3 = 0.6.10 ...@@ -59,7 +59,7 @@ meld3 = 0.6.10
plone.recipe.command = 1.1 plone.recipe.command = 1.1
pycrypto = 2.6 pycrypto = 2.6
rdiff-backup = 1.0.5 rdiff-backup = 1.0.5
slapos.cookbook = 0.78.3 slapos.cookbook = 0.79
slapos.recipe.cmmi = 0.2 slapos.recipe.cmmi = 0.2
slapos.recipe.download = 1.0.dev-r4053 slapos.recipe.download = 1.0.dev-r4053
slapos.recipe.template = 2.4.2 slapos.recipe.template = 2.4.2
...@@ -86,15 +86,15 @@ atomize = 0.1.1 ...@@ -86,15 +86,15 @@ atomize = 0.1.1
feedparser = 5.1.3 feedparser = 5.1.3
# Required by: # Required by:
# slapos.cookbook==0.78.3 # slapos.cookbook==0.79
inotifyx = 0.2.0-1 inotifyx = 0.2.0-1
# Required by: # Required by:
# slapos.cookbook==0.78.3 # slapos.cookbook==0.79
lock-file = 2.0 lock-file = 2.0
# Required by: # Required by:
# slapos.cookbook==0.78.3 # slapos.cookbook==0.79
netaddr = 0.7.10 netaddr = 0.7.10
# Required by: # Required by:
...@@ -118,11 +118,11 @@ psutil = 1.0.1 ...@@ -118,11 +118,11 @@ psutil = 1.0.1
pyflakes = 0.7.3 pyflakes = 0.7.3
# Required by: # Required by:
# slapos.cookbook==0.78.3 # slapos.cookbook==0.79
pytz = 2013b pytz = 2013b
# Required by: # Required by:
# slapos.cookbook==0.78.3 # slapos.cookbook==0.79
# slapos.toolbox==0.35.0 # slapos.toolbox==0.35.0
slapos.core = 0.35.1 slapos.core = 0.35.1
...@@ -135,7 +135,7 @@ supervisor = 3.0b2 ...@@ -135,7 +135,7 @@ supervisor = 3.0b2
unittest2 = 0.5.1 unittest2 = 0.5.1
# Required by: # Required by:
# slapos.cookbook==0.78.3 # slapos.cookbook==0.79
# slapos.toolbox==0.35.0 # slapos.toolbox==0.35.0
xml-marshaller = 0.9.7 xml-marshaller = 0.9.7
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment