 So, I'm here, or is the sound okay? I'm here to talk a bit about the leap-office update problem. I will first motivate where I'm coming from, how I decided to look into the problem. I gave last year a presentation about the leap-office crash reporter. I've implemented that for leap-office 5.2. We are using that in production in the TDF builds already. So how does the leap-office crash reporter work? It's based on a breakpad, a library developed by Google for Google Chrome, used by Mozilla for Firefox and Thunderbird. On the server side, we have a simple, triangle-based server that accepts crash reports, processes them, uses the symbols that we generate during the build to symbolify the crash reports. On the leap-office side, a signal handler intercepts the crash and writes out a mini-dump file. During the next startup, we upload the file plus some metadata to the server. So metadata is, for example, the OpenGL driver, the device, the GDI count recently. If we are in shutdown, because we have quite a number of shutdown-related crashes. So how does it look? So that's a chart from the crash reporter website, and it lists the number of crashes per day. You can see here that's 5.2.4, and we managed to squeeze in actually two nasty issues that we managed to fix for 5.2.5, where we had some shutdown crashes if there was an object in the clipboard, and some font stuff if we did not find a font, and we did not find a font because all the new, we only discovered new fonts, and all the printer-related fonts were not discovered, we uprooted it and created a crash report. So the crash reporter has some issues, the 5.2.4 build, we could have discovered the issue quite early if we would have known that there's a crash that affects a lot of users. But we only have absolute numbers, so we get only the information, okay, we have 50 crashes per day. But we don't know if these 50 crashes are from 500 users or from 5 million users. We have the issue that our RC builds are not used that much. I see it a lot in the crash reporter, where we have maybe 20 to 50 crashes a day for the RC and Beta builds, and then we have 500 or 5,000 for a final build. And our second issue that is quite bad, if you look here, we still have 250 crashes a day for 5.2.0, which was released, I think, in August last year, and 5.2.1 was released in September last year, so five and six months ago. And still a lot of users are using that and are reporting crashes. So these numbers show that users are not updating regularly or not everybody is updating. We released about once a month a new final build, but apparently quite a number of our users stay with these old builds and don't use a new build. So the solution is to, instead of reporting absolute numbers, divide the number of daily crashes by the number of active daily users or active daily installs. That's what Mozilla does, that's what we should do. So our problem is we don't have any idea how many daily users we have. We have some ideas how many people have downloaded the profits, but not how many people are actually using the profits. So I started, therefore, to look into how we can solve this update problem. We have some code already in this direction. We have the update checker. It checks if a new version is available and notifies the user. The user still needs to install manually, and apparently most users don't do that. And we had a Google Summer of Code project 2015 that already worked on the code for Mozilla, porting it to LibreOffice, integrating it into our build, but it's currently only enabled if you use this special configure flag here. So I did some work there recently. I started with the Google Summer of Code code because it was already integrated. The Mozilla concept looks good. I've enabled the signature tracking. I will talk about signatures later a bit more. They are important to ensure that we are only installing what we deliver and not some other stuff. I fixed the Windows build system and the update service. I will talk about the update service on Windows in a bit. I updated the version of the updated code that was brought into the LibreOffice code base as part of the Google Summer of Code project. Actually, that was quite a lot of work because the code has changed a lot. The code comes from Mozilla. They have a lot of specific needs. It had some code for Firefox OS, obviously, we don't need that. There's a lot of hard-coded Mozilla part in there. It's now integrated into the build system. The generation of the update files, the libraries, the services, the executables that we build. So how does updating work? Because it's not that easy. We have an oldly process that we want to update. It asks the update server, and the update server tells it, okay, here I have a new update. LibreOffice instance downloads the update. But now we have a new executable, the update that comes. Or we really need that because on Windows we can't change the file that's currently opened by another process. So we can't just change ourselves, which we can on Linux. But the problem is that this process is still a normal user process. And the LibreOffice instance is normally stored in a system folder. So we can't change that LibreOffice process. The solution that Mozilla has developed, and I think a few other update services use is to have Windows service that is installed during the installation. And that's a system user. So you start the system service, and that system service can now start an update process, more or less the same executable. But this time as a system user, which can update a file in a system folder. So actually we run here the real update code that generates a new LibreOffice instance, overwrites the old code, and then starts LibreOffice again with the old parameters. And we have then a new LibreOffice running. So the fun parts. I already mentioned there are a few problems. The first one is you can't change the file that's open. We have this update service and the update executable for that. And the second one that you realize quite quickly if you read Mozilla about the update code is there are a lot of things that can go wrong and that screw up your security badly. Like, we are running executable automatically that runs as a system user, and install new stuff in a system folder. We could more or less do anything if we screw up there. So to avoid that anyone ships code and we install, we need to make sure that at every step of here that the update file that we transport is signed, that the executable that has called us is signed by us, and that the executable that we will execute is signed by us. So make sure that we can trust every part of this process. And a huge problem that we have is multi-user setups. We don't store any installation information in a location that a user can change. So we can't store the information that we currently have started in update process until we reach the stage that we have the update service running. So there's potentially an issue with the race condition, and I haven't looked into that yet. And I suppose there's no easy solution on the leapfrog side yet. I think Mozilla users writes into the registry and checks the registry to detect that issue. Leapoffice does not use the registry on Windows at all. So how do the update files look? So they are ma files. It's just something that Mozilla guys have come up with. It's PCIP-based. We just take an archive. But it has the ability to generate partition updates. So it can contain information that some of the files have changed, and just write the diff of these two files. We have a tool to generate these partition update files. It's integrated into the build. My solution is I have the final, the full build files that I create. I download them when I want to generate a partition file. I diff the two versions and generate then the new partition version. An important part is the file can be signed after the whole archive has been created. That's quite important for the release engineering, so we can sign files in a central location. You can even store some release channel information, and you can check them in the update if you want to ensure that we are not going back or not installing updates from a different update channel. So that the user can't trick us into installing something that we have signed but that we actually don't want to use. Like in a company, you might want to use an update channel that only provides the stable releases of our still build. There's an executable. It's called MAR. Quite easy to remember. You work with more files. The executable is called the same, and you can use it to check what's in the file. You can uncompress them with that. You can check the signatures and so on. So the server. Mozilla uses Birog. It's tightly integrated into the Mozilla infrastructure. I tried to reuse it, but similar to the crash reporter, it makes a lot of assumptions about the infrastructure that we at TDF just don't have. So I looked at what we actually need, and we just need to return a few informations. We will send to the server the information about our build, and we get back a JSON file with the information about the update that's available, or if there's no update available at all. And the prof is just then downloads from the location that we provide the update. We have some unique problems that are not available for Mozilla. We have language packs. We have health packs. And I mentioned earlier we want to collect user information. We want to know how many users we actually have. It's not really user information. We trust how many people are checking for updates so that we have an estimation about how many users are currently using which version and integrate that back into the crash reporter. I have a simple jungle-based server running at the moment. It's running on one of my servers. And I've used that to test the infrastructure. So I have a prototype that works with Linux already. So what's done? And what, as I mentioned, it works on Linux. But on Linux, we can't update any profit installation that's installed into a secure location yet. I'm not sure if we will ever be. I'm not sure if we want to. It compiles on Windows. So every part now compiles even the update service. We can generate the more files, complete and partial. It's part of the build system, at least in my branch. You can tell it, OK, generate these more files. And they end up in WorkDeer and the initial server. So I think about 70% is done. But we still have a few things. On Windows installation, how does MSI play into the role? We install independently, suddenly, from MSI stuff. How does de-installing work with MSI again? The update service is not integrated into the MSI yet. So it's not installed at all. I have tested that it works on Windows because the update service is not installed yet. We need automated tests, because if you have these Partitial Update files, you have the problem. You have so many different configurations, suddenly. You have the build that you have done, a complete build. And you have the situation. You have an old build that you have updated, but you still need to make sure that the updated build is more or less the same as the old one, and that it works, and that the installation works. So we need tests there. It needs to be integrated into release engineering. So I still need to talk to our release engineers and see how that can be done. Thanks for listening. Do we have any questions? Yes. I will come to you and see how we can make at least an update notification for the OSI, and so on, and so on. For the goals I do, I want to know as well how many people are using your versions of the new version or just notify them. It's running for a year without problems if people do not update. I just want to give them the idea to update. Yes. So we have that update check a bit, but that's about for TDF builds to distribute then the complete update information. There's a difference. I mean, for organic and so on, we don't need a distribution just to trigger the user's first button for update. OK. Kenny? Is it possible to update the updater? Yes. So this updater executable is part of the normally profile. That's why we copy it. We copy it to a different location in a temporary directory so that we don't change our service. If you want to run this service, how are you going to do that? What? If you run your updater as a service in Windows, how are you going to reinstall the thing? That's the more. The one that stops the thing. That's the more complicated part. Mozilla does that. I still need to look into how they solve it, but they have solved it. So it's not impossible. But we're in on the moon, so no problem. We'll get there again. Yeah, but the bigger problem is because the update service is independent, it's independently installed as a different executable or even a different application. You don't update that with a normal update. You update your LibreOffice. That contains that code, but not the version that you are actually running. The math file contains the full LibreOffice or just the deep between the two releases? You can have both. So the full math file contains a full LibreOffice and the partial one contains a diff between basically two directories. Or if it detects that the diff is too big, it just takes the full file. OK, thanks.