root / lib / utils / version.py @ 653bc0f1
History | View | Annotate | Download (5 kB)
1 | 1eda3dd3 | Klaus Aehlig | #
|
---|---|---|---|
2 | effc1b86 | Jose A. Lopes | #
|
3 | effc1b86 | Jose A. Lopes | |
4 | effc1b86 | Jose A. Lopes | # Copyright (C) 2013 Google Inc.
|
5 | effc1b86 | Jose A. Lopes | #
|
6 | effc1b86 | Jose A. Lopes | # This program is free software; you can redistribute it and/or modify
|
7 | effc1b86 | Jose A. Lopes | # it under the terms of the GNU General Public License as published by
|
8 | effc1b86 | Jose A. Lopes | # the Free Software Foundation; either version 2 of the License, or
|
9 | effc1b86 | Jose A. Lopes | # (at your option) any later version.
|
10 | effc1b86 | Jose A. Lopes | #
|
11 | effc1b86 | Jose A. Lopes | # This program is distributed in the hope that it will be useful, but
|
12 | effc1b86 | Jose A. Lopes | # WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | effc1b86 | Jose A. Lopes | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | effc1b86 | Jose A. Lopes | # General Public License for more details.
|
15 | effc1b86 | Jose A. Lopes | #
|
16 | effc1b86 | Jose A. Lopes | # You should have received a copy of the GNU General Public License
|
17 | effc1b86 | Jose A. Lopes | # along with this program; if not, write to the Free Software
|
18 | effc1b86 | Jose A. Lopes | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
19 | effc1b86 | Jose A. Lopes | # 02110-1301, USA.
|
20 | effc1b86 | Jose A. Lopes | |
21 | effc1b86 | Jose A. Lopes | |
22 | effc1b86 | Jose A. Lopes | """Version utilities."""
|
23 | effc1b86 | Jose A. Lopes | |
24 | 1eda3dd3 | Klaus Aehlig | import re |
25 | 1eda3dd3 | Klaus Aehlig | |
26 | 0890e0d1 | Klaus Aehlig | from ganeti import constants |
27 | 0890e0d1 | Klaus Aehlig | |
28 | 1eda3dd3 | Klaus Aehlig | _FULL_VERSION_RE = re.compile(r"(\d+)\.(\d+)\.(\d+)")
|
29 | 1eda3dd3 | Klaus Aehlig | _SHORT_VERSION_RE = re.compile(r"(\d+)\.(\d+)")
|
30 | effc1b86 | Jose A. Lopes | |
31 | 0890e0d1 | Klaus Aehlig | # The first Ganeti version that supports automatic upgrades
|
32 | 0890e0d1 | Klaus Aehlig | FIRST_UPGRADE_VERSION = (2, 10, 0) |
33 | 0890e0d1 | Klaus Aehlig | |
34 | 0890e0d1 | Klaus Aehlig | CURRENT_VERSION = (constants.VERSION_MAJOR, constants.VERSION_MINOR, |
35 | 0890e0d1 | Klaus Aehlig | constants.VERSION_REVISION) |
36 | 0890e0d1 | Klaus Aehlig | |
37 | effc1b86 | Jose A. Lopes | # Format for CONFIG_VERSION:
|
38 | effc1b86 | Jose A. Lopes | # 01 03 0123 = 01030123
|
39 | effc1b86 | Jose A. Lopes | # ^^ ^^ ^^^^
|
40 | effc1b86 | Jose A. Lopes | # | | + Configuration version/revision
|
41 | effc1b86 | Jose A. Lopes | # | + Minor version
|
42 | effc1b86 | Jose A. Lopes | # + Major version
|
43 | effc1b86 | Jose A. Lopes | #
|
44 | effc1b86 | Jose A. Lopes | # It is stored as an integer. Make sure not to write an octal number.
|
45 | effc1b86 | Jose A. Lopes | |
46 | effc1b86 | Jose A. Lopes | # BuildVersion and SplitVersion must be in here because we can't import other
|
47 | effc1b86 | Jose A. Lopes | # modules. The cfgupgrade tool must be able to read and write version numbers
|
48 | effc1b86 | Jose A. Lopes | # and thus requires these functions. To avoid code duplication, they're kept in
|
49 | effc1b86 | Jose A. Lopes | # here.
|
50 | effc1b86 | Jose A. Lopes | |
51 | 1eda3dd3 | Klaus Aehlig | |
52 | effc1b86 | Jose A. Lopes | def BuildVersion(major, minor, revision): |
53 | effc1b86 | Jose A. Lopes | """Calculates int version number from major, minor and revision numbers.
|
54 | effc1b86 | Jose A. Lopes |
|
55 | effc1b86 | Jose A. Lopes | Returns: int representing version number
|
56 | effc1b86 | Jose A. Lopes |
|
57 | effc1b86 | Jose A. Lopes | """
|
58 | effc1b86 | Jose A. Lopes | assert isinstance(major, int) |
59 | effc1b86 | Jose A. Lopes | assert isinstance(minor, int) |
60 | effc1b86 | Jose A. Lopes | assert isinstance(revision, int) |
61 | effc1b86 | Jose A. Lopes | return (1000000 * major + |
62 | effc1b86 | Jose A. Lopes | 10000 * minor +
|
63 | effc1b86 | Jose A. Lopes | 1 * revision)
|
64 | effc1b86 | Jose A. Lopes | |
65 | effc1b86 | Jose A. Lopes | |
66 | effc1b86 | Jose A. Lopes | def SplitVersion(version): |
67 | effc1b86 | Jose A. Lopes | """Splits version number stored in an int.
|
68 | effc1b86 | Jose A. Lopes |
|
69 | effc1b86 | Jose A. Lopes | Returns: tuple; (major, minor, revision)
|
70 | effc1b86 | Jose A. Lopes |
|
71 | effc1b86 | Jose A. Lopes | """
|
72 | effc1b86 | Jose A. Lopes | assert isinstance(version, int) |
73 | effc1b86 | Jose A. Lopes | |
74 | effc1b86 | Jose A. Lopes | (major, remainder) = divmod(version, 1000000) |
75 | effc1b86 | Jose A. Lopes | (minor, revision) = divmod(remainder, 10000) |
76 | effc1b86 | Jose A. Lopes | |
77 | effc1b86 | Jose A. Lopes | return (major, minor, revision)
|
78 | 1eda3dd3 | Klaus Aehlig | |
79 | 1eda3dd3 | Klaus Aehlig | |
80 | 1eda3dd3 | Klaus Aehlig | def ParseVersion(versionstring): |
81 | 1eda3dd3 | Klaus Aehlig | """Parses a version string.
|
82 | 1eda3dd3 | Klaus Aehlig |
|
83 | 1eda3dd3 | Klaus Aehlig | @param versionstring: the version string to parse
|
84 | 1eda3dd3 | Klaus Aehlig | @type versionstring: string
|
85 | 1eda3dd3 | Klaus Aehlig | @rtype: tuple or None
|
86 | 1eda3dd3 | Klaus Aehlig | @return: (major, minor, revision) if parsable, None otherwise.
|
87 | 1eda3dd3 | Klaus Aehlig |
|
88 | 1eda3dd3 | Klaus Aehlig | """
|
89 | 1eda3dd3 | Klaus Aehlig | m = _FULL_VERSION_RE.match(versionstring) |
90 | 1eda3dd3 | Klaus Aehlig | if m is not None: |
91 | 1eda3dd3 | Klaus Aehlig | return (int(m.group(1)), int(m.group(2)), int(m.group(3))) |
92 | 1eda3dd3 | Klaus Aehlig | |
93 | 1eda3dd3 | Klaus Aehlig | m = _SHORT_VERSION_RE.match(versionstring) |
94 | 1eda3dd3 | Klaus Aehlig | if m is not None: |
95 | 1eda3dd3 | Klaus Aehlig | return (int(m.group(1)), int(m.group(2)), 0) |
96 | 1eda3dd3 | Klaus Aehlig | |
97 | 1eda3dd3 | Klaus Aehlig | return None |
98 | 0890e0d1 | Klaus Aehlig | |
99 | 0890e0d1 | Klaus Aehlig | |
100 | 0890e0d1 | Klaus Aehlig | def UpgradeRange(target, current=CURRENT_VERSION): |
101 | 0890e0d1 | Klaus Aehlig | """Verify whether a version is within the range of automatic upgrades.
|
102 | 0890e0d1 | Klaus Aehlig |
|
103 | 0890e0d1 | Klaus Aehlig | @param target: The version to upgrade to as (major, minor, revision)
|
104 | 0890e0d1 | Klaus Aehlig | @type target: tuple
|
105 | 0890e0d1 | Klaus Aehlig | @param current: The version to upgrade from as (major, minor, revision)
|
106 | 0890e0d1 | Klaus Aehlig | @type current: tuple
|
107 | 0890e0d1 | Klaus Aehlig | @rtype: string or None
|
108 | 0890e0d1 | Klaus Aehlig | @return: None, if within the range, and a human-readable error message
|
109 | 0890e0d1 | Klaus Aehlig | otherwise
|
110 | 0890e0d1 | Klaus Aehlig |
|
111 | 0890e0d1 | Klaus Aehlig | """
|
112 | 0890e0d1 | Klaus Aehlig | if target < FIRST_UPGRADE_VERSION or current < FIRST_UPGRADE_VERSION: |
113 | 0890e0d1 | Klaus Aehlig | return "automatic upgrades only supported from 2.10 onwards" |
114 | 0890e0d1 | Klaus Aehlig | |
115 | 0890e0d1 | Klaus Aehlig | if target[0] != current[0]: |
116 | 0890e0d1 | Klaus Aehlig | return "different major versions" |
117 | 0890e0d1 | Klaus Aehlig | |
118 | 0890e0d1 | Klaus Aehlig | if target[1] < current[1] - 1: |
119 | 0890e0d1 | Klaus Aehlig | return "can only downgrade one minor version at a time" |
120 | 0890e0d1 | Klaus Aehlig | |
121 | 0890e0d1 | Klaus Aehlig | return None |
122 | 78521495 | Klaus Aehlig | |
123 | 78521495 | Klaus Aehlig | |
124 | 78521495 | Klaus Aehlig | def ShouldCfgdowngrade(version, current=CURRENT_VERSION): |
125 | 78521495 | Klaus Aehlig | """Decide whether cfgupgrade --downgrade should be called.
|
126 | 78521495 | Klaus Aehlig |
|
127 | 78521495 | Klaus Aehlig | Given the current version and the version to change to, decide
|
128 | 78521495 | Klaus Aehlig | if in the transition process cfgupgrade --downgrade should
|
129 | 78521495 | Klaus Aehlig | be called
|
130 | 78521495 | Klaus Aehlig |
|
131 | 78521495 | Klaus Aehlig | @param version: The version to upgrade to as (major, minor, revision)
|
132 | 78521495 | Klaus Aehlig | @type version: tuple
|
133 | ec5e54bb | Klaus Aehlig | @param current: The version to upgrade from as (major, minor, revision)
|
134 | 78521495 | Klaus Aehlig | @type current: tuple
|
135 | 78521495 | Klaus Aehlig | @rtype: bool
|
136 | 78521495 | Klaus Aehlig | @return: True, if cfgupgrade --downgrade should be called.
|
137 | 78521495 | Klaus Aehlig |
|
138 | 78521495 | Klaus Aehlig | """
|
139 | 78521495 | Klaus Aehlig | return version[0] == current[0] and version[1] == current[1] - 1 |
140 | 2f1278d8 | Klaus Aehlig | |
141 | 2f1278d8 | Klaus Aehlig | |
142 | 2f1278d8 | Klaus Aehlig | def IsCorrectConfigVersion(targetversion, configversion): |
143 | 2f1278d8 | Klaus Aehlig | """Decide whether configuration version is compatible with the target.
|
144 | 2f1278d8 | Klaus Aehlig |
|
145 | 2f1278d8 | Klaus Aehlig | @param targetversion: The version to upgrade to as (major, minor, revision)
|
146 | 2f1278d8 | Klaus Aehlig | @type targetversion: tuple
|
147 | 2f1278d8 | Klaus Aehlig | @param configversion: The version of the current configuration
|
148 | 2f1278d8 | Klaus Aehlig | @type configversion: tuple
|
149 | 2f1278d8 | Klaus Aehlig | @rtype: bool
|
150 | 2f1278d8 | Klaus Aehlig | @return: True, if the configversion fits with the target version.
|
151 | 2f1278d8 | Klaus Aehlig |
|
152 | 2f1278d8 | Klaus Aehlig | """
|
153 | 2f1278d8 | Klaus Aehlig | return (configversion[0] == targetversion[0] and |
154 | 2f1278d8 | Klaus Aehlig | configversion[1] == targetversion[1]) |
155 | 9b85ede9 | Klaus Aehlig | |
156 | 9b85ede9 | Klaus Aehlig | |
157 | 9b85ede9 | Klaus Aehlig | def IsBefore(version, major, minor, revision): |
158 | 9b85ede9 | Klaus Aehlig | """Decide if a given version is strictly before a given version.
|
159 | 9b85ede9 | Klaus Aehlig |
|
160 | 9b85ede9 | Klaus Aehlig | @param version: (major, minor, revision) or None, with None being
|
161 | 9b85ede9 | Klaus Aehlig | before all versions
|
162 | 9b85ede9 | Klaus Aehlig | @type version: (int, int, int) or None
|
163 | 9b85ede9 | Klaus Aehlig | @param major: major version
|
164 | 9b85ede9 | Klaus Aehlig | @type major: int
|
165 | 9b85ede9 | Klaus Aehlig | @param minor: minor version
|
166 | 9b85ede9 | Klaus Aehlig | @type minor: int
|
167 | 9b85ede9 | Klaus Aehlig | @param revision: revision
|
168 | 9b85ede9 | Klaus Aehlig | @type revision: int
|
169 | 9b85ede9 | Klaus Aehlig |
|
170 | 9b85ede9 | Klaus Aehlig | """
|
171 | 9b85ede9 | Klaus Aehlig | if version is None: |
172 | 9b85ede9 | Klaus Aehlig | return True |
173 | 9b85ede9 | Klaus Aehlig | |
174 | 9b85ede9 | Klaus Aehlig | return version < (major, minor, revision) |