#!/usr/bin/env -S python
#
# Copyright C 2002-2003 by Isilon Systems, Inc. All rights not expressly
# granted herein are reserved.
# Created in the United States of America.
# 
# This digital media is protected by U.S. and international copyright and
# intellectual property laws. Unless otherwise specified, all information
# and screens appearing as part of this digital medium, including
# software, services, documents, text, images, icons, and logos design;
# the selection, assembly, arrangement, and design thereof; and the code
# that enables its presentation, are the sole property of Isilon Systems,
# Inc.
# 
# Except as otherwise required by applicable law, no part of any
# copyrighted material may be reproduced, modified, translated,
# distributed, published, or transmitted by any means, electronic or
# mechanical, for any purpose, without the prior written consent of Isilon
# Systems. 
#  
# Isilon and Isilon Systems are registered trademarks of Isilon Systems,
# Inc.  Legion is a trademark of Isilon Systems, Inc.  All other
# trademarks and registered trademarks are the property of their
# respective holders.
#
# $Id: isi_reimage 264876 2012-08-23 19:07:47Z jryan $

import sys
import getopt

import isi.sys.update.handlers as handlers
import isi.ui.lib.validators as validators


def usage(exitCode=2):
    print >> sys.stderr, '''\
    usage: %s [-mfuidhcr] [-b build]
              -u: to update instead of reimage
              -r: to do a rolling update. Implies -u and -m
              -f: force to reimage/update without confirmation
              -m: to reimage/update all the alive nodes on cluster
              -i: ignore md5 checking after install
              -h: help
-c, --check-only: run checks without reimaging or upgrading
        -b build: to reimage/update with the build
        --manual: ask for confirmation between rolling reboots.  Requires -r
    --drain-time: time to wait for connection drain between rolling reboots.
                  Default is 0 seconds. Requires -r
  --support-help: help for options usable by Isilon Support
''' % sys.argv[0],
    sys.exit(exitCode)

def support_usage(exitCode=2):
    print >> sys.stderr, '''\
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!! NOTE: The following options should only be used by Isilon Support!    !!!
!!! Used improperly, any of these options could render a cluster useless. !!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

 --skip-version-barrier-check: Allow update to any version
--skip-hardware-version-check: Allow reimage on any hardware
 --skip-rolling-upgrade-check: Allow rolling upgrade for any version
     --skip-preupgrade-checks: Allow upgrade/reimage from unsupported state
    --allow-multiple-versions: Allow reimage on mixed version cluster
            --skip-all-checks: Allow everything
                    --no-lock: Allow multiple update to proceed concurrently
                  --no-reboot: Do not reboot after reimage completes
                       --wipe: Also clean var-crash during reimage
''',
    sys.exit(exitCode)


if __name__ == '__main__':
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'fmuhircb:',
                ['support-help', 'skip-version-barrier-check',
                'skip-hardware-version-check', 'no-reboot', 'no-lock',
                'skip-rolling-upgrade-check', 'allow-multiple-versions',
                'manual', 'rolling', 'drain-time=', 'skip-all-checks',
                'wipe', 'skip-preupgrade-checks', 'check-only'])
    except:
        usage()

    if len(args) != 0:
        usage()

    upgrade_type = handlers.LOCAL_REIMAGE
    build = None
    force_reimage = False
    ignore_md5 = False
    option_dict = handlers.default_options()
    for opt in opts:
        if opt[0] == '-h':
            usage(exitCode=0)
        if opt[0] == '--support-help':
            support_usage(exitCode=0)
        elif opt[0] == '-m':
            if upgrade_type == handlers.LOCAL_REIMAGE:
                upgrade_type = handlers.CLUSTER_REIMAGE
            elif upgrade_type == handlers.LOCAL_UPDATE:
                upgrade_type = handlers.CLUSTER_UPDATE
        if opt[0] == '-u':
            if upgrade_type == handlers.LOCAL_REIMAGE:
                upgrade_type = handlers.LOCAL_UPDATE
            elif upgrade_type == handlers.CLUSTER_REIMAGE:
                upgrade_type = handlers.CLUSTER_UPDATE
        elif opt[0] == '-b':
            build = opt[1]
        elif opt[0] == '-f':
            force_reimage = True
        elif opt[0] == '-i':
            ignore_md5 = True
        elif opt[0] == '--check-only' or opt[0] == '-c':
            option_dict['check_only'] = True
        elif opt[0] == '--skip-version-barrier-check':
            option_dict['skip_version_barrier_check'] = True
        elif opt[0] == '--skip-hardware-version-check':
            option_dict['skip_hardware_version_check'] = True
        elif opt[0] == '--no-reboot':
            option_dict['no_reboot'] = True
        elif opt[0] == '--no-lock':
            option_dict['no_lock'] = True
        elif opt[0] == '--rolling' or opt[0] == '-r':
            option_dict['rolling_update'] = True
            upgrade_type = handlers.CLUSTER_UPDATE
        elif opt[0] == '--skip-rolling-upgrade-check':
            option_dict['skip_rolling_upgrade_check'] = True
        elif opt[0] == '--skip-preupgrade-checks':
            option_dict['skip_preupgrade_checks'] = True
        elif opt[0] == '--allow-multiple-versions':
            option_dict['allow_multiple_versions'] = True
        elif opt[0] == '--skip-all-checks':
            option_dict['allow_multiple_versions'] = True
            option_dict['skip_rolling_upgrade_check'] = True
            option_dict['skip_hardware_version_check'] = True
            option_dict['skip_version_barrier_check'] = True
            option_dict['skip_preupgrade_checks'] = True
        elif opt[0] == '--manual':
            option_dict['manual'] = True
        elif opt[0] == '--drain-time':
            try:
                option_dict['drain time'] = \
                        validators.DurationType().parse(opt[1])
            except validators.ArgumentError, e:
                print >> sys.stderr, \
                        "--drain-time takes a duration. %s" % str(e)
                usage()
        elif opt[0] == '--wipe':
            option_dict['wipe'] = True

    if (option_dict['manual'] and not option_dict['rolling_update']):
        print >> sys.stderr, "--manual only allowed for rolling updates."
        usage()
    if (option_dict['drain time'] and not option_dict['rolling_update']):
        print >> sys.stderr, "--drain-time only allowed for rolling updates."
        usage()
    if option_dict['wipe'] and (upgrade_type == handlers.LOCAL_UPDATE
            or upgrade_type == handlers.CLUSTER_UPDATE):
        print >> sys.stderr, "--wipe cannot be used during an update"
        usage()

    handler = handlers.create_handler(upgrade_type, build, force_reimage,
            ignore_md5, options = option_dict)

    if not handler or handler.handler_failed:
        sys.exit(1)
    else:
        sys.exit(0)

# vim:set filetype=python:
