Test our new work-in-progress upgrader script

Yunohost is a FOSS self hosting platform based on Debian which also provides an interface for installing / removing webapps and an LDAP based single signon. I think the ynhpanel.js is to create a panel at the top allowing the user to logout, switch to the Yunohost admin panel etc.

They can be found at:
http://Yunohost.org and
https://GitHub.com/yunohost

Trying with the new index.php nowā€¦

1 Like

For the sake of completion:

Lukas kindly talked me through the update process. (Thanks again mate!)

Problem was caused by some rights being set by the installer too restrictive for shared hosting setups.

Solution was a less restrictive updater/index.php which is by now available from the initial donwload link in the first post. So no need to worry about my problems anymore :wink:

1 Like

So the request to /updater/ returns the following response headers:

HTTP/1.1 200 OK
Server: nginx
Date: Sun, 26 Jun 2016 18:04:47 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
X-SSO-WAT: You've just been SSOed
Set-Cookie: SSOwAuthRedirect=;; Path=/yunohost/sso/; Max-Age=Thu, Jan 01 1970 00:00:00 UTC;
Strict-Transport-Security: max-age=15768000;
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Robots-Tag: none
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none

Can you also post the response headers as well as the response body? I guess that YunoHost magically decides that youā€™re not authenticated anymore and redirects you to their authentication page ā€¦ or something like that ā€¦

OK, Iā€™m starting to get out of my depth here, but I reloaded the new script version (Iā€™m presuming it was still at the same URL) and reloaded. I got a 200 response and the following:

Request headers:

POST /updater/ HTTP/1.1
Host: MYDOMAIN.com
Connection: keep-alive
Content-Length: 0
requesttoken: ECJ3UWcwBwEfBRkSHTsuQXJ7P0AcRCpjdHgIZggEDUU=:DcNi+wPrlHNQlKbp00ryj4A/F/PRAI9592JncYoEIIY=
Origin: https://MYDOMAIN.com
X-Updater-Auth: pccuDvlMGOMA95D+CksG5w7n6pmqKCGpT+Gcvz0NZnUuler7ksnI0E9u296OVMXI
OCS-APIREQUEST: true
Accept: */*
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.86 Safari/537.36
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
Cookie: oc_sessionPassphrase=Poi91wZGJbRX03pxgx3sPxymzpjeE6ZS%2FzdPpmcObE%2FfhG3gjjDcKrp8FN%2Bid4IEUiEuLiW9JGlsspKAY7Kl6SqNkK%2FoHjHpMCQMLOFQCMdZOsolTj9gy8WVXThDBJpB; oc3seonmlmh9=h35b5oq6432fhfq38duujsvif0

Response headers:

HTTP/1.1 200 OK
Server: nginx
Date: Sun, 26 Jun 2016 18:16:11 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
X-SSO-WAT: You've just been SSOed
Set-Cookie: SSOwAuthRedirect=;; Path=/yunohost/sso/; Max-Age=Thu, Jan 01 1970 00:00:00 UTC;
Strict-Transport-Security: max-age=15768000;
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Robots-Tag: none
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none

Response:

<head>
	<style>
		html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, code, del, dfn, em, img, q, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, dialog, figure, footer, header, nav, section {
			margin: 0;
			padding: 0;
			border: 0;
			outline: 0;
			font-weight: inherit;
			font-size: 100%;
			font-family: inherit;
			vertical-align: baseline;
			cursor: default;
		}
		body {
			font-family: 'Open Sans', Frutiger, Calibri, 'Myriad Pro', Myriad, sans-serif;
			background-color: #ffffff;
			font-weight: 400;
			font-size: .8em;
			line-height: 1.6em;
			color: #000;
			height: auto;
		}
		a {
			border: 0;
			color: #000;
			text-decoration: none;
			cursor: pointer;
		}
		ul {
			list-style: none;
		}
		.output ul {
			list-style: initial;
			padding: 0 30px;
		}
		#header {
			position: fixed;
			top: 0;
			left: 0;
			right: 0;
			height: 45px;
			line-height: 2.5em;
			background-color: #0082c9;
			box-sizing: border-box;
		}
		.header-appname {
			color: #fff;
			font-size: 20px;
			font-weight: 300;
			line-height: 45px;
			padding: 0;
			margin: 0;
			display: inline-block;
			position: absolute;
			margin-left: 5px;
		}
		#header svg {
			margin: 5px;
		}

		#content-wrapper {
			position: absolute;
			height: 100%;
			width: 100%;
			overflow-x: hidden;
			padding-top: 45px;
			box-sizing: border-box;
		}

		#content {
			position: relative;
			height: 100%;
			margin: 0 auto;
		}
		#app-navigation {
			width: 250px;
			height: 100%;
			float: left;
			box-sizing: border-box;
			background-color: #fff;
			padding-bottom: 44px;
			-webkit-user-select: none;
			-moz-user-select: none;
			-ms-user-select: none;
			user-select: none;
			border-right: 1px solid #eee;
		}
		#app-navigation > ul {
			position: relative;
			height: 100%;
			width: inherit;
			overflow: auto;
			box-sizing: border-box;
		}
		#app-navigation li {
			position: relative;
			width: 100%;
			box-sizing: border-box;
		}
		#app-navigation li > a {
			display: block;
			width: 100%;
			line-height: 44px;
			min-height: 44px;
			padding: 0 12px;
			overflow: hidden;
			box-sizing: border-box;
			white-space: nowrap;
			text-overflow: ellipsis;
			color: #000;
			opacity: .57;
		}
		#app-navigation li:hover > a, #app-navigation li:focus > a {
			opacity: 1;
		}

		#app-content {
			position: relative;
			height: 100%;
			overflow-y: auto;
		}
		#progress {
			width: 600px;
		}
		.section {
			padding: 25px 30px;
		}
		.hidden {
			display: none;
		}

		li.step{
			-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=57)";
			opacity: .57;
		}

		li.step h2 {
			padding: 5px 2px 5px 30px;
			margin-top: 12px;
			margin-bottom: 0;
			-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=57)";
			opacity: .57;
			background-position:8px 50%;
			background-repeat: no-repeat;
		}

		li.current-step, li.passed-step, li.failed-step, li.waiting-step {
			-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
			opacity: 1;
		}

		li.current-step h2 {
			background-image: url(data:image/gif;base64,R0lGODlhEAAQAOMAAP///zMzM9HR0ZycnMTExK6url5eXnd3d9/f3+np6cnJyUpKSjY2Nv///////////yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCgAPACwAAAAAEAAQAAAETvDJ+UqhWA7JmCSZtIDdo4ChsTwlkWDG9Szb9yQEehgGkuUKGCpE/AEHyJqRECxKfBjEkJJ7fZhRycmHkwhA4CmG4EORQyfb4xuyPsSSCAAh+QQJCgAPACwAAAAAEAAQAAAEUvDJ+QqhWBa5lmSZZChPV4LhYZQLwmzUQD7GMIEJcT3EMCQZ3WwyEISORx1BoVAmhcgJIoPYYXRAic5ImT6a05xEcClbg9MdwYtpasfnSZYXigAAIfkECQoADwAsAAAAABAAEAAABFDwyfkIoVgqaYxcmTQgT1eCYTGURrJcTyIR5DPAD1gwjCRYMgwPNaGFaqGMhaBQLJPLTXKCpOIowCJBgKk5SQnYr1K5YowwY8Y585klQXImAgAh+QQJCgAPACwAAAAAEAAQAAAEUPDJ+YSgWCI5hjSZRCRP9xxgqBDlkBjsQz7ERtsPSCyLJBCjDC81qYVmoQxjuVgBk0tGLznBVWMYIBJ4odhWm0TsR6NhM8aYMbMS+c6TbSgCACH5BAkKAA8ALAAAAAAQABAAAARQ8Mn5EKJY3leKHJlEJJw3gKFClMmwkQ+xyRNIGIYkEGOGHxhaBhbKLI4GFa94XOSKtQxilWEwPCKCALNZMEAJ6i4Wo4ZoVCFGJdKZKcT3JAIAIfkECQoADwAsAAAAABAAEAAABFDwyflSolgiSYgsGXd1DwGGitclxVZxLuGWDzIMkrBmN07JoUsoZCgeUiSicUjxURCezGIRLREEmAHWsMAlojoag8EERhlOSoojMZAzQlomAgAh+QQJCgAPACwAAAAAEAAQAAAEUPDJ+VKiWCJJCM/c1T2KB5ZPlxBXxW0pnFbjI6hZp2CETLWgzGBYKNWExCBlkEGYMAbDsyPAFKoHQ4EmuT0Yj8VC2ftKFswMyvw4jDNAcCYCACH5BAkKAA8ALAAAAAAQABAAAARQ8Mn5UqJYIkkIz9zVPYoHlk+XEFfFbSmcVuMjqFmnYIRMtaCcrlQTEnbBiYmCWFIGA1lHwNtAdyuJgfFYPAyGJGPQ1RZAC275cQhnzhJvJgIAIfkECQoADwAsAAAAABAAEAAABFHwyflSolgiSQjP3NU9igeWT5cQV8VtKZxW4yOoWadghEy1oJyuVBMSdsGJTzJggHASBsOAEVxKm4LzcVg8qINBciGmPgZIjMH7lRTEuYkZEwEAIfkECQoADwAsAAAAABAAEAAABE/wyflSolgiSQjP3NU9igeWT5cQV8VtKZxW4yOoWadghEy1oJyOQWQEO4RdcOKTDBYgnGSxOGAQl9KGAH0cDI9BygQyFMKvMhhtI1PI4kwEACH5BAkKAA8ALAAAAAAQABAAAARQ8Mn5UqJYIkkIz9zVPYoHlk+XEFclMQO3fatpMIyQdQoGgy3QjofDCTuEnnAyoxQMINXEYDhgEJfShgB9FGKekXDQMxGalEEsJRGYrpM3JQIAIfkEAQoADwAsAAAAABAAEAAABFHwyflSolgOSQjPEuN1j+KBC/N0CXFV0rI9zDF57XksC5J1CsyiAHqBfkCD0nDsEILHiQ+jmGFYk8GASEFcTD7ETDBanUAE3ykNMn0e5OINFAEAOw==);
		}

		li.current-step h2, li.passed-step h2, li.failed-step h2, li.waiting-step h2 {
			-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
			opacity: 1;
		}

		li.passed-step h2 {
			background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAWlBMVEUAAAAAqgAAvwAA1QAA3wAAxgAA0QAA1QAAzgAA0QAA1gAA1gAA1wAA1gAA0gAA1QAA1AAA1AAA1AAA1QAA0wAA1AAA1AAA1QAA0wAA1AAA1AAA1QAA1AAA1ACEAd/9AAAAHXRSTlMAAwQGCAkLDBUWGR8gLC2osrO3uru9v9LT1Nfq+K5OpOQAAABPSURBVBiVpYq3EYAwEMBEfnJONr//mhSYI5SgTifBPyLv5UPtP11tAZDI4b3aEiCeTAYErdoKAFl0TQk71wGZ1eTN2d2zXd09tw4gY8l3dg+HBDK71PO7AAAAAElFTkSuQmCC);
		}

		li.failed-step {
			background-color: #ffd4d4;
		}
		li.failed-step h2 {
			color: #000;
			background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAPFBMVEUAAACqAADMAADVAADVAADVAADVAADWAADWAADUAADUAADUAADVAADUAADTAADVAADUAADVAADUAADUAACCP69rAAAAE3RSTlMAAwUGDCorMjiHpaeosdPk6ervRw2uZQAAAERJREFUeAFjIA4w8QoDgRA7jM/ILQwGgmxQPheQw8HAJywswAoW4BSGCQjzM4MEeBACwizECiAAC4ah6NZiOgzT6YQBABtYB8QyiY2BAAAAAElFTkSuQmCC);
		}

		li.step .output {
			position: relative;
			padding: 5px 5px 5px 32px;
		}

		h2 {
			font-size: 20px;
			font-weight: 300;
			margin-bottom: 12px;
			color: #555;
		}

		button, a.button {
			font-family: 'Open Sans', Frutiger, Calibri, 'Myriad Pro', Myriad, sans-serif;
			font-size: 13px;
			font-weight: 600;
			color: #555;
			margin: 3px 3px 3px 0;
			padding: 5px;
			background-color: rgba(255, 255, 255, .95);
			border-radius: 3px;
			border: 1px solid rgba(240,240,240,.9);
			cursor: pointer;
			outline: none;
		}

		button:hover, button:focus, a.button:hover, a.button:focus {
			background-color: rgba(240,240,240,.9);
			color: #111;
		}

		code {
			font-family: monospace;
			font-size: 1.2em;
			background-color: #eee;
			border-radius: 2px;
			padding: 2px 6px 2px 4px;
		}

		#login code {
			display: block;
			border-radius: 3px;
		}

		#login form {
			margin-top: 5px;
		}

		#login input {
			padding: 5px;
			border-radius: 3px;
			border: 1px solid rgba(240,240,240,.9);
		}

	</style>
<script type="text/javascript" src="/ynhpanel.js"></script></head>
<body>
<div id="header">
	<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xml:space="preserve" height="34" width="62" enable-background="new 0 0 196.6 72" y="0px" x="0px" viewBox="0 0 62.000002 34"><path style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;image-rendering:auto;white-space:normal;text-indent:0;enable-background:accumulate;text-transform:none;text-decoration-style:solid" fill="#fff" d="m31.6 4.0001c-5.95 0.0006-10.947 4.0745-12.473 9.5549-1.333-2.931-4.266-5.0088-7.674-5.0092-4.6384 0.0005-8.4524 3.8142-8.453 8.4532-0.0008321 4.6397 3.8137 8.4544 8.4534 8.455 3.4081-0.000409 6.3392-2.0792 7.6716-5.011 1.5261 5.4817 6.5242 9.5569 12.475 9.5569 5.918 0.000457 10.89-4.0302 12.448-9.4649 1.3541 2.8776 4.242 4.9184 7.6106 4.9188 4.6406 0.000828 8.4558-3.8144 8.4551-8.455-0.000457-4.6397-3.8154-8.454-8.4551-8.4533-3.3687 0.0008566-6.2587 2.0412-7.6123 4.9188-1.559-5.4338-6.528-9.4644-12.446-9.464zm0 4.9623c4.4687-0.000297 8.0384 3.5683 8.0389 8.0371 0.000228 4.4693-3.5696 8.0391-8.0389 8.0388-4.4687-0.000438-8.0375-3.5701-8.0372-8.0388 0.000457-4.4682 3.5689-8.0366 8.0372-8.0371zm-20.147 4.5456c1.9576 0.000226 3.4908 1.5334 3.4911 3.491 0.000343 1.958-1.533 3.4925-3.4911 3.4927-1.958-0.000228-3.4913-1.5347-3.4911-3.4927 0.0002284-1.9575 1.5334-3.4907 3.4911-3.491zm40.205 0c1.9579-0.000343 3.4925 1.533 3.4927 3.491 0.000457 1.9584-1.5343 3.493-3.4927 3.4927-1.958-0.000228-3.4914-1.5347-3.4911-3.4927 0.000221-1.9575 1.5335-3.4907 3.4911-3.491z"/></svg>
	<h1 class="header-appname">Nextcloud Updater</h1>
</div>
<input type="hidden" id="updater-access-key" value="pccuDvlMGOMA95D+CksG5w7n6pmqKCGpT+Gcvz0NZnUuler7ksnI0E9u296OVMXI"/>
<input type="hidden" id="updater-endpoint" value="/updater/"/>
<input type="hidden" id="updater-step-start" value="0" />
<div id="content-wrapper">
	<div id="content">

		<div id="app-navigation">
			<ul>
				<li><a href="#progress">Update</a></li>
			</ul>
		</div>
		<div id="app-content">
					<ul id="progress" class="section">
				<li id="step-init" class="step icon-loading passed-step">
					<h2>Initializing</h2>
					<div class="output">Current version is 9.0.2.<br>
						Update to Nextcloud 9.0.51 available.<br>

													<button id="startUpdateButton">Start update</button>
													</div>
				</li>
				<li id="step-check-files" class="step ">
					<h2>Check for expected files</h2>
					<div class="output hidden"></div>
				</li>
				<li id="step-check-permissions" class="step ">
					<h2>Check for write permissions</h2>
					<div class="output hidden"></div>
				</li>
				<li id="step-enable-maintenance" class="step ">
					<h2>Enable maintenance mode</h2>
					<div class="output hidden"></div>
				</li>
				<li id="step-backup" class="step ">
					<h2>Create backup</h2>
					<div class="output hidden"></div>
				</li>
				<li id="step-download" class="step ">
					<h2>Downloading</h2>
					<div class="output hidden"></div>
				</li>
				<li id="step-extract" class="step ">
					<h2>Extracting</h2>
					<div class="output hidden"></div>
				</li>
				<li id="step-entrypoints" class="step ">
					<h2>Replace entry points</h2>
					<div class="output hidden"></div>
				</li>
				<li id="step-delete" class="step ">
					<h2>Delete old files</h2>
					<div class="output hidden"></div>
				</li>
				<li id="step-move" class="step ">
					<h2>Move new files in place</h2>
					<div class="output hidden"></div>
				</li>
				<li id="step-maintenance-mode" class="step ">
					<h2>Keep maintenance mode active?</h2>
					<div class="output hidden">
						<button id="maintenance-enable">Yes (for usage with command line tool)</button>
						<button id="maintenance-disable">No (for usage of the web based updater)</button>
					</div>
				</li>
				<li id="step-done" class="step ">
					<h2>Done</h2>
					<div class="output hidden">
						<a class="button" href="/updater/../">Go to back to your Nextcloud instance to finish the update</a>
					</div>
				</li>
			</ul>
				</div>
	</div>
</div>

</body>
	<script>
		var done = false;
		var started = false;
		var updaterStepStart = parseInt(document.getElementById('updater-step-start').value);
		function addStepText(id, text) {
			var el = document.getElementById(id);
			var output =el.getElementsByClassName('output')[0];
			if(typeof text === 'object') {
				text = JSON.stringify(text);
			}
			output.innerHTML = output.innerHTML + text;
			output.classList.remove('hidden');
		}

		function currentStep(id) {
			var el = document.getElementById(id);
			el.classList.remove('failed-step');
			el.classList.remove('passed-step');
			el.classList.remove('waiting-step');
			el.classList.add('current-step');
		}

		function errorStep(id) {
			var el = document.getElementById(id);
			el.classList.remove('passed-step');
			el.classList.remove('current-step');
			el.classList.remove('waiting-step');
			el.classList.add('failed-step');
		}

		function successStep(id) {
			var el = document.getElementById(id);
			el.classList.remove('failed-step');
			el.classList.remove('current-step');
			el.classList.remove('waiting-step');
			el.classList.add('passed-step');
		}

		function waitingStep(id) {
			var el = document.getElementById(id);
			el.classList.remove('failed-step');
			el.classList.remove('current-step');
			el.classList.remove('passed-step');
			el.classList.add('waiting-step');
		}

		function performStep(number, callback) {
			started = true;
			var httpRequest = new XMLHttpRequest();
			httpRequest.open('POST', document.getElementById('updater-endpoint').value);
			httpRequest.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
			httpRequest.setRequestHeader('X-Updater-Auth', document.getElementById('updater-access-key').value);
			httpRequest.onreadystatechange = function () {
				if (httpRequest.readyState != 4) { // 4 - request done
					return;
				}

				if (httpRequest.status != 200) {
					// failure
				}

				if(httpRequest.responseText.substr(0,1) !== '{') {
					// it seems that this is not a JSON object
					var response = {
						processed: false,
						response: 'Parsing response failed. ' + httpRequest.responseText
					};
					callback(response);
				} else {
					// parse JSON
					callback(JSON.parse(httpRequest.responseText));
				}

			};
			httpRequest.send("step="+number);
		}


		var performStepCallbacks = {
			0: function() { // placeholder that is called on start of the updater
				currentStep('step-check-files');
				performStep(1, performStepCallbacks[1]);
			},
			1: function(response) {
				if(response.proceed === true) {
					successStep('step-check-files');
					currentStep('step-check-permissions');
					performStep(2, performStepCallbacks[2]);
				} else {
					errorStep('step-check-files');

					var text = 'The following extra files have been found:<ul>';
					response['response'].forEach(function(file) {
						text += '<li>' + file + '</li>';
					});
					text += '</ul>';
					addStepText('step-check-files', text);
				}
			},
			2: function(response) {
				if(response.proceed === true) {
					successStep('step-check-permissions');
					currentStep('step-enable-maintenance');
					performStep(3, performStepCallbacks[3]);
				} else {
					errorStep('step-check-permissions');

					var text = 'The following places can not be written to:<ul>';
					response['response'].forEach(function(file) {
						text += '<li>' + file + '</li>';
					});
					text += '</ul>';
					addStepText('step-check-permissions', text);
				}
			},
			3: function(response) {
				if(response.proceed === true) {
					successStep('step-enable-maintenance');
					currentStep('step-backup');
					performStep(4, performStepCallbacks[4]);
				} else {
					errorStep('step-enable-maintenance');

					if(response.response) {
						addStepText('step-enable-maintenance', response.response);
					}
				}
			},
			4: function (response) {
				if (response.proceed === true) {
					successStep('step-backup');
					currentStep('step-download');
					performStep(5, performStepCallbacks[5]);
				} else {
					errorStep('step-backup');

					if(response.response) {
						addStepText('step-backup', response.response);
					}
				}
			},
			5: function (response) {
				if (response.proceed === true) {
					successStep('step-download');
					currentStep('step-extract');
					performStep(6, performStepCallbacks[6]);
				} else {
					errorStep('step-download');

					if(response.response) {
						addStepText('step-download', response.response);
					}
				}
			},
			6: function (response) {
				if (response.proceed === true) {
					successStep('step-extract');
					currentStep('step-entrypoints');
					performStep(7, performStepCallbacks[7]);
				} else {
					errorStep('step-extract');

					if(response.response) {
						addStepText('step-extract', response.response);
					}
				}
			},
			7: function (response) {
				if (response.proceed === true) {
					successStep('step-entrypoints');
					currentStep('step-delete');
					performStep(8, performStepCallbacks[8]);
				} else {
					errorStep('step-entrypoints');

					if(response.response) {
						addStepText('step-entrypoints', response.response);
					}
				}
			},
			8: function (response) {
				if (response.proceed === true) {
					successStep('step-delete');
					currentStep('step-move');
					performStep(9, performStepCallbacks[9]);
				} else {
					errorStep('step-delete');

					if(response.response) {
						addStepText('step-delete', response.response);
					}
				}
			},
			9: function (response) {
				if (response.proceed === true) {
					successStep('step-move');

					waitingStep('step-maintenance-mode');
					// show buttons to decide on maintenance mode
					var el = document.getElementById('step-maintenance-mode')
						.getElementsByClassName('output')[0];
					el.classList.remove('hidden');
				} else {
					errorStep('step-move');

					if(response.response) {
						addStepText('step-move', response.response);
					}
				}
			},
			10: function (response) {
				if (response.proceed === true) {
					successStep('step-maintenance-mode');
					currentStep('step-done');
					performStep(11, performStepCallbacks[11]);
				} else {
					errorStep('step-maintenance-mode');

					if(response.response) {
						addStepText('step-maintenance-mode', response.response);
					}
				}
			},
			11: function (response) {
				if (response.proceed === true) {
					successStep('step-done');

					// show button to get to the web based migration steps
					var el = document.getElementById('step-done')
						.getElementsByClassName('output')[0];
					el.classList.remove('hidden');
				} else {
					errorStep('step-done');
				}
				done = true;
			},
		};

		function startUpdate() {
			performStepCallbacks[updaterStepStart]({
				proceed: true
			});
		}

		function askForMaintenance(keepActive) {
			var el = document.getElementById('step-maintenance-mode')
				.getElementsByClassName('output')[0];
			if (keepActive) {
				el.innerHTML = 'Maintenance mode will kept active.<br>Now trigger the migration via command line: <code>./occ upgrade</code><br>';
				successStep('step-maintenance-mode');
				currentStep('step-done');
				performStep(11, performStepCallbacks[11]);
			} else {
				el.innerHTML = 'Maintenance mode will get disabled.<br>';
				currentStep('step-maintenance-mode');
				performStep(10, performStepCallbacks[10]);
			}
		}

		if(document.getElementById('startUpdateButton')) {
			document.getElementById('startUpdateButton').onclick = function (e) {
				e.preventDefault();
				startUpdate();
			};
		}
		if(document.getElementById('maintenance-enable')) {
			document.getElementById('maintenance-enable').onclick = function (e) {
				e.preventDefault();
				askForMaintenance(true);
			};
		}
		if(document.getElementById('maintenance-disable')) {
			document.getElementById('maintenance-disable').onclick = function (e) {
				e.preventDefault();
				askForMaintenance(false);
			};
		}

		// Show a popup when user tries to close page
		window.onbeforeunload = confirmExit;
		function confirmExit() {
			if (done === false && started === true) {
				return 'Update is in progress. Are you sure, you want to close?';
			}
		}
	</script>

Downloaded the new script and it worked flawlessly. Now I have a brand new Nextcloud 9.0.51.

Thank you, @LukasReschke!

1 Like

This seems in fact to be triggered by YunoHost. There doesnā€™t seem that much that we can do here except add some more error handling and fail gracefullyā€¦ One could probably tune the YunoHost config but I donā€™t really have any experience with it.

I guess Iā€™m just surprised Yunohost could be screwing things up given that the Yunohost javascript file isnā€™t even loaded (itā€™s a 404). Iā€™ll contact the Yunohost people though and see if thereā€™s a way to disable ynhpanel.js being includedā€¦

Tested on a clean Nextcloud 9.0.50 install inside a docker container.
(Nextcloud image build based on official Ubuntu 16.04 docker image)
Worked fine.

So, I ended up doing a manual upgrade which seemed to go just fine. Only the contents of the data folder and the config folder were copied across, hopefully eliminating the modifications that Yunohost made to the original ownCloud 9.0.2 files. Now Iā€™m the proud owner of a shiny new Nextcloud 9.0.51 instance. Going to the update page though shows me this:

I mean, I know Nextcloud development is going fast, but I think I must have missed the release notes for the past 91 versionsā€¦

1 Like

Daily always has the version number 100. Thatā€™s a small hack, will add a custom detection for that :wink:

maybe they fixed some small bugs carried from owncloud

OK, so thatā€™s expected and still safe to upgrade to then, right?

It is a daily. So there is no guarantee, that it is stable :wink: Beside that the update process itself is fine, but the version you upgrade to could possibly a bit unstable. Only do this when you know how to change the files on your server manually afterwards (just in case).

Well, yes, I get the daily thing. Had to hear that the version number itself isnā€™t indicative of a problem though. :wink:

Hi all, Hi @LukasReschke :slight_smile:

I want to share my experiences and findings with the updater so far - first and foremost this is to see, if I configured everything as I should have, because it doesnā€™t really work as it should I think.

for the test I had

'updater.release.channel' => 'daily',

in my config and ā€œdailyā€ as update channel.

  • The update went fine
  • but ever since I saw a top bar banner telling me ā€œA new version is available. Click here to learn on how to upgradeā€
  • please note!! This text was in English despite the language of NC been set to German
  • the admin page, too, told me a new version being available,
  • but clicking on the link and calling the the updater it told me ā€œno new version availableā€

Long story short: after upgrading to 9.0.51 and stying on the ā€œdailyā€ channel NC was not updated anymore.

Three hours ago switched the update channel back to stable:
- as of now no update option to 9.0.52 is available.

  • update option to 9.0.52 is now available. :slight_smile:

So much for now, thx for listening :slight_smile:

John

Hi ,

Just wanna confirm that I successfully updated Nextcloud from 9.0.51 to 9.0.52 without any issues. That is just amazing because I had to update OC since version 7 or earlier always manually.
The only thing I had to do afterwards was to switch on few apps and I had to adjust the .htaccess since I added there some more information.

Thumbs up from my side. :+1:

The only question I have is about the backup that was done during the update. What happens to the backup files/folder, are they going to stay until I am deleting them manually or do they get cleaned up (cron or next update) after some time?

Thanks again.

Good work.

Hello there, I am trying to update through /updater, but have the following issues.

To start with, it stated that I had the following:

In my /nextcloud folder was a /assets directory, which was empty so I moved that and then the updater was able to progress to the following:

My /updater folder is www-data:www-data, but then looking at some of my other directories (such as /nextcloud/lib/) they were root:www-data. I changed -R /nextcloud to www-data:www-data and it worked!

1 Like

Just a short update: despite version 9.0.52 being displayed as available, the update proccess will not work.

I can go to the update page and still see: you are running 9.0.51 - version 9.0.52 is available as well as the button ā€œContinue Updateā€.

Itā€™s just: clicking it only shows another button ā€œClick here to finishā€ ā€¦but NOTHING happens between these two clicks.

John

Edit: ok, I could do with some help here: has anyone a clue, what could possibly cause the ā€œContinue Updateā€ button to behave the way it does (nothing)?
Any idea anyone?

So I tried looking (although to be fair, pretty quickly) and didnā€™t find anyone else whoā€™d posted this but:

The updater resets the Maximum upload size back to default - itā€™d be nice if that (and potentially other values) get pulled prior to upgrade so they can be applied when the file is overwritten.