client.py 5.12 KB
Newer Older
1
# -*- coding: utf-8 -*-
Łukasz Nowak's avatar
Łukasz Nowak committed
2 3
##############################################################################
#
4 5
# Copyright (c) 2010, 2011, 2012 Vifib SARL and Contributors.
# All Rights Reserved.
Łukasz Nowak's avatar
Łukasz Nowak committed
6 7 8 9 10
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
11
# guarantees and support are strongly advised to contract a Free Software
Łukasz Nowak's avatar
Łukasz Nowak committed
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
##############################################################################

30
import atexit
Bryton Lacquement's avatar
Bryton Lacquement committed
31
from six.moves import configparser
32
import os
33
import sys
34

35
import slapos.slap.slap
36
from slapos.slap import SoftwareProductCollection
37

38
SOFTWARE_PRODUCT_NAMESPACE = "product."
39

Marco Mariani's avatar
Marco Mariani committed
40
class ClientConfig(object):
41 42
  state = None

43 44
  def __init__(self, args, configp=None):
    # XXX configp cannot possibly be optional
45 46 47 48
    """
    Set options given by parameters.
    """
    # Set options parameters
49 50
    for key, value in args.__dict__.items():
      setattr(self, key, value)
51 52

    # Merges the arguments and configuration
53
    try:
54
      configuration_dict = dict(configp.items('slapconsole'))
Bryton Lacquement's avatar
Bryton Lacquement committed
55
    except configparser.NoSectionError:
56 57 58 59
      pass
    else:
      for key in configuration_dict:
        if not getattr(self, key, None):
60
          setattr(self, key, configuration_dict[key])
61
    configuration_dict = dict(configp.items('slapos'))
62
    master_url = configuration_dict.get('master_url', None)
63 64 65 66 67 68
    # Backward compatibility, if no key and certificate given in option
    # take one from slapos configuration
    if not getattr(self, 'key_file', None) and \
          not getattr(self, 'cert_file', None):
      self.key_file = configuration_dict.get('key_file')
      self.cert_file = configuration_dict.get('cert_file')
69 70 71
    if not master_url:
      raise ValueError("No option 'master_url'")
    elif master_url.startswith('https') and \
72 73 74
         self.key_file is None and \
         self.cert_file is None:
        raise ValueError("No option 'key_file' and/or 'cert_file'")
75
    else:
76
      self.master_url = master_url
77

78 79
    self.master_rest_url = configuration_dict.get('master_rest_url')

80 81 82 83 84
    if self.key_file:
        self.key_file = os.path.expanduser(self.key_file)

    if self.cert_file:
        self.cert_file = os.path.expanduser(self.cert_file)
Marco Mariani's avatar
Marco Mariani committed
85

86

87
def init(conf, logger):
88
  """Initialize Slap instance, connect to server and create
89
  aliases to common software releases"""
90
  # XXX check certificate and key existence
91
  slap = slapos.slap.slap()
92 93 94
  slap.initializeConnection(conf.master_url,
      key_file=conf.key_file, cert_file=conf.cert_file,
      slapgrid_rest_uri=conf.master_rest_url)
95
  local = globals().copy()
96
  local['slap'] = slap
97
  # Create global shortcut functions to request instance and software
98 99 100
  def shorthandRequest(*args, **kwargs):
    return slap.registerOpenOrder().request(*args, **kwargs)
  def shorthandSupply(*args, **kwargs):
101
    # XXX-Cedric Implement computer_group support
102
    return slap.registerSupply().supply(*args, **kwargs)
103 104
  local['request'] = shorthandRequest
  local['supply'] = shorthandSupply
105
  local['product'] = SoftwareProductCollection(logger, slap)
106

107 108
  return local

109 110 111 112 113 114 115 116 117 118 119
def _getSoftwareReleaseFromSoftwareString(logger, software_string, product):
    """
    If Software string is a product:
    Return the best Software Release URL of the Software Product "X" of the
    string "product.X".
    Else, return as is.
    """
    if not software_string.startswith(SOFTWARE_PRODUCT_NAMESPACE):
        return software_string

    try:
120
        return product.__getattr__(software_string[len(SOFTWARE_PRODUCT_NAMESPACE):])
121
    except AttributeError as e:
Bryton Lacquement's avatar
Bryton Lacquement committed
122
       logger.error('Error: %s Exiting now.', e)
123
       sys.exit(1)
Marco Mariani's avatar
Marco Mariani committed
124

Marco Mariani's avatar
Marco Mariani committed
125
def do_console(local):
126 127 128 129 130 131 132 133 134 135 136 137 138 139
  # try to enable readline with completion and history
  try:
    import readline
  except ImportError:
    pass
  else:
    try:
      import rlcompleter
      readline.set_completer(rlcompleter.Completer(local).complete)
    except ImportError:
      pass
    readline.parse_and_bind("tab: complete")

    historyPath = os.path.expanduser("~/.slapconsolehistory")
140

141
    def save_history(historyPath=historyPath):
142 143
      if os.path.exists(os.path.dirname(historyPath)):
        readline.write_history_file(historyPath)
144 145 146 147
    if os.path.exists(historyPath):
      readline.read_history_file(historyPath)
    atexit.register(save_history)

148
  __import__("code").interact(banner="", local=local)