 Hey everyone, my name is Adam Shemalik and I'm a member of the Fedora modularity team in Fedora and welcome to the classroom about modularity for developers. So what I'm going to talk about today are mainly four points. So I want to quickly talk about why linear distributions are good and how modularity can improve them a little bit. Then I'll walk you through using modularity. I have prepared several specific cases that already happened and then we have packaging overview. This will be mainly a high-level overview of the differences between traditional packaging and packaging with modularity. And then I'll do a walkthrough through the whole process of creating a new module starting with an upstream source and finishing with a module. I want to do a live demo. I'll just walk you through all the steps you need to do and we have a great documentation that will cover everything. All right, so let's start with the first topic, why linear distributions? So first one, I have two benefits here and the first one is packaging and I love the new distributions for packaging. I remember when I started like 10 years ago and I moved from Windows XP back then to a Linux distribution, one of the best thing was actually packaging because I didn't have to go to the internet and download everything and just figure out how to install it. But the package manager, you brought the same for everything and that was great. And what I say that packaging makes software integrated, tested, updated and easily installable. And that's all of this, installable via DNF in Fedora, updated, tested and integrated to get together all thanks to our packages. So this is great. The other benefit is lifecycle and I say that it brings an over time stability to the diverse open source world and what I mean by this, let me show you using some pictures. So in the open source world there are hundreds, thousands, maybe 10,000 of projects and they are maintained on different life cycles and they are starting, new versions are starting or disappearing and it's kind of a mess. And if you want to run something in production, for example on a server, it might be tricky to figure out everything where it's supported if it gets updates and things like this. So what distributions do, they basically take some of these projects and they put them on the same life cycle. So it's easier to navigate. And then they are conveniently released as distribution releases in Fedora. It's for example Fedora 27 or Fedora 28. And this has one life cycle and you can be sure that packages will do the best to keep their packages updated through the whole life cycle of Fedora and that there won't be any breaking changes, etc. So that's great for, for example, running in production. And because there are many other distributions out there, we can choose the speed that we want. For example, Fedora is in the middle, releases every half a year, which might be great for developers. And then we have, for example, CentOS that releases every, I think it was every three years. And so it's, it's maybe a little bit suitable for servers. And then we have distributions like parts of the mix that basically don't have releases and just introduce new features all the time. And as I said, this is really good because different people have different needs. For example, developers tend to want newer versions and system administrators want the stability and package stuff and things like this. But even within a single release, there are people who want different pieces to move at different times. So for example, these are real quotes I got at conferences. For example, Fedora is too fast for me or Fedora is too slow for me. And it's always about some specific language runtime or application or a little piece within the distro. So there is a question, can Fedora be fast and slow at the same time? And the answer is yes. And that's what Fedora modularity does. So let me walk you through the modularity, how it works and what it is. So packages. Packages are the cold building blocks of the next distributions. We don't do anything to packages, anything new. They still say stay the same. Everything works fine. What's new though is something called modules. And these modules are logical groups of packages representing an application or a language runtime. And they have few benefits. So let me show you. So if we see the Linux, the Fedora release as we know it, the traditional one. I have Fedora 26 and Fedora 27 here. And if I want to see what Node.js, for example, were available, I could see there was just one version in each. But what happened with Fedora 28, at least Fedora 28 server edition that introduced modularity. And I can see some more options there. So modules are the way of delivering multiple versions. And they have multiple streams. And streams are basically series of backwards in backwards compatible versions. So if you choose one, you can be basically sure that it follows to be stable, but still gets updates. And what happens if there is a new Fedora release? Well, some streams will continue living throughout the life cycles of the underlying operating system. So if you're a developer, you can choose the newest one all the time. If you're assist admin or you have Fedora on a server, you can basically keep the same one you had before. So they have independent life cycles. But this is just a summary of the module benefits. We have multiple streams. So we can choose the version. We have lifecycle independence. So we can keep the version. And then there is something called user use case installation. I haven't talked about this, but I will show you in a bit. So with this, there are two other important mechanisms in modularity. One is defaults. And defaults mean that you can choose a specific version only when you want to. And this is important if you don't want to care about all the versions available. You just want to install a package as you're used to or an application. You basically get that thanks to defaults because there will be always one that is the default. And if you actually choose a specific version, then we have updates that will respect your choice and won't upgrade you to a different stream. So if you chose, for example, Node.js 8 back then and you keep updating your system and even upgrade to the new distribution release, you will still keep the same stream unless you specifically change the stream. So thanks to module, your system can move fast and slow at the same time. And this includes the packaging and lifecycle benefits included, which is the main difference from installing software from upstream that you have the packaging, how it's integrated, how it works together. It's maintained and it's on a specific lifecycle. So you can actually maybe run it in production. So that was about what modularity is and now let me show you how you can actually use it. So what can modules do? I have three specific cases that modules can provide and I'll just walk you through them and I'll demonstrate the command line. So case number one, if traditional packages move to modules and I have a specific example of the DWM package, which is a window manager in Fedora. It's a tiling window manager. There is also a second package accompanying it. So this is an example of a package that completely moved from standalone packages to the modular world. So you can see that there are three streams actually and one of them is default. So if you don't want to really care about modules and you maybe upgrade from Fedora 28 to 29 or you do a fresh installation and just install the package, everything stays the same. The module will be enabled in background and it'll just work for you. So I can show you how that works in the command line. So this is Fedora 28 and if I type DNF install DWM and this is just a normal package, it'll just show me the package and I can install it. I won't do it now. I don't want to waste your time but this is how it works. This is what we know. If I do it on Fedora 29 DNF install DWM, it'll do the same thing from the user perspective but there are other things happening in the background. So I'll just say no again and I can do command DNF module list and this command will show me all the modules that are available in the release. So I'll just scroll up a little bit and I can see DWM and there are those three streams and what happens is that the 6-1 is default so I'm getting packages automatically from it. If I want to install a different version, I can just specify it simply by typing DNF module install DWM for example colon 6.0 which is the older version and I get it then. I'll say no again because I don't want to waste the time. So that was moving packages from traditional to the modular world and let's have a look at the case number two. So this is additional versions becoming available and I have MongoDB as an example so in Fedora 28 we had a MongoDB package, MongoDB 3.6 and in 29 this package has been upgraded to 4.0 so everything is the same as normally but in addition they added two module streams and one is the 3.6 which is the one from Fedora 28 and there is one even older in case you want to use it for example on a server or somewhere and you have a dependency on the same thing. So what happens here if I have modules and traditional package in the combination? So let's have a look. So I will do this on Fedora 29 as well. So if I type DNF install MongoDB I will get the traditional package 4.0 version which is expected nothing new. If I want to use the alternative version I will do again DNF module list so see what's in there and I can see MongoDB right here. None of these are defaults so they are not consumed and I can install them using the same command I showed you before or I can do something called enable which will enable those packages on enable the module on my system and I will get the packages from the module but not from not the traditional one it'll be kind of overridden because enabled modules always have priority so if I do DNF module install goDB and was it 3.4 for example oh so this is the installation command sorry if I do DNF module enable this will enable the MongoDB module on my system and now I changed how the system behaves so if I do DNF module sorry DNF install MongoDB which is the package I get a version from the module that's how I can choose the alternative version as well all right let's have a look at the case number three so these are existing modules that just continue living and this is nothing special we had the Node.js in federal 28 and we still have it in federal 29 what happened here also is that Node.js stream six ended live for example so this module just stops existing and you need to upgrade to a new version one thing that's notable here is that I have Node.js 8 and 10 module streams and I also have packages which are standalone in federal 28 that's Node.js 8 and in federal 29 that Node.js 10 and one could wonder why I why the packages are there so that's a temporary state well I'll probably describe it later but this is mostly for building we are currently not able to build traditional packages against modules so this is a workaround but in the future there is a service coming that will actually do this but this is just an intermediate state so if you see something like this don't worry that's expected I don't think I will show you a demo for this because I showed all the commands before and it should just work exactly the same and now I have a bonus and this is the use case driven installation how do we simplify installation with modules so this is the picture with MongoDB again and let's have a look what's actually in the MongoDB 3.6 stream so if I expand it a little bit I can see that there are two profiles that are called also installation profiles and they basically help people to install the module in a different way so this is a database and I can install the database as a server or as a client or both and the benefit of this is that the user doesn't need to care about the individual packages but they can install the application in a specific use case and I can demonstrate that as well how that works so I'm again on Fedora 29 and if I do DNF module install now MongoDB it was 3.6 and I can do slash client to specify the profile so I can see that those two packages are installed MongoDB tools and MongoDB I say no and if I change client to server MongoDB server is getting installed plus some dependencies of course let me say no again so that was how modularity works for users and what you can actually achieve with modularity and now let's have a look at the packaging so this is a very simplified view on the packaging process for traditional packages and there are basically six steps three of which you use once and then three that you continue doing mostly forever so you get the source you package it send it on a review and then you push it to this git build it publish it and people can use it and if you have an update you again push the update build the update publish the update and it goes on and on and on what happens with modularity is that we change those orange steps so the ones that you perform all the time and we add one new which is the defined module that will you do just one time and let me walk you through all of these steps and just explain a little bit more detail so first is getting source this is the same you just go to the upstream crap whatever they have or or make a terrible yourself and that's it packaging again the same they are the same packaging guidelines you write the same spec no changes in there everything's good again you send it on a review it's the same the same review the same process the same rules what changes here is when you want to push it to this git so we have something called stream branching and this will this is mostly to simplify the workflows because historically if with traditional packages which is on the left you have to push the package into released branches and there is a branch for every release and even though you have the same version you need to push it into the branch into each branch so we have introduced something called stream branching and you can basically do branches on based on upstream versions mostly major versions or whatever makes sense that you want to maintain and then you can build those against anything and I'll show you in a bit so this is the this is the major difference between the branching and you can do the branching basically any way you like or anyway make sense and because we have those branches which are kind of release independent it's no longer clear where those things end up right so that's why we have modules and one of the main things here is that they define which branch goes into which release they also define more things like the installation profile or an API which I'll describe in a minute or the description but the main technical reason is that they define what gets built where and then if you want to build your software you build modules not packages and this is important if you have for example modules with multiple packages in it you just prepare all the packages push them into the branches and then you submit a single build that will build it everywhere and I said build it everywhere what does it mean so we have something called stream expansion and this is how it basically builds everywhere so this is a view on the source code and I can see basically one source for to apply for each application version I have two runtime versions so there is one source for each and there is just for simplification the rest of Fedora just so you can see how it works and if I want to build it this happens so everything gets built again everything so I have both runtimes on both Fedora releases and I have both applications on both runtime so this is something you theoretically can do and that's why you submit just one module build and just everything happens automatically for you and I'll also show you in a bit more details and then if you want to publish you again publish the whole modules and not the packages individually all right so let me go to the federal documentation and this is what you get if you go to docs.federaproject.org so this is the documentation and if I want to find information about modularity I just scroll down to engineering teams right here and then there is Fedora modularity link and everything that you want to know is in this section making modules and that's what I'm just going to walk through and I'm confident it will answer all the questions that were asked about the process so two links here adding new modules and updating existing modules I'll just go through the adding because that'll cover all the steps from the start to to the end I won't be actually doing these things but I'll be commenting and maybe even taking questions probably if there are any and clarifying the rest so we saw the process we need to go to upstream make the package and there is a link to the federal packaging guidelines so sorry to the federal review process and it points you to the packaging guidelines and everything is basically the same in there one new thing here is requesting the branch and this is the stream branches that are based on a upstream version and not the federal release so there is this command and one thing to note here that there is something called SL which is a service level so this is a way or this will be a way how to define how long is the module going to live and we are currently in the in the process of redesigning this because this is not ideal so you just need to select a date in the future basically one thing to note is that it needs to end either 12-0106-01 and just like select something mostly randomly this time and we will improve this and send information to the devl list and then there is the branch name of course this will create a ticket in the federal infrastructure or release engineer and one of the groups and they will make it for you get a notification this is a manual process so it might take a few hours but hopefully this won't take too long one nice thing is that if you have a module with only one package that shares the name and shares the branch this will create the module repository for you as well and let me show you how the repositories look so if i go to this git so that's src.fedora.project.org there are namespaces now so i have for example rpm so slash rpm slash httpd this is the upstream of httpd or i'm not sure if you have an httpd module but let's go to wdwm all right that's the package i actually talked about so this is the package and if i want to see the module it's in the modules time space of that slash modules slash dwm and let me even make that bigger and these are the stream branches that are created and these are in both packages and both modules so then you have the they have the package reviewed and everything is in place so you just push it into this git and you can go to the module definition i had the slide before a little bit empty because there are many details i want to cover so let's just have a look at the at the module definition so this is here it's defining modules in module md and there is a really good example here that will just show you everything you can use summary or description which is obvious it's the summary or description there is a license of this very file so you can just keep it to mit and these are the dependencies the these are the modular dependencies and this is a this is a way how to define in what releases forward releases you want to build if you leave it like this it means it requires all platforms so all federal releases which are active and it requires all platforms or federal releases which are active again so this will if you submit a build this will do the stream expansion across all the active releases for you automatically if you want to do something crazier i'll show you in a bit then there is api which actually as i said that modular streams are a series of backwards compatible versions these are the packages that have the promise and other packages doesn't have to have that because they can be bundled dependencies or libraries or something so these are the ones that you commit making stable installation profiles are here for helping people with installation so that was for example the client or server with the database everything is commanded again you basically need a name a description and list of packages and it'll just install it as a package group mostly and this is the definition of what belongs to this module so i have a module name there is a reference which is a branch in this kit it's not the version it's branch in this kit so you can actually select the right source you can even use commit or tags i don't think these are recommended generally but they are technically possible and if you know what you're doing you can definitely do that and also worth mentioning there is a tool called fedmod in fedora that can automate filling this thing filling this file for you if if you're interesting if you're interested all right love confusion is here about the dependencies if you want to do something different and just build this modules across all the platforms so let me scroll down and show you something more detailed and it's right here all right so we can so if i want to for example build just for single release i can just specify it if i want to build for everything except one release i can specify it this way if i want to selectively choose multiple i can do and if i want to build against other modules which is useful as i show on the slides with the stream expansion as i had a runtime and then an application i can do it here so this says it requires all platforms it requires old versions of no js so for example if i have two platforms active and two streams of no js this will create four different binary builds i would have the same module for you and then the client tooling will actually figure out what to install on the system automatically there is also an a complex example worth mentioning if you actually want to see i i'm not going to explain it here but if you want to do crazy stuff you can definitely have a look here and or even ask questions then on the irc all right so let me go back to the adding new modules and i have the module definition done and now and again everything here is documented so there is the request repo if it didn't happen before where you automatically there is how you can request branch and this is useful if you want to for example add a new stream to an existing module and one of the things that also worth mentioning there is no review for the module md file because it's basically just a configuration file that says these packages go here and we'll be built in this way and installed in this way so there is no review just request the repo pushing into this git again documented nicely then there is the module build so there is the section called building modules and i will talk about how it actually is built so as i said you don't build individual packages but you build modules and this is meant to help you for example if you have many different packages in there you can set a specific build order in advance and have one command that just builds everything for you and you don't have to wait and submit one package by one and i mentioned build orders let me also show you in the module md how that looks like i just search build or there yeah so this is in the section of components so this is where you define the packages package name descriptions and the this git branch you also have build order which is basically a build group so packages in the same build group are built at the same time and build groups with higher number are built later this is useful when you building an update of a module so let's go back to the building modules and let's talk about rebuild strategies so the default is that if you have a module with for example 10 packages and you only update a single package only the single package gets rebuilt which is meant to save resources save time and everything but if you're actually using build groups and you know that the first one needs to get rebuilt the first one and then you need to rebuild the other ones because there are for example build dependencies you can specify a different build groups different build group we have three here only changed is the default and it's just the changed packages all means everything gets rebuilt all the time regardless of it being updated or not and then it's changed and after so this means that the first package that gets rebuilt that this change gets rebuilt and then every other following build group that's also revealed so that's all the build dependencies actually worked out and you can specify it in the build commands by like this all right so we've covered how to get the package get it through review and push it to this git and that's where the story ends for packages and then we covered how to define a module push it to this git and submit a module build when you submit a module build and it succeeds the module exists in the system and can be actually consumed by other modules as well dependencies but if you actually want to use it or make it available for packages you need to submit in the module updates so again you don't do package updates individually but you do the module updates and that's also in the adding new modules section so I go right down which will be all publishing the module so we use body which is the same tool as for packages and there is a little complicated currently workflow how to do is so what you need to do is you need to find the find your module in koji and then there will be the koji tag value of it I can even show you how that's gonna work and I use this in body as a as an update oh I'm not sure I can even do something right now but this is a little bit confusing but it's everything is everything is shown here and everything should just work out you basically when you submit the build you can you need to remember the build I build ID and I think there is even a service running somewhere that will show you all the all the build IDs on the website otherwise you can do use the fat package package command when you're submitting the build and I kind of skip that here yeah when you submit the module build it'll tell you a module build name and then you need to use in the in the step for the body update and this is obviously also one of the steps that we want to improve a lot so this will be coming in the future and this will be basically supporting the modules updates a little bit more straightforward than that but this should this you just do so when you submit the module update and it gets tested by users gets karma and gets pushed into stable it's available and it's the scenario where the module exists but isn't enabled by default if you want to manage defaults we have a page here also managing defaults and there is a pegger repo in the relange in the relange namespace so you just go into it open files all right that's the new pegger oh sorry I clicked on the wrong link this is the one so it's the federal module defaults and if I go into the files I can see a file per module so for example the DWM we talked about I can open it here and this says that this is a file that defines module defaults and this is the module name DWM default stream is 6.1 and this can be sometimes missing so that means there is no default stream and then there are also default profiles so 6.0 has a default profile called default 6.1 has a profile default called default the profiles are the thing we talk about in the database scenario where you have client or server and basically if you want to install the module in some kind of default behavior if there is even any many modules define the default profile here so you don't have to enable and install individual packages but you can just install it and it works and you can even send the PR or I think the preferred way is to submit the open an issue into this repo we also have a note about submitting a federal change so if you change the default like mid release or if you introduce a new default that would have big effects on other people it's advised to open a federal change to notify everyone and just get in saying basically the same workflow as if you're introducing a new major version of something into federal there's a big impact right so that was the whole workflow right in there I can just show again this image so we talk about how to get source how to package it how to review that's the same process that has been here then you want to write the module d module md file the default that defines all the things about your module then there is a cycle of pushing building and publishing not the package back the module and just goes on again and that should be yet and I hope that was at least a little helpful or clear and yeah if you want to learn more there is the documentation link or if you want to access the documentation there and also welcome to connect with us on the IRC channel and please try modularity and that would be great if you if you could use it give us feedback and and get more versions into fedora all right are there any questions the one I wanted to call out was I'm not sure who was that asked the Bodie question did I feel like they got the answer to their question yes to summarize I think the question the question was is Bodie aware of modules the answer is yes it is and the way to go about it is submit your update just as you would for normal bare packages and if you type in the module name in the in the text field where you normally put in the the package names for the update it will list you any new module builds of your module which haven't been pushed out as an update yet up to that point so the the process is very similar to to pushing out updates for normal packages yeah thanks Niels so I think that's it all right thanks everyone for coming and I'll send a follow-up with the youtube link for the recording if you want to share that watch that again and we'll make sure that all the questions that are in the chat are answered