solar/snapshotter.py

130 lines
3.7 KiB
Python
Executable File

#!/usr/bin/env python
# Copyright 2015 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 click
import time
from itertools import takewhile
from subprocess import check_output, CalledProcessError
def get_vagrant_vms():
status = vagrant('status')
lines = status.splitlines()[2:]
vms = takewhile(lambda x: x.split(), lines)
vms = map(lambda x: x.split()[0], vms)
return vms
def vboxmanage(args, output_dict=False):
args = ['VBoxManage'] + args
if output_dict:
args = args + ['--machinereadable']
p = check_output(args, shell=False)
if not output_dict:
return p
elements = [line.split('=') for line in p.split('\n') if line]
return {
el[0]: el[1].strip('""')
for el in elements if el
}
def vagrant(*args):
args = ('vagrant', ) + args
p = check_output(args, shell=False)
return p
@click.group()
def cli():
pass
@cli.command()
@click.option('-n', default=None)
def take(n):
now = time.time()
if n is None:
n = 'solar-%d' % now
vms = get_vagrant_vms()
for vm in vms:
click.echo("Taking %s" % vm)
snap = vboxmanage(['snapshot', vm, 'take', n, '--live', '--description', 'solar: %d' % now])
click.echo(snap)
@click.option('-n', required=True)
@cli.command()
def restore(n):
vms = get_vagrant_vms()
for vm in vms:
vminfo = vboxmanage(['showvminfo', vm], output_dict=True)
was_running = False
if vminfo['VMState'] == 'running':
click.echo('[{vm}] Running, stopping'.format(vm=vm))
vboxmanage(['controlvm', vm, 'poweroff'])
was_running = True
click.echo("Restoring %s" % vm)
snap = vboxmanage(['snapshot', vm, 'restore', n])
if was_running:
vboxmanage(['startvm', vm, '--type', 'headless'])
click.echo(snap)
# wanted to use list but it would
@cli.command()
def show():
vms = get_vagrant_vms()
for vm in vms:
msg = "[{vm}] {snap}"
click.echo(click.style(vm, fg='green'))
try:
snap = vboxmanage(['snapshot', vm, 'list'], output_dict=True)
snap_num = (len(snap.keys()) / 3) - 1
if snap_num < 1:
click.echo(click.style(
'This machine does not have any snapshots',
fg='red'
))
else:
s = {}
for key, value in snap.items():
if not key.startswith('SnapshotName'):
continue
uuid_key = key.replace("SnapshotName", "SnapshotUUID")
click.echo('\t{name} (UUID {uuid})'.format(name=value, uuid=snap[uuid_key]))
except CalledProcessError:
click.echo(click.style(
'This machine does not have any snapshots',
fg='red'
))
click.echo('-' * 10)
@click.option('-n')
@cli.command()
def delete(n):
vms = get_vagrant_vms()
for vm in vms:
click.echo('Removing %s from %s' % (n, vm))
snap = vboxmanage(['snapshot', vm, 'delete', n])
click.echo(snap)
if __name__ == '__main__':
cli()