Statistics
| Branch: | Revision:

root / shared-filer / detach @ master

History | View | Annotate | Download (4.7 kB)

1 bd924ffd Dimitris Aragiorgis
#!/usr/bin/env python
2 bd924ffd Dimitris Aragiorgis
#
3 bd924ffd Dimitris Aragiorgis
# Copyright (C) 2012 Greek Research and Technology Network
4 bd924ffd Dimitris Aragiorgis
#
5 bd924ffd Dimitris Aragiorgis
# This program is free software; you can redistribute it and/or modify
6 bd924ffd Dimitris Aragiorgis
# it under the terms of the GNU General Public License as published by
7 bd924ffd Dimitris Aragiorgis
# the Free Software Foundation; either version 2 of the License, or
8 bd924ffd Dimitris Aragiorgis
# (at your option) any later version.
9 bd924ffd Dimitris Aragiorgis
#
10 bd924ffd Dimitris Aragiorgis
# This program is distributed in the hope that it will be useful, but
11 bd924ffd Dimitris Aragiorgis
# WITHOUT ANY WARRANTY; without even the implied warranty of
12 bd924ffd Dimitris Aragiorgis
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 bd924ffd Dimitris Aragiorgis
# General Public License for more details.
14 bd924ffd Dimitris Aragiorgis
#
15 bd924ffd Dimitris Aragiorgis
# You should have received a copy of the GNU General Public License
16 bd924ffd Dimitris Aragiorgis
# along with this program; if not, write to the Free Software
17 bd924ffd Dimitris Aragiorgis
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 bd924ffd Dimitris Aragiorgis
# 02110-1301, USA.
19 bd924ffd Dimitris Aragiorgis
20 bd924ffd Dimitris Aragiorgis
"""Detach the Image file from the loop device
21 bd924ffd Dimitris Aragiorgis
22 bd924ffd Dimitris Aragiorgis
This program detaches an Image file from the loop device it attached to.
23 bd924ffd Dimitris Aragiorgis
It is idempotent, if the file isn't losetup at all.
24 bd924ffd Dimitris Aragiorgis
25 bd924ffd Dimitris Aragiorgis
It takes it's input from environment variables. Specifically the
26 bd924ffd Dimitris Aragiorgis
following variable should be present:
27 bd924ffd Dimitris Aragiorgis
28 bd924ffd Dimitris Aragiorgis
 - VOL_NAME: The name of the Image file to which the device points
29 bd924ffd Dimitris Aragiorgis
30 bd924ffd Dimitris Aragiorgis
Returns O upon successfull unmapping, 1 upon failure
31 bd924ffd Dimitris Aragiorgis
32 bd924ffd Dimitris Aragiorgis
"""
33 bd924ffd Dimitris Aragiorgis
34 bd924ffd Dimitris Aragiorgis
import os
35 bd924ffd Dimitris Aragiorgis
import sys
36 bd924ffd Dimitris Aragiorgis
37 68abdf0d Dimitris Aragiorgis
sys.path.insert(0, "/etc/ganeti/share")
38 bd924ffd Dimitris Aragiorgis
39 bd924ffd Dimitris Aragiorgis
from ganeti import utils
40 bd924ffd Dimitris Aragiorgis
41 bd924ffd Dimitris Aragiorgis
42 bd924ffd Dimitris Aragiorgis
# Default shared directory
43 bd924ffd Dimitris Aragiorgis
SHARED_DIR = "/srv/ganeti/shared-file-storage"
44 bd924ffd Dimitris Aragiorgis
45 bd924ffd Dimitris Aragiorgis
46 bd924ffd Dimitris Aragiorgis
def ReadEnv():
47 bd924ffd Dimitris Aragiorgis
  """Read the mandatory enviromental variables
48 bd924ffd Dimitris Aragiorgis
49 bd924ffd Dimitris Aragiorgis
  """
50 bd924ffd Dimitris Aragiorgis
  name = os.getenv("VOL_NAME")
51 bd924ffd Dimitris Aragiorgis
  if name is None:
52 bd924ffd Dimitris Aragiorgis
    sys.stderr.write('The environment variable VOL_NAME is missing.\n')
53 bd924ffd Dimitris Aragiorgis
    return None
54 bd924ffd Dimitris Aragiorgis
  shared_dir_param = os.getenv("EXTP_SHARED_DIR")
55 bd924ffd Dimitris Aragiorgis
  if shared_dir_param is not None:
56 bd924ffd Dimitris Aragiorgis
    sys.stderr.write('Found shared dir param, value: %s\n' % shared_dir_param)
57 bd924ffd Dimitris Aragiorgis
58 bd924ffd Dimitris Aragiorgis
  return (name, shared_dir_param)
59 bd924ffd Dimitris Aragiorgis
60 bd924ffd Dimitris Aragiorgis
61 bd924ffd Dimitris Aragiorgis
def _ParseLosetupOutput(output, filename):
62 bd924ffd Dimitris Aragiorgis
  """Parse the output of `losetup -j <filename>`
63 bd924ffd Dimitris Aragiorgis
64 bd924ffd Dimitris Aragiorgis
  This method parses the output of `losetup -j <filename>` and returns
65 bd924ffd Dimitris Aragiorgis
  the corresponding loop device path for this filename
66 bd924ffd Dimitris Aragiorgis
  (e.g. /dev/loop0)
67 bd924ffd Dimitris Aragiorgis
68 bd924ffd Dimitris Aragiorgis
  @type output: string
69 bd924ffd Dimitris Aragiorgis
  @param output: the whole output of `losetup -j filename`
70 bd924ffd Dimitris Aragiorgis
  @type filename: string
71 bd924ffd Dimitris Aragiorgis
  @param filename: the complete file path to the file we search for
72 bd924ffd Dimitris Aragiorgis
  @rtype: string or None
73 bd924ffd Dimitris Aragiorgis
  @return: loop device path if the file is losetup, else None
74 bd924ffd Dimitris Aragiorgis
75 bd924ffd Dimitris Aragiorgis
  """
76 bd924ffd Dimitris Aragiorgis
  # `losetup -j file1` output looks like this
77 bd924ffd Dimitris Aragiorgis
  #   /dev/loop0: [X]:Y (/path/to/file1)
78 bd924ffd Dimitris Aragiorgis
  # if the file has been losetup. If not there is no output.
79 bd924ffd Dimitris Aragiorgis
  # If the file has been losetup more than once, then there will be
80 bd924ffd Dimitris Aragiorgis
  # multiple lines like the one above.
81 bd924ffd Dimitris Aragiorgis
  #
82 bd924ffd Dimitris Aragiorgis
  # We assume the following format (space is the seperator):
83 bd924ffd Dimitris Aragiorgis
  # field0: field1 (field2)
84 bd924ffd Dimitris Aragiorgis
85 bd924ffd Dimitris Aragiorgis
  field0 = 0
86 bd924ffd Dimitris Aragiorgis
  field_sep = " "
87 bd924ffd Dimitris Aragiorgis
  
88 bd924ffd Dimitris Aragiorgis
  lines = output.splitlines()
89 bd924ffd Dimitris Aragiorgis
  splitted_lines = map(lambda l: l.split(field_sep), lines)
90 bd924ffd Dimitris Aragiorgis
91 bd924ffd Dimitris Aragiorgis
  # Check empty output. If empty, the file is not losetup
92 bd924ffd Dimitris Aragiorgis
  if not splitted_lines:
93 bd924ffd Dimitris Aragiorgis
    return None
94 bd924ffd Dimitris Aragiorgis
95 bd924ffd Dimitris Aragiorgis
  # Check if we have more than one lines in the output
96 bd924ffd Dimitris Aragiorgis
  if len(splitted_lines) > 1:
97 bd924ffd Dimitris Aragiorgis
    sys.stderr.write("The file %s is losetup more than once" % filename)
98 bd924ffd Dimitris Aragiorgis
    sys.exit(1)
99 bd924ffd Dimitris Aragiorgis
100 bd924ffd Dimitris Aragiorgis
  # The file is losetup only once
101 bd924ffd Dimitris Aragiorgis
  # Take field0, remove the ":" at the end and we have our path
102 bd924ffd Dimitris Aragiorgis
  dev_path = splitted_lines[0][field0].split(":")[0]
103 bd924ffd Dimitris Aragiorgis
104 bd924ffd Dimitris Aragiorgis
  return dev_path
105 bd924ffd Dimitris Aragiorgis
106 bd924ffd Dimitris Aragiorgis
107 bd924ffd Dimitris Aragiorgis
def main():
108 bd924ffd Dimitris Aragiorgis
  sys.stderr.write('Detaching started: reading environment...\n')
109 bd924ffd Dimitris Aragiorgis
110 bd924ffd Dimitris Aragiorgis
  # Read environment
111 bd924ffd Dimitris Aragiorgis
  env = ReadEnv()
112 bd924ffd Dimitris Aragiorgis
  if env is None:
113 bd924ffd Dimitris Aragiorgis
    sys.stderr.write('Wrong environment. Aborting\n')
114 bd924ffd Dimitris Aragiorgis
    return 1
115 bd924ffd Dimitris Aragiorgis
116 bd924ffd Dimitris Aragiorgis
  file_name, shared_dir_param = env
117 bd924ffd Dimitris Aragiorgis
118 bd924ffd Dimitris Aragiorgis
  if shared_dir_param is None:
119 bd924ffd Dimitris Aragiorgis
    shared_dir_param = SHARED_DIR
120 bd924ffd Dimitris Aragiorgis
121 bd924ffd Dimitris Aragiorgis
  file_path = utils.PathJoin(shared_dir_param, file_name)
122 bd924ffd Dimitris Aragiorgis
123 bd924ffd Dimitris Aragiorgis
  sys.stderr.write('Read environment successfully: file name: %s\n' % file_path)
124 bd924ffd Dimitris Aragiorgis
125 bd924ffd Dimitris Aragiorgis
  # Check if the file exists
126 bd924ffd Dimitris Aragiorgis
  if not os.path.exists(file_path):
127 bd924ffd Dimitris Aragiorgis
    sys.stderr.write('File %s does not exist. Aborting\n' % file_path)
128 bd924ffd Dimitris Aragiorgis
    return 1
129 bd924ffd Dimitris Aragiorgis
130 bd924ffd Dimitris Aragiorgis
  # Check if the file is losetup
131 bd924ffd Dimitris Aragiorgis
  cmd1 = ["losetup", "-j", "%s" % file_path]
132 bd924ffd Dimitris Aragiorgis
  result = utils.RunCmd(cmd1)
133 bd924ffd Dimitris Aragiorgis
  if result.failed:
134 bd924ffd Dimitris Aragiorgis
    sys.stderr.write('losetup -j %s failed (%s): %s' %
135 bd924ffd Dimitris Aragiorgis
                     (dev_path, result.fail_reason, result.output))
136 bd924ffd Dimitris Aragiorgis
    return 1
137 bd924ffd Dimitris Aragiorgis
  else:
138 bd924ffd Dimitris Aragiorgis
    # Parse the result's output
139 bd924ffd Dimitris Aragiorgis
    dev_path = _ParseLosetupOutput(result.output, file_path)
140 bd924ffd Dimitris Aragiorgis
141 bd924ffd Dimitris Aragiorgis
    if dev_path is None:
142 bd924ffd Dimitris Aragiorgis
      # The file is not losetup (device is not attached). Return.
143 bd924ffd Dimitris Aragiorgis
      sys.stderr.write('File %s successfully detached\n' % file_path)
144 bd924ffd Dimitris Aragiorgis
      return 0
145 bd924ffd Dimitris Aragiorgis
    else:
146 bd924ffd Dimitris Aragiorgis
      # The file is losetup (device attached). Detach it.
147 bd924ffd Dimitris Aragiorgis
      cmd2 = ["losetup", "-d", "%s" % dev_path]
148 bd924ffd Dimitris Aragiorgis
      result = utils.RunCmd(cmd2)
149 bd924ffd Dimitris Aragiorgis
      if result.failed:
150 bd924ffd Dimitris Aragiorgis
        sys.stderr.write('Cannot `losetup -d` device: %s, detachment failed '
151 bd924ffd Dimitris Aragiorgis
                         '(%s): %s\n' %
152 bd924ffd Dimitris Aragiorgis
                          (dev_path, result.fail_reason, result.output))
153 bd924ffd Dimitris Aragiorgis
        return 1
154 bd924ffd Dimitris Aragiorgis
155 bd924ffd Dimitris Aragiorgis
      sys.stderr.write('File %s successfully detached\n' % file_path)
156 bd924ffd Dimitris Aragiorgis
      return 0
157 bd924ffd Dimitris Aragiorgis
158 bd924ffd Dimitris Aragiorgis
159 bd924ffd Dimitris Aragiorgis
if __name__ == "__main__":
160 bd924ffd Dimitris Aragiorgis
    sys.exit(main())