]> git.openstreetmap.org Git - nominatim.git/blob - utils/update.php
Merge remote-tracking branch 'upstream/master'
[nominatim.git] / utils / update.php
1 <?php
2
3 require_once(CONST_BasePath.'/lib/init-cmd.php');
4 require_once(CONST_BasePath.'/lib/setup_functions.php');
5 require_once(CONST_BasePath.'/lib/setup/SetupClass.php');
6 require_once(CONST_BasePath.'/lib/setup/AddressLevelParser.php');
7
8 ini_set('memory_limit', '800M');
9
10 use Nominatim\Setup\SetupFunctions as SetupFunctions;
11
12 // (long-opt, short-opt, min-occurs, max-occurs, num-arguments, num-arguments, type, help)
13 $aCMDOptions
14 = array(
15    'Import / update / index osm data',
16    array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
17    array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
18    array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
19
20    array('init-updates', '', 0, 1, 0, 0, 'bool', 'Set up database for updating'),
21    array('check-for-updates', '', 0, 1, 0, 0, 'bool', 'Check if new updates are available'),
22    array('no-update-functions', '', 0, 1, 0, 0, 'bool', 'Do not update trigger functions to support differential updates (assuming the diff update logic is already present)'),
23    array('import-osmosis', '', 0, 1, 0, 0, 'bool', 'Import updates once'),
24    array('import-osmosis-all', '', 0, 1, 0, 0, 'bool', 'Import updates forever'),
25    array('no-index', '', 0, 1, 0, 0, 'bool', 'Do not index the new data'),
26
27    array('calculate-postcodes', '', 0, 1, 0, 0, 'bool', 'Update postcode centroid table'),
28
29    array('import-file', '', 0, 1, 1, 1, 'realpath', 'Re-import data from an OSM file'),
30    array('import-diff', '', 0, 1, 1, 1, 'realpath', 'Import a diff (osc) file from local file system'),
31    array('osm2pgsql-cache', '', 0, 1, 1, 1, 'int', 'Cache size used by osm2pgsql'),
32
33    array('import-node', '', 0, 1, 1, 1, 'int', 'Re-import node'),
34    array('import-way', '', 0, 1, 1, 1, 'int', 'Re-import way'),
35    array('import-relation', '', 0, 1, 1, 1, 'int', 'Re-import relation'),
36    array('import-from-main-api', '', 0, 1, 0, 0, 'bool', 'Use OSM API instead of Overpass to download objects'),
37
38    array('index', '', 0, 1, 0, 0, 'bool', 'Index'),
39    array('index-rank', '', 0, 1, 1, 1, 'int', 'Rank to start indexing from'),
40    array('index-instances', '', 0, 1, 1, 1, 'int', 'Number of indexing instances (threads)'),
41
42    array('deduplicate', '', 0, 1, 0, 0, 'bool', 'Deduplicate tokens'),
43    array('recompute-word-counts', '', 0, 1, 0, 0, 'bool', 'Compute frequency of full-word search terms'),
44    array('update-address-levels', '', 0, 1, 0, 0, 'bool', 'Reimport address level configuration (EXPERT)'),
45    array('recompute-importance', '', 0, 1, 0, 0, 'bool', 'Recompute place importances'),
46    array('no-npi', '', 0, 1, 0, 0, 'bool', '(obsolete)'),
47   );
48
49 getCmdOpt($_SERVER['argv'], $aCMDOptions, $aResult, true, true);
50
51 if (!isset($aResult['index-instances'])) $aResult['index-instances'] = 1;
52
53 if (!isset($aResult['index-rank'])) $aResult['index-rank'] = 0;
54
55 date_default_timezone_set('Etc/UTC');
56
57 $oDB = new Nominatim\DB();
58 $oDB->connect();
59
60 $aDSNInfo = Nominatim\DB::parseDSN(CONST_Database_DSN);
61 if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
62
63 // cache memory to be used by osm2pgsql, should not be more than the available memory
64 $iCacheMemory = (isset($aResult['osm2pgsql-cache'])?$aResult['osm2pgsql-cache']:2000);
65 if ($iCacheMemory + 500 > getTotalMemoryMB()) {
66     $iCacheMemory = getCacheMemoryMB();
67     echo "WARNING: resetting cache memory to $iCacheMemory\n";
68 }
69 $sOsm2pgsqlCmd = CONST_Osm2pgsql_Binary.' -klas --number-processes 1 -C '.$iCacheMemory.' -O gazetteer -S '.CONST_Import_Style.' -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'];
70 if (isset($aDSNInfo['username']) && $aDSNInfo['username']) {
71     $sOsm2pgsqlCmd .= ' -U ' . $aDSNInfo['username'];
72 }
73 if (isset($aDSNInfo['hostspec']) && $aDSNInfo['hostspec']) {
74     $sOsm2pgsqlCmd .= ' -H ' . $aDSNInfo['hostspec'];
75 }
76 $aProcEnv = null;
77 if (isset($aDSNInfo['password']) && $aDSNInfo['password']) {
78     $aProcEnv = array_merge(array('PGPASSWORD' => $aDSNInfo['password']), $_ENV);
79 }
80
81 if (!is_null(CONST_Osm2pgsql_Flatnode_File) && CONST_Osm2pgsql_Flatnode_File) {
82     $sOsm2pgsqlCmd .= ' --flat-nodes '.CONST_Osm2pgsql_Flatnode_File;
83 }
84
85 if ($aResult['init-updates']) {
86     // sanity check that the replication URL is correct
87     $sBaseState = file_get_contents(CONST_Replication_Url.'/state.txt');
88     if ($sBaseState === false) {
89         echo "\nCannot find state.txt file at the configured replication URL.\n";
90         echo "Does the URL point to a directory containing OSM update data?\n\n";
91         fail('replication URL not reachable.');
92     }
93     // sanity check for pyosmium-get-changes
94     if (!CONST_Pyosmium_Binary) {
95         echo "\nCONST_Pyosmium_Binary not configured.\n";
96         echo "You need to install pyosmium and set up the path to pyosmium-get-changes\n";
97         echo "in your local settings file.\n\n";
98         fail('CONST_Pyosmium_Binary not configured');
99     }
100     $aOutput = 0;
101     $sCmd = CONST_Pyosmium_Binary.' --help';
102     exec($sCmd, $aOutput, $iRet);
103     if ($iRet != 0) {
104         echo "Cannot execute pyosmium-get-changes.\n";
105         echo "Make sure you have pyosmium installed correctly\n";
106         echo "and have set up CONST_Pyosmium_Binary to point to pyosmium-get-changes.\n";
107         fail('pyosmium-get-changes not found or not usable');
108     }
109
110     if (!$aResult['no-update-functions']) {
111         // instantiate setupClass to use the function therein
112         $cSetup = new SetupFunctions(array(
113                                       'enable-diff-updates' => true,
114                                       'verbose' => $aResult['verbose']
115                                      ));
116         $cSetup->connect();
117         $cSetup->createFunctions();
118     }
119
120     $sDatabaseDate = getDatabaseDate($oDB);
121     if (!$sDatabaseDate) {
122         fail('Cannot determine date of database.');
123     }
124     $sWindBack = strftime('%Y-%m-%dT%H:%M:%SZ', strtotime($sDatabaseDate) - (3*60*60));
125
126     // get the appropriate state id
127     $aOutput = 0;
128     $sCmd = CONST_Pyosmium_Binary.' -D '.$sWindBack.' --server '.CONST_Replication_Url;
129     exec($sCmd, $aOutput, $iRet);
130     if ($iRet != 0 || $aOutput[0] == 'None') {
131         fail('Error running pyosmium tools');
132     }
133
134     $oDB->exec('TRUNCATE import_status');
135     $sSQL = "INSERT INTO import_status (lastimportdate, sequence_id, indexed) VALUES('";
136     $sSQL .= $sDatabaseDate."',".$aOutput[0].', true)';
137
138     try {
139         $oDB->exec($sSQL);
140     } catch (\Nominatim\DatabaseError $e) {
141         fail('Could not enter sequence into database.');
142     }
143
144     echo "Done. Database updates will start at sequence $aOutput[0] ($sWindBack)\n";
145 }
146
147 if ($aResult['check-for-updates']) {
148     $aLastState = $oDB->getRow('SELECT sequence_id FROM import_status');
149
150     if (!$aLastState['sequence_id']) {
151         fail('Updates not set up. Please run ./utils/update.php --init-updates.');
152     }
153
154     system(CONST_BasePath.'/utils/check_server_for_updates.py '.CONST_Replication_Url.' '.$aLastState['sequence_id'], $iRet);
155     exit($iRet);
156 }
157
158 if (isset($aResult['import-diff']) || isset($aResult['import-file'])) {
159     // import diffs and files directly (e.g. from osmosis --rri)
160     $sNextFile = isset($aResult['import-diff']) ? $aResult['import-diff'] : $aResult['import-file'];
161
162     if (!file_exists($sNextFile)) {
163         fail("Cannot open $sNextFile\n");
164     }
165
166     // Import the file
167     $sCMD = $sOsm2pgsqlCmd.' '.$sNextFile;
168     echo $sCMD."\n";
169     $iErrorLevel = runWithEnv($sCMD, $aProcEnv);
170
171     if ($iErrorLevel) {
172         fail("Error from osm2pgsql, $iErrorLevel\n");
173     }
174
175     // Don't update the import status - we don't know what this file contains
176 }
177
178 if ($aResult['calculate-postcodes']) {
179     info('Update postcodes centroids');
180     $sTemplate = file_get_contents(CONST_BasePath.'/sql/update-postcodes.sql');
181     runSQLScript($sTemplate, true, true);
182 }
183
184 $sTemporaryFile = CONST_BasePath.'/data/osmosischange.osc';
185 $bHaveDiff = false;
186 $bUseOSMApi = isset($aResult['import-from-main-api']) && $aResult['import-from-main-api'];
187 $sContentURL = '';
188 if (isset($aResult['import-node']) && $aResult['import-node']) {
189     if ($bUseOSMApi) {
190         $sContentURL = 'https://www.openstreetmap.org/api/0.6/node/'.$aResult['import-node'];
191     } else {
192         $sContentURL = 'https://overpass-api.de/api/interpreter?data=node('.$aResult['import-node'].');out%20meta;';
193     }
194 }
195
196 if (isset($aResult['import-way']) && $aResult['import-way']) {
197     if ($bUseOSMApi) {
198         $sContentURL = 'https://www.openstreetmap.org/api/0.6/way/'.$aResult['import-way'].'/full';
199     } else {
200         $sContentURL = 'https://overpass-api.de/api/interpreter?data=(way('.$aResult['import-way'].');node(w););out%20meta;';
201     }
202 }
203
204 if (isset($aResult['import-relation']) && $aResult['import-relation']) {
205     if ($bUseOSMApi) {
206         $sContentURLsModifyXMLstr = 'https://www.openstreetmap.org/api/0.6/relation/'.$aResult['import-relation'].'/full';
207     } else {
208         $sContentURL = 'https://overpass-api.de/api/interpreter?data=((rel('.$aResult['import-relation'].');way(r);node(w));node(r));out%20meta;';
209     }
210 }
211
212 if ($sContentURL) {
213     file_put_contents($sTemporaryFile, file_get_contents($sContentURL));
214     $bHaveDiff = true;
215 }
216
217 if ($bHaveDiff) {
218     // import generated change file
219     $sCMD = $sOsm2pgsqlCmd.' '.$sTemporaryFile;
220     echo $sCMD."\n";
221     $iErrorLevel = runWithEnv($sCMD, $aProcEnv);
222     if ($iErrorLevel) {
223         fail("osm2pgsql exited with error level $iErrorLevel\n");
224     }
225 }
226
227 if ($aResult['deduplicate']) {
228     $oDB = new Nominatim\DB();
229     $oDB->connect();
230
231     if ($oDB->getPostgresVersion() < 9.3) {
232         fail('ERROR: deduplicate is only currently supported in postgresql 9.3');
233     }
234
235     $sSQL = 'select partition from country_name order by country_code';
236     $aPartitions = $oDB->getCol($sSQL);
237     $aPartitions[] = 0;
238
239     // we don't care about empty search_name_* partitions, they can't contain mentions of duplicates
240     foreach ($aPartitions as $i => $sPartition) {
241         $sSQL = 'select count(*) from search_name_'.$sPartition;
242         $nEntries = $oDB->getOne($sSQL);
243         if ($nEntries == 0) {
244             unset($aPartitions[$i]);
245         }
246     }
247
248     $sSQL = "select word_token,count(*) from word where substr(word_token, 1, 1) = ' '";
249     $sSQL .= ' and class is null and type is null and country_code is null';
250     $sSQL .= ' group by word_token having count(*) > 1 order by word_token';
251     $aDuplicateTokens = $oDB->getAll($sSQL);
252     foreach ($aDuplicateTokens as $aToken) {
253         if (trim($aToken['word_token']) == '' || trim($aToken['word_token']) == '-') continue;
254         echo 'Deduping '.$aToken['word_token']."\n";
255         $sSQL = 'select word_id,';
256         $sSQL .= ' (select count(*) from search_name where nameaddress_vector @> ARRAY[word_id]) as num';
257         $sSQL .= " from word where word_token = '".$aToken['word_token'];
258         $sSQL .= "' and class is null and type is null and country_code is null order by num desc";
259         $aTokenSet = $oDB->getAll($sSQL);
260
261         $aKeep = array_shift($aTokenSet);
262         $iKeepID = $aKeep['word_id'];
263
264         foreach ($aTokenSet as $aRemove) {
265             $sSQL = 'update search_name set';
266             $sSQL .= ' name_vector = array_replace(name_vector,'.$aRemove['word_id'].','.$iKeepID.'),';
267             $sSQL .= ' nameaddress_vector = array_replace(nameaddress_vector,'.$aRemove['word_id'].','.$iKeepID.')';
268             $sSQL .= ' where name_vector @> ARRAY['.$aRemove['word_id'].']';
269             $oDB->exec($sSQL);
270
271             $sSQL = 'update search_name set';
272             $sSQL .= ' nameaddress_vector = array_replace(nameaddress_vector,'.$aRemove['word_id'].','.$iKeepID.')';
273             $sSQL .= ' where nameaddress_vector @> ARRAY['.$aRemove['word_id'].']';
274             $oDB->exec($sSQL);
275
276             $sSQL = 'update location_area_country set';
277             $sSQL .= ' keywords = array_replace(keywords,'.$aRemove['word_id'].','.$iKeepID.')';
278             $sSQL .= ' where keywords @> ARRAY['.$aRemove['word_id'].']';
279             $oDB->exec($sSQL);
280
281             foreach ($aPartitions as $sPartition) {
282                 $sSQL = 'update search_name_'.$sPartition.' set';
283                 $sSQL .= ' name_vector = array_replace(name_vector,'.$aRemove['word_id'].','.$iKeepID.')';
284                 $sSQL .= ' where name_vector @> ARRAY['.$aRemove['word_id'].']';
285                 $oDB->exec($sSQL);
286
287                 $sSQL = 'update location_area_country set';
288                 $sSQL .= ' keywords = array_replace(keywords,'.$aRemove['word_id'].','.$iKeepID.')';
289                 $sSQL .= ' where keywords @> ARRAY['.$aRemove['word_id'].']';
290                 $oDB->exec($sSQL);
291             }
292
293             $sSQL = 'delete from word where word_id = '.$aRemove['word_id'];
294             $oDB->exec($sSQL);
295         }
296     }
297 }
298
299 if ($aResult['recompute-word-counts']) {
300     info('Recompute frequency of full-word search terms');
301     $sTemplate = file_get_contents(CONST_BasePath.'/sql/words_from_search_name.sql');
302     runSQLScript($sTemplate, true, true);
303 }
304
305 if ($aResult['index']) {
306     $sCmd = CONST_InstallPath.'/nominatim/nominatim -i -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'].' -t '.$aResult['index-instances'].' -r '.$aResult['index-rank'];
307     if (isset($aDSNInfo['hostspec']) && $aDSNInfo['hostspec']) {
308         $sCmd .= ' -H ' . $aDSNInfo['hostspec'];
309     }
310     if (isset($aDSNInfo['username']) && $aDSNInfo['username']) {
311         $sCmd .= ' -U ' . $aDSNInfo['username'];
312     }
313
314     runWithEnv($sCmd, $aProcEnv);
315
316     $oDB->exec('update import_status set indexed = true');
317 }
318
319 if ($aResult['update-address-levels']) {
320     echo 'Updating address levels from '.CONST_Address_Level_Config.".\n";
321     $oAlParser = new \Nominatim\Setup\AddressLevelParser(CONST_Address_Level_Config);
322     $oAlParser->createTable($oDB, 'address_levels');
323 }
324
325 if ($aResult['recompute-importance']) {
326     echo "Updating importance values for database.\n";
327     $oDB = new Nominatim\DB();
328     $oDB->connect();
329
330     $sSQL = 'ALTER TABLE placex DISABLE TRIGGER ALL;';
331     $sSQL .= 'UPDATE placex SET (wikipedia, importance) =';
332     $sSQL .= '   (SELECT wikipedia, importance';
333     $sSQL .= '    FROM compute_importance(extratags, country_code, osm_type, osm_id));';
334     $sSQL .= 'UPDATE placex s SET wikipedia = d.wikipedia, importance = d.importance';
335     $sSQL .= ' FROM placex d';
336     $sSQL .= ' WHERE s.place_id = d.linked_place_id and d.wikipedia is not null';
337     $sSQL .= '       and (s.wikipedia is null or s.importance < d.importance);';
338     $sSQL .= 'ALTER TABLE placex ENABLE TRIGGER ALL;';
339     $oDB->exec($sSQL);
340 }
341
342 if ($aResult['import-osmosis'] || $aResult['import-osmosis-all']) {
343     //
344     if (strpos(CONST_Replication_Url, 'download.geofabrik.de') !== false && CONST_Replication_Update_Interval < 86400) {
345         fail('Error: Update interval too low for download.geofabrik.de. ' .
346              "Please check install documentation (http://nominatim.org/release-docs/latest/Import-and-Update#setting-up-the-update-process)\n");
347     }
348
349     $sImportFile = CONST_InstallPath.'/osmosischange.osc';
350     $sCMDDownload = CONST_Pyosmium_Binary.' --server '.CONST_Replication_Url.' -o '.$sImportFile.' -s '.CONST_Replication_Max_Diff_size;
351     $sCMDImport = $sOsm2pgsqlCmd.' '.$sImportFile;
352     $sCMDIndex = CONST_InstallPath.'/nominatim/nominatim -i -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'].' -t '.$aResult['index-instances'];
353     if (isset($aDSNInfo['hostspec']) && $aDSNInfo['hostspec']) {
354         $sCMDIndex .= ' -H ' . $aDSNInfo['hostspec'];
355     }
356     if (isset($aDSNInfo['username']) && $aDSNInfo['username']) {
357         $sCMDIndex .= ' -U ' . $aDSNInfo['username'];
358     }
359
360     while (true) {
361         $fStartTime = time();
362         $aLastState = $oDB->getRow('SELECT *, EXTRACT (EPOCH FROM lastimportdate) as unix_ts FROM import_status');
363
364         if (!$aLastState['sequence_id']) {
365             echo "Updates not set up. Please run ./utils/update.php --init-updates.\n";
366             exit(1);
367         }
368
369         echo 'Currently at sequence '.$aLastState['sequence_id'].' ('.$aLastState['lastimportdate'].') - '.$aLastState['indexed']." indexed\n";
370
371         $sBatchEnd = $aLastState['lastimportdate'];
372         $iEndSequence = $aLastState['sequence_id'];
373
374         if ($aLastState['indexed']) {
375             // Sleep if the update interval has not yet been reached.
376             $fNextUpdate = $aLastState['unix_ts'] + CONST_Replication_Update_Interval;
377             if ($fNextUpdate > $fStartTime) {
378                 $iSleepTime = $fNextUpdate - $fStartTime;
379                 echo "Waiting for next update for $iSleepTime sec.";
380                 sleep($iSleepTime);
381             }
382
383             // Download the next batch of changes.
384             do {
385                 $fCMDStartTime = time();
386                 $iNextSeq = (int) $aLastState['sequence_id'];
387                 unset($aOutput);
388                 echo "$sCMDDownload -I $iNextSeq\n";
389                 if (file_exists($sImportFile)) {
390                     unlink($sImportFile);
391                 }
392                 exec($sCMDDownload.' -I '.$iNextSeq, $aOutput, $iResult);
393
394                 if ($iResult == 3) {
395                     echo 'No new updates. Sleeping for '.CONST_Replication_Recheck_Interval." sec.\n";
396                     sleep(CONST_Replication_Recheck_Interval);
397                 } elseif ($iResult != 0) {
398                     echo 'ERROR: updates failed.';
399                     exit($iResult);
400                 } else {
401                     $iEndSequence = (int)$aOutput[0];
402                 }
403             } while ($iResult);
404
405             // get the newest object from the diff file
406             $sBatchEnd = 0;
407             $iRet = 0;
408             exec(CONST_BasePath.'/utils/osm_file_date.py '.$sImportFile, $sBatchEnd, $iRet);
409             if ($iRet == 5) {
410                 echo "Diff file is empty. skipping import.\n";
411                 if (!$aResult['import-osmosis-all']) {
412                     exit(0);
413                 } else {
414                     continue;
415                 }
416             }
417             if ($iRet != 0) {
418                 fail('Error getting date from diff file.');
419             }
420             $sBatchEnd = $sBatchEnd[0];
421
422             // Import the file
423             $fCMDStartTime = time();
424             echo $sCMDImport."\n";
425             unset($sJunk);
426             $iErrorLevel = runWithEnv($sCMDImport, $aProcEnv);
427             if ($iErrorLevel) {
428                 echo "Error executing osm2pgsql: $iErrorLevel\n";
429                 exit($iErrorLevel);
430             }
431
432             // write the update logs
433             $iFileSize = filesize($sImportFile);
434             $sSQL = 'INSERT INTO import_osmosis_log';
435             $sSQL .= '(batchend, batchseq, batchsize, starttime, endtime, event)';
436             $sSQL .= " values ('$sBatchEnd',$iEndSequence,$iFileSize,'";
437             $sSQL .= date('Y-m-d H:i:s', $fCMDStartTime)."','";
438             $sSQL .= date('Y-m-d H:i:s')."','import')";
439             var_Dump($sSQL);
440             $oDB->exec($sSQL);
441
442             // update the status
443             $sSQL = "UPDATE import_status SET lastimportdate = '$sBatchEnd', indexed=false, sequence_id = $iEndSequence";
444             var_Dump($sSQL);
445             $oDB->exec($sSQL);
446             echo date('Y-m-d H:i:s')." Completed download step for $sBatchEnd in ".round((time()-$fCMDStartTime)/60, 2)." minutes\n";
447         }
448
449         // Index file
450         if (!$aResult['no-index']) {
451             $sThisIndexCmd = $sCMDIndex;
452             $fCMDStartTime = time();
453
454             echo "$sThisIndexCmd\n";
455             $iErrorLevel = runWithEnv($sThisIndexCmd, $aProcEnv);
456             if ($iErrorLevel) {
457                 echo "Error: $iErrorLevel\n";
458                 exit($iErrorLevel);
459             }
460
461             $sSQL = 'INSERT INTO import_osmosis_log';
462             $sSQL .= '(batchend, batchseq, batchsize, starttime, endtime, event)';
463             $sSQL .= " values ('$sBatchEnd',$iEndSequence,NULL,'";
464             $sSQL .= date('Y-m-d H:i:s', $fCMDStartTime)."','";
465             $sSQL .= date('Y-m-d H:i:s')."','index')";
466             var_Dump($sSQL);
467             $oDB->exec($sSQL);
468             echo date('Y-m-d H:i:s')." Completed index step for $sBatchEnd in ".round((time()-$fCMDStartTime)/60, 2)." minutes\n";
469
470             $sSQL = 'update import_status set indexed = true';
471             $oDB->exec($sSQL);
472         } else {
473             if ($aResult['import-osmosis-all']) {
474                 echo "Error: --no-index cannot be used with continuous imports (--import-osmosis-all).\n";
475                 exit(1);
476             }
477         }
478
479         $fDuration = time() - $fStartTime;
480         echo date('Y-m-d H:i:s')." Completed all for $sBatchEnd in ".round($fDuration/60, 2)." minutes\n";
481         if (!$aResult['import-osmosis-all']) exit(0);
482     }
483 }