Add support for filed in the vlmc tool
[archipelago] / xseg / tools / vlmc.py
1 #!/usr/bin/env python2.7
2 #
3 # vlmc tool
4 # (blockd-only atm)
5
6 import os, sys, subprocess, shutil, re, argparse
7
8 #FIXME 
9 XSEG_HOME="/root/archip/xseg/"
10 IMAGES="/srv/pithos/archip-data/images/"
11 XSEGBD_SYSFS="/sys/bus/xsegbd/"
12 DEVICE_PREFIX="/dev/xsegbd"
13 BLOCKD_LOGS="/srv/pithos/archip-data/logs/"
14
15 def vlmc_list(args):
16     print "name\t\t\t\tsize"
17     try:
18         for f in os.listdir(IMAGES):
19             print "%s\t\t\t\t%dM" % (f, os.stat(IMAGES + f).st_size / 1024 / 1024)
20
21         sys.exit(0)
22     except Exception, reason:
23         print >> sys.stderr, reason
24         sys.exit(-1)
25         
26 def vlmc_create(args):
27     name = args.name[0]
28     size = args.size
29     snap = args.snap
30
31     try:
32         old_dir = os.getcwd()
33         os.chdir(IMAGES)
34
35         try:
36             os.stat(name)
37             print "file exists"
38             os.chdir(old_dir)
39             sys.exit(-1)
40         except:
41             pass
42         
43         if snap:
44             shutil.copyfile(snap, name)
45         else:
46             f = os.open(name, os.O_CREAT | os.O_WRONLY, 0755)
47             size *= 1024*1024
48             os.lseek(f, size - 1, os.SEEK_SET)
49             os.write(f, "1")
50             os.close(f)
51
52         os.chdir(old_dir)
53         sys.exit(0)
54     except Exception, reason:
55         print >> sys.stderr, reason
56         sys.exit(-1)
57
58 def vlmc_remove(args):
59     name = args.name[0]
60
61     try:
62         old_dir = os.getcwd()
63         os.chdir(IMAGES)
64
65         try:
66             os.stat(name)
67         except:
68             print "file doesn't exist"
69             os.chdir(old_dir)
70             sys.exit(-1)
71         
72         os.unlink(IMAGES + '/' + name)
73
74         os.chdir(old_dir)
75         sys.exit(0)
76     except Exception, reason:
77         print >> sys.stderr, reason
78         sys.exit(-1)
79
80 def vlmc_map(args):
81     name = args.name[0]
82     try:
83         try:
84             r = subprocess.check_output(["ps", "-o", "command", "-C",
85             "blockd"]).splitlines()[1:]
86             result = [int(re.search('-p (\d+)', x).group(1)) for x in r]
87             result.sort()
88
89             prev = -1
90             for i in result:
91                 if i - prev > 1:
92                     port = prev + 1
93                     break
94                 else:
95                     prev = i
96
97             port = prev + 1
98         except:
99             port = 0
100             
101         old_dir = os.getcwd()
102         os.chdir(IMAGES)
103         f = os.open(BLOCKD_LOGS +  name, os.O_CREAT | os.O_WRONLY)
104         r = subprocess.Popen([XSEG_HOME + "peers/blockd", name, "-p", str(port),
105         "-g", "xsegdev:xsegbd:128:4096:64:1024:12"], stdout=f, stderr=f)
106
107         os.chdir(IMAGES)
108         fd = os.open(XSEGBD_SYSFS + "add", os.O_WRONLY)
109         os.write(fd, "%s %d:%d:128" % (name, port + 64, port))
110         os.close(fd)
111     except Exception, reason:
112         print >> sys.stderr, reason
113         sys.exit(-1)
114
115 def vlmc_unmap(args):
116     device = args.name[0]
117     try:
118         for f in os.listdir(XSEGBD_SYSFS + "devices/"):
119             d_id = open(XSEGBD_SYSFS + "devices/" + f + "/id").read().strip()
120             name = open(XSEGBD_SYSFS + "devices/"+ f + "/name").read().strip()
121             if device == DEVICE_PREFIX + d_id:
122                 fd = os.open(XSEGBD_SYSFS + "remove", os.O_WRONLY)
123                 os.write(fd, d_id)
124                 os.close(fd)
125
126                 break
127         
128         subprocess.check_output(["pkill", "-f", "blockd " + name + " "])
129     except Exception, reason:
130         print >> sys.stderr, reason
131         sys.exit(-1)
132
133 def vlmc_showmapped(args):
134     print "id\tpool\timage\tsnap\tdevice"
135     try:
136         for f in os.listdir(XSEGBD_SYSFS + "devices/"):
137             d_id = open(XSEGBD_SYSFS + "devices/" + f + "/id").read().strip()
138             name = open(XSEGBD_SYSFS + "devices/"+ f + "/name").read().strip()
139
140             print "%s\t%s\t%s\t%s\t%s" % (d_id, '-', name, '-', DEVICE_PREFIX +
141             d_id)
142     except Exception, reason:
143         print >> sys.stderr, reason
144         sys.exit(-1)
145
146 if __name__ == "__main__":
147     # parse arguments and discpatch to the correct func
148     parser = argparse.ArgumentParser(description='vlmc tool')
149     parser.add_argument('-c', '--config', type=str, nargs='?', help='config file')
150     subparsers = parser.add_subparsers()
151
152     create_parser = subparsers.add_parser('create', help='Create volume')
153     group = create_parser.add_mutually_exclusive_group(required=True)
154     group.add_argument('-s', '--size', type=int, nargs='?', help='requested size in MB for create')
155     group.add_argument('--snap', type=str, nargs='?', help='create from snapshot')
156     create_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
157     create_parser.add_argument('name', type=str, nargs=1, help='volume/device name')
158     create_parser.set_defaults(func=vlmc_create)
159
160     remove_parser = subparsers.add_parser('remove', help='Delete volume')
161     remove_parser.add_argument('name', type=str, nargs=1, help='volume/device name')
162     remove_parser.set_defaults(func=vlmc_remove)
163     remove_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
164
165     rm_parser = subparsers.add_parser('rm', help='Delete volume')
166     rm_parser.add_argument('name', type=str, nargs=1, help='volume/device name')
167     rm_parser.set_defaults(func=vlmc_remove)
168     rm_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
169
170     map_parser = subparsers.add_parser('map', help='Map volume')
171     map_parser.add_argument('name', type=str, nargs=1, help='volume/device name')
172     map_parser.set_defaults(func=vlmc_map)
173     map_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
174
175     unmap_parser = subparsers.add_parser('unmap', help='Unmap volume')
176     unmap_parser.add_argument('name', type=str, nargs=1, help='volume/device name')
177     unmap_parser.set_defaults(func=vlmc_unmap)
178     unmap_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
179
180     showmapped_parser = subparsers.add_parser('showmapped', help='Show mapped volumes')
181     showmapped_parser.set_defaults(func=vlmc_showmapped)
182     showmapped_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
183
184     list_parser = subparsers.add_parser('list', help='List volumes')
185     list_parser.set_defaults(func=vlmc_list)
186     list_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
187
188     ls_parser = subparsers.add_parser('ls', help='List volumes')
189     ls_parser.set_defaults(func=vlmc_list)
190     ls_parser.add_argument('-p', '--pool', type=str, nargs='?', help='for backwards compatiblity with rbd')
191
192     args = parser.parse_args()    
193
194     #FIXME
195     try:
196         if args.config == None:
197             execfile(os.path.expanduser("~/.xsegrc"))
198         else:
199             execfile(args.config)
200     except:
201         pass
202
203     args.func(args)