Ostree Software Updates #2884

Closed
wants to merge 1 commit into
from

Projects

None yet

4 participants

@petervo
Contributor
petervo commented Oct 1, 2015

To test, from inside the cockpit test directory run.

TEST_OS=fedora-atomic-22 ./testsuite-prepare

The generated image will have versions of ostree and rpm-ostree that work. It also contains a checked out copy of the current os at /var/local-tree and repo at /var/local-repo. You can run this image with vm-run and make changes to that tree and commit to that repo.

To make testing simplier there is a temporary ostree-run command.

./ostree-run

That will run the vm and gives you three commands

  • start-cockpit: Starts cockpit, needs to be run after every reboot.
  • start-httpd: Starts a http server on the local repo to allow you to pull updates. Until it is started you'll see errors when trying to check for updates. Doesn't persist between reboots.
  • prep-upgrade: This creates a new upgrade that installs a package, removes a package, upgrades a package and downgrades a package. This command should only be run once. If you want further updates you'll need to generate them yourself.

Because you'll probably be restarting the vm while testing running

virsh console id-from-ouput

will let you see when the machine has rebooted and is ready to accept commands again.

@petervo petervo referenced this pull request Oct 1, 2015
Closed

WIP: Rpm OSTree updates #2281

@petervo petervo added the needswork label Oct 1, 2015
@petervo
Contributor
petervo commented Oct 9, 2015

Still needs a little bit of work, but ready for initial review. It should now be testable with the fedora-atomic-22 vm we use for testing.

@petervo
Contributor
petervo commented Oct 13, 2015

@stefwalter @andreasn, instructions for manual testing are added at the top. LMK if you have questions.

@stefwalter
Contributor
@andreasn
Contributor

The spacing in top of this error looks a bit off.

screenshot from 2015-10-13 23-04-15

@andreasn
Contributor

The listing of all packages is very long and easily pushes down the box below quite a lot.
How do you feel about giving listing-body the properties height: 200px and overflow-y: scroll; ?

@andreasn
Contributor

The checking for updates text that appears briefly feels a bit twitchy. Maybe it just works to disable the button in that case since it appears so briefly.

@petervo
Contributor
petervo commented Oct 13, 2015

On 10/13/2015 02:31 PM, andreasn wrote:

The checking for updates text that appears briefly feels a bit twitchy.
Maybe it just works to disable the button in that case since it appears
so briefly.


Reply to this email directly or view it on GitHub
#2884 (comment).

It's only like that if there is nothing to pull otherwise it looks good.
But of course we don't know that till after we pull. We can put in on a
delay but of course there is no guarantee that it won't finish right
after the delay expires. So not sure what the solution is.

@petervo
Contributor
petervo commented Oct 13, 2015

The listing of all packages is very long and easily pushes down the box
below quite a lot.
How do you feel about giving listing-body the properties height: 200px
and overflow-y: scroll; ?

@stefwalter, design specifically said not to add scrolling. WDYT?

@andreasn
Contributor

design specifically said not to add scrolling.

If that's by design, I'm OK with that.

@andreasn
Contributor

We can put in on a delay but of course there is no guarantee that it won't finish right after the delay expires. So not sure what the solution is.

What if you put the message inside the listing-head div and make it go on the left of the box?

@andreasn
Contributor

Played around with the HTML and css a bit.
If the error message is put inside the listing-head div and gets a css property of display: inline; it looks a bit more balanced.

screenshot from 2015-10-16 15-54-33

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/base1/cockpit.css
@@ -742,6 +742,20 @@ tbody.active .listing-head {
clear: right;
}
+div.listing-maybe .listing-error {
@stefwalter
stefwalter Oct 20, 2015 Contributor

Could you add an example of how to use these styles to the playground/patterns.html?

@stefwalter
stefwalter Oct 20, 2015 Contributor

And this is worth merging early as a separate pull request, so others can make use of it.

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/ostree/app.js
@@ -0,0 +1,328 @@
+define([
+ "jquery",
+ "base1/cockpit",
+ "base1/angular",
+ "base1/moment",
+ "ostree/client",
+], function($, cockpit, angular, moment, client) {
+ 'use strict';
+
+ var _ = cockpit.gettext;
+ var phantom_checkpoint = phantom_checkpoint || function () { };
+
+ function track(item) {
@stefwalter
stefwalter Oct 20, 2015 Contributor

This function has a name that makes me think it does something different than what it does.

@stefwalter stefwalter commented on the diff Oct 20, 2015
pkg/ostree/app.js
+ return;
+
+ var key = item.osname.v;
+ if (item.id)
+ key = key + item.id.v;
+
+ if (item.checksum)
+ key = key + item.checksum.v;
+
+ return key;
+ }
+
+ function notify_result(promise, scope) {
+ promise
+ .progress(function(msg) {
+ scope.$applyAsync(function() {
@stefwalter
stefwalter Oct 20, 2015 Contributor

applyAsync is nice. I didn't know it existed.

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/ostree/app.js
+ });
+ });
+ }
+
+
+ return angular.module('ostree', [
+ 'ngRoute',
+ ])
+ .config([
+ '$routeProvider',
+ function($routeProvider) {
+ $routeProvider.when('/', {
+ templateUrl: 'index.html',
+ controller: 'indexController'
+ });
+ }])
@stefwalter
stefwalter Oct 20, 2015 Contributor

The brace should move one line up to align with 'function'

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/ostree/app.js
+ var message = null;
+ if (ex.problem === "access-denied")
+ message = _("Not authorized to update software on this system");
+ else
+ message = cockpit.message(ex);
+
+ $scope.curtains = { state: 'failed',
+ failure: ex,
+ message: message };
+ $scope.$digest();
+ phantom_checkpoint();
+ }
+
+ function check_empty() {
+ if (timeout)
+ window.clearTimeout(timeout);
@stefwalter
stefwalter Oct 20, 2015 Contributor

clearTimeout can be explicitly called with null, no need for the if.

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/ostree/app.js
+ '$scope',
+ '$timeout',
+ 'ostreeClient',
+ function($scope, $timeout, client) {
+ function show_failure(ex) {
+ var message = null;
+ if (ex.problem === "access-denied")
+ message = _("Not authorized to update software on this system");
+ else
+ message = cockpit.message(ex);
+
+ $scope.curtains = { state: 'failed',
+ failure: ex,
+ message: message };
+ $scope.$digest();
+ phantom_checkpoint();
@stefwalter
stefwalter Oct 20, 2015 Contributor

Suggest implementing a helper function for doing these two together. Either that, or figure out a way to call phantom_checkpoint() globally for any digest.

@stefwalter stefwalter and 1 other commented on an outdated diff Oct 20, 2015
pkg/ostree/index.html
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
+-->
+<html>
+
+<head>
+ <title>Software Updates</title>
+ <meta charset="utf-8">
+ <link href="../base1/cockpit.css" rel="stylesheet">
+ <link href="../ostree/ostree.css" rel="stylesheet">
+ <script src="../base1/bundle.js"></script>
+ <script src="../ostree/ostree.js"></script>
+</head>
+<body>
@stefwalter
stefwalter Oct 20, 2015 Contributor

Body should be hidden until curtains != silent. Well either that, or just explictly show it without involving angularjs.

@petervo
petervo Oct 20, 2015 Contributor

Are you sure, kube doesn't do that. ng-cloak and the curtains logic is on the main div inside the body, everything else is in a script tag which won't show.

If we want to use angular on the body we probably have to move the mainController.

@stefwalter
stefwalter Oct 20, 2015 Contributor

Our index.html framing wants to see body appear when the page is ready. This leads to less flicker, and allows the framing spinner to work properly. So in general we should move towards doing it that way. Unless it's dumb and broken ... in which case we should change index.html and come up with a new pattern.

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/ostree/app.js
+
+ $scope.curtains = { state: 'silent' };
+ var timeout = window.setTimeout(function() {
+ $scope.curtains = { state: 'connecting' };
+ $scope.$digest();
+ timeout = null;
+ }, 1000);
+
+ function handle(promise) {
+ promise
+ .always(function() {
+ window.clearTimeout(timeout);
+ timeout = null;
+ })
+ .done(function(connection) {
+ $(client).on("connectionLost.main", function(event, ex) {
@stefwalter
stefwalter Oct 20, 2015 Contributor

For multiple reconnects theseh event handlers will be connected multiple times. Why not just connect them once?

@stefwalter stefwalter commented on the diff Oct 20, 2015
pkg/ostree/app.js
+
+ $scope.itemMatches = function(item, proxy_arg) {
+ return client.item_matches(item, proxy_arg);
+ };
+
+ client.connect().
+ done(function () {
+ $(client).on("changed.ostreeIndex", function() {
+ $scope.runningMethod = client.running_method;
+ $scope.os_list = client.os_list;
+ $scope.$digest();
+ });
+
+ $scope.$applyAsync(function() {
+ $scope.runningMethod = client.running_method;
+ $scope.os_list = client.os_list;
@stefwalter
stefwalter Oct 20, 2015 Contributor

No phantom_checkpoint()?

@stefwalter
stefwalter Oct 20, 2015 Contributor

Should we just $scope.$watch(function() { phantom_checkpoint() }); ?

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/ostree/app.js
+ return angular.module('ostree', [
+ 'ngRoute',
+ ])
+ .config([
+ '$routeProvider',
+ function($routeProvider) {
+ $routeProvider.when('/', {
+ templateUrl: 'index.html',
+ controller: 'indexController'
+ });
+ }])
+
+ .controller('mainController', [
+ '$scope',
+ '$timeout',
+ 'ostreeClient',
@stefwalter
stefwalter Oct 20, 2015 Contributor

Why not just use the client global?

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/ostree/app.js
+ }])
+
+ /* Override the default angularjs exception handler */
+ .factory('$exceptionHandler', ['$log', function($log) {
+ return function(exception, cause) {
+
+ /* Displays an oops if we're running in cockpit */
+ cockpit.oops();
+
+ /* And log with the default implementation */
+ $log.error.apply($log, arguments);
+ };
+ }])
+
+ .factory('ostreeClient', [function() {
+ return client;
@stefwalter
stefwalter Oct 20, 2015 Contributor

Why not just use the client global? and leave this factory out?

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/ostree/app.js
+ };
+
+ scope.doUpgrade = function(os) {
+ scope.error = null;
+ var args = {
+ "reboot" : cockpit.variant("b", true)
+ };
+ var promise = client.run_transaction("Upgrade", [args], os);
+ notify_result(promise, scope);
+ };
+ }
+ };
+ }
+ ])
+
+ .filter('packages', ["$filter", function() {
@stefwalter
stefwalter Oct 20, 2015 Contributor

Why is $filter needed here?

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/ostree/app.js
+ var promise = client.run_transaction("Upgrade", [args], os);
+ notify_result(promise, scope);
+ };
+ }
+ };
+ }
+ ])
+
+ .filter('packages', ["$filter", function() {
+ return function(number) {
+ var format = cockpit.ngettext(_("$0 package"), _("$0 packages"), number);
+ return cockpit.format(format, number);
+ };
+ }])
+
+ .filter('releaseName', ["$filter", function() {
@stefwalter
stefwalter Oct 20, 2015 Contributor

Why $filter?

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/ostree/client.js
@@ -0,0 +1,513 @@
+define(["jquery",
@stefwalter
stefwalter Oct 20, 2015 Contributor

Can we put these on the next line, indented 4 spaces?

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/ostree/client.js
@@ -0,0 +1,513 @@
+define(["jquery",
+ "base1/cockpit",
+], function($, cockpit) {
+ "use strict";
@stefwalter
stefwalter Oct 20, 2015 Contributor

Indentation.

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/ostree/client.js
+ var DEST = 'org.projectatomic.rpmostree1';
+ var PATH = '/org/projectatomic/rpmostree1';
+
+ var SYSROOT = 'org.projectatomic.rpmostree1.Sysroot';
+ var SYSROOT_PATH = '/org/projectatomic/rpmostree1/Sysroot';
+
+ var OS = 'org.projectatomic.rpmostree1.OS';
+ var TRANSACTION = 'org.projectatomic.rpmostree1.Transaction';
+
+ /*
+ * Breaks down progress messages into
+ * a string that can be displayed
+ * Similar to the cli output but simplier.
+ * We don't display object counts or bytes/s.
+ * Percentages are only possible when
+ * we actually know what is going to be pulled
@stefwalter
stefwalter Oct 20, 2015 Contributor

Can we have a description of the structs/tuples involved in this comment?

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/ostree/client.js
+ empty = false;
+ }
+
+ self.empty = empty;
+ self.valid = true;
+ })
+ .fail(function(ex) {
+ self.error = cockpit.message(ex);
+ })
+ .always(function() {
+ self.ready = true;
+ $(self).triggerHandler("changed");
+ });
+ }
+
+ function RPMOSTreeDbusClient() {
@stefwalter
stefwalter Oct 20, 2015 Contributor

Capital 'B'?

@stefwalter stefwalter and 1 other commented on an outdated diff Oct 20, 2015
pkg/ostree/client.js
+ }
+ } else {
+ console.warn("Unexpected transaction response", args);
+ fail({ "problem": "protocol-error" });
+ }
+ }
+ });
+ transaction_client.call("/", TRANSACTION, "Start");
+ });
+ });
+
+ return dp;
+ };
+ }
+
+ return new RPMOSTreeDbusClient();
@stefwalter
stefwalter Oct 20, 2015 Contributor

We haven't done this before. But now come to think of it, it's a great way to do a singleton without the nonsense we do in kubernetes/client.js

Are there any downsides that you know about?

@petervo
petervo Oct 20, 2015 Contributor

I couldn't think of any off the top of my head

@stefwalter
stefwalter Oct 20, 2015 Contributor

Can you comment that that this is a singleton, above the return.

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/ostree/index.html
+under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+Cockpit is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
+-->
+<html>
+
+<head>
+ <title>Software Updates</title>
@stefwalter
stefwalter Oct 20, 2015 Contributor

translatable.

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/ostree/index.html
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
+-->
+<html>
+
+<head>
+ <title>Software Updates</title>
+ <meta charset="utf-8">
+ <link href="../base1/cockpit.css" rel="stylesheet">
+ <link href="../ostree/ostree.css" rel="stylesheet">
+ <script src="../base1/bundle.js"></script>
+ <script src="../ostree/ostree.js"></script>
@stefwalter
stefwalter Oct 20, 2015 Contributor

No need to go up, just ostree.js

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/ostree/index.html
+
+Cockpit is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
+-->
+<html>
+
+<head>
+ <title>Software Updates</title>
+ <meta charset="utf-8">
+ <link href="../base1/cockpit.css" rel="stylesheet">
+ <link href="../ostree/ostree.css" rel="stylesheet">
@stefwalter
stefwalter Oct 20, 2015 Contributor

No need to go up, just ostree.css

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/ostree/index.html
+ </td>
+ </tr>
+ </tbody>
+ <tbody ng-repeat="item in knownVersions(os) track by track(item)"
+ ng-class="{ active: itemMatches(item, 'BootedDeployment') }">
+ <tr>
+ <td>
+ <ostree-item item="item" running-method = "runningMethod"></ostree-item>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</script>
+
+ <script>
+ require(["base1/cockpit",
@stefwalter
stefwalter Oct 20, 2015 Contributor

Lets use the usual indentation style we see elsewhere for this.

@stefwalter stefwalter commented on the diff Oct 20, 2015
test/check-ostree
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
+
+from testlib import *
+import json
+import os
+import sys
+import unittest
+
+INSTALL_RPMS = [
+ "empty-1-0.noarch",
+ "cockpit-shell-wip-0.1.noarch",
+ "cockpit-networkmanager-wip-2.noarch",
@stefwalter
stefwalter Oct 20, 2015 Contributor

Why are we using cockpit rpms here?

@petervo
petervo Oct 20, 2015 Contributor

Because that way we can pregenerate these empty RPMs with what will always be a greater and lesser version than what the base tree has installed and test for those changes. All other installed rpms the versions are subject to change depending on the exact version of the tree we happen to run the test against.

@stefwalter
stefwalter Oct 20, 2015 Contributor

Sounds fine.

@stefwalter stefwalter and 1 other commented on an outdated diff Oct 20, 2015
test/ostree-run
@@ -0,0 +1,29 @@
+#!/usr/bin/python
@stefwalter
stefwalter Oct 20, 2015 Contributor

This won't be merged right?

@petervo
petervo Oct 20, 2015 Contributor

Right, the commit this is part of is clearly marked to not be merged.

@stefwalter stefwalter commented on the diff Oct 20, 2015
tools/cockpit.spec
@@ -424,6 +427,14 @@ cluster. Installed on the Kubernetes master. This package is not yet complete.
%endif
+%package ostree
+Summary: Cockpit user interface for rpm-ostree
@stefwalter
stefwalter Oct 20, 2015 Contributor

Dependencies need to be added.

@petervo
petervo Oct 20, 2015 Contributor

I held off on doing this since the version we would need to depend on doesn't exist yet. Also adding the dependency will pull rpm-ostree into all our test systems, we probably need a skip mechanism on the other OSes.

On the other hand this packages is really only for atomic and you can't have an atomic system without rpm-ostree. Installing this packages without rpm-ostree just results in the getting the curtain message.

@stefwalter stefwalter commented on an outdated diff Oct 20, 2015
pkg/ostree/ostree.css
+.curtains {
+ height: 100%;
+ width: 100%;
+ position: fixed;
+}
+
+.ostree-progress {
+ max-width: 300px;
+ max-height: 15px;
+ line-height: 1;
+ font-size: 13px;
+ overflow: hidden;
+ padding-bottom: 10px;
+ text-overflow: ellipsis;
+ text-align: right;
+ float: right;
@stefwalter
stefwalter Oct 20, 2015 Contributor

indentation.

@petervo
Contributor
petervo commented Oct 21, 2015

@stefwalter addressed the rest of the review points.

@andreasn, i moved the check for updates progress and error messages to display-inline blocks like you asked. I'm not sure it really looks better esp on small screens but let me know what you think.

@petervo
Contributor
petervo commented Nov 6, 2015

@stefwalter @andreasn The upstream rpm-ostree changes are in giving us the option to deploy a specific commit. I can change this PR so that it uses that new deploy command when upgrading to avoid potential races. Are there any other changes we want to make to the way this UI works before we get this in?

@stefwalter
Contributor

Are there any other changes we want to make to the way this UI works before we get this in?

I think that was the only big missing thing. We can iterate further on the UI once it's in and people start using it.

@petervo petervo changed the title from WIP: ostree to Ostree Software Updates Nov 20, 2015
@petervo petervo added blocked and removed needswork labels Nov 20, 2015
@petervo
Contributor
petervo commented Nov 20, 2015

Updated to use the deploy command instead of upgrade, once we have a rpm-ostree rpm we can use this should be good to go.

@stefwalter
Contributor

@cgwalters When can we expect a new rpm-ostree release?

@stefwalter
Contributor

New upstream release is available. I guess we have to wait for it to be in a Fedora Atomic tree?

@petervo petervo was assigned by stefwalter Nov 23, 2015
@dperpeet
Contributor
dperpeet commented Dec 1, 2015

Fixes #645

@stefwalter stefwalter added needswork and removed blocked labels Dec 16, 2015
@petervo petervo added the blocked label Dec 17, 2015
@petervo
Contributor
petervo commented Dec 17, 2015

Depends on #3343 and new testing docker images to be deployed for the tests to pass.

@petervo petervo ostree: UI for managing atomic host updates
88c25eb
@stefwalter stefwalter added the priority label Dec 17, 2015
@stefwalter
Contributor

We agreed this would be good to get in for the next release. So bumping priority.

@stefwalter stefwalter added a commit that closed this pull request Dec 17, 2015
@stefwalter stefwalter ostree: UI for managing atomic host updates
Fixes #645
Closes #2884

Signed-off-by: Stef Walter <stefw@redhat.com>
 * Fixed merge conflict in test/vm-install
3b7913a
@petervo petervo deleted the petervo:ostree branch Dec 17, 2015
@sub-mod sub-mod added a commit to sub-mod/cockpit that referenced this pull request Dec 20, 2015
@stefwalter @sub-mod stefwalter + sub-mod ostree: UI for managing atomic host updates
Fixes #645
Closes #2884

Signed-off-by: Stef Walter <stefw@redhat.com>
 * Fixed merge conflict in test/vm-install
e349af1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment