Merge pull request #23488 from cellscape/lxc-cloud-fixes

LXC cloud fixes
This commit is contained in:
Thomas S Hatch 2015-05-15 12:09:35 -06:00
commit d9af0c3e82
4 changed files with 47 additions and 22 deletions

View file

@ -355,7 +355,7 @@ class CloudClient(object):
'''
Destroy the named VMs
'''
mapper = salt.cloud.Map(self._opts_defaults())
mapper = salt.cloud.Map(self._opts_defaults(destroy=True))
if isinstance(names, str):
names = names.split(',')
return salt.utils.cloud.simple_types_filter(
@ -376,7 +376,7 @@ class CloudClient(object):
'delvol_on_destroy': True})
'''
mapper = salt.cloud.Map(self._opts_defaults())
providers = mapper.map_providers_parallel()
providers = self.opts['providers']
if provider in providers:
provider += ':{0}'.format(providers[provider].iterkeys().next())
else:
@ -450,7 +450,7 @@ class CloudClient(object):
kwargs={'image': 'ami-10314d79'}
)
'''
mapper = salt.cloud.Map(self._opts_defaults(action=fun))
mapper = salt.cloud.Map(self._opts_defaults(action=fun, names=names))
if names and not provider:
self.opts['action'] = fun
return mapper.do_action(names, kwargs)

View file

@ -423,10 +423,22 @@ def create(vm_, call=None):
kwarg['host'] = prov['target']
cret = _runner().cmd('lxc.cloud_init', [vm_['name']], kwarg=kwarg)
ret['runner_return'] = cret
if cret['result']:
ret['result'] = False
ret['result'] = cret['result']
if not ret['result']:
ret['Error'] = 'Error while creating {0},'.format(vm_['name'])
else:
ret['changes']['created'] = 'created'
# When using cloud states to manage LXC containers
# __opts__['profile'] is not implicitly reset between operations
# on different containers. However list_nodes will hide container
# if profile is set in opts assuming that it have to be created.
# But in cloud state we do want to check at first if it really
# exists hence the need to remove profile from global opts once
# current container is created.
if 'profile' in __opts__:
del __opts__['profile']
return ret

View file

@ -179,12 +179,15 @@ def cloud_init_interface(name, vm_=None, **kwargs):
size = vm_.get('size', '20G')
script = vm_.get('script', None)
script_args = vm_.get('script_args', None)
options = vm_.get('options', None)
if image:
profile['template'] = image
if vgname:
profile['vgname'] = vgname
if backing:
profile['backing'] = backing
if options:
profile.update(options)
users = vm_.get('users', None)
if users is None:
users = []
@ -876,6 +879,7 @@ def init(name,
__salt__['lxc.clone'](name, clone_from,
profile=profile, **kwargs))
if not ret.get('cloned', False):
ret['result'] = False
return ret
cfg = _LXCConfig(name=name, nic=nic, nic_opts=nic_opts,
bridge=bridge, gateway=gateway,
@ -897,6 +901,7 @@ def init(name,
__salt__['lxc.create'](name, config=cfile.name,
profile=profile, **kwargs))
if not ret.get('created', False):
ret['result'] = False
return ret
path = '/var/lib/lxc/{0}/config'.format(name)
old_chunks = []
@ -2049,8 +2054,8 @@ def bootstrap(name, config=None, approve_key=True,
cp(name, cfg_files['pubkey'],
os.path.join(configdir, 'minion.pub'))
bootstrap_args = bootstrap_args.format(configdir)
cmd = ('PATH=$PATH:/bin:/sbin:/usr/sbin'
' {0} /tmp/bootstrap.sh {1}').format(
cmd = ("{0} -c 'PATH=$PATH:/bin:/sbin:/usr/sbin"
" {0} /tmp/bootstrap.sh {1}'").format(
bootstrap_shell, bootstrap_args)
# log ASAP the forged bootstrap command which can be wrapped
# out of the output in case of unexpected problem
@ -2161,7 +2166,7 @@ def run_cmd(name, cmd, no_start=False, preserve_state=True,
if not use_vt:
res = __salt__['cmd.run_all'](cmd, python_shell=False)
else:
stdout, stderr = '', ''
stdout_str, stderr_str = '', ''
try:
proc = vt.Terminal(cmd,
shell=True,
@ -2181,33 +2186,33 @@ def run_cmd(name, cmd, no_start=False, preserve_state=True,
except IOError:
cstdout, cstderr = '', ''
if cstdout:
stdout += cstdout
stdout_str += cstdout
else:
cstdout = ''
if cstderr:
stderr += cstderr
stderr_str += cstderr
else:
cstderr = ''
# done by vt itself
# if stdout:
# log.debug(stdout)
# log.debug(stdout_str)
# if stderr:
# log.debug(stderr)
# log.debug(stderr_str)
if not cstdout and not cstderr and not proc.isalive():
break
except KeyboardInterrupt:
break
res = {'retcode': proc.exitstatus,
'pid': 2,
'stdout': stdout,
'stderr': stderr}
'stdout': stdout_str,
'stderr': stderr_str}
except vt.TerminalException:
trace = traceback.format_exc()
log.error(trace)
res = {'retcode': 127,
'pid': '2',
'stdout': stdout,
'stderr': stderr}
'stdout': stdout_str,
'stderr': stderr_str}
finally:
proc.terminate()
else:

View file

@ -49,6 +49,15 @@ def _valid(name, comment='', changes=None):
'comment': comment}
def _get_instance(names):
# for some reason loader overwrites __opts__['test'] with default
# value of False, thus store and then load it again after action
test = __opts__['test']
instance = __salt__['cloud.action'](fun='show_instance', names=names)
__opts__['test'] = test
return instance
def present(name, cloud_provider, onlyif=None, unless=None, **kwargs):
'''
Spin up a single instance on a cloud provider, using salt-cloud. This state
@ -77,8 +86,7 @@ def present(name, cloud_provider, onlyif=None, unless=None, **kwargs):
'changes': {},
'result': None,
'comment': ''}
instance = __salt__['cloud.action'](
fun='show_instance', names=[name])
instance = _get_instance([name])
retcode = __salt__['cmd.retcode']
prov = str([a for a in instance][0])
if onlyif is not None:
@ -153,10 +161,10 @@ def absent(name, onlyif=None, unless=None):
'result': None,
'comment': ''}
retcode = __salt__['cmd.retcode']
instance = __salt__['cloud.action'](fun='show_instance', names=[name])
instance = _get_instance([name])
if not instance or \
('Not Actioned/Not Running' in ret
and name in ret['Not Actioned/Not Running']):
('Not Actioned/Not Running' in instance
and name in instance['Not Actioned/Not Running']):
ret['result'] = True
ret['comment'] = 'Instance {0} already absent'.format(name)
return ret
@ -241,7 +249,7 @@ def profile(name, profile, onlyif=None, unless=None, **kwargs):
elif isinstance(unless, string_types):
if retcode(unless) == 0:
return _valid(name, comment='unless execution succeeded')
instance = __salt__['cloud.action'](fun='show_instance', names=[name])
instance = _get_instance([name])
prov = str(instance.iterkeys().next())
if instance and 'Not Actioned' not in prov:
ret['result'] = True