Mercurial > illumos > illumos-gate
comparison usr/src/cmd/beadm/beadm.py @ 13025:3c7681e3e323
PSARC 2010/059 SNAP BE Management
6964804 SNAP BE management into ON
6971379 libbe should capture and give useful error when installgrub or ict.py fails.
6971390 beadm does not support labeled brand zones
6971394 BEADM_ERR_BE_DOES_NOT_EXIST has an extra space
6971397 libbe error messages need internationalization
6971402 Remove be_get_last_zone_be_callback
6971409 be_create_menu returns errors from both be_errno_t and errno sets
author | Glenn Lagasse <glenn.lagasse@oracle.com> |
---|---|
date | Wed, 04 Aug 2010 12:28:19 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
13024:c176c071a066 | 13025:3c7681e3e323 |
---|---|
1 #!/usr/bin/python2.6 | |
2 # | |
3 # CDDL HEADER START | |
4 # | |
5 # The contents of this file are subject to the terms of the | |
6 # Common Development and Distribution License (the "License"). | |
7 # You may not use this file except in compliance with the License. | |
8 # | |
9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
10 # or http://www.opensolaris.org/os/licensing. | |
11 # See the License for the specific language governing permissions | |
12 # and limitations under the License. | |
13 # | |
14 # When distributing Covered Code, include this CDDL HEADER in each | |
15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
16 # If applicable, add the following below this CDDL HEADER, with the | |
17 # fields enclosed by brackets "[]" replaced with your own identifying | |
18 # information: Portions Copyright [yyyy] [name of copyright owner] | |
19 # | |
20 # CDDL HEADER END | |
21 # | |
22 | |
23 # | |
24 # Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. | |
25 # | |
26 | |
27 """ | |
28 beadm - The Boot Environment Administration tool. Use this CLI to | |
29 manage boot environments. | |
30 """ | |
31 | |
32 import getopt | |
33 import gettext | |
34 import os | |
35 import sys | |
36 import shutil | |
37 import traceback | |
38 import time | |
39 import subprocess | |
40 | |
41 from beadm import _ | |
42 from beadm.BootEnvironment import * | |
43 import beadm.messages as msg | |
44 import libbe_py as lb | |
45 | |
46 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
47 def usage(): | |
48 '''Defines parameters and options of the command beadm.''' | |
49 print >> sys.stderr, _(""" | |
50 Usage: | |
51 beadm subcommand cmd_options | |
52 | |
53 subcommands: | |
54 | |
55 beadm activate beName | |
56 beadm create [-a] [-d description] | |
57 [-e non-activeBeName | beName@snapshot] | |
58 [-o property=value] ... [-p zpool] beName | |
59 beadm create beName@snapshot | |
60 beadm destroy [-fF] beName | beName@snapshot | |
61 beadm list [[-a] | [-d] [-s]] [-H] [beName] | |
62 beadm mount beName mountpoint | |
63 beadm rename beName newBeName | |
64 beadm unmount [-f] beName""") | |
65 sys.exit(1) | |
66 | |
67 | |
68 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
69 # Public Command Line functions described in beadm(1) | |
70 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
71 | |
72 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
73 def activate(opts): | |
74 """ | |
75 Function: activate | |
76 | |
77 Description: Activate a Boot Environment.The following is the | |
78 subcommand, options and args that make up the | |
79 opts object passed in: | |
80 | |
81 Parameters: | |
82 opts - A string containing the active subcommand | |
83 | |
84 Returns: | |
85 0 - Success | |
86 1 - Failure | |
87 """ | |
88 | |
89 if len(opts) != 1: | |
90 msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) | |
91 usage() | |
92 | |
93 be = BootEnvironment() | |
94 | |
95 if lb.beVerifyBEName(opts[0]) != 0: | |
96 msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1) | |
97 return 1 | |
98 | |
99 rc = lb.beActivate(opts[0]) | |
100 if rc == 0: | |
101 return 0 | |
102 | |
103 be.msg_buf["0"] = opts[0] | |
104 if rc == msg.Msgs.BE_ERR_BE_NOENT: | |
105 be.msg_buf["1"] = \ | |
106 msg.getMsg(msg.Msgs.BEADM_ERR_BE_DOES_NOT_EXIST, opts[0]) | |
107 elif rc == msg.Msgs.BE_ERR_PERM or rc == msg.Msgs.BE_ERR_ACCESS: | |
108 be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_PERMISSIONS, rc) | |
109 msg.printMsg(msg.Msgs.BEADM_ERR_ACTIVATE, be.msg_buf, -1) | |
110 return 1 | |
111 else: | |
112 be.msg_buf["1"] = lb.beGetErrDesc(rc) | |
113 if be.msg_buf["1"] == None: | |
114 be.msg_buf["1"] = \ | |
115 msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc) | |
116 | |
117 msg.printMsg(msg.Msgs.BEADM_ERR_ACTIVATE, be.msg_buf, -1) | |
118 return 1 | |
119 | |
120 | |
121 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
122 def create(opts): | |
123 """ | |
124 Function: create | |
125 | |
126 Description: Create a Boot Environment. The following is the | |
127 subcommand, options and args that make up the | |
128 opts object passed in: | |
129 | |
130 create [-a] [-d description] | |
131 [-e non-activeBeName | beName@Snapshot] | |
132 [-o property=value] ... [-p zpool] beName | |
133 | |
134 create beName@Snapshot | |
135 | |
136 Parameters: | |
137 opts - A object containing the create subcommand | |
138 and all the options and arguments passed in | |
139 on the command line mentioned above. | |
140 | |
141 Returns: | |
142 0 - Success | |
143 1 - Failure | |
144 """ | |
145 | |
146 be = BootEnvironment() | |
147 | |
148 activate = False | |
149 | |
150 try: | |
151 opts_args, be.trgt_be_name_or_snapshot = getopt.getopt(opts, | |
152 "ad:e:o:p:") | |
153 except getopt.GetoptError: | |
154 msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) | |
155 usage() | |
156 | |
157 # Counters for detecting multiple options. | |
158 # e.g. beadm create -p rpool -p rpool2 newbe | |
159 num_a_opts = 0 | |
160 num_e_opts = 0 | |
161 num_p_opts = 0 | |
162 num_d_opts = 0 | |
163 | |
164 for opt, arg in opts_args: | |
165 if opt == "-a": | |
166 activate = True | |
167 num_a_opts += 1 | |
168 elif opt == "-e": | |
169 be.src_be_name_or_snapshot = arg | |
170 num_e_opts += 1 | |
171 elif opt == "-o": | |
172 key, value = arg.split("=") | |
173 be.properties[key] = value | |
174 elif opt == "-p": | |
175 be.trgt_rpool = arg | |
176 num_p_opts += 1 | |
177 elif opt == "-d": | |
178 be.description = arg | |
179 num_d_opts += 1 | |
180 | |
181 if num_a_opts > 1 or num_e_opts > 1 or num_p_opts > 1 or num_d_opts > 1: | |
182 msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) | |
183 usage() | |
184 | |
185 # Check that all info provided from the user is legitimate. | |
186 if (verifyCreateOptionsArgs(be) != 0): | |
187 usage() | |
188 | |
189 if initBELog("create", be) != 0: | |
190 return 1 | |
191 | |
192 msg.printMsg(msg.Msgs.BEADM_MSG_BE_CREATE_START, | |
193 be.trgt_be_name_or_snapshot[0], be.log_id) | |
194 | |
195 if '@' in be.trgt_be_name_or_snapshot[0]: | |
196 # Create a snapshot | |
197 rc = createSnapshot(be) | |
198 else: | |
199 if lb.beVerifyBEName(be.trgt_be_name_or_snapshot[0]) != 0: | |
200 msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1) | |
201 return 1 | |
202 | |
203 # Create a BE based on a snapshot | |
204 if be.src_be_name_or_snapshot is not None and \ | |
205 '@' in be.src_be_name_or_snapshot: | |
206 # Create a BE from a snapshot | |
207 rc = createBEFromSnapshot(be) | |
208 else: | |
209 rc = createBE(be) | |
210 | |
211 # Activate the BE if the user chose to. | |
212 if activate and rc == 0: | |
213 rc = activateBE(be) | |
214 cleanupBELog(be) | |
215 | |
216 return rc | |
217 | |
218 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
219 def destroy(opts): | |
220 """ | |
221 Function: destroy | |
222 | |
223 Description: Destroy a Boot Environment. The following is the | |
224 subcommand, options and args that make up the | |
225 opts object passed in: | |
226 | |
227 destroy [-fF] beName | beName@snapshot | |
228 | |
229 Parameters: | |
230 opts - A object containing the destroy subcommand | |
231 and all the options and arguments passed in | |
232 on the command line mentioned above. | |
233 | |
234 Returns: | |
235 0 - Success | |
236 1 - Failure | |
237 """ | |
238 | |
239 force_unmount = 0 | |
240 suppress_prompt = False | |
241 be_active_on_boot = None | |
242 be = BootEnvironment() | |
243 | |
244 try: | |
245 opts_args, be.trgt_be_name_or_snapshot = getopt.getopt(opts, "fF") | |
246 except getopt.GetoptError: | |
247 msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) | |
248 usage() | |
249 | |
250 # Counters for detecting multiple options. | |
251 # e.g. beadm destroy -f -f newbe | |
252 num_f_opts = 0 | |
253 num_sf_opts = 0 | |
254 | |
255 for opt, arg in opts_args: | |
256 if opt == "-f": | |
257 force_unmount = 1 | |
258 num_sf_opts += 1 | |
259 elif opt == "-F": | |
260 suppress_prompt = True | |
261 num_f_opts += 1 | |
262 | |
263 if num_sf_opts > 1 or num_f_opts > 1: | |
264 msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) | |
265 usage() | |
266 | |
267 if len(be.trgt_be_name_or_snapshot) != 1: | |
268 msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) | |
269 usage() | |
270 | |
271 is_snapshot = False | |
272 | |
273 if "@" in be.trgt_be_name_or_snapshot[0]: | |
274 is_snapshot = True | |
275 be_name, snap_name = be.trgt_be_name_or_snapshot[0].split("@") | |
276 if lb.beVerifyBEName(be_name) != 0: | |
277 msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1) | |
278 return 1 | |
279 else: | |
280 if lb.beVerifyBEName(be.trgt_be_name_or_snapshot[0]) != 0: | |
281 msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1) | |
282 return 1 | |
283 | |
284 # Get the 'active' BE and the 'active on boot' BE. | |
285 be_active, be_active_on_boot = getActiveBEAndActiveOnBootBE() | |
286 | |
287 # If the user is trying to destroy the 'active' BE then quit now. | |
288 if not is_snapshot and be_active == be.trgt_be_name_or_snapshot[0]: | |
289 be.msg_buf["0"] = be.msg_buf["1"] = be_active | |
290 msg.printMsg(msg.Msgs.BEADM_ERR_DESTROY_ACTIVE, be.msg_buf, -1) | |
291 return 1 | |
292 | |
293 if not suppress_prompt: | |
294 | |
295 # Display a destruction question and wait for user response. | |
296 # Quit if negative user response. | |
297 | |
298 if not displayDestructionQuestion(be): | |
299 return 0 | |
300 | |
301 if is_snapshot: | |
302 | |
303 # Destroy a snapshot. | |
304 rc = lb.beDestroySnapshot(be_name, snap_name) | |
305 else: | |
306 | |
307 # Destroy a BE. Passing in 1 for the second arg destroys | |
308 # any snapshots the BE may have as well. | |
309 | |
310 rc = lb.beDestroy(be.trgt_be_name_or_snapshot[0], 1, force_unmount) | |
311 | |
312 # Check if the BE that was just destroyed was the | |
313 # 'active on boot' BE. If it was, display a message letting | |
314 # the user know that the 'active' BE is now also the | |
315 # 'active on boot' BE. | |
316 if be_active_on_boot == be.trgt_be_name_or_snapshot[0] and rc == 0: | |
317 msg.printMsg(msg.Msgs.BEADM_MSG_ACTIVE_ON_BOOT, | |
318 be_active, -1) | |
319 | |
320 if rc == 0: | |
321 try: | |
322 shutil.rmtree("/var/log/beadm/" + \ | |
323 be.trgt_be_name_or_snapshot[0], True) | |
324 except: | |
325 msg.printMsg(msg.Msgs.BEADM_ERR_LOG_RM, | |
326 "/var/log/beadm/" + be.trgt_be_name_or_snapshot[0], -1) | |
327 | |
328 return 0 | |
329 | |
330 be.msg_buf["0"] = be.trgt_be_name_or_snapshot[0] | |
331 if rc == msg.Msgs.BE_ERR_MOUNTED: | |
332 be.msg_buf["1"] = be.msg_buf["2"] = be.trgt_be_name_or_snapshot[0] | |
333 msg.printMsg(msg.Msgs.BEADM_ERR_MOUNTED, be.msg_buf, -1) | |
334 return 1 | |
335 elif rc == msg.Msgs.BE_ERR_DESTROY_CURR_BE: | |
336 msg.printMsg(msg.Msgs.BEADM_ERR_DESTROY_ACTIVE, \ | |
337 be.msg_buf["0"], -1) | |
338 return 1 | |
339 elif rc == msg.Msgs.BE_ERR_ZONES_UNMOUNT: | |
340 be.msg_buf["1"] = be.trgt_be_name_or_snapshot[0] | |
341 msg.printMsg(msg.Msgs.BE_ERR_ZONES_UNMOUNT, be.msg_buf, -1) | |
342 return 1 | |
343 elif rc == msg.Msgs.BE_ERR_PERM or rc == msg.Msgs.BE_ERR_ACCESS: | |
344 be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_PERMISSIONS, rc) | |
345 msg.printMsg(msg.Msgs.BEADM_ERR_DESTROY, be.msg_buf, -1) | |
346 return 1 | |
347 else: | |
348 be.msg_buf["1"] = lb.beGetErrDesc(rc) | |
349 if be.msg_buf["1"] == None: | |
350 be.msg_buf["1"] = \ | |
351 msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc) | |
352 | |
353 msg.printMsg(msg.Msgs.BEADM_ERR_DESTROY, be.msg_buf, -1) | |
354 return 1 | |
355 | |
356 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
357 def list(opts): | |
358 """ | |
359 Description: List the attributes of a Boot Environment. | |
360 The following is the subcommand, options | |
361 and args that make up the opts object | |
362 passed in: | |
363 | |
364 list [[-a] | [-d] [-s]] [-H] [beName] | |
365 | |
366 -a displays all info | |
367 -d displays BE info plus dataset info | |
368 -s displays BE info plus snapshot info | |
369 -H displays info parsable by a computer | |
370 | |
371 Parameters: | |
372 opts - A object containing the list subcommand | |
373 and all the options and arguments passed in | |
374 on the command line mentioned above. | |
375 | |
376 Returns: | |
377 0 - Success | |
378 1 - Failure | |
379 """ | |
380 | |
381 be = BootEnvironment() | |
382 | |
383 list_all_attrs = "" | |
384 list_datasets = "" | |
385 list_snapshots = "" | |
386 dont_display_headers = False | |
387 be_name = None | |
388 be_list = None | |
389 | |
390 # Counters for detecting multiple options. | |
391 # e.g. beadm list -a -a newbe | |
392 num_a_opts = 0 | |
393 num_d_opts = 0 | |
394 num_s_opts = 0 | |
395 num_h_opts = 0 | |
396 | |
397 try: | |
398 opts_args, be.trgt_be_name_or_snapshot = getopt.getopt(opts, "adHs") | |
399 except getopt.GetoptError: | |
400 msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) | |
401 usage() | |
402 | |
403 for opt, arg in opts_args: | |
404 if opt == "-a": | |
405 list_all_attrs = opt | |
406 num_a_opts += 1 | |
407 elif opt == "-d": | |
408 list_datasets = opt | |
409 num_d_opts += 1 | |
410 elif opt == "-s": | |
411 list_snapshots = opt | |
412 num_s_opts += 1 | |
413 elif opt == "-H": | |
414 dont_display_headers = True | |
415 num_h_opts += 1 | |
416 | |
417 if num_a_opts > 1 or num_d_opts > 1 or num_s_opts > 1 or num_h_opts > 1: | |
418 msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) | |
419 usage() | |
420 | |
421 if len(be.trgt_be_name_or_snapshot) > 1: | |
422 msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) | |
423 usage() | |
424 | |
425 if len(be.trgt_be_name_or_snapshot) == 1: | |
426 be_name = be.trgt_be_name_or_snapshot[0] | |
427 if lb.beVerifyBEName(be_name) != 0: | |
428 msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1) | |
429 return 1 | |
430 | |
431 if (list_all_attrs == "-a" and (list_datasets == "-d" \ | |
432 or list_snapshots == "-s")): | |
433 msg.printMsg(msg.Msgs.BEADM_ERR_MUTUALLY_EXCL, | |
434 list_all_attrs + " " + list_datasets + " " + | |
435 list_snapshots, -1) | |
436 usage() | |
437 | |
438 list_options = "" | |
439 | |
440 # When zones are implemented add "listZones == "-z" below | |
441 | |
442 # Coelesce options to pass to displayBEs | |
443 | |
444 if (list_datasets == "-d" and list_snapshots == "-s" or \ | |
445 list_all_attrs == "-a"): | |
446 list_options = "-a" | |
447 elif list_datasets != "" or list_snapshots != "" or list_all_attrs != "": | |
448 list_options = list_datasets + " " + list_snapshots | |
449 | |
450 rc, be_list = lb.beList() | |
451 if rc != 0: | |
452 if rc == msg.Msgs.BE_ERR_BE_NOENT: | |
453 if be_name == None: | |
454 msg.printMsg(msg.Msgs.BEADM_ERR_NO_BES_EXIST, | |
455 None, -1) | |
456 return 1 | |
457 | |
458 string = \ | |
459 msg.getMsg(msg.Msgs.BEADM_ERR_BE_DOES_NOT_EXIST, | |
460 be_name) | |
461 else: | |
462 string = lb.beGetErrDesc(rc) | |
463 if string == None: | |
464 string = \ | |
465 msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc) | |
466 | |
467 msg.printMsg(msg.Msgs.BEADM_ERR_LIST, string, -1) | |
468 return 1 | |
469 | |
470 # classify according to command line options | |
471 if list_options.find("-a") != -1 or \ | |
472 (list_options.find("-d") != -1 and list_options.find("-s") != -1): | |
473 list_object = CompleteList(dont_display_headers) #all | |
474 elif list_options.find("-d") != -1: | |
475 list_object = DatasetList(dont_display_headers) #dataset | |
476 elif list_options.find("-s") != -1: | |
477 list_object = SnapshotList(dont_display_headers) #snapshot | |
478 else: list_object = BEList(dont_display_headers) #only BE | |
479 | |
480 # use list method for object | |
481 if list_object.list(be_list, dont_display_headers, be_name) != 0: | |
482 msg.printMsg(msg.Msgs.BEADM_ERR_LIST_DATA, None, -1) | |
483 return 1 | |
484 | |
485 return 0 | |
486 | |
487 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
488 def mount(opts): | |
489 """ | |
490 Description: Mount a Boot Environment on a directory. | |
491 The following is the subcommand, options | |
492 and args that make up the opts object | |
493 passed in: | |
494 | |
495 mount beName [mountpoint] | |
496 | |
497 Parameters: | |
498 opts - A object containing the mount subcommand | |
499 and all the options and arguments passed in | |
500 on the command line mentioned above. | |
501 | |
502 Returns: | |
503 0 - Success | |
504 1 - Failure | |
505 """ | |
506 | |
507 be = BootEnvironment() | |
508 | |
509 mountpoint = None | |
510 | |
511 try: | |
512 be_name_mnt_point = getopt.getopt(opts, "")[1] | |
513 except getopt.GetoptError: | |
514 msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) | |
515 usage() | |
516 | |
517 mnt_point_len = len(be_name_mnt_point) | |
518 | |
519 if mnt_point_len != 2: | |
520 msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) | |
521 usage() | |
522 else: | |
523 # Check for leading / in mount point | |
524 mountpoint = be_name_mnt_point[1] | |
525 if not mountpoint.startswith('/'): | |
526 msg.printMsg(msg.Msgs.BEADM_ERR_MOUNTPOINT, | |
527 mountpoint, -1) | |
528 return 1 | |
529 | |
530 if lb.beVerifyBEName(be_name_mnt_point[0]) != 0: | |
531 msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1) | |
532 return 1 | |
533 | |
534 rc = lb.beMount(be_name_mnt_point[0], mountpoint) | |
535 if rc == 0: | |
536 return 0 | |
537 | |
538 be.msg_buf["0"] = be_name_mnt_point[0] | |
539 if rc == msg.Msgs.BE_ERR_MOUNTED: | |
540 be.msg_buf["1"] = \ | |
541 msg.getMsg(msg.Msgs.BEADM_ERR_MOUNT_EXISTS, | |
542 be_name_mnt_point[0]) | |
543 elif rc == msg.Msgs.BE_ERR_BE_NOENT: | |
544 be.msg_buf["1"] = \ | |
545 msg.getMsg(msg.Msgs.BEADM_ERR_BE_DOES_NOT_EXIST, | |
546 be_name_mnt_point[0]) | |
547 elif rc == msg.Msgs.BE_ERR_PERM or rc == msg.Msgs.BE_ERR_ACCESS: | |
548 be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_PERMISSIONS, rc) | |
549 msg.printMsg(msg.Msgs.BEADM_ERR_MOUNT, be.msg_buf, -1) | |
550 return 1 | |
551 else: | |
552 be.msg_buf["1"] = lb.beGetErrDesc(rc) | |
553 if be.msg_buf["1"] == None: | |
554 be.msg_buf["1"] = \ | |
555 msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc) | |
556 | |
557 msg.printMsg(msg.Msgs.BEADM_ERR_MOUNT, be.msg_buf, -1) | |
558 return 1 | |
559 | |
560 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
561 def unmount(opts): | |
562 """ | |
563 Description: Unmount a Boot Environment. | |
564 The following is the subcommand, options | |
565 and args that make up the opts object | |
566 passed in: | |
567 | |
568 unmount [-f] beName | |
569 | |
570 Parameters: | |
571 opts - A object containing the unmount subcommand | |
572 and all the options and arguments passed in | |
573 on the command line mentioned above. | |
574 | |
575 Returns: | |
576 0 - Success | |
577 1 - Failure | |
578 """ | |
579 | |
580 be = BootEnvironment() | |
581 | |
582 force_unmount = 0 | |
583 | |
584 # Counter for detecting multiple options. | |
585 # e.g. beadm unmount -f -f newbe | |
586 num_f_opts = 0 | |
587 | |
588 try: | |
589 optlist, args = getopt.getopt(opts, "f") | |
590 except getopt.GetoptError: | |
591 msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) | |
592 usage() | |
593 | |
594 for opt, arg in optlist: | |
595 if opt == "-f": | |
596 force_unmount = 1 | |
597 num_f_opts += 1 | |
598 | |
599 if num_f_opts > 1: | |
600 msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) | |
601 usage() | |
602 | |
603 if len(args) != 1: | |
604 msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) | |
605 usage() | |
606 | |
607 if lb.beVerifyBEName(args[0]) != 0: | |
608 msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1) | |
609 return 1 | |
610 | |
611 rc = lb.beUnmount(args[0], force_unmount) | |
612 if rc == 0: | |
613 return 0 | |
614 | |
615 be.msg_buf["0"] = args[0] | |
616 if rc == msg.Msgs.BE_ERR_UMOUNT_CURR_BE: | |
617 be.msg_buf["1"] = \ | |
618 msg.getMsg(msg.Msgs.BEADM_ERR_UNMOUNT_ACTIVE, | |
619 args[0]) | |
620 elif rc == msg.Msgs.BE_ERR_UMOUNT_SHARED: | |
621 be.msg_buf["1"] = \ | |
622 msg.getMsg(msg.Msgs.BEADM_ERR_SHARED_FS, args[0]) | |
623 elif rc == msg.Msgs.BE_ERR_PERM or rc == msg.Msgs.BE_ERR_ACCESS: | |
624 be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_PERMISSIONS, rc) | |
625 msg.printMsg(msg.Msgs.BEADM_ERR_UNMOUNT, be.msg_buf, -1) | |
626 return 1 | |
627 else: | |
628 be.msg_buf["1"] = lb.beGetErrDesc(rc) | |
629 if be.msg_buf["1"] == None: | |
630 be.msg_buf["1"] = \ | |
631 msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc) | |
632 | |
633 msg.printMsg(msg.Msgs.BEADM_ERR_UNMOUNT, be.msg_buf, -1) | |
634 return 1 | |
635 | |
636 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
637 def rename(opts): | |
638 """ | |
639 Description: Rename the name of a Boot Environment. | |
640 The following is the subcommand, options | |
641 and args that make up the opts object | |
642 passed in: | |
643 | |
644 rename beName newBeName | |
645 | |
646 Parameters: | |
647 opts - A object containing the mount subcommand | |
648 and all the options and arguments passed in | |
649 on the command line mentioned above. | |
650 | |
651 Returns: | |
652 0 - Success | |
653 1 - Failure | |
654 """ | |
655 | |
656 be = BootEnvironment() | |
657 | |
658 try: | |
659 be_names = getopt.getopt(opts, "")[1] | |
660 except getopt.GetoptError: | |
661 msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) | |
662 usage() | |
663 | |
664 if len(be_names) != 2: | |
665 msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) | |
666 usage() | |
667 | |
668 if lb.beVerifyBEName(be_names[0]) != 0: | |
669 msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1) | |
670 return 1 | |
671 | |
672 if lb.beVerifyBEName(be_names[1]) != 0: | |
673 msg.printMsg(msg.Msgs.BEADM_ERR_BENAME, None, -1) | |
674 return 1 | |
675 | |
676 rc = lb.beRename(be_names[0], be_names[1]) | |
677 | |
678 if rc == 0: | |
679 return 0 | |
680 | |
681 be.msg_buf["0"] = be_names[0] | |
682 if rc == msg.Msgs.BE_ERR_BE_NOENT: | |
683 be.msg_buf["1"] = \ | |
684 msg.getMsg(msg.Msgs.BEADM_ERR_BE_DOES_NOT_EXIST, | |
685 be_names[0]) | |
686 elif rc == msg.Msgs.BE_ERR_PERM or rc == msg.Msgs.BE_ERR_ACCESS: | |
687 be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_PERMISSIONS, rc) | |
688 msg.printMsg(msg.Msgs.BEADM_ERR_RENAME, be.msg_buf, -1) | |
689 return 1 | |
690 else: | |
691 be.msg_buf["1"] = lb.beGetErrDesc(rc) | |
692 if be.msg_buf["1"] == None: | |
693 be.msg_buf["1"] = \ | |
694 msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc) | |
695 | |
696 msg.printMsg(msg.Msgs.BEADM_ERR_RENAME, be.msg_buf, -1) | |
697 return 1 | |
698 | |
699 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
700 # End of CLI public functions | |
701 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
702 | |
703 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
704 # Verify the options and arguments for the beadm create subcommand | |
705 | |
706 def verifyCreateOptionsArgs(be): | |
707 """Check valid BE names.""" | |
708 | |
709 len_be_args = len(be.trgt_be_name_or_snapshot) | |
710 if len_be_args < 1: | |
711 msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) | |
712 return 1 | |
713 if len_be_args > 1: | |
714 msg.printMsg(msg.Msgs.BEADM_ERR_OPT_ARGS, None, -1) | |
715 idx = 0 | |
716 while len_be_args > idx: | |
717 msg.printMsg(msg.Msgs.BEADM_MSG_FREE_FORMAT, | |
718 be.trgt_be_name_or_snapshot[idx], -1) | |
719 idx += 1 | |
720 return 1 | |
721 | |
722 return 0 | |
723 | |
724 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
725 def parseCLI(cli_opts_args): | |
726 """Parse command line interface arguments.""" | |
727 | |
728 gettext.install("beadm", "/usr/lib/locale") | |
729 | |
730 if len(cli_opts_args) == 0: | |
731 usage() | |
732 | |
733 subcommand = cli_opts_args[0] | |
734 opts_args = cli_opts_args[1:] | |
735 | |
736 if subcommand == "activate": | |
737 rc = activate(opts_args) | |
738 elif subcommand == "create": | |
739 rc = create(opts_args) | |
740 elif subcommand == "destroy": | |
741 rc = destroy(opts_args) | |
742 elif subcommand == "list": | |
743 rc = list(opts_args) | |
744 elif subcommand == "mount": | |
745 rc = mount(opts_args) | |
746 elif subcommand == "rename": | |
747 rc = rename(opts_args) | |
748 elif subcommand == "upgrade": | |
749 rc = upgrade(opts_args) | |
750 elif subcommand == "unmount" or \ | |
751 subcommand == "umount": #aliased for convenience | |
752 rc = unmount(opts_args) | |
753 elif subcommand == "verify": | |
754 rc = verify() | |
755 else: | |
756 msg.printMsg(msg.Msgs.BEADM_ERR_ILL_SUBCOMMAND, | |
757 subcommand, -1) | |
758 usage() | |
759 | |
760 return(rc) | |
761 | |
762 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
763 def main(): | |
764 """main function.""" | |
765 | |
766 gettext.install("beadm", "/usr/lib/locale") | |
767 | |
768 if not isBeadmSupported(): | |
769 return(1) | |
770 | |
771 return(parseCLI(sys.argv[1:])) | |
772 | |
773 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
774 def initBELog(log_id, be): | |
775 """ | |
776 Initiate the BE log | |
777 | |
778 Format of the log | |
779 yyyymmdd_hhmmss - 20071130_140558 | |
780 yy - year; 2007 | |
781 mm - month; 11 | |
782 dd - day; 30 | |
783 hh - hour; 14 | |
784 mm - minute; 05 | |
785 ss - second; 58 | |
786 """ | |
787 | |
788 # /var/log/beadm/<beName>/<logId>.log.<yyyymmdd_hhmmss> | |
789 | |
790 date = time.strftime("%Y%m%d_%H%M%S", time.localtime()) | |
791 | |
792 be.log = "/var/log/beadm/" + be.trgt_be_name_or_snapshot[0] + \ | |
793 "/" + log_id + ".log" + "." + date | |
794 | |
795 if not os.path.isfile(be.log) and not os.path.islink(be.log): | |
796 if not os.path.isdir(os.path.dirname(be.log)): | |
797 try: | |
798 os.makedirs(os.path.dirname(be.log), 0644) | |
799 except OSError: | |
800 be.msg_buf["0"] = be.trgt_be_name_or_snapshot[0] | |
801 be.msg_buf["1"] = \ | |
802 msg.getMsg(msg.Msgs.BEADM_ERR_PERMISSIONS, | |
803 0) | |
804 msg.printMsg(msg.Msgs.BEADM_ERR_CREATE, | |
805 be.msg_buf, -1) | |
806 return 1 | |
807 try: | |
808 be.log_id = open(be.log, "a") | |
809 except IOError: | |
810 msg.printMsg(msg.Msgs.BEADM_ERR_LOG_CREATE, | |
811 None, -1) | |
812 return 1 | |
813 else: | |
814 # Should never happen due to new time stamp each call | |
815 msg.printMsg(msg.Msgs.BEADM_ERR_LOG_CREATE, None, -1) | |
816 return 1 | |
817 | |
818 return 0 | |
819 | |
820 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
821 def cleanupBELog(be): | |
822 """Clean up BE log.""" | |
823 | |
824 be.log_id.close() | |
825 | |
826 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
827 def displayDestructionQuestion(be): | |
828 """Display a destruction question and wait for user response.""" | |
829 | |
830 msg.printMsg(msg.Msgs.BEADM_MSG_DESTROY, be.trgt_be_name_or_snapshot[0], -1) | |
831 while True: | |
832 try: | |
833 value = raw_input().strip().upper() | |
834 except KeyboardInterrupt: | |
835 return False | |
836 if (value == 'Y' or value == 'YES'): | |
837 return True | |
838 elif len(value) == 0 or value == 'N' or value == 'NO': | |
839 msg.printMsg(msg.Msgs.BEADM_MSG_DESTROY_NO, | |
840 be.trgt_be_name_or_snapshot[0], -1) | |
841 return False | |
842 else: | |
843 msg.printMsg(msg.Msgs.BEADM_ERR_INVALID_RESPONSE, | |
844 -1) | |
845 | |
846 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
847 def setMaxColumnWidths(be_max_w, ds_max_w, ss_max_w, be_list): | |
848 """Figure out max column widths for BE's, Datasets and Snapshots.""" | |
849 | |
850 for be_item in be_list: | |
851 if be_item.get("orig_be_name") is not None: | |
852 determineMaxBEColWidth(be_item, be_max_w) | |
853 if be_item.get("dataset") is not None: | |
854 determineMaxDSColWidth(be_item, ds_max_w) | |
855 if be_item.get("snap_name") is not None: | |
856 determineMaxSSColWidth(be_item, ss_max_w) | |
857 | |
858 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
859 def getActiveBEAndActiveOnBootBE(): | |
860 """Return the 'active on boot' BE, the 'active' BE or None.""" | |
861 | |
862 active_be = None | |
863 active_be_on_boot = None | |
864 | |
865 rc, be_list = lb.beList() | |
866 | |
867 if rc != 0: | |
868 if rc == msg.Msgs.BE_ERR_BE_NOENT: | |
869 string = \ | |
870 msg.getMsg(msg.Msgs.BEADM_ERR_NO_BES_EXIST) | |
871 else: | |
872 string = lb.beGetErrDesc(rc) | |
873 if string == None: | |
874 string = \ | |
875 msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc) | |
876 | |
877 msg.printMsg(msg.Msgs.BEADM_ERR_LIST, string, -1) | |
878 return None | |
879 | |
880 for be_vals in be_list: | |
881 srcBeName = be_vals.get("orig_be_name") | |
882 if be_vals.get("active"): | |
883 active_be = srcBeName | |
884 if be_vals.get("active_boot"): | |
885 active_be_on_boot = srcBeName | |
886 if active_be is not None and active_be_on_boot is not None: | |
887 break | |
888 | |
889 return active_be, active_be_on_boot | |
890 | |
891 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
892 def createSnapshot(be): | |
893 """Create a snapshot.""" | |
894 | |
895 be_name, snap_name = be.trgt_be_name_or_snapshot[0].split("@") | |
896 | |
897 rc = lb.beCreateSnapshot(be_name, snap_name)[0] | |
898 | |
899 if rc == 0: | |
900 return 0 | |
901 | |
902 be.msg_buf["0"] = be.trgt_be_name_or_snapshot[0] | |
903 if rc == msg.Msgs.BE_ERR_BE_NOENT: | |
904 be.msg_buf["1"] = \ | |
905 msg.getMsg(msg.Msgs.BEADM_ERR_BE_DOES_NOT_EXIST, | |
906 be_name) | |
907 elif rc == msg.Msgs.BE_ERR_SS_EXISTS: | |
908 be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_SNAP_EXISTS, | |
909 be.trgt_be_name_or_snapshot[0]) | |
910 elif rc == msg.Msgs.BE_ERR_PERM or rc == msg.Msgs.BE_ERR_ACCESS: | |
911 be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_PERMISSIONS, rc) | |
912 msg.printMsg(msg.Msgs.BEADM_ERR_CREATE, be.msg_buf, -1) | |
913 return 1 | |
914 else: | |
915 be.msg_buf["1"] = lb.beGetErrDesc(rc) | |
916 if be.msg_buf["1"] == None: | |
917 be.msg_buf["1"] = \ | |
918 msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc) | |
919 | |
920 msg.printMsg(msg.Msgs.BEADM_ERR_CREATE, be.msg_buf, -1) | |
921 | |
922 return 1 | |
923 | |
924 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
925 def createBE(be): | |
926 """Create a Boot Environment.""" | |
927 | |
928 rc = lb.beCopy(be.trgt_be_name_or_snapshot[0], be.src_be_name_or_snapshot, | |
929 None, be.trgt_rpool, be.properties, be.description)[0] | |
930 | |
931 if rc == 0: | |
932 msg.printMsg(msg.Msgs.BEADM_MSG_BE_CREATE_SUCCESS, | |
933 be.trgt_be_name_or_snapshot[0], be.log_id) | |
934 return 0 | |
935 | |
936 be.msg_buf["0"] = be.trgt_be_name_or_snapshot[0] | |
937 if rc == msg.Msgs.BE_ERR_BE_NOENT: | |
938 be.msg_buf["1"] = \ | |
939 msg.getMsg(msg.Msgs.BEADM_ERR_BE_DOES_NOT_EXIST, | |
940 be.src_be_name_or_snapshot) | |
941 elif rc == msg.Msgs.BE_ERR_BE_EXISTS: | |
942 be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_BE_EXISTS, | |
943 be.trgt_be_name_or_snapshot[0]) | |
944 elif rc == msg.Msgs.BE_ERR_PERM or rc == msg.Msgs.BE_ERR_ACCESS: | |
945 be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_PERMISSIONS, rc) | |
946 msg.printMsg(msg.Msgs.BEADM_ERR_CREATE, be.msg_buf, -1) | |
947 return 1 | |
948 else: | |
949 be.msg_buf["1"] = lb.beGetErrDesc(rc) | |
950 if be.msg_buf["1"] == None: | |
951 be.msg_buf["1"] = \ | |
952 msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc) | |
953 | |
954 msg.printMsg(msg.Msgs.BEADM_ERR_CREATE, be.msg_buf, be.log_id) | |
955 | |
956 return 1 | |
957 | |
958 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
959 def createBEFromSnapshot(be): | |
960 """Create a BE based off a snapshot.""" | |
961 | |
962 be_name, snap_name = be.src_be_name_or_snapshot.split("@") | |
963 | |
964 rc = lb.beCopy(be.trgt_be_name_or_snapshot[0], be_name, snap_name, | |
965 be.trgt_rpool, be.properties, be.description)[0] | |
966 | |
967 if rc == 0: | |
968 msg.printMsg(msg.Msgs.BEADM_MSG_BE_CREATE_SUCCESS, | |
969 be.trgt_be_name_or_snapshot[0], be.log_id) | |
970 return 0 | |
971 | |
972 be.msg_buf["0"] = be.trgt_be_name_or_snapshot[0] | |
973 if rc == msg.Msgs.BE_ERR_SS_NOENT: | |
974 be.msg_buf["1"] = \ | |
975 msg.getMsg(msg.Msgs.BEADM_ERR_SNAP_DOES_NOT_EXISTS, | |
976 be.src_be_name_or_snapshot) | |
977 elif rc == msg.Msgs.BE_ERR_BE_EXISTS: | |
978 be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_BE_EXISTS, \ | |
979 be.trgt_be_name_or_snapshot[0]) | |
980 elif rc == msg.Msgs.BE_ERR_BE_NOENT: | |
981 be.msg_buf["1"] = \ | |
982 msg.getMsg(msg.Msgs.BEADM_ERR_BE_DOES_NOT_EXIST, \ | |
983 be_name) | |
984 elif rc == msg.Msgs.BE_ERR_PERM or rc == msg.Msgs.BE_ERR_ACCESS: | |
985 be.msg_buf["1"] = msg.getMsg(msg.Msgs.BEADM_ERR_PERMISSIONS, rc) | |
986 msg.printMsg(msg.Msgs.BEADM_ERR_CREATE, be.msg_buf, -1) | |
987 return 1 | |
988 else: | |
989 be.msg_buf["1"] = lb.beGetErrDesc(rc) | |
990 if be.msg_buf["1"] == None: | |
991 be.msg_buf["1"] = \ | |
992 msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc) | |
993 | |
994 msg.printMsg(msg.Msgs.BEADM_ERR_CREATE, be.msg_buf, be.log_id) | |
995 | |
996 return 1 | |
997 | |
998 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
999 def activateBE(be): | |
1000 """ | |
1001 Activate a BE. Called from create() when -a is provided as CLI | |
1002 Option. | |
1003 """ | |
1004 | |
1005 rc = lb.beActivate(be.trgt_be_name_or_snapshot[0]) | |
1006 if rc == 0: | |
1007 return 0 | |
1008 | |
1009 be.msg_buf["0"] = be.trgt_be_name_or_snapshot[0] | |
1010 if rc == msg.Msgs.BE_ERR_BE_NOENT: | |
1011 be.msg_buf["1"] = \ | |
1012 msg.getMsg(msg.Msgs.BEADM_ERR_BE_DOES_NOT_EXIST, opts[0]) | |
1013 else: | |
1014 be.msg_buf["1"] = lb.beGetErrDesc(rc) | |
1015 if be.msg_buf["1"] == None: | |
1016 be.msg_buf["1"] = \ | |
1017 msg.getMsg(msg.Msgs.BEADM_ERR_NO_MSG, rc) | |
1018 | |
1019 msg.printMsg(msg.Msgs.BEADM_ERR_ACTIVATE, be.msg_buf, -1) | |
1020 | |
1021 return 1 | |
1022 | |
1023 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
1024 def isBeadmSupported(): | |
1025 """ | |
1026 Currently the only environment that beadm is supported in is | |
1027 a global zone. Check that beadm is executing in a | |
1028 global zone and not in a non-global zone. | |
1029 """ | |
1030 | |
1031 try: | |
1032 proc = subprocess.Popen("/sbin/zonename", | |
1033 stdout = subprocess.PIPE, | |
1034 stderr = subprocess.STDOUT) | |
1035 # Grab stdout. | |
1036 zonename = proc.communicate()[0].rstrip('\n') | |
1037 except OSError, (errno, strerror): | |
1038 msg.printMsg(msg.Msgs.BEADM_ERR_OS, strerror, -1) | |
1039 # Ignore a failed attempt to retreive the zonename. | |
1040 return True | |
1041 | |
1042 if zonename != "global": | |
1043 msg.printMsg(msg.Msgs.BEADM_ERR_NOT_SUPPORTED_NGZ, None, -1) | |
1044 return False | |
1045 | |
1046 return True | |
1047 | |
1048 | |
1049 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
1050 if __name__ == "__main__": | |
1051 try: | |
1052 RC = main() | |
1053 except SystemExit, e: | |
1054 raise e | |
1055 except: | |
1056 traceback.print_exc() | |
1057 sys.exit(99) | |
1058 sys.exit(RC) |