nova/tools/xenserver/vdi_chain_cleanup.py
Brian Waldon 317378f742 Update pep8 dependency to v1.1
The latest release of pep8 adds stricter rules for extraneous
whitespace within lines. This patch also addresses these new
violations acoss the codebase.

Change-Id: Ib7e50281870473df1704ed50868c5c2e26bdb02e
2012-05-24 06:59:05 -07:00

129 lines
3.6 KiB
Python

#!/usr/bin/env python
# Copyright 2012 OpenStack, LLC
#
# 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.
"""
This script is designed to cleanup any VHDs (and their descendents) which have
a bad parent pointer.
The script needs to be run in the dom0 of the affected host.
The available actions are:
- print: display the filenames of the affected VHDs
- delete: remove the affected VHDs
- move: move the affected VHDs out of the SR into another directory
"""
import glob
import os
import subprocess
import sys
class ExecutionFailed(Exception):
def __init__(self, returncode, stdout, stderr, max_stream_length=32):
self.returncode = returncode
self.stdout = stdout[:max_stream_length]
self.stderr = stderr[:max_stream_length]
self.max_stream_length = max_stream_length
def __repr__(self):
return "<ExecutionFailed returncode=%s out='%s' stderr='%s'>" % (
self.returncode, self.stdout, self.stderr)
__str__ = __repr__
def execute(cmd, ok_exit_codes=None):
if ok_exit_codes is None:
ok_exit_codes = [0]
proc = subprocess.Popen(
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = proc.communicate()
if proc.returncode not in ok_exit_codes:
raise ExecutionFailed(proc.returncode, stdout, stderr)
return proc.returncode, stdout, stderr
def usage():
print "usage: %s <SR PATH> <print|delete|move>" % sys.argv[0]
sys.exit(1)
def main():
if len(sys.argv) < 3:
usage()
sr_path = sys.argv[1]
action = sys.argv[2]
if action not in ('print', 'delete', 'move'):
usage()
if action == 'move':
if len(sys.argv) < 4:
print "error: must specify where to move bad VHDs"
sys.exit(1)
bad_vhd_path = sys.argv[3]
if not os.path.exists(bad_vhd_path):
os.makedirs(bad_vhd_path)
bad_leaves = []
descendents = {}
for fname in glob.glob(os.path.join(sr_path, "*.vhd")):
(returncode, stdout, stderr) = execute(
['vhd-util', 'query', '-n', fname, '-p'], ok_exit_codes=[0, 22])
stdout = stdout.strip()
if stdout.endswith('.vhd'):
try:
descendents[stdout].append(fname)
except KeyError:
descendents[stdout] = [fname]
elif 'query failed' in stdout:
bad_leaves.append(fname)
def walk_vhds(root):
yield root
if root in descendents:
for child in descendents[root]:
for vhd in walk_vhds(child):
yield vhd
for bad_leaf in bad_leaves:
for bad_vhd in walk_vhds(bad_leaf):
print bad_vhd
if action == "print":
pass
elif action == "delete":
os.unlink(bad_vhd)
elif action == "move":
new_path = os.path.join(bad_vhd_path,
os.path.basename(bad_vhd))
os.rename(bad_vhd, new_path)
else:
raise Exception("invalid action %s" % action)
if __name__ == '__main__':
main()