65 ('DEFAULT', 'instance_user'): (None, None), |
63 ('DEFAULT', 'instance_user'): (None, None), |
66 ('DEFAULT', 'onready'): (None, None), |
64 ('DEFAULT', 'onready'): (None, None), |
67 ('DEFAULT', 'list_notifier_drivers'): (None, None), |
65 ('DEFAULT', 'list_notifier_drivers'): (None, None), |
68 } |
66 } |
69 |
67 |
|
68 HEAT_CONF_EXCEPTIONS = [ |
|
69 ('database', 'connection'), |
|
70 ('keystone_authtoken', 'auth_uri'), |
|
71 ('keystone_authtoken', 'identity_uri'), |
|
72 ('keystone_authtoken', 'admin_user'), |
|
73 ('keystone_authtoken', 'admin_password'), |
|
74 ('keystone_authtoken', 'admin_tenant_name'), |
|
75 ('keystone_authtoken', 'signing_dir'), |
|
76 ] |
70 |
77 |
71 def update_mapping(section, key, mapping): |
78 HEAT_MOVE_CONFIG = { |
72 """ look for deprecated variables and, if found, convert it to the new |
79 ('filter:authtoken', 'auth_uri'): ('keystone_authtoken', 'auth_uri'), |
73 section/key. |
80 ('filter:authtoken', 'identity_uri'): |
74 """ |
81 ('keystone_authtoken', 'identity_uri'), |
75 |
82 ('filter:authtoken', 'admin_tenant_name'): |
76 if (section, key) in mapping: |
83 ('keystone_authtoken', 'admin_tenant_name'), |
77 print "Deprecated value found: [%s] %s" % (section, key) |
84 ('filter:authtoken', 'admin_user'): ('keystone_authtoken', 'admin_user'), |
78 section, key = mapping[(section, key)] |
85 ('filter:authtoken', 'admin_password'): |
79 if section is None and key is None: |
86 ('keystone_authtoken', 'admin_password'), |
80 print "Removing from configuration" |
87 } |
81 else: |
|
82 print "Updating to: [%s] %s" % (section, key) |
|
83 return section, key |
|
84 |
|
85 |
|
86 def alter_mysql_tables(engine): |
|
87 """ Convert MySQL tables to use utf8 |
|
88 """ |
|
89 |
|
90 import MySQLdb |
|
91 |
|
92 for _none in range(5): |
|
93 try: |
|
94 db = MySQLdb.connect(host=engine.url.host, |
|
95 user=engine.url.username, |
|
96 passwd=engine.url.password, |
|
97 db=engine.url.database) |
|
98 break |
|
99 except MySQLdb.OperationalError as err: |
|
100 # mysql is not ready. sleep for 2 more seconds |
|
101 time.sleep(2) |
|
102 else: |
|
103 print "Unable to connect to MySQL: %s" % err |
|
104 print ("Please verify MySQL is properly configured and online " |
|
105 "before using svcadm(1M) to clear this service.") |
|
106 sys.exit(smf_include.SMF_EXIT_ERR_FATAL) |
|
107 |
|
108 cursor = db.cursor() |
|
109 cursor.execute("ALTER DATABASE %s CHARACTER SET = 'utf8'" % |
|
110 engine.url.database) |
|
111 cursor.execute("ALTER DATABASE %s COLLATE = 'utf8_general_ci'" % |
|
112 engine.url.database) |
|
113 cursor.execute("SHOW tables") |
|
114 res = cursor.fetchall() |
|
115 if res: |
|
116 cursor.execute("SET foreign_key_checks = 0") |
|
117 for item in res: |
|
118 cursor.execute("ALTER TABLE %s.%s CONVERT TO " |
|
119 "CHARACTER SET 'utf8', COLLATE 'utf8_general_ci'" |
|
120 % (engine.url.database, item[0])) |
|
121 cursor.execute("SET foreign_key_checks = 1") |
|
122 db.commit() |
|
123 db.close() |
|
124 |
|
125 |
|
126 def modify_conf(old_file, mapping=None): |
|
127 """ Copy over all uncommented options from the old configuration file. In |
|
128 addition, look for deprecated section/keys and convert them to the new |
|
129 section/key. |
|
130 """ |
|
131 |
|
132 new_file = old_file + '.new' |
|
133 |
|
134 # open the previous version |
|
135 old = iniparse.ConfigParser() |
|
136 old.readfp(open(old_file)) |
|
137 |
|
138 # open the new version |
|
139 new = iniparse.ConfigParser() |
|
140 try: |
|
141 new.readfp(open(new_file)) |
|
142 except IOError as err: |
|
143 if err.errno == errno.ENOENT: |
|
144 # The upgrade did not deliver a .new file so, return |
|
145 print "%s not found - continuing with %s" % (new_file, old_file) |
|
146 return |
|
147 else: |
|
148 raise |
|
149 print "\nupdating %s" % old_file |
|
150 |
|
151 # walk every single section for uncommented options |
|
152 default_items = set(old.items('DEFAULT')) |
|
153 for section in old.sections() + ['DEFAULT']: |
|
154 |
|
155 # DEFAULT items show up in every section so remove them |
|
156 if section != 'DEFAULT': |
|
157 section_items = set(old.items(section)) - default_items |
|
158 else: |
|
159 section_items = default_items |
|
160 |
|
161 for key, value in section_items: |
|
162 # keep a copy of the old value |
|
163 oldvalue = value |
|
164 oldsection = section |
|
165 |
|
166 if mapping is not None: |
|
167 section, key = update_mapping(section, key, mapping) |
|
168 |
|
169 if section is None and key is None: |
|
170 # option is deprecated so continue |
|
171 continue |
|
172 |
|
173 if not new.has_section(section): |
|
174 if section != 'DEFAULT': |
|
175 new.add_section(section) |
|
176 |
|
177 # print to the log when a value for the same section.key is |
|
178 # changing to a new value |
|
179 try: |
|
180 new_value = new.get(section, key) |
|
181 if new_value != value and '%SERVICE' not in new_value: |
|
182 print "Changing [%s] %s:\n- %s\n+ %s" % \ |
|
183 (section, key, oldvalue, new_value) |
|
184 print |
|
185 except NoOptionError: |
|
186 # the new configuration file does not have this option set so |
|
187 # just continue |
|
188 pass |
|
189 |
|
190 # Only copy the old value to the new conf file if the entry doesn't |
|
191 # exist or if it contains '%SERVICE' |
|
192 if not new.has_option(section, key) or \ |
|
193 '%SERVICE' in new.get(section, key): |
|
194 new.set(section, key, value) |
|
195 section = oldsection |
|
196 |
|
197 # copy the old conf file to a backup |
|
198 today = datetime.now().strftime("%Y%m%d%H%M%S") |
|
199 shutil.copy2(old_file, old_file + '.' + today) |
|
200 |
|
201 # copy the new conf file in place |
|
202 with open(old_file, 'wb+') as fh: |
|
203 new.write(fh) |
|
204 |
88 |
205 |
89 |
206 def start(): |
90 def start(): |
207 # pull out the current version of config/upgrade-id |
91 # pull out the current version of config/upgrade-id |
208 p = Popen(['/usr/bin/svcprop', '-p', 'config/upgrade-id', |
92 p = Popen(['/usr/bin/svcprop', '-p', 'config/upgrade-id', |
223 |
107 |
224 # look for any .new files |
108 # look for any .new files |
225 if glob.glob('/etc/heat/*.new'): |
109 if glob.glob('/etc/heat/*.new'): |
226 # the versions are different, so perform an upgrade |
110 # the versions are different, so perform an upgrade |
227 # modify the configuration files |
111 # modify the configuration files |
|
112 |
|
113 # backup all the old configuration files |
|
114 create_backups('/etc/heat') |
|
115 |
228 modify_conf('/etc/heat/api-paste.ini') |
116 modify_conf('/etc/heat/api-paste.ini') |
229 modify_conf('/etc/heat/heat.conf', HEAT_CONF_MAPPINGS) |
117 |
|
118 # before modifying heat.conf, move the [filter:authtoken] entries from |
|
119 # the updated api-paste.ini to the old heat.conf |
|
120 move_conf('/etc/heat/api-paste.ini', '/etc/heat/heat.conf', |
|
121 HEAT_MOVE_CONFIG) |
|
122 |
|
123 modify_conf('/etc/heat/heat.conf', HEAT_CONF_MAPPINGS, |
|
124 HEAT_CONF_EXCEPTIONS) |
230 |
125 |
231 config = iniparse.RawConfigParser() |
126 config = iniparse.RawConfigParser() |
232 config.read('/etc/heat/heat.conf') |
127 config.read('/etc/heat/heat.conf') |
233 # In certain cases the database section does not exist and the |
128 # In certain cases the database section does not exist and the |
234 # default database chosen is sqlite. |
129 # default database chosen is sqlite. |