Current File : //bin/ai-wizard
#!/usr/bin/python2.7 -E

#
# Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
#

"""
ai-wizard

A utility for launching a web browser and starting the AI Manifest Wizard
in it.  Uses xdg-open or calls firefox directly.
"""

import gettext
from optparse import OptionParser
import os
import socket
import sys
import traceback

from solaris_install import CalledProcessError, Popen, run
from solaris_install.ai_wizard import _
from solaris_install.ai.server import Server

# Executables accessed by ai-wizard
XDG_OPEN = '/usr/bin/xdg-open'
FIREFOX = '/usr/bin/firefox'
UNAME = '/usr/bin/uname'
SVCPROP = '/usr/bin/svcprop'

# messages to STDERR
WIZARD_ERR_OPT_ARGS = _("Error: Invalid options and arguments")
WIZARD_ERR_RUN_CMD = _("Error while running a command:\n%s")
WIZARD_ERR_UNAVAIL_CMD = _("Error: %s command not available")
WIZARD_ERR_NO_HOSTNAME = _("Error: Cannot determine system's host name")
WIZARD_ERR_NO_PORT = _("Error: Cannot determine wizard's port number")
WIZARD_WARN_NO_DOMAIN = _("Warning: Cannot determine system's domain name")
# messages to STDOUT
WIZARD_MSG_CMD = _("Running command '%s'")

# Only one server needed for invocation
AIServer = Server()

def print_err(string):
    '''Print message to stderr.'''
    print >> sys.stderr, string


def print_out(string):
    '''Print message to stdeout.'''
    print >> sys.stdout, string


def usage():
    '''Defines parameters and options of the command ai-wizard.'''
    print >> sys.stderr, _("Usage:")
    print >> sys.stderr, _("\tai-wizard [-p port]")
    sys.exit(1)


def main():
    '''main function.'''
    gettext.install('ai-wizard', '/usr/lib/locale')
    return run_wizard(sys.argv[1:])


def get_options(cmd_options=None):
    '''parse the command line options'''
    description = _("Start the Oracle Automated Install Manifest Wizard")
    usage = _("%prog [-p port]")
    parser = OptionParser(usage=usage, description=description)

    parser.add_option("-p", "--port", dest="port", default=AIServer.http_port,
                      type='int',
                      help=_("port number for the AI Webserver"))
    options, args = parser.parse_args(cmd_options)

    if args:
        parser.error(_("Unexpected arguments(s): %s") % args)

    return options


def run_wizard(opts):
    '''Start the wizard'''
    options = get_options(opts)

    # Build up the command to execute and run it
    url = get_url(options.port)
    if url is None:
        return 1
    cmd = get_command(url)
    if cmd is None:
        return 1
    print_out(WIZARD_MSG_CMD % (" ".join(cmd)))
    p = run(cmd, check_result=Popen.ANY)
    if p.returncode != 0:
        print_err(WIZARD_ERR_RUN_CMD % (cmd))
        print_err(p.stderr)
        return 1

    return 0


def get_url(port):
    '''Build the URL for the AI webserver runing on this system.'''
    schema = 'http'

    ip = get_ip()
    if ip is None:
        return None

    return "%s://%s:%d" % (schema, ip, port)


def get_ip():
    '''Get the first valid IP that AI Webserver is listening on.'''
    networks = AIServer.active_networks
    if networks:
        return iter(networks).next()
    else:
        return None


def get_command(url):
    """Get the command to start the Wizard.  One of:
       - 'xdg-open <url>' if 'xdg-open' command available
           this command works best as it takes into account local vs remote
           connection, etc
       - or 'firefox <url>' if 'firefox' command available
           (this automatically adds the "-remote OpenURL()" params as requried)
       - or None

       Returns:
       - a list containing command and params, suitable for passing to run()
       - None
    """
    if check_executable(XDG_OPEN):
        return [XDG_OPEN, url]

    # Not fatal - print a warning and try using firefox direcly instead
    print_err(WIZARD_ERR_UNAVAIL_CMD % (XDG_OPEN))
    if check_executable(FIREFOX):
        return [FIREFOX, url]

    print_err(WIZARD_ERR_UNAVAIL_CMD % (FIREFOX))
    return None


def check_executable(executable):
    '''Check if given path exists and is executable.'''
    return os.path.isfile(executable) and os.access(executable, os.X_OK)


if __name__ == "__main__":
    try:
        RC = main()
    except SystemExit as err:
        raise err
    except:
        traceback.print_exc()
        sys.exit(99)
    sys.exit(RC)