1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 """Version utilities."""
32
33 import re
34
35 from ganeti import constants
36
37 _FULL_VERSION_RE = re.compile(r"(\d+)\.(\d+)\.(\d+)")
38 _SHORT_VERSION_RE = re.compile(r"(\d+)\.(\d+)")
39
40
41 FIRST_UPGRADE_VERSION = (2, 10, 0)
42
43 CURRENT_VERSION = (constants.VERSION_MAJOR, constants.VERSION_MINOR,
44 constants.VERSION_REVISION)
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
62 """Calculates int version number from major, minor and revision numbers.
63
64 Returns: int representing version number
65
66 """
67 assert isinstance(major, int)
68 assert isinstance(minor, int)
69 assert isinstance(revision, int)
70 return (1000000 * major +
71 10000 * minor +
72 1 * revision)
73
74
76 """Splits version number stored in an int.
77
78 Returns: tuple; (major, minor, revision)
79
80 """
81 assert isinstance(version, int)
82
83 (major, remainder) = divmod(version, 1000000)
84 (minor, revision) = divmod(remainder, 10000)
85
86 return (major, minor, revision)
87
88
90 """Parses a version string.
91
92 @param versionstring: the version string to parse
93 @type versionstring: string
94 @rtype: tuple or None
95 @return: (major, minor, revision) if parsable, None otherwise.
96
97 """
98 m = _FULL_VERSION_RE.match(versionstring)
99 if m is not None:
100 return (int(m.group(1)), int(m.group(2)), int(m.group(3)))
101
102 m = _SHORT_VERSION_RE.match(versionstring)
103 if m is not None:
104 return (int(m.group(1)), int(m.group(2)), 0)
105
106 return None
107
108
110 """Verify whether a version is within the range of automatic upgrades.
111
112 @param target: The version to upgrade to as (major, minor, revision)
113 @type target: tuple
114 @param current: The version to upgrade from as (major, minor, revision)
115 @type current: tuple
116 @rtype: string or None
117 @return: None, if within the range, and a human-readable error message
118 otherwise
119
120 """
121 if target < FIRST_UPGRADE_VERSION or current < FIRST_UPGRADE_VERSION:
122 return "automatic upgrades only supported from 2.10 onwards"
123
124 if target[0] != current[0]:
125 return "different major versions"
126
127 if target[1] < current[1] - 1:
128 return "can only downgrade one minor version at a time"
129
130 return None
131
132
134 """Decide whether cfgupgrade --downgrade should be called.
135
136 Given the current version and the version to change to, decide
137 if in the transition process cfgupgrade --downgrade should
138 be called
139
140 @param version: The version to upgrade to as (major, minor, revision)
141 @type version: tuple
142 @param current: The version to upgrade from as (major, minor, revision)
143 @type current: tuple
144 @rtype: bool
145 @return: True, if cfgupgrade --downgrade should be called.
146
147 """
148 return version[0] == current[0] and version[1] == current[1] - 1
149
150
152 """Decide whether configuration version is compatible with the target.
153
154 @param targetversion: The version to upgrade to as (major, minor, revision)
155 @type targetversion: tuple
156 @param configversion: The version of the current configuration
157 @type configversion: tuple
158 @rtype: bool
159 @return: True, if the configversion fits with the target version.
160
161 """
162 return (configversion[0] == targetversion[0] and
163 configversion[1] == targetversion[1])
164