OSDN Git Service

Merge branch 'dev' of ssh://raid.local.hde.co.jp/hde/karesansui/karesansui into dev
[karesansui/karesansui.git] / bin / add_iscsi.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 #
4 # This file is part of Karesansui.
5 #
6 # Copyright (C) 2010 HDE, Inc.
7 #
8 # This program is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU General Public License
10 # as published by the Free Software Foundation; either version 2
11 # of the License, or (at your option) any later version.
12 #
13
14 """ 
15 <comment-ja>
16
17
18  使用方法: add_disk.py [オプション]
19
20   オプション:
21   --version             show program's version number and exit
22   -h, --help            show this help message and exit
23   -t HOST, --target=HOST
24                         ターゲットホスト名
25   -a AUTH, --auth=AUTH  認証タイプ
26   -u USER, --user=USER  認証ユーザー名
27   -p PASSWORD, --password=PASSWORD
28                         認証パスワード
29   -w PASSWORD_FILE, --password-file=PASSWORD_FILE
30                         認証パスワード
31   -s, --autostart       自動起動
32
33 </comment-ja>
34 <comment-en>
35 Attach a new disk device to the domain.
36
37  usage: add_disk.py [options]
38
39   options:
40   --version             show program's version number and exit
41   -h, --help            show this help message and exit
42   -t HOST, --target=HOST
43                         Target host name
44   -a AUTH, --auth=AUTH  Authentication type
45   -u USER, --user=USER  Authentication user name
46   -p PASSWORD, --password=PASSWORD
47                         Authentication password
48   -w PASSWORD_FILE, --password-file=PASSWORD_FILE
49                         Authentication password file
50   -s, --autostart       Autostart
51
52 </comment-en>
53 """
54
55 import os
56 import sys
57 import logging
58 import fcntl
59 from optparse import OptionParser
60
61 from ksscommand import KssCommand, KssCommandException, KssCommandOptException
62 import __cmd__
63
64 try:
65     import karesansui
66     from karesansui import __version__
67     from karesansui.lib.utils import load_locale, execute_command
68     from karesansui.lib.parser.iscsid import iscsidParser
69     from karesansui.lib.dict_op import DictOp
70     from karesansui.lib.iscsi import iscsi_parse_node, iscsi_print_format_node
71     from karesansui.lib.const import ISCSI_CONFIG_KEY_AUTH_METHOD, ISCSI_CONFIG_KEY_AUTH_USER, \
72         ISCSI_CONFIG_KEY_AUTH_PASSWORD, ISCSI_CONFIG_KEY_SATRTUP, ISCSI_CONFIG_VALUE_AUTH_METHOD_CHAP, \
73         ISCSI_CONFIG_VALUE_AUTH_METHOD_NONE, ISCSI_CONFIG_VALUE_SATRTUP_ON, ISCSI_CONFIG_VALUE_SATRTUP_OFF, \
74         ISCSI_CMD, ISCSI_CMD_OPTION_MODE, ISCSI_CMD_OPTION_MODE_DISCOVERY, ISCSI_CMD_OPTION_TYPE, \
75         ISCSI_CMD_OPTION_TYPE_SENDTARGETS, ISCSI_CMD_OPTION_PORTAL
76
77 except ImportError:
78     print >>sys.stderr, "[Error] karesansui package was not found."
79     sys.exit(1)
80
81 _ = load_locale()
82
83 usage = '%prog [options]'
84
85 def getopts():
86     optp = OptionParser(usage=usage, version=__version__)
87     optp.add_option('-t', '--target', dest='host', help=_('Target host name'), default=None)
88     optp.add_option('-a', '--auth', dest='auth', help=_('Authentication type'), default=None)
89     optp.add_option('-u', '--user', dest='user', help=_('Authentication user'), default=None)
90     optp.add_option('-p', '--password', dest='password', help=_('Authentication password'), default=None)
91     optp.add_option('-w', '--password-file', dest='password_file', help=_('Authentication password file'), default=None)
92     optp.add_option('-s', '--autostart', dest='autostart', action="store_true", help=_('Autostart'), default=False)
93     return optp.parse_args()
94
95 def chkopts(opts):
96     if not opts.host:
97         raise KssCommandOptException('ERROR: %s option is required.' % '-t or --target')
98
99     if opts.auth:
100         if not opts.auth == ISCSI_CONFIG_VALUE_AUTH_METHOD_CHAP and not opts.auth == ISCSI_CONFIG_VALUE_AUTH_METHOD_NONE:
101             raise KssCommandOptException('ERROR: %s option is require %s or %s.' % '-a', ISCSI_CONFIG_VALUE_AUTH_METHOD_CHAP, ISCSI_CONFIG_VALUE_AUTH_METHOD_NONE)
102         if opts.auth == ISCSI_CONFIG_VALUE_AUTH_METHOD_CHAP:
103             if opts.user is None:
104                 raise KssCommandOptException('ERROR: %s option is required.' % '-u or --user')
105             if opts.password is None and opts.password_file is None:
106                 raise KssCommandOptException('ERROR: %s option is required.' % '-p or --password or -w or --password-file')
107             if opts.password_file is not None and not os.path.exists(opts.password_file):
108                 raise KssCommandOptException('ERROR: %s is not found.' % opts.password_file)
109
110 class AddIscsi(KssCommand):
111
112     def process(self):
113         (opts, args) = getopts()
114         chkopts(opts)
115         self.up_progress(10)
116
117         original_parser = iscsidParser()
118         new_parser = iscsidParser()
119         dop = DictOp()
120
121         dop.addconf("original", original_parser.read_conf())
122         dop.addconf("new", new_parser.read_conf())
123
124         self.up_progress(10)
125
126         dop.cdp_set("new", ISCSI_CONFIG_KEY_AUTH_METHOD, opts.auth)
127         if opts.auth == ISCSI_CONFIG_VALUE_AUTH_METHOD_CHAP:
128             password = ""
129             if opts.password is not None:
130                 password = opts.password
131             elif opts.password_file is not None and os.path.exists(opts.password_file):
132                 try:
133                     fp = open(opts.password_file, "r")
134                     try:
135                         fcntl.lockf(fp.fileno(), fcntl.LOCK_SH)
136                         try:
137                             password = fp.readline().strip("\n")
138                         finally:
139                             fcntl.lockf(fp.fileno(), fcntl.LOCK_UN)
140
141                         self.up_progress(10)
142                     finally:
143                         fp.close()
144
145                 except Exception, e:
146                     self.logger.error('Failed to read file. - target host=%s password_file=%s' \
147                                       % (opts.host,opts.password_file))
148                     print >>sys.stderr, _('Failed to read file. - target host=%s password_file=%s') \
149                           % (opts.host, opts.password_file)
150                     raise
151
152                 os.remove(opts.password_file)
153                 self.up_progress(10)
154
155
156             dop.cdp_set("new", ISCSI_CONFIG_KEY_AUTH_METHOD, opts.auth)
157             dop.cdp_set("new", ISCSI_CONFIG_KEY_AUTH_USER, opts.user)
158             dop.cdp_set("new", ISCSI_CONFIG_KEY_AUTH_PASSWORD, password)
159         else:
160             dop.comment("new", ISCSI_CONFIG_KEY_AUTH_USER)
161             dop.comment("new", ISCSI_CONFIG_KEY_AUTH_PASSWORD)
162
163         if opts.autostart:
164             dop.cdp_set("new", ISCSI_CONFIG_KEY_SATRTUP, ISCSI_CONFIG_VALUE_SATRTUP_ON)
165         else:
166             dop.cdp_set("new", ISCSI_CONFIG_KEY_SATRTUP, ISCSI_CONFIG_VALUE_SATRTUP_OFF)
167
168         new_parser.write_conf(dop.getconf("new"))
169         self.up_progress(10)
170
171         discovery_command_args = (ISCSI_CMD,
172                                   ISCSI_CMD_OPTION_MODE,
173                                   ISCSI_CMD_OPTION_MODE_DISCOVERY,
174                                   ISCSI_CMD_OPTION_TYPE,
175                                   ISCSI_CMD_OPTION_TYPE_SENDTARGETS,
176                                   ISCSI_CMD_OPTION_PORTAL,
177                                   opts.host
178                                   )
179
180         (discovery_rc,discovery_res) = execute_command(discovery_command_args)
181         self.up_progress(10)
182
183         original_parser.write_conf(dop.getconf("original"))
184         self.up_progress(10)
185
186         if discovery_rc != 0:
187             raise KssCommandException('Failed to add iSCSI. - host=%s message=%s' % (opts.host, discovery_res))
188
189         if discovery_res == []:
190             raise KssCommandException('Failed to add iSCSI. - host=%s message=No exist permit iSCSI disk for target.' % (opts.host))
191
192         for node_line in discovery_res:
193             if not node_line:
194                 continue
195
196             node = iscsi_parse_node(node_line)
197
198             self.logger.info("%s" % (iscsi_print_format_node(node)))
199             print >>sys.stdout, _("%s") % (iscsi_print_format_node(node))
200
201         return True
202
203 if __name__ == "__main__":
204     target = AddIscsi()
205     sys.exit(target.run())