32 |
32 |
# or implied, of GRNET S.A.
|
33 |
33 |
|
34 |
34 |
import os
|
|
35 |
from logging import getLogger
|
35 |
36 |
|
36 |
37 |
from collections import defaultdict
|
37 |
38 |
from ConfigParser import RawConfigParser, NoOptionError, NoSectionError
|
|
39 |
from re import match
|
38 |
40 |
|
39 |
41 |
try:
|
40 |
42 |
from collections import OrderedDict
|
... | ... | |
42 |
44 |
from kamaki.clients.utils.ordereddict import OrderedDict
|
43 |
45 |
|
44 |
46 |
|
|
47 |
log = getLogger(__name__)
|
|
48 |
|
45 |
49 |
# Path to the file that stores the configuration
|
46 |
50 |
CONFIG_PATH = os.path.expanduser('~/.kamakirc')
|
47 |
51 |
HISTORY_PATH = os.path.expanduser('~/.kamaki.history')
|
... | ... | |
60 |
64 |
'log_token': 'off',
|
61 |
65 |
'log_data': 'off',
|
62 |
66 |
'max_threads': 7,
|
63 |
|
'history_file': HISTORY_PATH
|
64 |
|
},
|
65 |
|
'cli': {
|
66 |
|
'user': 'astakos',
|
67 |
|
'file': 'pithos',
|
68 |
|
'server': 'cyclades',
|
69 |
|
'flavor': 'cyclades',
|
70 |
|
'network': 'cyclades',
|
71 |
|
'image': 'image',
|
72 |
|
'config': 'config',
|
73 |
|
'history': 'history'
|
|
67 |
'history_file': HISTORY_PATH,
|
|
68 |
'user_cli': 'astakos',
|
|
69 |
'file_cli': 'pithos',
|
|
70 |
'server_cli': 'cyclades',
|
|
71 |
'flavor_cli': 'cyclades',
|
|
72 |
'network_cli': 'cyclades',
|
|
73 |
'image_cli': 'image',
|
|
74 |
'config_cli': 'config',
|
|
75 |
'history_cli': 'history'
|
74 |
76 |
# Optional command specs:
|
75 |
77 |
# 'livetest': 'livetest',
|
76 |
78 |
# 'astakos': 'snf-astakos'
|
77 |
79 |
},
|
78 |
|
'remote0': {
|
79 |
|
'remote_url': '',
|
80 |
|
'remote_token': ''
|
81 |
|
#'pithos_type': 'object-store',
|
82 |
|
#'pithos_version': 'v1',
|
83 |
|
#'cyclades_type': 'compute',
|
84 |
|
#'cyclades_version': 'v2.0',
|
85 |
|
#'image_type': 'image',
|
86 |
|
#'image_version': '',
|
87 |
|
#'astakos_type': 'identity',
|
88 |
|
#'astakos_version': 'v2.0'
|
|
80 |
'remotes':
|
|
81 |
{
|
|
82 |
'default': {
|
|
83 |
'url': '',
|
|
84 |
'token': ''
|
|
85 |
#'pithos_type': 'object-store',
|
|
86 |
#'pithos_version': 'v1',
|
|
87 |
#'cyclades_type': 'compute',
|
|
88 |
#'cyclades_version': 'v2.0',
|
|
89 |
#'plankton_type': 'image',
|
|
90 |
#'plankton_version': '',
|
|
91 |
#'astakos_type': 'identity',
|
|
92 |
#'astakos_version': 'v2.0'
|
|
93 |
}
|
89 |
94 |
}
|
90 |
95 |
}
|
91 |
96 |
|
92 |
97 |
|
93 |
98 |
class Config(RawConfigParser):
|
94 |
|
def __init__(self, path=None):
|
|
99 |
def __init__(self, path=None, with_defaults=True):
|
95 |
100 |
RawConfigParser.__init__(self, dict_type=OrderedDict)
|
96 |
101 |
self.path = path or os.environ.get(CONFIG_ENV, CONFIG_PATH)
|
97 |
102 |
self._overrides = defaultdict(dict)
|
98 |
|
self._load_defaults()
|
|
103 |
if with_defaults:
|
|
104 |
self._load_defaults()
|
99 |
105 |
self.read(self.path)
|
100 |
106 |
|
|
107 |
@staticmethod
|
|
108 |
def _remote_name(full_section_name):
|
|
109 |
matcher = match('remote "(\w+)"', full_section_name)
|
|
110 |
return matcher.groups()[0] if matcher else None
|
|
111 |
|
|
112 |
def guess_version(self):
|
|
113 |
checker = Config(self.path, with_defaults=False)
|
|
114 |
sections = checker.sections()
|
|
115 |
log.warning('Config file heuristic 1: global section ?')
|
|
116 |
if 'global' in sections:
|
|
117 |
if checker.get('global', 'url') or checker.get('global', 'token'):
|
|
118 |
log.warning('..... config file has an old global section')
|
|
119 |
return 2.0
|
|
120 |
log.warning('Config file heuristic 2: at least 1 remote section ?')
|
|
121 |
for section in sections:
|
|
122 |
if self._remote_name(section):
|
|
123 |
log.warning('... found %s section' % section)
|
|
124 |
return 3.0
|
|
125 |
log.warning('All heuristics failed, cannot decide')
|
|
126 |
return 0.0
|
|
127 |
|
101 |
128 |
def _load_defaults(self):
|
102 |
129 |
for section, options in DEFAULTS.items():
|
103 |
130 |
for option, val in options.items():
|