Statistics
| Branch: | Tag: | Revision:

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)