 volunteers help out. I'll show you a forum so that the developers have time to actually go and develop the software itself. But we are all pretty active in this community, supporting users. This is the forum. It's really great. Highly recommend using it if you have problems with let's encrypt or cert bot. So other things about being an open source developer. Lots of people use your projects, which is great. People are always coming up to you and being like, oh, my god, I love cert bot. I love let's encrypt. Thank you for the work you do. One downside of working on a really high profile project that gets lots of attention is sometimes you do get negative comments or rude comments. And that's the thing you have to deal with. That's pretty rare. One other cool part of being an open source developer is there are many opportunities for mentoring people all over the world, like people you've never met. And it's really cool to watch someone go from not really understanding how to implement something to like walking them through the process of implementing a feature and giving them feedback on the pull request. And it's really cool that you're not just doing that with coworkers that are in your office but with people all over the world. And it's a great way to make friends. I have definitely befriended some of the people who I've worked with remotely on open source projects. One other downside of working on a really high profile project where everyone's watching you is everyone is watching everything you do. So in the beginning, I definitely felt some pressure to do a really good job and not mess up. As you can see in GitHub, 816 people are watching the project. So that means every time one of us posts a comment or makes a pull request, 800 people get an email about that, which was a bit intimidating in the beginning. But now it's OK. So the project we're working on today is called CERTBOT. From the description on GitHub, CERTBOT previously, the Let's Encrypt client, is the EFF's tool to obtain certs from Let's Encrypt and optionally auto-enable HTTPS on your server. It can also act as a client for any other certificate authority that uses the ACME protocol. So since this is our first livestream, we picked really small issues to implement and small pull requests to review. Eventually, if this one's successful and people like it, we will do more in the future. So most of the tasks we'll be working on today are around certificate management, so like managing certificates on your server or checking the status of your certificates, stuff like that. And I'll try to explain what I'm doing as I go along. But there will be times where I'm silent and thinking, because I am, in fact, actually trying to get work done. And every 15 minutes or so, I'll check back to the chat window, but I don't want to be too distracted by it. I think I'll mostly check it when I'm running tests. So if you have any questions, feel free to ask them in the chat. And I will answer them every 15 minutes or so. And also I think some of my coworkers are watching the chat, and they can answer any questions you have if I'm too busy. And I know this is going to come up. People are going to ask what text editor I'm using. So I'm just going to post it in the chat now. I'm using VIM. And the main plugin you'll see me using is called VIM Pugetive, and it's my favorite VIM plugin. It lets you see who last edited what lines in a file. And I mostly use it to figure out where I was making changes most recently, if I close and reopen a file. OK, let's get started. So let's start with looking at a pull request that I have assigned to me. So this is pretty straightforward. So someone opened an issue saying we should replace instances of is instance x string with is instance x six dot string types. And this is for the sake of being compatible with both Python 2 and 3. So I'm just going to read these comments. And you can see that this issue had a good first issue tag on it. So if you want to get started working on our project, or I think most projects on GitHub, now use the good first issue label to mark issues that are good for beginners or for first time contributors. OK, so let's look at this person's pull request. So I see that despite it being fairly simple, the tests on Travis are failing. OK, and this person thinks that the Travis errors are not due to the changes in the pull request that they made. OK, so I see here they've changed some of the type documentation we have. Yep, this looks fine. This also looks fine. Yep, this looks fine. OK, so these changes are pretty straightforward. Let's see what's wrong with the tests and why they're failing. OK, so I see that two of the integration tests have failed. But it seems like none of our unit tests have failed, which means that the code this person submitted is probably correct, and that there's something else going on, which is why the tests are failing. So Travis is a bit slow. So right now the Docker image that these tests are running is just being built. OK, dependencies are being installed. OK, and here something was wrong. OK, so it's trying to download this package called NOS, which we use for parallelizing our tests. And it says that it cannot fetch index base URL, which is interesting, because that's what the base URL has always been. No distributions at all found for NOS. OK, so let's see what's going on. So I've already checked out this person's code locally. And then we double-checked that was the username. This is nvix. And so the integration tests that are failing, or the Docker image that they're using, is in here, maybe. So I think two of them are failing. One was the Debian Weezy, and the other is Precise. So let's start with Weezy. OK, so let's build everything in this Docker file up to the command that we know fails. So let's see what happens when we try pip install NOS. OK. Again, same error, good. So let's see what the log say. I wrote dot pip. Oops, dot log. Oh, Vim isn't installed. No. This is a common problem I have with Docker. I always try to use Vim. Whoa. Vy is not installed. OK, I'm going to install Vim. So it's downloading and packing NOS, getting this page. Could not fetch URL. Huh. HTTP error 403. SSL is required. OK. So it's failing because seems SSL is required. And the URL it's using is HTTP only. That's very, it's very fitting that this problem is happening during like a certbot live stream because certbot is a tool for like encouraging people to use like SSL and HTTPS. OK. How do I make pip use HTTPS instead of pip? Pip, the usage is pip command options. Which one of these options can be used to force pip to use HTTPS instead of HTTP? So version help verbose quiet. Proxy timeout exists action. I have no idea what this is. File name, nope. OK. This has a URL in it. Find links URL. URL to look for packages at. This one also has a URL, index URL. Base of URL of Python package index. And here's the default HTTP. Yeah, this is the one it was giving us an error for. So maybe if we try. So pip install because I forgot to add BS. OK. So that seems to fix the problem. So I suppose we need to modify this so that that option. Oh, actually, I just realized I'm doing this. I'm making these changes that fix the problem. All on that person's branch with a pull request. So I'm going to actually switch to another branch. What should I name the branch? Check out the inlet directory. So I just ran pip help install outside of the Docker image for the old version of Debian. And I can see that in these newer ones, the default is now, in fact, HTTPS, which is good. I wonder if there's a way to set pip environment variables. Because if anyone modifies the stalker file to, for there to be more pip dependencies, they'll all have to set this flag. Pimp, upper, what, I see. So you just take whatever was in your flag and you change it to this format. And you add pip at the front here. So we want pip index URL. This is quite what I want. I want it in the Docker file. Environment variables declared with the end statement. OK. So I just add ENV in front of it. OK. Let's see if we can build this Docker image on installing those. What was the other one it failed on? OK. It was precise. This is the whole log. Yes. Again, it's failing on those and it's looking for it. It's trying to download the package using HTTPS. OK. It seems to be the same problem. So I think we should just modify the other Docker file. So it's interesting that this person who submitted this pull request five days ago encountered this error. But I haven't seen any other pull requests with this problem. Oh, wait. Maybe this one. It's also from five days ago. Let's see if other tests are failing because of the same problem on other pull requests. OK. Well, a lot of tests are failing here. But also, these two, the same integration tests, are failing. So let's see if it's the same problem that is affecting everyone who submits pull requests. So the person who submitted this pull request was correct in guessing that the Travis errors are not due to their changes. Good job, random open source contributor. OK. Let's make a pull request. Actually, let's run the test to make sure they actually work. So while I am waiting for the tests to run, let's see if anyone's posted any questions in the chat. OK. No questions that did not get answered. OK, they're done. Oops. Yay. Everything passed. Cool. Forcing to use HTTP to make a pull request for it. And that will automatically run all the tests on Travis. It uses, OK, it's our first pull request. And let's tell this contributor that it is, in fact, not their fault. I'll come back to reviewing this pull request when the changes that I've just submitted are merged. And we can run this person's tests. So see, so I have some issues reserved for the live stream under the label live stream. OK. So these are our options. We can show inspiration, expiration and renew dates and cert bot renew output. We can add some documentation. That's kind of boring. We can implement authorization deactivation in Acme. That sounds kind of hard. And also, like, we'd have to spend quite a bit of time reading the Acme spec. Oh, also I just remembered, totally unrelated. The reason why this live stream is on Halloween is because I am dressed as cert bot. Yeah. I almost forgot. OK. Back to implementing, picking something to implement. So this one wouldn't be too hard. Modify the revoke sub command to also accept cert name. Oh, also before I start this, I should mention that the live stream will, I'll probably stop streaming around 11.30 because that will be about an hour in length. I think that's a good amount of time for the first stream. I'm just supposed to comment about that. So some background. So I've spent a lot of time working on the intersection of certificate management and revoking certificates. So let's make a branch for this issue. Revoke cert, that's what we'll call it. So just some background. Sometimes you may want to revoke your SSL certificates. There's a variety of reasons why you'd want to do this. The most common ones seem to be like your private key was leaked and so now you need to revoke your certificate and get anyone because otherwise people could impersonate you or say you no longer control that domain or you're transferring ownership of the domain and you just want to invalidate the certificates that you have. So that's why you might revoke a certificate. So cert bot help revoke. Let's start here. So the usage for the revoke sub-command right now is you have to pass insert path and path to the full chain but this is kind of confusing to some of our users because a lot of them just know they're... like they manage their certificates using the certificate names so mine are a bit confusing because I use a bunch of testing domains and usually these will have distinct names. So it's not great from a UX perspective to require users to supply paths to specific certificates and instead if they could just do it using a certificate name that would be a lot better. So that is the change we are going to try and implement. That would be straightforward, I hope. Okay, so I know that revoke is defined in this main file like the high level revoke sub-command that is. Okay, so we're here. So here I think it just first tries to find your key. And I see... I guess some users specify their key path if for some reason your account key is missing. I don't think very many people use this option though. And then here it just determines it from your account. So when I say your account, I mean like when you first use cert bot to get a certificate an account is created on lots of script for you and we store all those details and I think we hide them away from the user. I see in the actual revoking happens here and I see that there's references to the cert path here and here, so it's all over the place. So I'm just going to put a break point here just because I know that if I forget to do this now and when I start changing the code and like run it I don't want to accidentally actually revoke any certificates I have and putting the break point there will stop me from doing that. Okay, so I think the easiest way to do this would be to just at the very top if config.CertPath is none and config.CertName this is where I want to put the stuff. Otherwise, if you've gotten to the point where you've somehow managed to call revoke and you don't have cert path or cert name defined then I should raise an error because that doesn't make any sense. Okay, so we need a way of taking a cert name and finding the cert path that goes with it and I know that a few months ago I wrote a function like that somewhere. I don't remember what file I put it in. Maybe it was insert manager. Okay, not update some links, not rename lineage, not that. Okay, lineage for cert name. That's almost what we want, not quite. Domains for cert name, no. Accept all the matches, nope. Okay, I don't think it's in this file. Ah, storage, it's probably in storage. CertPath for cert name, yes. So it even says here in the doc string if cert name was specified but you need a value for cert path, yes. This is the one we want. Okay, so we just set config and config doc that should work. I don't know if the storage imported anyway. Okay, cool. Do not need to, the way that we print, I actually just want to raise an exception. Breakpoint is there. So let's make sure that the old way works which is when you pass in the paths. So probably have that in my history. Yeah, it gets to the breakpoint, just fine. So, it's a cert name. Okay, it says error argument, cert path is required. Okay, so I know that cert bot has like a bunch of command line argument parsing that happens before it gets to like any of the main places where these sub commands are defined. So let's go see what is happening there. I know that's in ci.py. Just look for revoke, usage. So I'm going to need to update this usage string as well. This is for some of the testing stuff. I see, so here's where we're adding the cert path flag to the revoke command. And I guess it's failing because it's set to true. Required is set to true, so maybe it's not required anymore. False. Did it actually work? What is the value of cert path? Did it set correctly? Yep, cool. I guess that's it. The tests will pass with these changes introduced. And I will also need to add a few more tests to make sure that cert name, like parsing cert name works. Yeah, and I see the, so I need to add a few more unit tests and also here's an integration test that I'll need to add eventually. So let's run the tests. These are going to take a few minutes, so I'll see what's going on in the Twitch stream. What message is two lines up? I don't know. The short message. Okay, so the tests have finished running. Whoa, they all passed. Amazing. Usually when I make changes, lots of things break. Okay, so someone in the Twitch chat pointed out that I missed a doc string, like updating one of them. So let's do that before I start writing tests. Also, the live stream is going to end in about five minutes. So I said two lines up. Presumably they mean two lines above where I made changes. So let's just jump to where I made changes. Good catch. Thank you, Twitch stream viewer for catching my mistake. So in manage certificates. Manage certificates. Oh yes, I missed quite a few. Just go back and check all the places where my book is mentioned. Okay, so these are correct overview. Did I miss another one? So it's been one hour since the stream has started. Obviously there's like one minute left, so I don't have time to write tests for this, but I don't think it will be too difficult. Yeah, so I'll stop here. Thank you for watching. If you like this stream, you should let us know. Maybe on Twitter or by sending an email to info.eff.org, or just like posting in the Twitch chat. Maybe we'll do some more. And if you really like cert bot and want to support our work, you could look through the good volunteer tasks label we have, which I think someone posted a link to. It's actually, we renamed it recently to good first issues. Yeah, and we can help you contribute, and we can like walk you through the process and answer any questions you have. We're really friendly, so you can contribute to cert bot. Or you could join the EFF. That's one thing you could do. I think, or you could also donate to Let's Encrypt. Yeah, and I'll stick around for a few minutes and answer any questions in Twitch, but the stream is over. Thank you all for watching. This was lots of fun. I'm surprised at how much work I got done, and it was much less of a disaster than I was expecting. So I'll hang around in the chat room, to cut off the streaming now.