Blame view

sources/lib/private/updater.php 7.58 KB
03e52840d   Kload   Init
1
2
3
4
5
6
7
  <?php
  /**
   * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
   * This file is licensed under the Affero General Public License version 3 or
   * later.
   * See the COPYING-README file.
   */
31b7f2792   Kload   Upgrade to ownclo...
8
  namespace OC;
f7d878ff1   kload   [enh] Update to 7...
9

03e52840d   Kload   Init
10
11
12
13
14
15
16
17
18
  use OC\Hooks\BasicEmitter;
  
  /**
   * Class that handles autoupdating of ownCloud
   *
   * Hooks provided in scope \OC\Updater
   *  - maintenanceStart()
   *  - maintenanceEnd()
   *  - dbUpgrade()
03e52840d   Kload   Init
19
20
   *  - failure(string $message)
   */
31b7f2792   Kload   Upgrade to ownclo...
21
22
23
24
25
26
  class Updater extends BasicEmitter {
  
  	/**
  	 * @var \OC\Log $log
  	 */
  	private $log;
6d9380f96   Cédric Dupont   Update sources OC...
27
28
29
  	private $simulateStepEnabled;
  
  	private $updateStepEnabled;
31b7f2792   Kload   Upgrade to ownclo...
30
31
32
33
34
  	/**
  	 * @param \OC\Log $log
  	 */
  	public function __construct($log = null) {
  		$this->log = $log;
6d9380f96   Cédric Dupont   Update sources OC...
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
  		$this->simulateStepEnabled = true;
  		$this->updateStepEnabled = true;
  	}
  
  	/**
  	 * Sets whether the database migration simulation must
  	 * be enabled.
  	 * This can be set to false to skip this test.
  	 *
  	 * @param bool $flag true to enable simulation, false otherwise
  	 */
  	public function setSimulateStepEnabled($flag) {
  		$this->simulateStepEnabled = $flag;
  	}
  
  	/**
  	 * Sets whether the update must be performed.
  	 * This can be set to false to skip the actual update.
  	 *
  	 * @param bool $flag true to enable update, false otherwise
  	 */
  	public function setUpdateStepEnabled($flag) {
  		$this->updateStepEnabled = $flag;
31b7f2792   Kload   Upgrade to ownclo...
58
  	}
03e52840d   Kload   Init
59
60
  	/**
  	 * Check if a new version is available
f7d878ff1   kload   [enh] Update to 7...
61
  	 *
31b7f2792   Kload   Upgrade to ownclo...
62
  	 * @param string $updaterUrl the url to check, i.e. 'http://apps.owncloud.com/updater.php'
6d9380f96   Cédric Dupont   Update sources OC...
63
  	 * @return array|bool
03e52840d   Kload   Init
64
  	 */
31b7f2792   Kload   Upgrade to ownclo...
65
66
67
  	public function check($updaterUrl) {
  
  		// Look up the cache - it is invalidated all 30 minutes
03e52840d   Kload   Init
68
69
70
  		if ((\OC_Appconfig::getValue('core', 'lastupdatedat') + 1800) > time()) {
  			return json_decode(\OC_Appconfig::getValue('core', 'lastupdateResult'), true);
  		}
31b7f2792   Kload   Upgrade to ownclo...
71

03e52840d   Kload   Init
72
  		\OC_Appconfig::setValue('core', 'lastupdatedat', time());
31b7f2792   Kload   Upgrade to ownclo...
73

03e52840d   Kload   Init
74
75
76
77
78
79
80
  		if (\OC_Appconfig::getValue('core', 'installedat', '') == '') {
  			\OC_Appconfig::setValue('core', 'installedat', microtime(true));
  		}
  
  		$version = \OC_Util::getVersion();
  		$version['installed'] = \OC_Appconfig::getValue('core', 'installedat');
  		$version['updated'] = \OC_Appconfig::getValue('core', 'lastupdatedat');
6d9380f96   Cédric Dupont   Update sources OC...
81
  		$version['updatechannel'] = \OC_Util::getChannel();
03e52840d   Kload   Init
82
  		$version['edition'] = \OC_Util::getEditionString();
31b7f2792   Kload   Upgrade to ownclo...
83
  		$version['build'] = \OC_Util::getBuild();
03e52840d   Kload   Init
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
  		$versionString = implode('x', $version);
  
  		//fetch xml data from updater
  		$url = $updaterUrl . '?version=' . $versionString;
  
  		// set a sensible timeout of 10 sec to stay responsive even if the update server is down.
  		$ctx = stream_context_create(
  			array(
  				'http' => array(
  					'timeout' => 10
  				)
  			)
  		);
  		$xml = @file_get_contents($url, 0, $ctx);
  		if ($xml == false) {
  			return array();
  		}
837968727   Kload   [enh] Upgrade to ...
101
  		$loadEntities = libxml_disable_entity_loader(true);
03e52840d   Kload   Init
102
  		$data = @simplexml_load_string($xml);
837968727   Kload   [enh] Upgrade to ...
103
  		libxml_disable_entity_loader($loadEntities);
03e52840d   Kload   Init
104
105
106
107
108
109
  
  		$tmp = array();
  		$tmp['version'] = $data->version;
  		$tmp['versionstring'] = $data->versionstring;
  		$tmp['url'] = $data->url;
  		$tmp['web'] = $data->web;
31b7f2792   Kload   Upgrade to ownclo...
110
  		// Cache the result
03e52840d   Kload   Init
111
  		\OC_Appconfig::setValue('core', 'lastupdateResult', json_encode($data));
03e52840d   Kload   Init
112

31b7f2792   Kload   Upgrade to ownclo...
113
  		return $tmp;
03e52840d   Kload   Init
114
115
116
117
  	}
  
  	/**
  	 * runs the update actions in maintenance mode, does not upgrade the source files
6d9380f96   Cédric Dupont   Update sources OC...
118
119
120
  	 * except the main .htaccess file
  	 *
  	 * @return bool true if the operation succeeded, false otherwise
03e52840d   Kload   Init
121
122
123
124
  	 */
  	public function upgrade() {
  		\OC_DB::enableCaching(false);
  		\OC_Config::setValue('maintenance', true);
6d9380f96   Cédric Dupont   Update sources OC...
125

03e52840d   Kload   Init
126
127
  		$installedVersion = \OC_Config::getValue('version', '0.0.0');
  		$currentVersion = implode('.', \OC_Util::getVersion());
31b7f2792   Kload   Upgrade to ownclo...
128
129
130
131
  		if ($this->log) {
  			$this->log->debug('starting upgrade from ' . $installedVersion . ' to ' . $currentVersion, array('app' => 'core'));
  		}
  		$this->emit('\OC\Updater', 'maintenanceStart');
a293d369c   Kload   Update sources to...
132

6d9380f96   Cédric Dupont   Update sources OC...
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
  		try {
  			$this->doUpgrade($currentVersion, $installedVersion);
  		} catch (\Exception $exception) {
  			$this->emit('\OC\Updater', 'failure', array($exception->getMessage()));
  		}
  
  		\OC_Config::setValue('maintenance', false);
  		$this->emit('\OC\Updater', 'maintenanceEnd');
  	}
  
  	/**
  	 * runs the update actions in maintenance mode, does not upgrade the source files
  	 * except the main .htaccess file
  	 *
  	 * @param string $currentVersion current version to upgrade to
  	 * @param string $installedVersion previous version from which to upgrade from
  	 *
  	 * @return bool true if the operation succeeded, false otherwise
  	 */
  	private function doUpgrade($currentVersion, $installedVersion) {
  		// Update htaccess files for apache hosts
  		if (isset($_SERVER['SERVER_SOFTWARE']) && strstr($_SERVER['SERVER_SOFTWARE'], 'Apache')) {
  			\OC_Setup::updateHtaccess();
  		}
837968727   Kload   [enh] Upgrade to ...
157
158
159
  		// create empty file in data dir, so we can later find
  		// out that this is indeed an ownCloud data directory
  		// (in case it didn't exist before)
f7d878ff1   kload   [enh] Update to 7...
160
  		file_put_contents(\OC_Config::getValue('datadirectory', \OC::$SERVERROOT . '/data') . '/.ocdata', '');
837968727   Kload   [enh] Upgrade to ...
161

a293d369c   Kload   Update sources to...
162
163
164
  		/*
  		 * START CONFIG CHANGES FOR OLDER VERSIONS
  		 */
6d9380f96   Cédric Dupont   Update sources OC...
165
  		if (!\OC::$CLI && version_compare($installedVersion, '6.90.1', '<')) {
837968727   Kload   [enh] Upgrade to ...
166
  			// Add the trusted_domains config if it is not existant
a293d369c   Kload   Update sources to...
167
  			// This is added to prevent host header poisoning
6d9380f96   Cédric Dupont   Update sources OC...
168
  			\OC_Config::setValue('trusted_domains', \OC_Config::getValue('trusted_domains', array(\OC_Request::serverHost())));
a293d369c   Kload   Update sources to...
169
  		}
6d9380f96   Cédric Dupont   Update sources OC...
170

a293d369c   Kload   Update sources to...
171
172
173
  		/*
  		 * STOP CONFIG CHANGES FOR OLDER VERSIONS
  		 */
6d9380f96   Cédric Dupont   Update sources OC...
174
175
176
  		// pre-upgrade repairs
  		$repair = new \OC\Repair(\OC\Repair::getBeforeUpgradeRepairSteps());
  		$repair->run();
a293d369c   Kload   Update sources to...
177

6d9380f96   Cédric Dupont   Update sources OC...
178
179
  		// simulate DB upgrade
  		if ($this->simulateStepEnabled) {
f7d878ff1   kload   [enh] Update to 7...
180
  			$this->checkCoreUpgrade();
6d9380f96   Cédric Dupont   Update sources OC...
181
182
  
  			// simulate apps DB upgrade
f7d878ff1   kload   [enh] Update to 7...
183
  			$this->checkAppUpgrade($currentVersion);
03e52840d   Kload   Init
184

03e52840d   Kload   Init
185
  		}
31b7f2792   Kload   Upgrade to ownclo...
186

6d9380f96   Cédric Dupont   Update sources OC...
187
188
189
190
191
192
  		// upgrade from OC6 to OC7
  		// TODO removed it again for OC8
  		$sharePolicy = \OC_Appconfig::getValue('core', 'shareapi_share_policy', 'global');
  		if ($sharePolicy === 'groups_only') {
  			\OC_Appconfig::setValue('core', 'shareapi_only_share_with_group_members', 'yes');
  		}
31b7f2792   Kload   Upgrade to ownclo...
193

6d9380f96   Cédric Dupont   Update sources OC...
194
  		if ($this->updateStepEnabled) {
f7d878ff1   kload   [enh] Update to 7...
195
  			$this->doCoreUpgrade();
03e52840d   Kload   Init
196

6d9380f96   Cédric Dupont   Update sources OC...
197
198
199
  			$disabledApps = \OC_App::checkAppsRequirements();
  			if (!empty($disabledApps)) {
  				$this->emit('\OC\Updater', 'disabledApps', array($disabledApps));
03e52840d   Kload   Init
200
  			}
f7d878ff1   kload   [enh] Update to 7...
201
202
  
  			$this->doAppUpgrade();
6d9380f96   Cédric Dupont   Update sources OC...
203
204
205
206
207
208
209
210
211
212
  
  			// post-upgrade repairs
  			$repair = new \OC\Repair(\OC\Repair::getRepairSteps());
  			$repair->run();
  
  			//Invalidate update feed
  			\OC_Appconfig::setValue('core', 'lastupdatedat', 0);
  
  			// only set the final version if everything went well
  			\OC_Config::setValue('version', implode('.', \OC_Util::getVersion()));
03e52840d   Kload   Init
213
  		}
03e52840d   Kload   Init
214
  	}
f7d878ff1   kload   [enh] Update to 7...
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
  
  	protected function checkCoreUpgrade() {
  		// simulate core DB upgrade
  		\OC_DB::simulateUpdateDbFromStructure(\OC::$SERVERROOT . '/db_structure.xml');
  
  		$this->emit('\OC\Updater', 'dbSimulateUpgrade');
  	}
  
  	protected function doCoreUpgrade() {
  		// do the real upgrade
  		\OC_DB::updateDbFromStructure(\OC::$SERVERROOT . '/db_structure.xml');
  
  		$this->emit('\OC\Updater', 'dbUpgrade');
  	}
  
  	/**
  	 * @param string $version the oc version to check app compatibilty with
  	 */
  	protected function checkAppUpgrade($version) {
  		$apps = \OC_App::getEnabledApps();
  
  
  		foreach ($apps as $appId) {
  			if ($version) {
  				$info = \OC_App::getAppInfo($appId);
  				$compatible = \OC_App::isAppCompatible($version, $info);
  			} else {
  				$compatible = true;
  			}
  
  			if ($compatible && \OC_App::shouldUpgrade($appId)) {
  				if (file_exists(\OC_App::getAppPath($appId) . '/appinfo/database.xml')) {
  					\OC_DB::simulateUpdateDbFromStructure(\OC_App::getAppPath($appId) . '/appinfo/database.xml');
  				}
  			}
  		}
  
  		$this->emit('\OC\Updater', 'appUpgradeCheck');
  	}
  
  	protected function doAppUpgrade() {
  		$apps = \OC_App::getEnabledApps();
  
  		foreach ($apps as $appId) {
  			if (\OC_App::shouldUpgrade($appId)) {
  				\OC_App::updateApp($appId);
  				$this->emit('\OC\Updater', 'appUpgrade', array($appId, \OC_App::getAppVersion($appId)));
  			}
  		}
  	}
31b7f2792   Kload   Upgrade to ownclo...
265
  }
a293d369c   Kload   Update sources to...
266