|
1 #!/usr/bin/python2.6 |
|
2 |
|
3 # Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. |
|
4 # |
|
5 # Licensed under the Apache License, Version 2.0 (the "License"); you may |
|
6 # not use this file except in compliance with the License. You may obtain |
|
7 # a copy of the License at |
|
8 # |
|
9 # http://www.apache.org/licenses/LICENSE-2.0 |
|
10 # |
|
11 # Unless required by applicable law or agreed to in writing, software |
|
12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|
13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|
14 # License for the specific language governing permissions and limitations |
|
15 # under the License. |
|
16 |
|
17 from ConfigParser import NoOptionError |
|
18 from datetime import datetime |
|
19 import errno |
|
20 import glob |
|
21 import os |
|
22 import shutil |
|
23 from subprocess import check_call, Popen, PIPE |
|
24 import sys |
|
25 import traceback |
|
26 |
|
27 import iniparse |
|
28 import smf_include |
|
29 |
|
30 |
|
31 def modify_conf(old_file): |
|
32 """ Copy over all uncommented options from the old configuration file. |
|
33 """ |
|
34 |
|
35 new_file = old_file + '.new' |
|
36 |
|
37 # open the previous version |
|
38 old = iniparse.ConfigParser() |
|
39 old.readfp(open(old_file)) |
|
40 |
|
41 # open the new version |
|
42 new = iniparse.ConfigParser() |
|
43 try: |
|
44 new.readfp(open(new_file)) |
|
45 except IOError as err: |
|
46 if err.errno == errno.ENOENT: |
|
47 # The upgrade did not deliver a .new file so, return |
|
48 print "%s not found - continuing with %s" % (new_file, old_file) |
|
49 return |
|
50 else: |
|
51 raise |
|
52 print "\nupdating %s" % old_file |
|
53 |
|
54 # walk every single section for uncommented options |
|
55 default_items = set(old.items('DEFAULT')) |
|
56 for section in old.sections() + ['DEFAULT']: |
|
57 |
|
58 # DEFAULT items show up in every section so remove them |
|
59 if section != 'DEFAULT': |
|
60 section_items = set(old.items(section)) - default_items |
|
61 else: |
|
62 section_items = default_items |
|
63 |
|
64 for key, value in section_items: |
|
65 # keep a copy of the old value |
|
66 oldvalue = value |
|
67 |
|
68 if not new.has_section(section): |
|
69 if section != 'DEFAULT': |
|
70 new.add_section(section) |
|
71 |
|
72 # print to the log when a value for the same section.key is |
|
73 # changing to a new value |
|
74 try: |
|
75 new_value = new.get(section, key) |
|
76 if new_value != value and '%SERVICE' not in new_value: |
|
77 print "Changing [%s] %s:\n- %s\n+ %s" % \ |
|
78 (section, key, oldvalue, new_value) |
|
79 print |
|
80 except NoOptionError: |
|
81 # the new configuration file does not have this option set so |
|
82 # just continue |
|
83 pass |
|
84 |
|
85 # Only copy the old value to the new conf file if the entry doesn't |
|
86 # exist or if it contains '%SERVICE' |
|
87 if not new.has_option(section, key) or \ |
|
88 '%SERVICE' in new.get(section, key): |
|
89 new.set(section, key, value) |
|
90 |
|
91 # copy the old conf file to a backup |
|
92 today = datetime.now().strftime("%Y%m%d%H%M%S") |
|
93 shutil.copy2(old_file, old_file + '.' + today) |
|
94 |
|
95 # copy the new conf file in place |
|
96 with open(old_file, 'wb+') as fh: |
|
97 new.write(fh) |
|
98 |
|
99 |
|
100 def start(): |
|
101 # pull out the current version of config/upgrade-id |
|
102 p = Popen(['/usr/bin/svcprop', '-p', 'config/upgrade-id', |
|
103 os.environ['SMF_FMRI']], stdout=PIPE, stderr=PIPE) |
|
104 curr_ver, _err = p.communicate() |
|
105 curr_ver = curr_ver.strip() |
|
106 |
|
107 # extract the openstack-upgrade-id from the pkg |
|
108 p = Popen(['/usr/bin/pkg', 'contents', '-H', '-t', 'set', '-o', 'value', |
|
109 '-a', 'name=openstack.upgrade-id', |
|
110 'pkg:/cloud/openstack/swift'], stdout=PIPE, stderr=PIPE) |
|
111 pkg_ver, _err = p.communicate() |
|
112 pkg_ver = pkg_ver.strip() |
|
113 |
|
114 if curr_ver == pkg_ver: |
|
115 # No need to upgrade |
|
116 sys.exit(smf_include.SMF_EXIT_OK) |
|
117 |
|
118 # look for any .new files |
|
119 if glob.glob('/etc/swift/*.new'): |
|
120 # the versions are different, so perform an upgrade |
|
121 # modify the configuration files |
|
122 modify_conf('/etc/swift/account-server.conf') |
|
123 modify_conf('/etc/swift/container-reconciler.conf') |
|
124 modify_conf('/etc/swift/container-server.conf') |
|
125 modify_conf('/etc/swift/container-sync-realms.conf') |
|
126 modify_conf('/etc/swift/dispersion.conf') |
|
127 modify_conf('/etc/swift/memcache.conf') |
|
128 modify_conf('/etc/swift/object-expirer.conf') |
|
129 modify_conf('/etc/swift/object-server.conf') |
|
130 modify_conf('/etc/swift/proxy-server.conf') |
|
131 modify_conf('/etc/swift/swift.conf') |
|
132 |
|
133 # update the current version |
|
134 check_call(['/usr/sbin/svccfg', '-s', os.environ['SMF_FMRI'], 'setprop', |
|
135 'config/upgrade-id', '=', pkg_ver]) |
|
136 check_call(['/usr/sbin/svccfg', '-s', os.environ['SMF_FMRI'], 'refresh']) |
|
137 |
|
138 sys.exit(smf_include.SMF_EXIT_OK) |
|
139 |
|
140 |
|
141 if __name__ == '__main__': |
|
142 os.putenv('LC_ALL', 'C') |
|
143 try: |
|
144 smf_include.smf_main() |
|
145 except Exception as err: |
|
146 print 'Unknown error: %s' % err |
|
147 print |
|
148 traceback.print_exc(file=sys.stdout) |
|
149 sys.exit(smf_include.SMF_EXIT_ERR_FATAL) |