beadm.py revision f169c0eae91b2ee787cf8d6dcf8edd9159d4c9e2
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
#
"""
beadm - The Boot Environment Administration tool. Use this CLI to
manage boot environments.
"""
import getopt
import gettext
import os
import sys
import shutil
import traceback
import time
import subprocess
from beadm import _
from beadm.BootEnvironment import *
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def usage():
'''Defines parameters and options of the command beadm.'''
Usage:
beadm subcommand cmd_options
subcommands:
beadm activate beName
beadm create [-a] [-d description]
[-e non-activeBeName | beName@snapshot]
[-o property=value] ... [-p zpool] beName
beadm create beName@snapshot
beadm destroy [-fF] beName | beName@snapshot
beadm list [[-a] | [-d] [-s]] [-H] [beName]
beadm mount beName mountpoint
beadm rename beName newBeName
beadm unmount [-f] beName""")
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Public Command Line functions described in beadm(1)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"""
Function: activate
Description: Activate a Boot Environment.The following is the
subcommand, options and args that make up the
opts object passed in:
Parameters:
opts - A string containing the active subcommand
Returns:
0 - Success
1 - Failure
"""
usage()
be = BootEnvironment()
return 1
if rc == 0:
return 0
return 1
else:
return 1
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"""
Function: create
Description: Create a Boot Environment. The following is the
subcommand, options and args that make up the
opts object passed in:
create [-a] [-d description]
[-e non-activeBeName | beName@Snapshot]
[-o property=value] ... [-p zpool] beName
create beName@Snapshot
Parameters:
opts - A object containing the create subcommand
and all the options and arguments passed in
on the command line mentioned above.
Returns:
0 - Success
1 - Failure
"""
be = BootEnvironment()
try:
"ad:e:o:p:")
except getopt.GetoptError:
usage()
# Counters for detecting multiple options.
# e.g. beadm create -p rpool -p rpool2 newbe
num_a_opts = 0
num_e_opts = 0
num_p_opts = 0
num_d_opts = 0
if opt == "-a":
num_a_opts += 1
elif opt == "-e":
num_e_opts += 1
elif opt == "-o":
elif opt == "-p":
num_p_opts += 1
elif opt == "-d":
num_d_opts += 1
usage()
# Check that all info provided from the user is legitimate.
usage()
return 1
# Create a snapshot
else:
return 1
# Create a BE based on a snapshot
if be.src_be_name_or_snapshot is not None and \
# Create a BE from a snapshot
else:
# Activate the BE if the user chose to.
return rc
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"""
Function: destroy
Description: Destroy a Boot Environment. The following is the
subcommand, options and args that make up the
opts object passed in:
destroy [-fF] beName | beName@snapshot
Parameters:
opts - A object containing the destroy subcommand
and all the options and arguments passed in
on the command line mentioned above.
Returns:
0 - Success
1 - Failure
"""
force_unmount = 0
be_active_on_boot = None
be = BootEnvironment()
try:
except getopt.GetoptError:
usage()
# Counters for detecting multiple options.
# e.g. beadm destroy -f -f newbe
num_f_opts = 0
num_sf_opts = 0
if opt == "-f":
force_unmount = 1
num_sf_opts += 1
elif opt == "-F":
num_f_opts += 1
usage()
usage()
return 1
else:
return 1
# Get the 'active' BE and the 'active on boot' BE.
# If the user is trying to destroy the 'active' BE then quit now.
return 1
if not suppress_prompt:
# Display a destruction question and wait for user response.
# Quit if negative user response.
if not displayDestructionQuestion(be):
return 0
if is_snapshot:
# Destroy a snapshot.
else:
# Destroy a BE. Passing in 1 for the second arg destroys
# any snapshots the BE may have as well.
# Check if the BE that was just destroyed was the
# 'active on boot' BE. If it was, display a message letting
# the user know that the 'active' BE is now also the
# 'active on boot' BE.
be_active, -1)
if rc == 0:
try:
except:
return 0
return 1
return 1
return 1
return 1
else:
return 1
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"""
Description: List the attributes of a Boot Environment.
The following is the subcommand, options
and args that make up the opts object
passed in:
list [[-a] | [-d] [-s]] [-H] [beName]
-a displays all info
-d displays BE info plus dataset info
-s displays BE info plus snapshot info
-H displays info parsable by a computer
Parameters:
opts - A object containing the list subcommand
and all the options and arguments passed in
on the command line mentioned above.
Returns:
0 - Success
1 - Failure
"""
be = BootEnvironment()
list_all_attrs = ""
list_datasets = ""
list_snapshots = ""
be_name = None
be_list = None
# Counters for detecting multiple options.
# e.g. beadm list -a -a newbe
num_a_opts = 0
num_d_opts = 0
num_s_opts = 0
num_h_opts = 0
try:
except getopt.GetoptError:
usage()
if opt == "-a":
num_a_opts += 1
elif opt == "-d":
num_d_opts += 1
elif opt == "-s":
num_s_opts += 1
elif opt == "-H":
num_h_opts += 1
usage()
usage()
return 1
or list_snapshots == "-s")):
list_snapshots, -1)
usage()
list_options = ""
# When zones are implemented add "listZones == "-z" below
# Coelesce options to pass to displayBEs
list_all_attrs == "-a"):
list_options = "-a"
if rc != 0:
if be_name == None:
None, -1)
return 1
string = \
else:
if string == None:
string = \
return 1
# classify according to command line options
# use list method for object
return 1
return 0
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"""
Description: Mount a Boot Environment on a directory.
The following is the subcommand, options
and args that make up the opts object
passed in:
mount beName [mountpoint]
Parameters:
opts - A object containing the mount subcommand
and all the options and arguments passed in
on the command line mentioned above.
Returns:
0 - Success
1 - Failure
"""
be = BootEnvironment()
mountpoint = None
try:
except getopt.GetoptError:
usage()
if mnt_point_len != 2:
usage()
else:
# Check for leading / in mount point
mountpoint, -1)
return 1
return 1
if rc == 0:
return 0
return 1
else:
return 1
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"""
Description: Unmount a Boot Environment.
The following is the subcommand, options
and args that make up the opts object
passed in:
unmount [-f] beName
Parameters:
opts - A object containing the unmount subcommand
and all the options and arguments passed in
on the command line mentioned above.
Returns:
0 - Success
1 - Failure
"""
be = BootEnvironment()
force_unmount = 0
# Counter for detecting multiple options.
# e.g. beadm unmount -f -f newbe
num_f_opts = 0
try:
except getopt.GetoptError:
usage()
if opt == "-f":
force_unmount = 1
num_f_opts += 1
if num_f_opts > 1:
usage()
usage()
return 1
if rc == 0:
return 0
args[0])
return 1
else:
return 1
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"""
Description: Rename the name of a Boot Environment.
The following is the subcommand, options
and args that make up the opts object
passed in:
rename beName newBeName
Parameters:
opts - A object containing the mount subcommand
and all the options and arguments passed in
on the command line mentioned above.
Returns:
0 - Success
1 - Failure
"""
be = BootEnvironment()
try:
except getopt.GetoptError:
usage()
usage()
return 1
return 1
if rc == 0:
return 0
be_names[0])
return 1
else:
return 1
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# End of CLI public functions
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Verify the options and arguments for the beadm create subcommand
def verifyCreateOptionsArgs(be):
"""Check valid BE names."""
if len_be_args < 1:
return 1
if len_be_args > 1:
idx = 0
while len_be_args > idx:
idx += 1
return 1
return 0
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def parseCLI(cli_opts_args):
"""Parse command line interface arguments."""
usage()
if subcommand == "activate":
elif subcommand == "create":
elif subcommand == "destroy":
elif subcommand == "list":
elif subcommand == "mount":
elif subcommand == "rename":
elif subcommand == "upgrade":
elif subcommand == "unmount" or \
elif subcommand == "verify":
else:
subcommand, -1)
usage()
return(rc)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def main():
"""main function."""
if not isBeadmSupported():
return(1)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"""
Initiate the BE log
Format of the log
yyyymmdd_hhmmss - 20071130_140558
yy - year; 2007
mm - month; 11
dd - day; 30
hh - hour; 14
mm - minute; 05
ss - second; 58
"""
try:
except OSError:
0)
return 1
try:
except IOError:
None, -1)
return 1
else:
# Should never happen due to new time stamp each call
return 1
return 0
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def cleanupBELog(be):
"""Clean up BE log."""
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def displayDestructionQuestion(be):
"""Display a destruction question and wait for user response."""
while True:
try:
except KeyboardInterrupt:
return False
return True
return False
else:
-1)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"""Figure out max column widths for BE's, Datasets and Snapshots."""
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def getActiveBEAndActiveOnBootBE():
"""Return the 'active on boot' BE, the 'active' BE or None."""
active_be = None
active_be_on_boot = None
if rc != 0:
string = \
else:
if string == None:
string = \
return None
if active_be is not None and active_be_on_boot is not None:
break
return active_be, active_be_on_boot
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def createSnapshot(be):
"""Create a snapshot."""
if rc == 0:
return 0
return 1
else:
return 1
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"""Create a Boot Environment."""
if rc == 0:
return 0
return 1
else:
return 1
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def createBEFromSnapshot(be):
"""Create a BE based off a snapshot."""
if rc == 0:
return 0
return 1
else:
return 1
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def activateBE(be):
"""
Activate a BE. Called from create() when -a is provided as CLI
Option.
"""
if rc == 0:
return 0
else:
return 1
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def isBeadmSupported():
"""
Currently the only environment that beadm is supported in is
a global zone. Check that beadm is executing in a
global zone and not in a non-global zone.
"""
try:
# Grab stdout.
# Ignore a failed attempt to retreive the zonename.
return True
if zonename != "global":
return False
return True
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if __name__ == "__main__":
try:
except SystemExit, e:
raise e
except: