I have a list of boxes and need to list only the outdated ones.
For example, input will look something like this:
maier/alpine-3.1.3-x86_64 (virtualbox, 1.2.0) maier/alpine-3.1.3-x86_64 (virtualbox, 1.3.0) ubuntu/precise64 (virtualbox, 20151202.0.0) ubuntu/vivid64 (virtualbox, 20150821.0.0) ubuntu/vivid64 (virtualbox, 20150903.0.0) ubuntu/vivid64 (virtualbox, 20151113.0.0) ubuntu/vivid64 (virtualbox, 20151127.0.0) ubuntu/vivid64 (virtualbox, 20151211.0.0) ubuntu/wily64 (virtualbox, 20151203.0.0)
Output will look roughly like this:
maier/alpine-3.1.3-x86_64 (virtualbox, 1.2.0) ubuntu/vivid64 (virtualbox, 20150821.0.0) ubuntu/vivid64 (virtualbox, 20150903.0.0) ubuntu/vivid64 (virtualbox, 20151113.0.0) ubuntu/vivid64 (virtualbox, 20151127.0.0)
Note the format consists of: name
, provider
, version
It seems like there would be an easy way to do this from Bash scripting alone, e.g. I can version sort a particular column with sort
, but I wasn't quite able to figure it out so I roughed it out in Python instead.
Is there are better way to do this?
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""Attempt to remove outdated Vagrant boxes"""
import os
import re
import subprocess
from distutils.version import StrictVersion
def search(text):
"""Return a dictionary containing all the named subgroups of the match."""
patt = r'^(?P<name>[^ ]+) +\((?P<provider>[^ ]+), +(?P<version>[^ ]+)\)$'
return re.search(patt, text).groupdict()
output = subprocess.check_output(['vagrant', 'box', 'list'],
stderr=subprocess.DEVNULL).decode().rstrip()
box_list = (search(line) for line in output.splitlines())
box_dict = {}
for box in box_list:
name = box.get('name')
version = box.get('version')
box_dict[name] = box_dict.get(name, []) + [version]
outdated_boxes = {}
for box in box_dict:
versions = box_dict[box]
# remove the most recent version
if len(versions) > 1:
outdated_boxes[box] = sorted(versions, key=StrictVersion)[:-1]
for box in outdated_boxes:
versions = outdated_boxes[box]
for version in versions:
command = ['vagrant', 'box', 'remove', box, '--box-version', version]
print(*command)
os.system(' '.join(command))
# process = subprocess.Popen(command)
# process.wait()
print()