 Welcome to my talk about the automatic update for LibreOffice that I'm working on. It's one of these features that has been requested for quite some time by users. And I've been working on it now for a bit more than a year. I've already talked a bit about it a year ago. This time I will talk about what's still open and why it's not ready for LibreOffice 6.0. Let's start with the motivation, why working on an automatic update, at least from my side. I did the work on the crash reporter. That here is our reports that we got during, I think, the last month. And the one that you see here that's much higher than the other versions is 5.2.4. A version that is not supported anymore. There's actually a newer 5.2 version. There's 5.2.7 that has a lot of bug fixes and so on. You can see we are now here, 5.2 was released. I think somewhere beginning of 2017 or even still in 2016. And despite of that, we still have a lot of people using an old version that contains a lot of crashes. Each of these persons that's using 5.2.4 gets for each crash a dialogue when they start the next time. And still they don't update. So from these data we see obviously we need to help users so that they stay up to date automatically. I will quickly talk about the different components of the automatic update and then talk about which components are not working. The main focus will be on the not working parts. So how does the update actually work? We are reusing the Mozilla code. It's called MAR based updater because the file format that they use for the update files are MAR files. I have merged the code to master I think half a year ago. And you can enable it with this minus minus enable online update is equal to MAR. And compared to my last presentation about that, we are now using always an own process for the updating. So we have our LibreOffice that does the downloading of the update file but then updating the running LibreOffice instance is not done anymore on Linux. It's now always that we hand the task over to the updater process. Shut down LibreOffice, let the updater do the update work and then restart LibreOffice. What we already do is we distribute daily builds with the updater enabled for Linux and for Windows. The Linux builds are currently done on Jenkins. They are automatic. The Windows builds are done manually because they are still a bit fragile. They sometimes have issues with our Windows build that the scripts were originally written for Linux. So I am still working on that and that means also because I need to spend some time for each Windows build that they are not that regular as the Linux builds. For Linux, there's one build a day. So you get about, I think, midnight German time that the Jenkins job starts and tries to build a new build and does an incremental update for the last three days. If we look at the incremental updates, we see that they are quite small. So a full build is about 180 megabytes. Let's build here and the incremental updates that are generated are between 1 and 10 megabytes. The 10 megabytes happens, for example, if someone decides to include new images or something like that or if someone changes a huge part of the code. So how does the update work? We have our running LibreOffice or all the work for the automatic update happens during startup basically to avoid that we would need to restart LibreOffice later on when someone has already done some work in a document. So as early as possible we request from our update server that's running on TDF infrastructure we send the server, our build ID, our language packs that we need and the update server tells us whether there's an update inside of a small snippet. Instead of what's written there it's actually JSON and that snippet then contains the location of the update files size and hash. In a second step we then ask the LibreOffice download server or in the future most likely our mirror network for the download file and download these files. And that's basically the point when the LibreOffice process is done and hands over now to the update process that we use our update files to generate a new LibreOffice. If we look a bit closer what I described right now is basically that first green block and what's shown here is actually what happens on Windows because the update service and privileged update executable is only available on Windows. We hand over to our updater, the updater applies at least on Linux directly our incremental update and starts the new LibreOffice. On Windows it's a bit more complicated because usually we are installed in one of the system locations and the normal user can't update our installation. So what we do is, what we should do, it's not implemented yet, is call and service. That's installed when we install LibreOffice that more or less grants us privileges to update the file in a system location. So now I'm getting to the parts of the updater work that are not done yet. I already mentioned that the updater service is a huge missing piece. It builds already, it's also taken from the Mozilla code, but it needs a lot of low level adaptions for our LibreOffice build process. Mozilla does not ship MSI files, so there's still a lot to do to integrate this updater service with our MSI process, with our MSI generation. That's one of the main blocking things that prevented me from even trying to get it into 6.0. I mentioned the updater server. It's a really, really small, Django-based server that I've written. It's just a few hundred lines of code and it does not match. It basically just stores hash, size and location, hash and size, so that when we generate the update file, we store there all this information because we potentially download files from an untrusted location, especially if we use a mirror network. We try to collect some statistics. That's mainly because we want to know how many people are actually using LibreOffice and the method that we use right now of trying to analyze the log files later is quite difficult. The project is on GitHub and we have actually a running test instance that's used for our daily builds that shows that it's actually working mostly already. I mentioned that Mozilla is not using MSI files for the installations, so the whole update code for Mozilla does not handle MSI installations, MSP patch updates. That's something that I need to patch into that code. A huge problem is MSP generation in LibreOffice. It's part of our build, but you need to configure that part with a few files that are more or less undocumented. It also requires that you change how you build LibreOffice, so it generates then CAB files that are then later packaged again and so on. The question for all of that is why? We have MSI files, we can install them and basically what we are interested in is the difference between two MSI files. That's why I started a new project. It's basically extracting our Perl-based installer code for MSP generation. We written in Python and that takes now two MSI files, the PCP files, that store some information about how the MSP file should look like, takes some of the config stuff that we have in our build, but now explicitly as part of the command line. And then generates MSP files. Good yet, it works for some simple cases, but I have a lot of cases where the applied MSP file produces invalid installations later. One of the big problems that comes up often is that one of the updates is bad and I currently don't find these cases before they are shipped and reported back to me. So because we have many more ways how an installation could be created, like it's an original version directly downloaded, it's an old version updated a few times and so on, you need to do some basic testing on each of these versions. So you have all the incremental updates that you support, the official version and updating through a full update. Currently, my best idea is to use the UI testing, which allows me to basically control the profit instance through the UI out of the Python process and use that to do some basic testing to make sure that the generated update files produce valid installations. I will try to show you a quick demo if I have time. Does it show documents? So as you can see here, it's, oh, can't see much. Here's the old build ID. It's the build from yesterday night. If we now start, so now it's downloading, updating, producing a new build. It started already the new build, but we can, after an update, we always open a web page that we store that shows them the release info, what happened, potentially some donation information. And if we check now the file, you see we have the new build ID already here. That's it. Any questions? Stefan? I don't plan to do any work on Mac. If someone does it, the Mozilla code supports it, but I don't have access to a Mac. Yeah, Linux is mostly for me to do the work, and Windows is the main target. So I don't think that TDF would do incremental updates for Linux. The main target would be Windows right now. Well, it was surprisingly easy to extract the code into Python. I think it could be made an easy hack and replace a lot of our actually Perl code, and many of the configuration stuff that nobody knows anymore into something clean that's written from scratch. What he wants to do? That's why we use the Mozilla code and not something we did ourselves. The Mozilla security team spent quite a lot of time on it. So there's a checking of security certificates on each part. All the update files are signed by a certificate that's hard-coded into your executable. So into the old build must be the certificate information for the update that you're going to install. Otherwise, you would not call the updater, and then each process checks that the calling application is signed as well. Yeah, and as mentioned, the Mozilla team spent quite a lot of time analyzing it. They have a list of security bugs that they found, and we need to check that. That's why I don't write it myself. Yeah, yeah, good.