7060060 Informational message to report bad image should include service name
7131425 Automated Installer should not allow setting up non-AI images and should check validity of image
7090169 installadm list -c backtrace if image directory has been removed
--- a/usr/src/cmd/installadm/create_service.py Thu Jan 19 11:19:52 2012 +0100
+++ b/usr/src/cmd/installadm/create_service.py Thu Jan 19 06:40:40 2012 -0700
@@ -20,7 +20,7 @@
#
# CDDL HEADER END
#
-# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
#
'''
AI create-service
@@ -379,7 +379,7 @@
logging.debug("Creating alias of service %s", options.aliasof)
print _("\nCreating %(arch)s alias: %(name)s\n") % \
- {'arch': 'SPARC' if image.arch == 'sparc' else 'x86',
+ {'arch': image.arch,
'name': options.svcname}
logging.debug("Creating AIService aliasname %s base svc=%s, bootargs=%s",
@@ -514,6 +514,11 @@
options.imagepath)
except CalledProcessError as err:
raise SystemExit(err.popen.stderr)
+ except ImageError as err:
+ print >> sys.stderr, str(err)
+ shutil.rmtree(options.imagepath, ignore_errors=True)
+ raise SystemExit(cw(_('Please re-enter command and specify '
+ 'a valid Automated Installer ISO file')))
else:
try:
image = InstalladmPkgImage.image_create(options.srcimage,
@@ -553,7 +558,7 @@
image=image, iso=have_iso)
print _("\nCreating %(arch)s service: %(name)s\n") % \
- {'arch': 'SPARC' if image.arch == 'sparc' else 'x86',
+ {'arch': image.arch,
'name': options.svcname}
# If image was created in temporary location, move to correct
--- a/usr/src/cmd/installadm/delete_service.py Thu Jan 19 11:19:52 2012 +0100
+++ b/usr/src/cmd/installadm/delete_service.py Thu Jan 19 06:40:40 2012 -0700
@@ -19,7 +19,7 @@
#
# CDDL HEADER END
#
-# Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
'''
AI delete-service
'''
@@ -174,11 +174,10 @@
arch = sname.split('default-')[1]
_warning = """
WARNING: The service you are deleting, or a dependent alias, is
- the alias for the default %(sarch)s service. Without the '%(name)s'
+ the alias for the default %(arch)s service. Without the '%(name)s'
service, %(arch)s clients will fail to boot unless explicitly
assigned to a service using the create-client command.
- """ % {'sarch': arch,
- 'arch': ('x86', 'SPARC')[arch == 'sparc'],
+ """ % {'arch': arch,
'name': sname}
print >> sys.stderr, cw(_(_warning))
--- a/usr/src/cmd/installadm/image.py Thu Jan 19 11:19:52 2012 +0100
+++ b/usr/src/cmd/installadm/image.py Thu Jan 19 06:40:40 2012 -0700
@@ -19,7 +19,7 @@
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
-# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
#
'''
Classes and functions for managing client images on an installadm server
@@ -74,8 +74,8 @@
class InstalladmImage(object):
'''Represents an AI client image on the installadm server'''
- NO_ZLIB = _("\nError:\tThe image at %(path)s is not a valid autoinstall "
- "image.\n")
+ INVALID_AI_IMAGE = _("\nError:\tThe image at %(path)s is not a valid "
+ "Automated Installer image.")
def __init__(self, image_path):
self._path = image_path
@@ -84,19 +84,25 @@
def verify(self):
'''
- Check that the image exists and appears valid (has a solaris.zlib file)
+ Check that the image directory exists, appears to be a valid net
+ boot image (has a solaris.zlib file), and is a valid Automated
+ Installer image (has an auto_install/ai.dtd file).
Raises: ImageError if path checks fail
Pre-conditions: Expects self.path to return a valid image_path
Returns: None
'''
# check image_path exists
if not os.path.isdir(self.path):
- raise ImageError(cw(_("\nError:\tThe image_path (%s) is not "
- "a directory. Please provide a "
- "different image path.\n") % self.path))
- # check that the image_path has a solaris.zlib file
- if not os.path.exists(os.path.join(self.path, "solaris.zlib")):
- raise ImageError(cw(self.NO_ZLIB % {"path": self.path}))
+ raise ImageError(cw(_("\nError:\tThe image path (%s) is not "
+ "a directory. Please provide a "
+ "different image path.\n") % self.path))
+
+ # check that the image_path has solaris.zlib and
+ # auto_install/ai.dtd files
+ if not (os.path.exists(os.path.join(self.path, "solaris.zlib")) and
+ os.path.exists(os.path.join(self.path,
+ "auto_install/ai.dtd"))):
+ raise ImageError(cw(self.INVALID_AI_IMAGE % {"path": self.path}))
@property
def version(self):
@@ -215,7 +221,8 @@
DEFAULT_PKG_NAME = 'install-image/solaris-auto-install'
ARCH_VARIANT = u'variant.arch'
SVC_NAME_ATTR = 'com.oracle.install.service-name'
- NO_ZLIB = _("\nError: The pkg image is not an autoinstall image.\n")
+ INVALID_AI_IMAGE = _(
+ "\nError:\tThe pkg image is not an Automated Installer image.\n")
def __init__(self, image_path, pkg_image=None):
super(InstalladmPkgImage, self).__init__(image_path)
@@ -248,7 +255,8 @@
order.append(pub.prefix)
if not publishers:
- raise ImageError(_("Error: There are no enabled publishers."))
+ raise ImageError(_("\nError:\tThere are no enabled "
+ "publishers.\n"))
if arch is None:
arch = root_img.img.get_variants()[cls.ARCH_VARIANT]
@@ -305,11 +313,13 @@
# Returns a list of tuples; should only be one publisher with
# one package
if len(p5i_data) != 1:
- raise ImageError("Error: More than one publisher in p5i file")
+ raise ImageError(_("\nError:\tMore than one publisher "
+ "in p5i file.\n"))
pub, pkgs = p5i_data[0]
if len(pkgs) != 1:
- raise ImageError("Error: More than one package in p5i file")
+ raise ImageError(_("\nError:\tMore than one package "
+ "in p5i file.\n"))
if pub and self.pkg_image.has_publisher(prefix=pub.prefix):
img_pub = self.pkg_image.get_publisher(prefix=pub.prefix,
@@ -376,6 +386,7 @@
cmd = [com.SETUP_IMAGE_SCRIPT, com.IMAGE_CREATE, iso, targetdir]
Popen.check_call(cmd, stderr=Popen.STORE)
iso_img = cls(targetdir)
+ iso_img.verify()
iso_img._prep_ai_webserver()
return iso_img
--- a/usr/src/cmd/installadm/list.py Thu Jan 19 11:19:52 2012 +0100
+++ b/usr/src/cmd/installadm/list.py Thu Jan 19 06:40:40 2012 -0700
@@ -19,7 +19,7 @@
#
# CDDL HEADER END
#
-# Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
#
"""
AI List Services
@@ -33,7 +33,7 @@
from optparse import OptionParser
-from osol_install.auto_install.installadm_common import _
+from osol_install.auto_install.installadm_common import _, cli_wrap as cw
from osol_install.auto_install.service import AIService, VersionError
# FDICT contains the width of each field that gets printed
@@ -50,6 +50,9 @@
_WARNED_ABOUT = set()
+ARCH_UNKNOWN = _('* - Architecture unknown, service image does '
+ 'not exist or is inaccessible.\n')
+
def warn_version(version_err):
'''Prints a short warning about version incompatibility to stderr
@@ -116,34 +119,26 @@
return loptions
-def which_arch(path):
+def which_arch(service):
"""
- Looks to see if the platform pointed to by path is x86 or Sparc.
- If the path does not exist then we are unable to determine the
+ Looks to see if the platform of the service is i386 or sparc.
+ If the service.image does not exist then we are unable to determine the
architecture.
Args
- path = directory path to examine
+ service - service object to query
Returns
- x86 if <path>/platform/i86pc exists
- Sparc if <path>/platform/sun4v exists
- - if neither exists
+ * if service.arch is None
+ otherwise return the value service.arch
Raises
None
"""
- lpath = os.path.join(path, 'platform/i86pc')
- if os.path.exists(lpath):
- arch = 'x86'
- else:
- lpath = os.path.join(path, 'platform/sun4v')
- if os.path.exists(lpath):
- arch = 'Sparc'
- else:
- arch = '-'
+ if service.arch is None:
+ return '*'
- return arch
+ return service.arch
def print_local_services(sdict, width, awidth):
@@ -177,6 +172,7 @@
"""
tkeys = sdict.keys()
tkeys.sort()
+ missing_image = False
for aservice in tkeys:
firstone = True
for info in sdict[aservice]:
@@ -188,7 +184,14 @@
print info['aliasof'].ljust(awidth),
print info['status'].ljust(FDICT['status']),
print info['arch'].ljust(FDICT['arch']),
+ # If the architecture can't be identified, either the image is
+ # missing or not accessible.
+ if info['arch'] == "*":
+ missing_image = True
print info['path']
+
+ if missing_image:
+ print cw(ARCH_UNKNOWN)
print
@@ -203,7 +206,7 @@
{
'service1': [
- { 'ipath':<path1>, 'client':<client1>, <arch': <arch>},
+ { 'ipath':<path1>, 'client':<client1>, 'arch': <arch>},
....
],
....
@@ -230,7 +233,7 @@
except VersionError as version_err:
warn_version(version_err)
continue
- arch = service.arch
+ arch = which_arch(service)
image_path = [service.image.path]
client_info = config.get_clients(servicename)
for clientkey in client_info:
@@ -342,7 +345,7 @@
width = max(len(servicename), width)
info['status'] = serv[config.PROP_STATUS]
info['path'] = serv[config.PROP_IMAGE_PATH]
- info['arch'] = which_arch(info['path'])
+ info['arch'] = which_arch(service)
if config.PROP_ALIAS_OF in serv:
# have an alias
aliasof = serv[config.PROP_ALIAS_OF]
@@ -463,6 +466,7 @@
# sort the keys so that the service names are in alphabetic order.
tkeys = sdict.keys()
tkeys.sort()
+ missing_image = False
for aservice in tkeys:
service_firstone = True
for aclient in sdict[aservice]:
@@ -473,6 +477,10 @@
print ' ' * width,
print aclient['client'].ljust(FDICT['cadd']),
print aclient['arch'].ljust(FDICT['arch']),
+ # If the architecture can't be identified, either the image is
+ # missing or not accessible.
+ if aclient['arch'] == '*':
+ missing_image = True
path_firstone = True
cpaths = list()
for cpath in aclient['ipath']:
@@ -484,6 +492,8 @@
path_firstone = False
print cpath
cpaths.insert(0, cpath)
+ if missing_image:
+ print cw(ARCH_UNKNOWN)
# start of list_local_clients
sdict, width = get_clients(lservices, sname=name)
--- a/usr/src/cmd/installadm/service.py Thu Jan 19 11:19:52 2012 +0100
+++ b/usr/src/cmd/installadm/service.py Thu Jan 19 06:40:40 2012 -0700
@@ -19,7 +19,7 @@
#
# CDDL HEADER END
#
-# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
#
'''
Objects and functions supporting accessing and modifying AI service instances
@@ -676,7 +676,15 @@
'''
# Verify the image and ensure the mountpoints exist
- self.image.verify()
+ try:
+ self.image.verify()
+ except ImageError as error:
+ # verify doesn't know anything about services so prepend the
+ # service name to the exception to give the user sufficient
+ # context to fix the problem and re-raise the exception
+ raise ImageError(cw(_('Service Name: %s\n') %
+ self.name + str(error)))
+
# Mount service's image to /etc/netboot/<svcname>
self._lofs_mount(self.image.path, self.mountpoint)
# Do second lofi mount of menu.lst(x86) or system.conf(sparc)