 Next up is a Steph Walter, a very strange name for me to pronounce because my first name is Walter and his last name is Walter. He's going to talk to you guys about Cockpit Linux in the Linux control in your browser and he'll tell you all about it. Hey everyone, so one of the things that I love to do on Linux is bring it together, integrate it, finish all the pieces. To make it into something that someone can use out of the box without having to put it together themselves. I know everyone has their different angle on Linux, but that's mine. And that drove me to work on Cockpit. I want to share that with you today. Not only about Cockpit, what it does, but how it works, which I think is pretty awesome. You're free to follow along. I'm not here spouting off some future bullshit. This is all stuff that works. We're going to have lots of demos. We're going to have lots of action here. In fact, we can tweak them depending on what you want to see. You can use this on any operating system here. There's a URL there, cockpit-project.org, slash running.html. It's just a command or two and you'll have this running on your machine. So, typically when people think about Linux, not those of us here, but those of us who haven't used Linux before, we typically bring them into Linux this way with a root shell prompt. Now, if you give me a root shell prompt, a root bash prompt, I will conquer the world. And that's because we have a mental model of how this all works, how the different pieces of a Linux system fit together, where to find information, how to diagnose problems, how the processes play with each other. And the file system is laid out. For us, this is native and intuitive. It feels comfortable like a nest. But to those just coming into this, it looks like that. It looks scary and they run away. So, one of the things we set out to do with cockpit is we had two goals. One, make Linux usable by non-expert admins. That is the Windows admins in the crowd, non-expert Linux admins, right? They are experts in their domain but not in Linux. We wanted to make sure that they could approach it and make it usable. But more than that, even for all of us who have used Linux for a long time, we wanted to make sure that the complex features in Linux were discoverable. So, you don't have to spend the time to learn every single thing about the technologies that underlie the tasks you're trying to accomplish in order to get something done. Because I've only a short time, I'm going to skip over the first one a bit and show you cockpit for the second case. But let's just give you basics on how to log in. Cockpit runs on port 9090 on a machine, typically. We'll see exceptions to that rule. And port 9090 is the WebSM port. When we connect to that port, we see a login prompt. I log in with my system credentials. Same way I log into a desktop or a SSH session. And I'm off to the races. And I'm not off to the races. There we go. So, we log in. Cockpit has all these various tabs and areas to dive into different topics of the system. Various dashboards and so on. But the basic idea is it's very easy to get started. So, it's remote. It can be connected from anywhere in the world. You don't have to be sitting at the machine that much. It's obvious. And secondly, it's interactive. The stuff that you do in cockpit happens right away. This is different from config management tools, which typically are declarative. You declare what you'd like to happen across a cluster of machines, and then the config management system makes that happen. Microsoft is copying cockpit. They announced a project called Honolulu, which they're putting on their headless server. And if you take a look at it, it looks just like cockpit. This is where we got there first. Cockpit got there first. Microsoft is following. And if you actually look at the implementation of cockpit, which we will do today and look at the implementation of Honolulu, you'll find they're even copying those parts. So, win. But I want to show you a complex task. Many of you might be familiar with this task, but just as many not. How to create a network bond on your machine. Now, typically, if you were to do this, you would first read blog posts about your particular distro, various opinions about people who say, this is the way or that is the way to do it, how to make a network bond persist past boot, and then you would figure out how to actually execute the commands, read the manual pages, and so on. This is an arduous process. But with cockpit, what we just do is we go into the networking. We click add bond. We choose the various devices, interfaces that we want. We can, of course, choose the various modes, active backup, round robin, and so on. And it didn't work at all. Nice. Well, fail for the demo, but luckily I have one prepared. Here's a video of doing this task successfully. So, again, we can choose the mode, we can choose which nick, and off we go. We have a bond. We can then assign a pre-address to it as you would, start to configure it as a network interface. So that's much easier than spending half a day learning how to do this. Of course, you should still learn how to do this. Everyone should at some point in their lives, but if you just want to make a bond right now and move on to the actual intent, the task that you want to accomplish, you don't want to have to spend time on all that. Here's another example, to mount an ice scuzzy disk, which is somewhat more vague to me, even the commands and tools and packages involved are somewhat mysterious. But here I can start to actually perform this task. We can set up, of course, the ice scuzzy initiator, as you see, connect to the target, authentication, and there we go. And now, of course, we have the disk available for use. This is just a demo, so it's only 100 megs, but we can start to use that drive, create a partition on it, format it, and so on. And again, the last example we're going to look at before we dive in, Kubernetes dashboard. Here we can discover a cluster. Click properly. Discover a cluster. I'm going to log into it, a Kubernetes cluster for running containers. In this case, it's our bots cluster that runs various bots for the cockpit project, runs machine learning tasks, and so on. We have a dashboard that then displays that information for us. We can dive into the containers that are involved, see the nodes, their load. In this case, the cluster is significantly overloaded. And we can inspect the various things. Diagnose, troubleshoot, look at the systems, and so on. Now, I could do this for every different part of cockpit, but we don't have time for that today. Instead, I'm going to show you how this works, because if this was all there was to it, it's very shiny and fancy, but I wouldn't be that excited about cockpit, to be honest. I would be like, wow, good stuff, move on. But the way that it's implemented, I find very compelling, and it's what drew me into this in the first place. Remember, I talked about integrating the Linux system, making it coherent and function as an out-of-the-box unit, rather than a bag of parts that everyone has to put together themselves. Cockpit is really a Linux session in your web browser that lets you build and interact with all the different parts of your system directly from JavaScript. Cockpit is pure interface. There's no mid-tier at all. This is one of the principles that we have. We don't store any data about the system. We have a bit of data about how the UI should be laid out, someones preferences, what language they've chosen, and so on, but we store no data about the system itself. The system owns its own state. We talk directly to services like SystemD, which owns data about all the various unit files, various services, talk to Docker, Kubernetes, OS tree, SSSD, the journal, and so on. Those are the things. That's the mid-tier. This system is its own mid-tier, its own business line. And how does this work? So over here, on the right-hand side, we have various system APIs. It's a kernel APIs, divas, processes to spawn. Some of those are APIs. Some of them are just random commands, but some processes that you spawn are real APIs. They produce output in a predictable way and take predictable input. It's unique sockets and files that are APIs, such as the password file. Its format, its layout is a predictable API. Now, over on this side, we have web browsers. How do we actually make this work? On this side, we have all the logic for driving those APIs. How does it actually connect across? We have this thing called the Cockpit Bridge, which runs as a user session. I'm sorry, as a user, as the user that you logged in as. And it sends back and forth these various packets, various frames of information. Many of them are JSON, but other have file content, bits and parts of interacting with the APIs. And in order to connect to that bridge, running as a user on the Linux system, which talks this protocol on its standard in and standard out, we have a web socket, which listens on port 9090, terminates SSL, and so on. And basically every frame that comes in the web socket gets passed the standard in and standard out of that process. And then, of course, the JavaScript here is able to interact with the system. We're going to look at this. I would love to actually do demos of every single one here, and I can, despite the flaws you saw earlier, but I doubt we have time. So I'm going to show you these instead like this, because that will be faster. Here, what we're going to do is we're going to interact with the DBS API on the system from JavaScript. So we're in the, this is the Firefox JavaScript console, and I'm opening a proxy to a DBS API, cockpit itself, the pieces that are running on the system don't know anything about this API. But the JavaScript can introspect and access properties, can invoke methods on this API directly from the JavaScript code. You can see that the name up there changed, and of course, logged into the system, the name has changed here as well. This is the same as the case for spawning commands. Again, from JavaScript, we'll spawn a command. We will spawn a ping command in this case, and we'll see its output as if we were running it directly. Again, this is from JavaScript, in the JavaScript console of a logged-in cockpit session. And ditto for files, we can access files in the same way. I'll skip over this, but take my word for it. So, how does this work? There is a protocol for web access to system APIs. We have documentation on it, and this is what it looks like. You can actually do these commands and interact with this directly from the command line. Like we said, that this bridge process speaks this protocol in standard-in and standard-out. And here we have opening a connection to a debus API. We have some response that comes back, and here we have a call method to a debus API. And again, in this case, there is no reply, no arguments, no out arguments from that method from the set static hostname method. But here we have the reply. The same applies to spawning a process. Let's actually do this. Here we are. Again, you can do this on your systems. And what I'll do is I'll copy and paste this here. You can see it. We can see that it responded with a bunch of different packets of output. These are the frames. Of course, it's transferred over a WebSocket. Those frames become the WebSocket frames, and the browser is able to natively interpret them. We can see the output was all sent back. And then here we have the status, exit status, and various other information that comes out of this. So under the covers, that's how it's implemented and how the browser can interact with the system natively. One of the conclusions that this leads you to is that in 2018, in-process APIs, ones that require on the caller and the library itself or the API being in the same Linux process, they really are implementation details. They're not APIs, so to speak. We're in a world where different pieces of the system are expected to run in different places. In this case, we have a web browser interacting with the system. But that same is true for microservices. The same is true for all sorts of different ways that modern systems are pieced together. APIs need to be callable from out of process and hopefully from out of off the system. Many of the APIs we talk to are not callable from off the system, but they're remote-to-bowl. We can remote them. What we can't remote is something like a C API, a Python API, an object-introspection API, and so on. Those are in-process and they're implementation details. It's not 2017. So, let's skip that part. So, let's add a plugin. Adding a piece to cockpit is as easy as writing a shell script. And I want to show you this today. I don't want to show you a video because I want to show you this in real life. I'm going to start with something that's a little bit done here. Half started, so I don't have to write the boilerplate, but we're going to actually write the logic in here. So, let's look at... We have two files here in this directory. One is a manifest that talks about this plugin. It talks about this piece of cockpit, this piece of cockpit, the UI that will show up there. And you can see we have this label and a reference to the file to show in the UI. Pretty basic stuff. And over here, we have an HTML file with some JavaScript in it to perform that we want to show up there. So, what we're going to do is link this into a directory so that cockpit can find it. I'm going to use my local account. And let's see if we can access this code in cockpit. Just first the boilerplate. Nothing special. I'm going to log into my local system in cockpit. And again, let's make sure that works. And that's embarrassing. My username has a dot. Thank you. That's perfect. And here I was going to go and disable SE Linux. And you can see that our plugin shows up over here on the side. Let's make this a bit bigger so we can all see it. Now, this doesn't really do anything yet. We can... Let's look at the code for this plugin. We have a path field. We have an export button. And we have this box here, this output box. Let's look at the code here. It says, when the export button is clicked, call the run function. Here's the run function. When the run function is run, we'll get the value out of the path box. And we'll pass it to this command. Just like we did earlier. We'll spawn the export fs command. We'll compose a command here. Again, this little snippet here is very cool. When we execute this, if we logged in with a user account, like my stuff account that I just logged in there, it will allow me to... And I am allowed to use sudo or polkit to escalate privileges. Cockpit provides this option here that allows this command to be run via sudo. So it makes it very simple to do these things. You can see that if we type something here, and click the button, nothing really happens, except for it actually does something. You can see that this has been exported, but nothing happened here. So let's change that. What we're going to do is watch the file, this etab file. And when it changes, we want to invoke this changed function. And here we have a changed function. And we want to perform a task when the change function is invoked. Proc equals con. Bon. And we want to run export fs. We want to get the output of export fs. Again, we want to run that with sudo. And we want to call a function with the results. And then let's write a function with the results where we append it to the output. So there we go. OK. Now what we can do is refresh here. And again, already we're starting to see results there. When that file changed, when we saw something happen there, we called this function, we called export fs. We appended the results there. Now when I export a new directory, you'll see that it actually changes. I guess I shouldn't have used append here. I can use replace. Well, let's leave it for now. That's fine. We won't get into the details. But you can see that that works like that. But more importantly, if I were to export something from the command line, you can see that it reacts instantly and starts to show stuff in the UI. This really is a part of the session and can react and talk natively to the system. And building this stuff, that's why we're able to have so many different parts of the UI. Parts of the system represented in cockpit show different pieces because it's so easy to build this stuff and pull it together to talk to whatever API, even to talk to other config management systems, to talk to things like Kubernetes or MGMT that James was showing us earlier. All right. There's got to be a catch. There's got to be a massive PHP application that sits its fat ass on your server and just takes over, right? No. Cockpit is zero footprint, plausibly zero footprint. It does not run when you're not using it. It really does not run when you're using it. It starts with socket activation. It exits after you're done using it. It has very few dependencies. It's written in C on your server. There's nothing really... It's like 1.5 megabytes on your server. There's no JS stack. There's no Perl stack. There's no Java running there. So you can see this. Again, due to the lack of time, I'm going to show this as a video, but you can try this on your own machines. Up at the top, we have all the processes that have Cockpit in their name being watched every two seconds. Now I'm going to connect to Cockpit. You see that there's nothing running, and all of a sudden, CockpitWS does this. We use... Sorry, CockpitWS shows up. We use system desocket activation to do this. And when we log in, you can see the bridge is started, the session is started, and various other processes are started, just like a real login session. And again, when we log out, they all go away. Boom. And 10 minutes later, that one will go away too. We won't wait for 10 minutes. It's a real login session. When we log in, let's pop open the terminal in Cockpit. We can see that when I run a command, the ID command inside of Cockpit, it's running as the user that I logged in as. But more than that, if I check with the system about who logged in, you can see my session there. And if I check the processes in that session, you can see that all of those processes are listed there. This is the same login session that I logged in as. It's a login session. It's a PAM session. It's an SELinux session. It's all the different kinds of sessions. The JavaScript is part of that session. It works over SSH. We talked about connecting to one machine over Cockpit WS, but we're able to connect to other machines over SSH and have them show up in Cockpit as well. If I log in here and I connect to the dashboard, I can connect to other machines here like this. I'm going to connect to an atomic machine. Here's the SSH fingerprint to connect that we haven't connected to this machine before. In addition, this machine does not have either Cockpit running. It doesn't have a normal password authentication. I need to use an SSH key to connect to it. I can use an SSH key here. Let us again. We will try this again and we will try it again. There we go. If my SSH password matches that of my login, the key will be unlocked automatically. This uses a real SSH agent to connect all the standard bits and bobs that you're familiar with. If we had time, we could actually look at that. Now I'm able to connect to this other system. In this case, it's an atomic system. There's different options on the side here as I switch between the two. Different things, the system represents its UI, the UI that's relevant to that. I can look at, for example, the OS TreeStyle updates of that other system. Cockpit integrates with config management. I'm trying to wrap this up very quickly here, so I apologize for going through it fast. Not only do we see in foreman, in manageIQ, in over connections to Cockpit, as you list hosts, you can dive into Cockpit to troubleshoot a specific host on that machine. We see that here. We see that in CloudForms as well. There's a Cockpit button there as you list the virtual machines that are running Linux. Not only that, but it will react to changes from config management. Let's say I didn't want to upgrade this machine here. I'm going to instead, instead of bonking that button, just updating and rebooting the OS Tree on this machine, I'm going to use Ansible to do it. Yeah, exactly. I'm going to use Ansible to do it. As we do this, you'll see the UI will actually update. Don't bail on me, Ansible. You can see, buttons are being disabled. We can see that as the task is getting done, the UI is reacting to the state of the system. Cockpit in no way wants to own your system or its state, but it takes into account the stuff that's going on. The system is now being rebooted into the new updated version of that atomic host, and we will then be able to reconnect to it and see that it's now running 725. And of course, I can bonk the button to go back without a problem. All right. Well, I hope that gave you a whirlwind view of Cockpit, how it's implemented.