diff options
author | David Ames <david.ames@canonical.com> | 2019-02-12 15:57:46 -0800 |
---|---|---|
committer | David Ames <david.ames@canonical.com> | 2019-02-12 15:57:51 -0800 |
commit | 80b597d5a242e5338dfef044d60b340794e0d824 (patch) | |
tree | ffb98abde4d0e872791a78af462d0b7edbfea4d0 | |
parent | 081bfba4a2014308370f4b09f333b6b9ede54246 (diff) |
Using the new version of the sync tool which removes the charmhelpers
directory before syncing, run charm helpers sync to find any unexpected
missing dependencies.
Change-Id: I1d414271c6191829992a8628de62f160dfc66ee0
Notes
Notes (review):
Verified+1: Canonical CI <uosci-testing-bot@ubuntu.com>
Code-Review+1: David Ames <david.ames@canonical.com>
Code-Review+2: Frode Nordahl <frode.nordahl@canonical.com>
Workflow+1: Frode Nordahl <frode.nordahl@canonical.com>
Verified+2: Zuul
Submitted-by: Zuul
Submitted-at: Tue, 19 Feb 2019 16:06:45 +0000
Reviewed-on: https://review.openstack.org/636491
Project: openstack/charm-nova-cloud-controller
Branch: refs/heads/master
-rw-r--r-- | charm-helpers-hooks.yaml | 2 | ||||
-rw-r--r-- | charmhelpers/contrib/openstack/amulet/utils.py | 16 | ||||
-rw-r--r-- | charmhelpers/contrib/openstack/context.py | 10 | ||||
-rw-r--r-- | charmhelpers/contrib/openstack/templating.py | 2 | ||||
-rw-r--r-- | charmhelpers/contrib/openstack/utils.py | 18 | ||||
-rw-r--r-- | charmhelpers/contrib/python.py | 21 | ||||
-rw-r--r-- | charmhelpers/contrib/storage/linux/ceph.py | 27 | ||||
-rw-r--r-- | charmhelpers/core/host.py | 1 | ||||
-rw-r--r-- | charmhelpers/core/host_factory/ubuntu.py | 8 | ||||
-rw-r--r-- | charmhelpers/fetch/python/__init__.py (renamed from charmhelpers/contrib/python/__init__.py) | 2 | ||||
-rw-r--r-- | charmhelpers/fetch/python/debug.py | 54 | ||||
-rw-r--r-- | charmhelpers/fetch/python/packages.py (renamed from charmhelpers/contrib/python/packages.py) | 0 | ||||
-rw-r--r-- | charmhelpers/fetch/python/rpdb.py | 56 | ||||
-rw-r--r-- | charmhelpers/fetch/python/version.py | 32 |
14 files changed, 224 insertions, 25 deletions
diff --git a/charm-helpers-hooks.yaml b/charm-helpers-hooks.yaml index 3fdc331..afc3bd4 100644 --- a/charm-helpers-hooks.yaml +++ b/charm-helpers-hooks.yaml | |||
@@ -12,6 +12,6 @@ include: | |||
12 | - payload | 12 | - payload |
13 | - contrib.network.ip | 13 | - contrib.network.ip |
14 | - contrib.peerstorage | 14 | - contrib.peerstorage |
15 | - contrib.python.packages | 15 | - contrib.python |
16 | - contrib.charmsupport | 16 | - contrib.charmsupport |
17 | - contrib.hardening|inc=* | 17 | - contrib.hardening|inc=* |
diff --git a/charmhelpers/contrib/openstack/amulet/utils.py b/charmhelpers/contrib/openstack/amulet/utils.py index ea1fd8f..53fa650 100644 --- a/charmhelpers/contrib/openstack/amulet/utils.py +++ b/charmhelpers/contrib/openstack/amulet/utils.py | |||
@@ -88,14 +88,14 @@ class OpenStackAmuletUtils(AmuletUtils): | |||
88 | validation_function = self.validate_v2_endpoint_data | 88 | validation_function = self.validate_v2_endpoint_data |
89 | xenial_queens = OPENSTACK_RELEASES_PAIRS.index('xenial_queens') | 89 | xenial_queens = OPENSTACK_RELEASES_PAIRS.index('xenial_queens') |
90 | if openstack_release and openstack_release >= xenial_queens: | 90 | if openstack_release and openstack_release >= xenial_queens: |
91 | validation_function = self.validate_v3_endpoint_data | 91 | validation_function = self.validate_v3_endpoint_data |
92 | expected = { | 92 | expected = { |
93 | 'id': expected['id'], | 93 | 'id': expected['id'], |
94 | 'region': expected['region'], | 94 | 'region': expected['region'], |
95 | 'region_id': 'RegionOne', | 95 | 'region_id': 'RegionOne', |
96 | 'url': self.valid_url, | 96 | 'url': self.valid_url, |
97 | 'interface': self.not_null, | 97 | 'interface': self.not_null, |
98 | 'service_id': expected['service_id']} | 98 | 'service_id': expected['service_id']} |
99 | return validation_function(endpoints, admin_port, internal_port, | 99 | return validation_function(endpoints, admin_port, internal_port, |
100 | public_port, expected) | 100 | public_port, expected) |
101 | 101 | ||
diff --git a/charmhelpers/contrib/openstack/context.py b/charmhelpers/contrib/openstack/context.py index 8a20375..78a339f 100644 --- a/charmhelpers/contrib/openstack/context.py +++ b/charmhelpers/contrib/openstack/context.py | |||
@@ -1427,11 +1427,11 @@ class ZeroMQContext(OSContextGenerator): | |||
1427 | ctxt = {} | 1427 | ctxt = {} |
1428 | if is_relation_made('zeromq-configuration', 'host'): | 1428 | if is_relation_made('zeromq-configuration', 'host'): |
1429 | for rid in relation_ids('zeromq-configuration'): | 1429 | for rid in relation_ids('zeromq-configuration'): |
1430 | for unit in related_units(rid): | 1430 | for unit in related_units(rid): |
1431 | ctxt['zmq_nonce'] = relation_get('nonce', unit, rid) | 1431 | ctxt['zmq_nonce'] = relation_get('nonce', unit, rid) |
1432 | ctxt['zmq_host'] = relation_get('host', unit, rid) | 1432 | ctxt['zmq_host'] = relation_get('host', unit, rid) |
1433 | ctxt['zmq_redis_address'] = relation_get( | 1433 | ctxt['zmq_redis_address'] = relation_get( |
1434 | 'zmq_redis_address', unit, rid) | 1434 | 'zmq_redis_address', unit, rid) |
1435 | 1435 | ||
1436 | return ctxt | 1436 | return ctxt |
1437 | 1437 | ||
diff --git a/charmhelpers/contrib/openstack/templating.py b/charmhelpers/contrib/openstack/templating.py index a623315..050f8af 100644 --- a/charmhelpers/contrib/openstack/templating.py +++ b/charmhelpers/contrib/openstack/templating.py | |||
@@ -183,7 +183,7 @@ class OSConfigRenderer(object): | |||
183 | /tmp/templates/grizzly/api-paste.ini | 183 | /tmp/templates/grizzly/api-paste.ini |
184 | /tmp/templates/havana/api-paste.ini | 184 | /tmp/templates/havana/api-paste.ini |
185 | 185 | ||
186 | Since it was registered with the grizzly release, it first seraches | 186 | Since it was registered with the grizzly release, it first searches |
187 | the grizzly directory for nova.conf, then the templates dir. | 187 | the grizzly directory for nova.conf, then the templates dir. |
188 | 188 | ||
189 | When writing api-paste.ini, it will find the template in the grizzly | 189 | When writing api-paste.ini, it will find the template in the grizzly |
diff --git a/charmhelpers/contrib/openstack/utils.py b/charmhelpers/contrib/openstack/utils.py index 4e432a2..86b011b 100644 --- a/charmhelpers/contrib/openstack/utils.py +++ b/charmhelpers/contrib/openstack/utils.py | |||
@@ -83,7 +83,8 @@ from charmhelpers.fetch import ( | |||
83 | add_source as fetch_add_source, | 83 | add_source as fetch_add_source, |
84 | SourceConfigError, | 84 | SourceConfigError, |
85 | GPGKeyError, | 85 | GPGKeyError, |
86 | get_upstream_version | 86 | get_upstream_version, |
87 | filter_missing_packages | ||
87 | ) | 88 | ) |
88 | 89 | ||
89 | from charmhelpers.fetch.snap import ( | 90 | from charmhelpers.fetch.snap import ( |
@@ -309,6 +310,15 @@ def error_out(msg): | |||
309 | sys.exit(1) | 310 | sys.exit(1) |
310 | 311 | ||
311 | 312 | ||
313 | def get_installed_semantic_versioned_packages(): | ||
314 | '''Get a list of installed packages which have OpenStack semantic versioning | ||
315 | |||
316 | :returns List of installed packages | ||
317 | :rtype: [pkg1, pkg2, ...] | ||
318 | ''' | ||
319 | return filter_missing_packages(PACKAGE_CODENAMES.keys()) | ||
320 | |||
321 | |||
312 | def get_os_codename_install_source(src): | 322 | def get_os_codename_install_source(src): |
313 | '''Derive OpenStack release codename from a given installation source.''' | 323 | '''Derive OpenStack release codename from a given installation source.''' |
314 | ubuntu_rel = lsb_release()['DISTRIB_CODENAME'] | 324 | ubuntu_rel = lsb_release()['DISTRIB_CODENAME'] |
@@ -972,7 +982,9 @@ def _ows_check_charm_func(state, message, charm_func_with_configs): | |||
972 | """ | 982 | """ |
973 | if charm_func_with_configs: | 983 | if charm_func_with_configs: |
974 | charm_state, charm_message = charm_func_with_configs() | 984 | charm_state, charm_message = charm_func_with_configs() |
975 | if charm_state != 'active' and charm_state != 'unknown': | 985 | if (charm_state != 'active' and |
986 | charm_state != 'unknown' and | ||
987 | charm_state is not None): | ||
976 | state = workload_state_compare(state, charm_state) | 988 | state = workload_state_compare(state, charm_state) |
977 | if message: | 989 | if message: |
978 | charm_message = charm_message.replace("Incomplete relations: ", | 990 | charm_message = charm_message.replace("Incomplete relations: ", |
@@ -1241,7 +1253,7 @@ def remote_restart(rel_name, remote_service=None): | |||
1241 | 1253 | ||
1242 | 1254 | ||
1243 | def check_actually_paused(services=None, ports=None): | 1255 | def check_actually_paused(services=None, ports=None): |
1244 | """Check that services listed in the services object and and ports | 1256 | """Check that services listed in the services object and ports |
1245 | are actually closed (not listened to), to verify that the unit is | 1257 | are actually closed (not listened to), to verify that the unit is |
1246 | properly paused. | 1258 | properly paused. |
1247 | 1259 | ||
diff --git a/charmhelpers/contrib/python.py b/charmhelpers/contrib/python.py new file mode 100644 index 0000000..84cba8c --- /dev/null +++ b/charmhelpers/contrib/python.py | |||
@@ -0,0 +1,21 @@ | |||
1 | # Copyright 2014-2019 Canonical Limited. | ||
2 | # | ||
3 | # Licensed under the Apache License, Version 2.0 (the "License"); | ||
4 | # you may not use this file except in compliance with the License. | ||
5 | # You may obtain a copy of the License at | ||
6 | # | ||
7 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
8 | # | ||
9 | # Unless required by applicable law or agreed to in writing, software | ||
10 | # distributed under the License is distributed on an "AS IS" BASIS, | ||
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
12 | # See the License for the specific language governing permissions and | ||
13 | # limitations under the License. | ||
14 | |||
15 | from __future__ import absolute_import | ||
16 | |||
17 | # deprecated aliases for backwards compatibility | ||
18 | from charmhelpers.fetch.python import debug # noqa | ||
19 | from charmhelpers.fetch.python import packages # noqa | ||
20 | from charmhelpers.fetch.python import rpdb # noqa | ||
21 | from charmhelpers.fetch.python import version # noqa | ||
diff --git a/charmhelpers/contrib/storage/linux/ceph.py b/charmhelpers/contrib/storage/linux/ceph.py index 7682820..63c9304 100644 --- a/charmhelpers/contrib/storage/linux/ceph.py +++ b/charmhelpers/contrib/storage/linux/ceph.py | |||
@@ -856,12 +856,22 @@ def _keyring_path(service): | |||
856 | return KEYRING.format(service) | 856 | return KEYRING.format(service) |
857 | 857 | ||
858 | 858 | ||
859 | def create_keyring(service, key): | 859 | def add_key(service, key): |
860 | """Create a new Ceph keyring containing key.""" | 860 | """ |
861 | Add a key to a keyring. | ||
862 | |||
863 | Creates the keyring if it doesn't already exist. | ||
864 | |||
865 | Logs and returns if the key is already in the keyring. | ||
866 | """ | ||
861 | keyring = _keyring_path(service) | 867 | keyring = _keyring_path(service) |
862 | if os.path.exists(keyring): | 868 | if os.path.exists(keyring): |
863 | log('Ceph keyring exists at %s.' % keyring, level=WARNING) | 869 | with open(keyring, 'r') as ring: |
864 | return | 870 | if key in ring.read(): |
871 | log('Ceph keyring exists at %s and has not changed.' % keyring, | ||
872 | level=DEBUG) | ||
873 | return | ||
874 | log('Updating existing keyring %s.' % keyring, level=DEBUG) | ||
865 | 875 | ||
866 | cmd = ['ceph-authtool', keyring, '--create-keyring', | 876 | cmd = ['ceph-authtool', keyring, '--create-keyring', |
867 | '--name=client.{}'.format(service), '--add-key={}'.format(key)] | 877 | '--name=client.{}'.format(service), '--add-key={}'.format(key)] |
@@ -869,6 +879,11 @@ def create_keyring(service, key): | |||
869 | log('Created new ceph keyring at %s.' % keyring, level=DEBUG) | 879 | log('Created new ceph keyring at %s.' % keyring, level=DEBUG) |
870 | 880 | ||
871 | 881 | ||
882 | def create_keyring(service, key): | ||
883 | """Deprecated. Please use the more accurately named 'add_key'""" | ||
884 | return add_key(service, key) | ||
885 | |||
886 | |||
872 | def delete_keyring(service): | 887 | def delete_keyring(service): |
873 | """Delete an existing Ceph keyring.""" | 888 | """Delete an existing Ceph keyring.""" |
874 | keyring = _keyring_path(service) | 889 | keyring = _keyring_path(service) |
@@ -905,7 +920,7 @@ def get_ceph_nodes(relation='ceph'): | |||
905 | 920 | ||
906 | def configure(service, key, auth, use_syslog): | 921 | def configure(service, key, auth, use_syslog): |
907 | """Perform basic configuration of Ceph.""" | 922 | """Perform basic configuration of Ceph.""" |
908 | create_keyring(service, key) | 923 | add_key(service, key) |
909 | create_key_file(service, key) | 924 | create_key_file(service, key) |
910 | hosts = get_ceph_nodes() | 925 | hosts = get_ceph_nodes() |
911 | with open('/etc/ceph/ceph.conf', 'w') as ceph_conf: | 926 | with open('/etc/ceph/ceph.conf', 'w') as ceph_conf: |
@@ -1068,7 +1083,7 @@ def ensure_ceph_keyring(service, user=None, group=None, | |||
1068 | if not key: | 1083 | if not key: |
1069 | return False | 1084 | return False |
1070 | 1085 | ||
1071 | create_keyring(service=service, key=key) | 1086 | add_key(service=service, key=key) |
1072 | keyring = _keyring_path(service) | 1087 | keyring = _keyring_path(service) |
1073 | if user and group: | 1088 | if user and group: |
1074 | check_call(['chown', '%s.%s' % (user, group), keyring]) | 1089 | check_call(['chown', '%s.%s' % (user, group), keyring]) |
diff --git a/charmhelpers/core/host.py b/charmhelpers/core/host.py index 79953a4..47c1fc3 100644 --- a/charmhelpers/core/host.py +++ b/charmhelpers/core/host.py | |||
@@ -46,6 +46,7 @@ if __platform__ == "ubuntu": | |||
46 | lsb_release, | 46 | lsb_release, |
47 | cmp_pkgrevno, | 47 | cmp_pkgrevno, |
48 | CompareHostReleases, | 48 | CompareHostReleases, |
49 | get_distrib_codename, | ||
49 | ) # flake8: noqa -- ignore F401 for this import | 50 | ) # flake8: noqa -- ignore F401 for this import |
50 | elif __platform__ == "centos": | 51 | elif __platform__ == "centos": |
51 | from charmhelpers.core.host_factory.centos import ( # NOQA:F401 | 52 | from charmhelpers.core.host_factory.centos import ( # NOQA:F401 |
diff --git a/charmhelpers/core/host_factory/ubuntu.py b/charmhelpers/core/host_factory/ubuntu.py index a6d375a..d7e920e 100644 --- a/charmhelpers/core/host_factory/ubuntu.py +++ b/charmhelpers/core/host_factory/ubuntu.py | |||
@@ -72,6 +72,14 @@ def lsb_release(): | |||
72 | return d | 72 | return d |
73 | 73 | ||
74 | 74 | ||
75 | def get_distrib_codename(): | ||
76 | """Return the codename of the distribution | ||
77 | :returns: The codename | ||
78 | :rtype: str | ||
79 | """ | ||
80 | return lsb_release()['DISTRIB_CODENAME'].lower() | ||
81 | |||
82 | |||
75 | def cmp_pkgrevno(package, revno, pkgcache=None): | 83 | def cmp_pkgrevno(package, revno, pkgcache=None): |
76 | """Compare supplied revno with the revno of the installed package. | 84 | """Compare supplied revno with the revno of the installed package. |
77 | 85 | ||
diff --git a/charmhelpers/contrib/python/__init__.py b/charmhelpers/fetch/python/__init__.py index d7567b8..bff99dc 100644 --- a/charmhelpers/contrib/python/__init__.py +++ b/charmhelpers/fetch/python/__init__.py | |||
@@ -1,4 +1,4 @@ | |||
1 | # Copyright 2014-2015 Canonical Limited. | 1 | # Copyright 2014-2019 Canonical Limited. |
2 | # | 2 | # |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); |
4 | # you may not use this file except in compliance with the License. | 4 | # you may not use this file except in compliance with the License. |
diff --git a/charmhelpers/fetch/python/debug.py b/charmhelpers/fetch/python/debug.py new file mode 100644 index 0000000..757135e --- /dev/null +++ b/charmhelpers/fetch/python/debug.py | |||
@@ -0,0 +1,54 @@ | |||
1 | #!/usr/bin/env python | ||
2 | # coding: utf-8 | ||
3 | |||
4 | # Copyright 2014-2015 Canonical Limited. | ||
5 | # | ||
6 | # Licensed under the Apache License, Version 2.0 (the "License"); | ||
7 | # you may not use this file except in compliance with the License. | ||
8 | # You may obtain a copy of the License at | ||
9 | # | ||
10 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
11 | # | ||
12 | # Unless required by applicable law or agreed to in writing, software | ||
13 | # distributed under the License is distributed on an "AS IS" BASIS, | ||
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
15 | # See the License for the specific language governing permissions and | ||
16 | # limitations under the License. | ||
17 | |||
18 | from __future__ import print_function | ||
19 | |||
20 | import atexit | ||
21 | import sys | ||
22 | |||
23 | from charmhelpers.fetch.python.rpdb import Rpdb | ||
24 | from charmhelpers.core.hookenv import ( | ||
25 | open_port, | ||
26 | close_port, | ||
27 | ERROR, | ||
28 | log | ||
29 | ) | ||
30 | |||
31 | __author__ = "Jorge Niedbalski <jorge.niedbalski@canonical.com>" | ||
32 | |||
33 | DEFAULT_ADDR = "0.0.0.0" | ||
34 | DEFAULT_PORT = 4444 | ||
35 | |||
36 | |||
37 | def _error(message): | ||
38 | log(message, level=ERROR) | ||
39 | |||
40 | |||
41 | def set_trace(addr=DEFAULT_ADDR, port=DEFAULT_PORT): | ||
42 | """ | ||
43 | Set a trace point using the remote debugger | ||
44 | """ | ||
45 | atexit.register(close_port, port) | ||
46 | try: | ||
47 | log("Starting a remote python debugger session on %s:%s" % (addr, | ||
48 | port)) | ||
49 | open_port(port) | ||
50 | debugger = Rpdb(addr=addr, port=port) | ||
51 | debugger.set_trace(sys._getframe().f_back) | ||
52 | except Exception: | ||
53 | _error("Cannot start a remote debug session on %s:%s" % (addr, | ||
54 | port)) | ||
diff --git a/charmhelpers/contrib/python/packages.py b/charmhelpers/fetch/python/packages.py index 6e95028..6e95028 100644 --- a/charmhelpers/contrib/python/packages.py +++ b/charmhelpers/fetch/python/packages.py | |||
diff --git a/charmhelpers/fetch/python/rpdb.py b/charmhelpers/fetch/python/rpdb.py new file mode 100644 index 0000000..9b31610 --- /dev/null +++ b/charmhelpers/fetch/python/rpdb.py | |||
@@ -0,0 +1,56 @@ | |||
1 | # Copyright 2014-2015 Canonical Limited. | ||
2 | # | ||
3 | # Licensed under the Apache License, Version 2.0 (the "License"); | ||
4 | # you may not use this file except in compliance with the License. | ||
5 | # You may obtain a copy of the License at | ||
6 | # | ||
7 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
8 | # | ||
9 | # Unless required by applicable law or agreed to in writing, software | ||
10 | # distributed under the License is distributed on an "AS IS" BASIS, | ||
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
12 | # See the License for the specific language governing permissions and | ||
13 | # limitations under the License. | ||
14 | |||
15 | """Remote Python Debugger (pdb wrapper).""" | ||
16 | |||
17 | import pdb | ||
18 | import socket | ||
19 | import sys | ||
20 | |||
21 | __author__ = "Bertrand Janin <b@janin.com>" | ||
22 | __version__ = "0.1.3" | ||
23 | |||
24 | |||
25 | class Rpdb(pdb.Pdb): | ||
26 | |||
27 | def __init__(self, addr="127.0.0.1", port=4444): | ||
28 | """Initialize the socket and initialize pdb.""" | ||
29 | |||
30 | # Backup stdin and stdout before replacing them by the socket handle | ||
31 | self.old_stdout = sys.stdout | ||
32 | self.old_stdin = sys.stdin | ||
33 | |||
34 | # Open a 'reusable' socket to let the webapp reload on the same port | ||
35 | self.skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||
36 | self.skt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) | ||
37 | self.skt.bind((addr, port)) | ||
38 | self.skt.listen(1) | ||
39 | (clientsocket, address) = self.skt.accept() | ||
40 | handle = clientsocket.makefile('rw') | ||
41 | pdb.Pdb.__init__(self, completekey='tab', stdin=handle, stdout=handle) | ||
42 | sys.stdout = sys.stdin = handle | ||
43 | |||
44 | def shutdown(self): | ||
45 | """Revert stdin and stdout, close the socket.""" | ||
46 | sys.stdout = self.old_stdout | ||
47 | sys.stdin = self.old_stdin | ||
48 | self.skt.close() | ||
49 | self.set_continue() | ||
50 | |||
51 | def do_continue(self, arg): | ||
52 | """Stop all operation on ``continue``.""" | ||
53 | self.shutdown() | ||
54 | return 1 | ||
55 | |||
56 | do_EOF = do_quit = do_exit = do_c = do_cont = do_continue | ||
diff --git a/charmhelpers/fetch/python/version.py b/charmhelpers/fetch/python/version.py new file mode 100644 index 0000000..3eb4210 --- /dev/null +++ b/charmhelpers/fetch/python/version.py | |||
@@ -0,0 +1,32 @@ | |||
1 | #!/usr/bin/env python | ||
2 | # coding: utf-8 | ||
3 | |||
4 | # Copyright 2014-2015 Canonical Limited. | ||
5 | # | ||
6 | # Licensed under the Apache License, Version 2.0 (the "License"); | ||
7 | # you may not use this file except in compliance with the License. | ||
8 | # You may obtain a copy of the License at | ||
9 | # | ||
10 | # http://www.apache.org/licenses/LICENSE-2.0 | ||
11 | # | ||
12 | # Unless required by applicable law or agreed to in writing, software | ||
13 | # distributed under the License is distributed on an "AS IS" BASIS, | ||
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
15 | # See the License for the specific language governing permissions and | ||
16 | # limitations under the License. | ||
17 | |||
18 | import sys | ||
19 | |||
20 | __author__ = "Jorge Niedbalski <jorge.niedbalski@canonical.com>" | ||
21 | |||
22 | |||
23 | def current_version(): | ||
24 | """Current system python version""" | ||
25 | return sys.version_info | ||
26 | |||
27 | |||
28 | def current_version_string(): | ||
29 | """Current system python version as string major.minor.micro""" | ||
30 | return "{0}.{1}.{2}".format(sys.version_info.major, | ||
31 | sys.version_info.minor, | ||
32 | sys.version_info.micro) | ||