#!/usr/bin/python2.6
#
# 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
# or http://www.opensolaris.org/os/licensing.
# 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
#
# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
'''
perform all Python Slim Install Completion Tasks (ICT)

ICT module performs all error checking and logging, so limited
error checking is performed here.

Sets exit status to non-zero value if major failure during
script, 0 otherwise

Parameters:
        target root pathname - required
        debugging level (if invalid, ignored)

This Python script has been taken from the former install-finish shell script
with some tasks taken from the Transfer Module (transfer_mod.py).
'''
import sys
import getopt
import os
import platform

from osol_install.ict import ICT, \
    ICT_INVALID_PARAMETER, \
    info_msg, \
    _dbg_msg, \
    prerror

from osol_install.liblogsvc import LS_DBGLVL_ERR, \
    LS_DBGLVL_EMERG, \
    LS_DBGLVL_INFO, \
    LS_DBGLVL_WARN

# Test to see if running in an automated install environment
def autoinstall_exists():
    '''
    autoinstall_exists - Determine if this script is being
    invoked from an Automated Install.
    '''
    if os.path.exists('/.autoinstall'):
        return 1
    else:
        return 0

# Test to see if running in a text install environment
def textinstall_exists():
    '''
    textinstall_exists - Determine if this script is being
    invoked from a Text Install.
    '''
    if os.path.exists('/.textinstall'):
        return 1
    else:
        return 0

# Test to see if running on a SPARC platform
IS_SPARC = (platform.platform().find('sparc') >= 0)

info_msg('Starting Python script of Install Completion Tasks')

BASEDIR = ""           # argument B
USER_SPEC_DBGLVL = ""  # argument d
ROOT_PW = ""           # argument R
NU_GOS  = ""           # argument n
NU_LOGIN = ""          # argument l
NU_PW = ""             # argument p
NU_GID = "101"         # argument G
NU_UID = "10"          # argument U
NO_NETWORK = False     # argument N

#parse command line arguments
try:
    OPTS, ARGS = getopt.getopt(sys.argv[1:],'B:d:R:n:l:p:G:U:N')

except getopt.GetoptError, err:
    prerror('Parsing command line arguments failed. (%s)' % str(err))

    prerror('Usage: -B <target basedir>')
    prerror('       [-d <debug level>] -  LS_DBGLVL_EMERG ' +
            'LS_DBGLVL_ERR LS_DBGLVL_WARN LS_DBGLVL_INFO')
    prerror('       [-R <root password>] - default is blank')
    prerror('       [-n <new user name (GOS)>] - default is blank')
    prerror('       [-l <new user login>]')
    prerror('       [-p <new user password>] - default is blank')
    prerror('       [-G <new user GID>] - default is 101')
    prerror('       [-U <new user UID>] - default is 10')
    prerror('       [-N] - do not configure networking.  ' + \
            'Default is configure nwam.  Only applicable to text install')
    sys.exit(ICT_INVALID_PARAMETER)

for o, a in OPTS:
    if o in '-B':
        BASEDIR = a
    if o in '-d':
        USER_SPEC_DBGLVL = a
    if o in '-R':
        ROOT_PW = a
    if o in '-n':
        NU_GOS  = a
    if o in '-l':
        NU_LOGIN = a
    if o in '-p':
        NU_PW = a
    if o in '-G':
        NU_GID = a
    if o in '-U':
        NU_UID = a
    if o in '-N':
        NO_NETWORK = True

#perform ICT initialization, specifying root target path, debugging level

if not BASEDIR:
    prerror('caller must provide the root target directory.')
    sys.exit(ICT_INVALID_PARAMETER)

#if debugging level is known symbolic value, use liblogsvc symbol
DBGLVL = -1 #default to no change in debugging level
if USER_SPEC_DBGLVL == 'LS_DBGLVL_EMERG':
    DBGLVL = LS_DBGLVL_EMERG
elif USER_SPEC_DBGLVL == 'LS_DBGLVL_ERR':
    DBGLVL = LS_DBGLVL_ERR
elif USER_SPEC_DBGLVL == 'LS_DBGLVL_WARN':
    DBGLVL = LS_DBGLVL_WARN
elif USER_SPEC_DBGLVL == 'LS_DBGLVL_INFO':
    DBGLVL = LS_DBGLVL_INFO

if DBGLVL != -1:
    ICTO = ICT(BASEDIR, DBGLVL) #set debugging level
else:
    ICTO = ICT(BASEDIR) #take default for debugging level

# Log arguments.  Password hashes only logged in debug mode.
info_msg('BASEDIR: %s' % BASEDIR)
info_msg('USER_SPEC_DBGLVL: %s' % USER_SPEC_DBGLVL)
_dbg_msg('ROOT_PW: %s' % ROOT_PW)
info_msg('NU_GOS: %s' % NU_GOS)
info_msg('NU_LOGIN: %s' % NU_LOGIN)
_dbg_msg('NU_PW: %s' % NU_PW)
info_msg('NU_GID: %s' % NU_GID)
info_msg('NU_UID: %s' % NU_UID)

#perform nearly all Slim Install Completion Tasks

SA = [] #init array of return statuses

if autoinstall_exists():
    # Doing an automated install

    if IS_SPARC:
        # Invoke the required ICT for SPARC platform

        #ICTs ported from Transfer Module
        SA.append(ICTO.create_smf_repository())
        #ICTs ported from original install-finish
        SA.append(ICTO.set_partition_active())
        SA.append(ICTO.update_dumpadm_nodename())
        SA.append(ICTO.setup_dev_namespace())
        SA.append(ICTO.create_sparc_boot_menu())
        SA.append(ICTO.copy_sparc_bootlst())
        SA.append(ICTO.add_sysidtool_sys_unconfig())
        SA.append(ICTO.configure_nwam())
        SA.append(ICTO.set_flush_content_cache_false())
        SA.append(ICTO.apply_sysconfig_profile())
        SA.append(ICTO.smf_correct_sys_profile())
        SA.append(ICTO.update_boot_archive())
    else:
        # Invoke the required ICT for non-SPARC platform

        #ICTs ported from Transfer Module
        SA.append(ICTO.create_smf_repository())
        #ICTs ported from original install-finish
        SA.append(ICTO.set_boot_device_property())
        SA.append(ICTO.add_splash_image_to_grub_menu())
        SA.append(ICTO.set_partition_active())
        SA.append(ICTO.remove_bootpath())
        SA.append(ICTO.fix_grub_entry())
        SA.append(ICTO.add_operating_system_grub_entry())
        SA.append(ICTO.update_dumpadm_nodename())
        SA.append(ICTO.explicit_bootfs())
        SA.append(ICTO.enable_happy_face_boot())
        SA.append(ICTO.setup_dev_namespace())
        SA.append(ICTO.copy_splash_xpm())
        SA.append(ICTO.add_sysidtool_sys_unconfig())
        SA.append(ICTO.configure_nwam())
        SA.append(ICTO.set_flush_content_cache_false())
        SA.append(ICTO.copy_capability_file())
        SA.append(ICTO.apply_sysconfig_profile())
        SA.append(ICTO.smf_correct_sys_profile())
        SA.append(ICTO.update_boot_archive())

else:
    # Doing a GUI install or a Text Install

    # At this time there is no SPARC specific processed needed for GUI install
    # SPARC specific processing is needed for Text Install

    #ICTs ported from Transfer Module
    SA.append(ICTO.create_smf_repository())
    SA.append(ICTO.create_mnttab())
    SA.append(ICTO.cleanup_unneeded_files_and_dirs())
    SA.append(ICTO.generate_sc_profile())
    SA.append(ICTO.delete_misc_trees())
    #ICTs ported from original install-finish
    if not IS_SPARC:
        SA.append(ICTO.set_boot_device_property())
        SA.append(ICTO.add_splash_image_to_grub_menu())
    SA.append(ICTO.remove_livecd_coreadm_conf())
    SA.append(ICTO.set_partition_active())
    if not IS_SPARC:
        SA.append(ICTO.remove_bootpath())
        SA.append(ICTO.fix_grub_entry())
        SA.append(ICTO.add_operating_system_grub_entry())
    SA.append(ICTO.update_dumpadm_nodename())
    if IS_SPARC:
        SA.append(ICTO.create_sparc_boot_menu())
        SA.append(ICTO.copy_sparc_bootlst())
    else:
        SA.append(ICTO.explicit_bootfs())
        if not textinstall_exists():
            SA.append(ICTO.enable_happy_face_boot())
    if not IS_SPARC:
        SA.append(ICTO.copy_splash_xpm())
    SA.append(ICTO.smf_correct_sys_profile())
    SA.append(ICTO.add_sysidtool_sys_unconfig())
    if textinstall_exists():
        PKG_REMOVE_LIST = ['pkg:/system/install/media/internal',
                           'pkg:/system/install/text-install']
    else:
        # GUI installer
        PKG_REMOVE_LIST = ['pkg:/system/install/media/internal',
                           'pkg:/system/install/gui-install',
			   'pkg:/system/install/locale']
    if NO_NETWORK:
        SA.append(ICTO.do_not_configure_network())
    else:
        SA.append(ICTO.enable_nwam())

    SA.append(ICTO.remove_livecd_environment())
    SA.append(ICTO.remove_specific_packages(PKG_REMOVE_LIST))
    SA.append(ICTO.set_flush_content_cache_false())
    # Password is pre-expired in GUI case since user didn't explicitly set it
    SA.append(ICTO.set_root_password(ROOT_PW, not textinstall_exists()))
    SA.append(ICTO.create_new_user(NU_GOS, NU_LOGIN, NU_PW, NU_GID, NU_UID))
    SA.append(ICTO.set_homedir_map(NU_LOGIN))
    SA.append(ICTO.setup_rbac(NU_LOGIN))
    SA.append(ICTO.setup_sudo(NU_LOGIN))
    if not IS_SPARC:
        SA.append(ICTO.copy_capability_file())
    SA.append(ICTO.reset_image_uuid())
    SA.append(ICTO.update_boot_archive())

info_msg('Post-transfer Python Install Completion Tasks finished.')

ERRCOUNT = 0
for returned_status in SA:
    if returned_status != 0:
        ERRCOUNT += 1

if ERRCOUNT > 0:
    info_msg(str(ERRCOUNT) + ' out of ' + str(len(SA)) +
        ' total Python ICTs finished with errors')
    sys.exit(1) #signal script completed, exiting with failure status
else:
    info_msg('All ' + str(len(SA)) + ' Python ICTs finished successfully')
    sys.exit(0) #signal script completed, exiting with success status
