Vladimir Kozhukalov da0b679764 Removed sleep in execute util in fuel-agent
Sometimes when parted performs some action
it fails to re-read updated partition table
on a disk. It occurs mostly when you run parted
command several times without delay. We had
sleep(1) in execute utility as a fast workaround.

Looks like the issue can be addressed with just
additional call or partprobe right after failed
parted command. This patch impelemnts this
assumption.

But it is still not a real fix, it is again just
a workaround. Real fix is to launch parted one time
for every disk passing to it a whole table
(all partition at once). We are going to implement
this as soon as possible, right after addressing
most prioritized issues.

Change-Id: I539800271260c3d3f1b3560f8111ba8b6cacc9c4
Implements: blueprint image-based-provisioning
2014-10-13 15:46:18 +04:00

119 lines
3.9 KiB
Python

# Copyright 2014 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import locale
import math
import os
import re
import shlex
import subprocess
import jinja2
import stevedore.driver
from fuel_agent import errors
from fuel_agent.openstack.common import log as logging
LOG = logging.getLogger(__name__)
#NOTE(agordeev): signature compatible with execute from oslo
def execute(*cmd, **kwargs):
command = ' '.join(cmd)
LOG.debug('Trying to execute command: %s', command)
commands = [c.strip() for c in re.split(ur'\|', command)]
env = os.environ
env['PATH'] = '/bin:/usr/bin:/sbin:/usr/sbin'
check_exit_code = kwargs.pop('check_exit_code', [0])
ignore_exit_code = False
to_filename = kwargs.get('to_filename')
cwd = kwargs.get('cwd')
if isinstance(check_exit_code, bool):
ignore_exit_code = not check_exit_code
check_exit_code = [0]
elif isinstance(check_exit_code, int):
check_exit_code = [check_exit_code]
to_file = None
if to_filename:
to_file = open(to_filename, 'wb')
process = []
for c in commands:
try:
# NOTE(eli): Python's shlex implementation doesn't like unicode.
# We have to convert to ascii before shlex'ing the command.
# http://bugs.python.org/issue6988
encoded_command = c.encode('ascii')
process.append(subprocess.Popen(
shlex.split(encoded_command),
env=env,
stdin=(process[-1].stdout if process else None),
stdout=(to_file
if (len(process) == len(commands) - 1) and to_file
else subprocess.PIPE),
stderr=(subprocess.PIPE),
cwd=cwd
))
except OSError as e:
raise errors.ProcessExecutionError(exit_code=1, stdout='',
stderr=e, cmd=command)
if len(process) >= 2:
process[-2].stdout.close()
stdout, stderr = process[-1].communicate()
if not ignore_exit_code and process[-1].returncode not in check_exit_code:
raise errors.ProcessExecutionError(exit_code=process[-1].returncode,
stdout=stdout,
stderr=stderr,
cmd=command)
return (stdout, stderr)
def parse_unit(s, unit, ceil=True):
"""Converts '123.1unit' string into 124 if ceil is True
and converts '123.9unit' into 123 if ceil is False.
"""
flt = locale.atof(s.split(unit)[0])
if ceil:
return int(math.ceil(flt))
return int(math.floor(flt))
def B2MiB(b, ceil=True):
if ceil:
return int(math.ceil(float(b) / 1024 / 1024))
return int(math.floor(float(b) / 1024 / 1024))
def get_driver(name):
return stevedore.driver.DriverManager(
namespace='fuel_agent.drivers', name=name).driver
def render_and_save(tmpl_dir, tmpl_names, tmpl_data, file_name):
env = jinja2.Environment(loader=jinja2.FileSystemLoader(tmpl_dir))
template = env.get_or_select_template(tmpl_names)
output = template.render(tmpl_data)
try:
with open(file_name, 'w') as f:
f.write(output)
except Exception:
raise errors.TemplateWriteError(
'Something goes wrong while trying to save'
'templated data to {0}'.format(file_name))