Merge lp:~jr.allen/unifield-server/us3292 into lp:unifield-server
- us3292
- Merge into trunk
Proposed by
jftempo
Status: | Merged |
---|---|
Merged at revision: | 4476 |
Proposed branch: | lp:~jr.allen/unifield-server/us3292 |
Merge into: | lp:unifield-server |
Diff against target: |
277 lines (+86/-30) 1 file modified
bin/updater.py (+86/-30) |
To merge this branch: | bzr merge lp:~jr.allen/unifield-server/us3292 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email: mp+329608@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bin/updater.py' |
2 | --- bin/updater.py 2017-07-13 14:59:01 +0000 |
3 | +++ bin/updater.py 2017-08-25 15:24:51 +0000 |
4 | @@ -584,13 +584,12 @@ |
5 | def _is_major(oldVer, newVer): |
6 | oldVer = oldVer.split('.') |
7 | newVer = newVer.split('.') |
8 | - if oldVer[0] != newVer[0]: |
9 | - return True |
10 | - if oldVer[0] >= 10: |
11 | + if int(oldVer[0]) >= 10: |
12 | # for 10.x and onward, second position indicates minor |
13 | # version: https://www.postgresql.org/support/versioning/ |
14 | - return False |
15 | - if oldVer[1] != newVer[1]: |
16 | + return oldVer[0] != newVer[0] |
17 | + if (oldVer[0] != newVer[0] or |
18 | + oldVer[0] == newVer[0] and oldVer[1] != newVer[1]): |
19 | return True |
20 | return False |
21 | |
22 | @@ -615,12 +614,11 @@ |
23 | """ |
24 | This function is run on every server start (see openerp-server.py). |
25 | If the conditions are not right for a PostgreSQL update, it |
26 | - immeditately returns, so that the server can start up (the common case). |
27 | + immediately returns, so that the server can start up (the common case). |
28 | If an update is required, then it attempts the update. If the |
29 | update fails, it must leave the server in the same condition it |
30 | started, i.e. with the original Postgres up and running. |
31 | """ |
32 | - |
33 | # Postgres updates are only done on Windows. |
34 | if os.name != "nt": |
35 | return |
36 | @@ -632,7 +630,7 @@ |
37 | try: |
38 | log = open(log_file, 'a') |
39 | except Exception as e: |
40 | - log = os.stderr |
41 | + log = sys.stderr |
42 | warn("Could not open %s correctly: %s" % (log_file, e)) |
43 | |
44 | # If there is no patch file available, then there's no |
45 | @@ -690,17 +688,22 @@ |
46 | # 1. figure out where the old PG is and copy it to pgsql-next |
47 | # 2. patch pgsql-next, nuke patch file |
48 | # 3. prepare new db dir using new initdb, old user/pass. |
49 | + # 3.5 Alter tables to work around a bug |
50 | # 4. stop server |
51 | # 5. pg_upgrade -> if fail, clean db dir, goto 8 |
52 | # 6. commit to new bin dir, put it in '..\pgsql' |
53 | # 7. if old was 8.4, change service entry |
54 | # 8. start server |
55 | + # 9. Alter tables again to back out workaround |
56 | |
57 | warn("Postgres major update from %s to %s" % (oldVer, newVer)) |
58 | import tools |
59 | |
60 | stopped = False |
61 | pg_new_db = None |
62 | + run_analyze = False |
63 | + re_alter = False |
64 | + failed = False |
65 | try: |
66 | env = os.environ |
67 | if tools.config.get('db_user'): |
68 | @@ -709,7 +712,7 @@ |
69 | env['PGPASSWORD'] = tools.config['db_password'] |
70 | |
71 | pg_new = r'..\pgsql-next' |
72 | - if oldVer == '8.4.14': |
73 | + if oldVer == '8.4.17': |
74 | svc = 'PostgreSQL_For_OpenERP' |
75 | pg_old = r'D:\MSF data\Unifield\PostgreSQL' |
76 | else: |
77 | @@ -736,7 +739,7 @@ |
78 | warn("Removing previous %s directory" % pg_new) |
79 | shutil.rmtree(pg_new) |
80 | |
81 | - if oldVer == '8.4.14': |
82 | + if oldVer == '8.4.17': |
83 | warn("Creating %s by selective copy from %s" % (pg_new, pg_old)) |
84 | os.mkdir(pg_new) |
85 | for d in ('bin', 'lib', 'share'): |
86 | @@ -761,16 +764,16 @@ |
87 | raise RuntimeError('New data directory %s already exists.' % pg_new_db) |
88 | pwf = tempfile.NamedTemporaryFile(delete=False) |
89 | pwf.write(tools.config.get('db_password')) |
90 | - # TODO: apply same fix here for trust as in the AIO |
91 | - cmd = [ os.path.join(pg_new, 'bin', 'initdb'), |
92 | + pwf.close() |
93 | + cmd = [ os.path.join(pg_new, 'bin', 'initdb.exe'), |
94 | '--pwfile', pwf.name, |
95 | - '--data-checksums', '-A', 'md5', |
96 | + '-A', 'md5', |
97 | '-U', tools.config.get('db_user'), |
98 | '--locale', 'English_United States', |
99 | '-E', 'UTF8', pg_new_db |
100 | ] |
101 | - rc = subprocess.call(cmd, stdout=log, stderr=log) |
102 | - pwf.close() |
103 | + warn('initdb: %r' % cmd) |
104 | + rc = subprocess.call(cmd, stdout=log, stderr=log, env=env) |
105 | os.remove(pwf.name) |
106 | if rc != 0: |
107 | raise RuntimeError("initdb returned %d" % rc) |
108 | @@ -782,12 +785,37 @@ |
109 | f.write("listen_addresses = 'localhost'\n") |
110 | f.write("shared_buffers = 1024MB\n") |
111 | |
112 | + # 3.5: Alter tables to work around |
113 | + # https://bugs.launchpad.net/openobject-server/+bug/782688 |
114 | + cmd = [ os.path.join(pg_old, 'bin', 'psql'), '-A', '-t', '-c', |
115 | + 'select datname from pg_database where not datistemplate and datname != \'postgres\'', 'postgres' ] |
116 | + try: |
117 | + out = subprocess.check_output(cmd, stderr=log, env=env) |
118 | + except subprocess.CalledProcessError as e: |
119 | + warn("alter tables failed to get db list: %s" % e) |
120 | + out = "" |
121 | + dbs = out.split() |
122 | + |
123 | + cf = tempfile.NamedTemporaryFile(delete=False) |
124 | + for db in dbs: |
125 | + warn("alter tables in %s" % db) |
126 | + cf.write("\\connect \"%s\"\n alter table ir_actions alter column \"name\" drop not null;\n" % db) |
127 | + cf.close() |
128 | + cmd = [ os.path.join(pg_old, 'bin', 'psql'), '-f', cf.name, 'postgres' ] |
129 | + out = None |
130 | + try: |
131 | + out = subprocess.check_output(cmd, stderr=log, env=env) |
132 | + except subprocess.CalledProcessError as e: |
133 | + warn("problem running psql: %s" % e) |
134 | + warn("alter tables output is: ", out) |
135 | + os.remove(cf.name) |
136 | + re_alter = True |
137 | + |
138 | # 4: stop old service |
139 | subprocess.call('net stop %s' % svc, stdout=log, stderr=log) |
140 | stopped = True |
141 | |
142 | # 5: pg_upgrade |
143 | - run_analyze = False |
144 | cmd = [ os.path.join(pg_new, 'bin', 'pg_upgrade'), |
145 | '-b', os.path.join(pg_old, 'bin'), |
146 | '-B', os.path.join(pg_new, 'bin'), |
147 | @@ -799,7 +827,7 @@ |
148 | |
149 | # The pg_upgrade went ok, so we are committed now. Nuke the |
150 | # old db directory and move the upgraded one into place. |
151 | - warn("pg_upgrade returned %d, commiting to new version" % rc) |
152 | + warn("pg_upgrade returned %d, committing to new version" % rc) |
153 | run_analyze = True |
154 | |
155 | warn("Rename %s to %s." % (pg_new_db, pg_old_db)) |
156 | @@ -811,7 +839,7 @@ |
157 | shutil.rmtree(pg_old_db2) |
158 | |
159 | # 6: commit to new bin dir |
160 | - if oldVer == '8.4.14': |
161 | + if oldVer == '8.4.17': |
162 | # Move pg_new to it's final name. |
163 | os.rename(pg_new, r'..\pgsql') |
164 | # For 8.4->9.9.x transition, nuke 8.4 install |
165 | @@ -820,24 +848,27 @@ |
166 | '--mode', 'unattended', |
167 | ] |
168 | rc = subprocess.call(cmd, stdout=log, stderr=log) |
169 | - if rc != 0: |
170 | - warn("PostgreSQL 8.4 uninstall returned %d" % rc) |
171 | + warn("PostgreSQL 8.4 uninstall returned %d" % rc) |
172 | pg_old = r'..\pgsql' |
173 | else: |
174 | warn("Remove %s." % pg_old) |
175 | shutil.rmtree(pg_old) |
176 | + warn("Remove done.") |
177 | |
178 | - warn("Rename %s to %s." % (pg_new, pg_old)) |
179 | - os.rename(pg_new, pg_old) |
180 | + warn("Rename %s to %s." % (pg_new, pg_old)) |
181 | + shutil.move(pg_new, pg_old) |
182 | + warn("Rename done.") |
183 | |
184 | pgp = os.path.normpath(os.path.join(pg_old, 'bin')) |
185 | if tools.config['pg_path'] != pgp: |
186 | warn("Setting pg_path to %s." % pgp) |
187 | tools.config['pg_path'] = pgp |
188 | tools.config.save() |
189 | + else: |
190 | + warn("pg_path is correct") |
191 | |
192 | # 7: change service entry to the correct install location |
193 | - if oldVer == '8.4.14': |
194 | + if oldVer == '8.4.17': |
195 | cmd = [ |
196 | os.path.join(pg_old, 'bin', 'pg_ctl'), |
197 | 'register', '-N', 'Postgres', |
198 | @@ -853,6 +884,7 @@ |
199 | except Exception as e: |
200 | s = str(e) or type(e) |
201 | warn('Failed to update Postgres:', s) |
202 | + failed = True |
203 | finally: |
204 | try: |
205 | if pg_new_db is not None and os.path.exists(pg_new_db): |
206 | @@ -866,10 +898,30 @@ |
207 | if stopped: |
208 | warn('Starting service %s' % svc) |
209 | subprocess.call('net start %s' % svc, stdout=log, stderr=log) |
210 | + |
211 | + # 9. re-alter tables to put the problematic constraint back on |
212 | + if re_alter: |
213 | + cf = tempfile.NamedTemporaryFile(delete=False) |
214 | + for db in dbs: |
215 | + warn("alter tables in %s" % db) |
216 | + cf.write("\\connect \"%s\"\n alter table ir_actions alter column \"name\" set not null;\n" % db) |
217 | + cf.close() |
218 | + cmd = [ os.path.join(pg_old, 'bin', 'psql'), '-f', cf.name, 'postgres' ] |
219 | + out = None |
220 | + try: |
221 | + out = subprocess.check_output(cmd, stderr=log, env=env) |
222 | + except subprocess.CalledProcessError as e: |
223 | + warn("problem running psql: %s" % e) |
224 | + warn("re-alter tables output is: ", out) |
225 | + os.remove(cf.name) |
226 | + |
227 | if run_analyze: |
228 | cmd = [ os.path.join(r'..\pgsql', 'bin', 'vacuumdb'), |
229 | '--all', '--analyze-only' ] |
230 | subprocess.call(cmd, stdout=log, stderr=log, env=env) |
231 | + |
232 | + if not failed: |
233 | + warn("Major update done.") |
234 | return |
235 | |
236 | # https://stackoverflow.com/questions/51658/cross-platform-space-remaining-on-volume-using-python |
237 | @@ -895,12 +947,12 @@ |
238 | assert pf == None |
239 | |
240 | # one good file |
241 | - with open('pgsql-8.4.14-9.6.3-patch', 'wb') as f: |
242 | + with open('pgsql-8.4.17-9.6.3-patch', 'wb') as f: |
243 | f.write('Fake patch for testing.') |
244 | pf, oldVer, newVer = _find_pg_patch() |
245 | - assert oldVer == '8.4.14' |
246 | + assert oldVer == '8.4.17' |
247 | assert newVer == '9.6.3' |
248 | - assert pf == 'pgsql-8.4.14-9.6.3-patch' |
249 | + assert pf == 'pgsql-8.4.17-9.6.3-patch' |
250 | |
251 | # two files: oops |
252 | warn("Expect 2 messages on stderr after this:") |
253 | @@ -910,16 +962,20 @@ |
254 | assert pf == None |
255 | |
256 | # one file with wrong version format |
257 | - os.remove('pgsql-8.4.14-9.6.3-patch') |
258 | + os.remove('pgsql-8.4.17-9.6.3-patch') |
259 | pf, oldVer, newVer = _find_pg_patch() |
260 | assert pf == None |
261 | |
262 | - assert _is_major('8.4.14', '9.6.3') |
263 | - assert not _is_major('8.4.14', '8.4.15') |
264 | + assert _is_major('8.4.17', '9.6.3') |
265 | + assert not _is_major('8.4.16', '8.4.17') |
266 | + assert _is_major('9.5.6', '9.6.3') |
267 | assert _is_major('9.6.9', '10.1') |
268 | assert not _is_major('10.1', '10.2') |
269 | assert _is_major('21.9', '22.1') |
270 | |
271 | os.chdir('..') |
272 | shutil.rmtree(d) |
273 | - assert get_free_space_mb("D:\\") != None |
274 | + root = "D:\\" |
275 | + if sys.platform != 'win32': |
276 | + root = '/' |
277 | + assert get_free_space_mb(root) != None |