Commit 1ecf5954 authored by Julien Muchembled's avatar Julien Muchembled

New vm.* recipes to build VM images and execute commands inside them

parent 0f601ebf
...@@ -40,6 +40,8 @@ setup(name=name, ...@@ -40,6 +40,8 @@ setup(name=name,
'download-unpacked = slapos.recipe.downloadunpacked:Recipe', 'download-unpacked = slapos.recipe.downloadunpacked:Recipe',
'gitclone = slapos.recipe.gitclone:Recipe', 'gitclone = slapos.recipe.gitclone:Recipe',
'npm = slapos.recipe.npm:Npm', 'npm = slapos.recipe.npm:Npm',
'vm.install-debian = slapos.recipe.vm:InstallDebianRecipe',
'vm.run = slapos.recipe.vm:RunRecipe',
], ],
'zc.buildout.uninstall': [ 'zc.buildout.uninstall': [
'gitclone = slapos.recipe.gitclone:uninstall', 'gitclone = slapos.recipe.gitclone:uninstall',
......
...@@ -4,3 +4,60 @@ try: ...@@ -4,3 +4,60 @@ try:
except ImportError: except ImportError:
from pkgutil import extend_path from pkgutil import extend_path
__path__ = extend_path(__path__, __name__) __path__ = extend_path(__path__, __name__)
import errno, logging, os, shutil
import zc.buildout
logger = logging.getLogger(__name__)
def generatePassword(length=8):
from random import SystemRandom
from string import ascii_lowercase
return ''.join(SystemRandom().sample(ascii_lowercase, length))
def rmtree(path):
try:
os.remove(path)
except OSError, e:
if e.errno != errno.EISDIR:
raise
shutil.rmtree(path)
class EnvironMixin:
def __init__(self, allow_none=True):
environment = self.options.get('environment', '').strip()
if environment:
from os import environ
if '=' in environment:
self._environ = env = {}
for line in environment.splitlines():
line = line.strip()
if line:
try:
k, v = line.split('=', 1)
except ValueError:
raise zc.buildout.UserError('Line %r in environment is incorrect' %
line)
k = k.strip()
if k in env:
raise zc.buildout.UserError('Key %r is repeated' % k)
env[k] = v.strip() % environ
else:
self._environ = {k: v.strip() % environ
for k, v in self.buildout[environment].iteritems()}
else:
self._environ = None if allow_none else {}
@property
def environ(self):
if self._environ is not None:
from os import environ
env = self._environ.copy()
for k, v in env.iteritems():
logger.info(
'Environment %r set to %r' if k in environ else
'Environment %r added with %r', k, v)
for kw in environ.iteritems():
env.setdefault(*kw)
return env
...@@ -35,6 +35,7 @@ import subprocess ...@@ -35,6 +35,7 @@ import subprocess
import sys import sys
import tempfile import tempfile
import zc.buildout import zc.buildout
from slapos.recipe import rmtree, EnvironMixin
ARCH_MAP = { ARCH_MAP = {
'i386': 'x86', 'i386': 'x86',
...@@ -122,17 +123,9 @@ def guessOperatingSystem(): ...@@ -122,17 +123,9 @@ def guessOperatingSystem():
assert target, 'Unknown architecture' assert target, 'Unknown architecture'
return target return target
def rmtree(path):
try:
os.remove(path)
except OSError, e:
if e.errno != errno.EISDIR:
raise
shutil.rmtree(path)
TRUE_LIST = ('y', 'on', 'yes', 'true', '1') TRUE_LIST = ('y', 'on', 'yes', 'true', '1')
class Script: class Script(EnvironMixin):
"""Free script building system""" """Free script building system"""
def _checkPromise(self, promise_key, location): def _checkPromise(self, promise_key, location):
promise_text = self.options.get(promise_key) promise_text = self.options.get(promise_key)
...@@ -285,43 +278,15 @@ class Script: ...@@ -285,43 +278,15 @@ class Script:
self.keep_on_error = True self.keep_on_error = True
else: else:
self.keep_on_error = False self.keep_on_error = False
EnvironMixin.__init__(self, False)
def getEnvironment(self):
# prepare cool dictionary
wanted_env = {}
for line in self.options.get('environment', '').splitlines():
line = line.strip()
if not line:
continue
if not '=' in line:
raise zc.buildout.UserError('Line %r in environment is incorrect' %
line)
key, value = line.split('=', 1)
key = key.strip()
value = value.strip()
if key in wanted_env:
raise zc.buildout.UserError('Key %r is repeated' % key)
wanted_env[key] = value
env = {}
for k, v in os.environ.iteritems():
change = wanted_env.pop(k, None)
if change is not None:
env[k] = change % os.environ
self.logger.info('Environment %r setup to %r' % (k, env[k]))
else:
env[k] = v
for k, v in wanted_env.iteritems():
self.logger.info('Environment %r added with %r' % (k, v))
env[k] = v
return env
def install(self): def install(self):
location = self.options['location'] location = self.options['location']
if os.path.lexists(location): if os.path.lexists(location):
self.logger.warning('Removing already existing path %r', location) self.logger.warning('Removing already existing path %r', location)
rmtree(location) rmtree(location)
env = self.getEnvironment() # env is used in script exec'ed below # env is used in script exec'ed below
env = self.environ
try: try:
exec self.script exec self.script
self._checkPromise('slapos_promise', location) self._checkPromise('slapos_promise', location)
......
This diff is collapsed.
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