Created
December 31, 2014 02:17
-
-
Save s3u/5104f77b2b55900f243c to your computer and use it in GitHub Desktop.
vol-agent
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import subprocess | |
import requests | |
import os | |
# The purpose of this script is to find look for unmounted volumes, and mount them. If a volume is unitialized, it | |
# will initialize as ext4. | |
# | |
# The simplest way to run this is via cron. Use the following crontab entry | |
# | |
# */1 * * * * python /somepath/agent.py >> /var/log/vol-agent.log | |
# | |
# This script will act based on the following stimuli: | |
# | |
# 1. A volume has been attached to the VM, e.g. via | |
# nova volume-attach <VM-UUID> <Volume-UUID> | |
# 2. The VM's metadata has been updated to include the list of volumes that must be auto-mounted. | |
# nova meta <VM-UUID> set volumes="space delimited volume-UUIDs" | |
# | |
# This script will then mount the specified volumes under | |
# | |
# /mnt/slaves/<volume-UUID> | |
# | |
# Feel free to modify to the default conventions. | |
# | |
# To unmount a volume, follow the same type of stimuli | |
# | |
# 1. Remove the volume's UUID from the metadata. Simply remove the volume's UUID from the value of the | |
# `volumes` parameter in the `nova meta` command. | |
# 2. Detach the volume via `nova volume-detach <VM-UUID> <Volume-UUID>` | |
# | |
# Parses `lsblk` output to determine uninitialized volumes. | |
def parse_lsblk(out): | |
blkDict = [] | |
for l in out: | |
d = {} | |
for t in l.split(): | |
k, v = t.split('=', 1) | |
d[k] = v[1:-1] | |
blkDict.append(d) | |
return blkDict | |
# Run `lsblk` to find uninitialized volumes. If found one, initialize as ext4 file system | |
cmd = ['lsblk', '--bytes', '--pairs', '--output', 'KNAME,FSTYPE,UUID'] | |
p = subprocess.Popen(cmd, stdout=subprocess.PIPE) | |
out = p.communicate() | |
out = out[0].splitlines() | |
parsed = parse_lsblk(out) | |
for volume in parsed: | |
if volume['FSTYPE'] == '': | |
# Initialize the volume | |
print "Initializing %s" % volume['KNAME'] | |
cmd = ['mkfs', '-t', 'ext4', '/dev/%s' % volume['KNAME']] | |
p = subprocess.Popen(cmd, stdout=subprocess.PIPE) | |
out = p.communicate() | |
# | |
# Find the list of volumes that must be mounted. | |
r = requests.get('http://169.254.169.254/openstack/latest/meta_data.json') | |
if r.status_code != 200: | |
sys.exit(0) | |
meta = r.json()["meta"] | |
volumes = meta["volumes"] or '' | |
volumes = [] or volumes.split(',') | |
# Unmount removed | |
try: | |
os.makedirs('/mnt/slaves') | |
except: | |
pass | |
mounted = os.listdir('/mnt/slaves') | |
for m in mounted: | |
if m not in volumes: | |
print "Unmounting /mnt/slaves/%s" % m | |
cmd = ['umount', '/mnt/slaves/' + m] | |
p = subprocess.Popen(cmd, stdout=subprocess.PIPE) | |
out = p.communicate() | |
for volume in (volume for volume in volumes if len(volume) > 0): | |
disk = '/dev/disk/by-id/virtio-' + volume[:20] | |
if not os.path.exists(disk): | |
sys.exit(0) | |
device = os.path.realpath('/dev/disk/by-id/' + os.readlink(disk)) | |
try: | |
os.makedirs('/mnt/slaves/' + volume) | |
except: | |
pass | |
try: | |
print ("Mounting %s at /mnt/slaves/%s" % (device, volume)) | |
cmd = ['mount', device, '/mnt/slaves/' + volume] | |
p = subprocess.Popen(cmd, stdout=subprocess.PIPE) | |
out = p.communicate() | |
except: | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment