 Bonjour tout le monde, je viens de parler d'un docker de package, j'ai travaillé sur un docker de package pour Debian, je viens de donner un peu de feedback sur ce task. Le premier, un peu d'introduction pour moi-même, je suis Arnaud, j'ai travaillé sur Linux et Open Source, c'est mon travail. J'ai utilisé Debian pour beaucoup de temps, mais je n'ai pas un contributeur de Debian, donc c'est un peu nouveau pour moi de faire tout ce package pour travailler avec Debian. Ce que je veux dire, c'est que j'étais vraiment une personne de faute pour le travail. Mais, de toute façon, pourquoi j'ai travaillé sur ce package ? J'ai travaillé pour un collaborateur, j'ai utilisé un docker, il y a beaucoup de gens aujourd'hui, j'ai utilisé un docker dans notre infrastructure et j'ai utilisé un docker pour nos clients. J'ai utilisé un Debian dans notre infrastructure et pour nos clients. Donc, travailler sur le package de docker pour Debian, ça fait du sens pour nous. La situation avec un docker, je ne sais si vous êtes vraiment familiar avec ça, mais le package de Debian pour un docker était très mauvais, parce qu'il n'y avait pas de package en stretch, il n'y avait pas d'installation pour un docker. Et le package de Debian était étendu en unstable, il n'y avait pas de package en testant, parce que le package était un peu bloqué, et le package était déjà 1 an, un peu outdated, pas vraiment maintenu. La situation était très mauvaise, il y avait vraiment du travail à faire. Parce que j'ai commencé à collaborer, j'ai eu un peu de temps libre pour commencer. C'était un de mes projets, c'était de travailler sur ce package et essayer d'improver la situation. La première chose, c'est de ne pas savoir ce sont les packages pour Debian. Si vous voulez installer un docker sur Debian, ce sont les packages. Il y a deux packages. Vous pouvez installer de Debian, mais vous pouvez aussi installer un docker sur le website docker, et si vous allez dans l'installe d'instruction sur le website docker, ils vont direct vous à leur propre docker et vous installez sur leur docker. Il est important de comprendre la différence entre ces deux packages. Donc, d'abord, il y a quelques basics. Vous devez savoir ce qui se passe. Tout le monde sait de cette langue, je pense. Go est un langage compilé, et il s'appelle Statically Linked Binary. Nous ne parlons pas de shared libraries. Ce n'est pas le sujet, mais nous parlons vraiment de la dépendance. C'est un langage compilé, donc nous devons construire la dépendance avant qu'on puisse construire un grand package, comme un docker. C'est vraiment ce qu'on parle. Je vais essayer d'expliquer la différence entre les deux packages. Donc, docker.io C'est le nom de la package d'Adebian. Je n'appelle pas l'office d'Adebian, parce que c'est l'office d'Adebian. Donc, c'est un package. Et le deuxième package, c'est le nom docker-ce. Et ce package, je dis un package officiel, parce que ce n'est pas le ship d'Adebian, c'est le ship d'Adebian. Donc, une des premières différences, c'est qu'il n'y a pas de package source pour ce package. Vous pouvez installer le binaire, mais vous n'avez pas le package source. Mais le package d'Adebian est disponible sur GitHub. Ce n'est pas comme ça. Il n'y a pas de chose très grave. Vous pouvez vraiment voir comment construire le package. Et vous pouvez aussi rébuilder le package vous-même et tout le code est open source. Donc, vraiment, les packages boss vont vous installer le docker. C'est vraiment la différence entre les bus. Qu'est-ce que vous devez installer sur votre computer ? Donc, la plus importante c'est les dependencies de build. Donc, docker CE, qui est le package d'docker eux-mêmes, il y a des dependencies de build des directrices vendaires. Donc, ça signifie que c'est une pratique très commune dans GoLang. Ce qu'ils font c'est qu'ils embednent toutes les dependencies dans le code source. Donc, je peux vous montrer ça, je pense, rapidement. Si vous n'êtes pas familiar, peut-être que peut-être que beaucoup de gens connaissent ça. C'est pour exemple le docker engine, c'est nommé Mobi, mais c'est le code source. Et ensuite, vous avez un directeur, c'est le directeur vendard. Et ensuite, vous cliquez ici. Et ce qu'il y a ici, c'est que toutes les dependencies de build sont ici dans le code source. Et ensuite, vous avez toutes les dependencies de build ici. Donc, ils gardent un copier local d'un laboratoire qu'ils utilisent. Et c'est ce qu'il y a quand vous installez le package de docker CE. C'est ce que c'est construit. C'est construit avec toutes les dependencies dans les codes source. C'est très facile pour eux de construire ce package. Ils n'ont pas de dependency dans ce package. C'est plus... C'est la façon d'aider les laboratoires et les dependencies. C'est à dire qu'on ne utilise pas ce directeur vendard. On discute ces directeurs qui contiennent toutes les dependencies de build et on fait les dependencies de build d'autres packages de docker. C'est à dire que, comme un package, nous devons contrôler et maintenir toutes les dependencies de docker. Et c'est une très grande différence quand il vient de packages. Je ne sais pas si c'est un clock, c'est une ligne de code. C'est une petite utilité qui vous donne des numéros qui peuvent être utiles. Donc, si vous roulez ça dans le docker engine et vous exclut la première ligne, vous exclut le directeur vendard. Vous avez 180 000 lines de code. 180 000 de code. C'est seulement le source code de docker. Si vous regardez le directeur vendard, vous avez 600 000 lines de code un peu plus. C'est à dire 3 times plus que le nombre de lines de code de docker. Vous avez toutes les dependencies de build et, comme vous pouvez le voir, c'est beaucoup. Et pour vous donner d'autres numéros qui sont plus intéressantes maintenant. Si vous regardez le package de docker de docker.com, ils ont 18 dependencies de build qui sont comme, ok. C'est assez facile pour eux, pour les packages. Si vous regardez le package de docker.io, nous avons 120 dependencies de build et nous devons prendre et manager chaque nouvelle version, nous devons bumper beaucoup de dependencies. C'est beaucoup de travail. Et ça explique pourquoi si vous installez le package de docker.com, chaque mois vous avez une nouvelle version de la package. Parce qu'ils n'ont pas de travail pour les packages. Donc vous avez une nouvelle version chaque mois. Mais si vous avez un package de DBN, comme un package, nous avons beaucoup de travail pour maintenir cette package. Et c'est la raison pour que pour un moment, cette package était assez non-maintainée et très complexe. Donc c'est là où tout le travail est pour le package de docker. C'est ce qui fait compliqué et difficile. Ouais, c'est ça. Donc maintenant que vous savez ce que le travail est pour le package de docker, je vais maintenant essayer de vous montrer où sont les challenges et ce qui fait compliqué. Donc la première chose compliquée c'est de vous comprendre ce qui est pour le package et ce qui n'est pas pour le package. Parce que le docker workflow c'est difficile de comprendre ce qui se passe parfois. Donc pour exemple, vous avez le docker CE repository qui est le top repository qui contient tout ce qu'il y a. C'est là où le docker est construit. Et vous avez cette repository d'engin. Donc quand j'ai commencé je pensais que ce sont deux différents components donc peut-être c'est mieux de le package indépendant. Donc c'est juste que le docker engin, ce que vous devez faire c'est que le repository est github.commobiMobi parce qu'ils peuvent changer le nom et rebrander le nom. Donc ici c'est et le docker command-line interface c'est docker slash clé. Vous réalisez que ok, nous sommes dans MobiProject. Nous allons voir le relire. Et le dernier relire a été réalisé en juin 2017. Donc évidemment, vous ne savez pas qu'est-ce que pour le package. Parce que le dernier relire était long et il n'y a pas de relire anymore. Donc ce que vous découvrez après c'est que, qu'est-ce que vous devez savoir le fonctionnement et ce qui s'est passé c'est qu'il y a un repository pour l'engin, c'est le repository pour le interface command-line et ces deux repositories sont merged dans le docker CE Super repository avec un tool custom. Il n'y a pas des modèles ou quelque chose comme ça. C'est vraiment merge avec un tool custom ils peuvent copier le code et puis les cherries choisissent des comites pour que, au final, vous ne pouvez pas dire qu'il y a un relire vous ne savez pas, il ne correspond à l'engin de l'engin de l'engin du docker command-line interface. Donc vous ne pouvez pas packager Mobi et vous ne pouvez pas packager le docker command-line interface séparément et faire quelque chose de modulaire. Donc c'était mon premier attempt et il n'y a pas de fonctionnement donc j'ai compris que c'était vraiment pas le right thing to do it. C'est ok. J'ai dû packager le docker CE. Et puis j'ai continué et j'ai dit ok mais je voulais packager immediately the big docker repository because it was very complicated so I wanted to split this task in some smaller tasks and easier to do. So I tried to package. So there was two big debuts and see for docker was it RunC and the other is containerD I found out that RunC is very well maintained in Debian there is a package up to date and maintained. So I thought ok let's let's package that you know I found my starting point on this task at last. And I spent a lot of days working on that packaging container day bumping the package and I ended up with a proper package and the sad thing is that in this package is not used actually we don't use it. All this work I just discarded it for two reasons. One of the things that make packaging docker complicated. It's about the versions and the way they handle the version. When I was working on that I found that docker required a commit from a date between the version 1.0 and 1.0.1 of containerD and I wanted to package I didn't want to package a random snapshot of containerD I wanted to package a tag a release. So I package 1.0.1 and later on down the way I found out that I couldn't build docker against this version because docker takes this commit but I found out too late that docker uses the commit not from the stable branch they use the commit from the unstable branch at this point. So I discovered that I just packaged something that was unusable I couldn't use containerD and build docker against it. And that's a common practice with docker for all the dependencies you don't have many tags or release. So that was the first mistake and the second one is that I found that anyway I could never use I could never build docker against containerD because of circular dependencies and that's really again one of the big issues it's that all the top level dependencies of docker they all depend on docker and all these big blocks on the top they all depend on each other and it's all plagued with circular dependency actually it's not possible to package it independently and I don't know how because in the existing package that was already in Debian they managed to do different package but they are circular dependency I have no idea how they managed to build that but the thing is that after one year without maintaining the package I couldn't bump the different pieces because of the circular dependency so in the end the solution so that is the picture you get from maybe the docker blog but that's really what you get when you are under the hood, it's not that clean and these are different pieces of docker all of them are in a different git repository but in the end all these pieces that are across here these are things that we cannot package it independently and we don't do that anymore so now it's a bit technical but it's an interesting part is that we solve this by using multi upstream tarbol in the package so that's on the right that's what you can see on the tracker page of docker.io and what it shows is that when we build docker actually we fetch different repositories we fetch container day docker distribution, docker go events docker go matrix, docker live network docker swarm kits all these elements, they seem to be modular but they are not modular at all and we just cannot package it so by using this multi upstream tarbol now we get to have a package that is easier to maintain and that and that doesn't have this circular dependency so now we got something that is looking a bit better and quickly I don't have much time anymore so after solving all that and knowing basically how to package this big thing the other thing that really make it complicated is dealing with dependency in Golang when you do the package it's very difficult one of the things is that in Go you don't really know what are the required version for dependency most of the time either you don't know you know that you need this dependency but you don't know which required version and maybe you know actually that this particular version works but you don't know if a version before or after will work and we can have only one package so often you cannot get exactly the same version that upstream use and you don't know if it works or not until you build so packaging docker it's just about building and see if it works or not and you have nothing better than that you don't have strict requirements and often the libraries don't use semantic versioning so you are really like walking blindly there so it's a lot of time just building trying and crossing your fingers it's a lot of time wasted honestly when you do all this packaging very annoying but yeah that's how it is one of the big complicated thing so it's that we cannot have two concurrent version of the same library installed so right now we packaging the latest version of docker and it depends on systemd version 18 or 17 version 17 the go package of systemd and in debian we have the version 16 so if we bump it to the version 17 we break another package that cannot work with version 17 but if we don't then we cannot build docker and we can only have one library installed in debian in the packages so at some point we are bumping to this limitation and it's end up that we still have to keep some vendering because so right now in this the next version of docker we still have to keep inside embedded this version of go systemd because we cannot upgrade it without breaking the rest of the world and we can just wait until other packages catch up and hopefully we can bump this library but it turns out that packaging and removing every vendored libraries the way we wish we could do it turns out that it's not possible and often here and there we cannot so we are not there we don't reach what we really it's not as good as we would like to be these packages and another complicated thing in golon is that you don't even know sometimes what's a library sometimes there's a big application and the source code is an application so a library but you don't know only some directors in the source code are meant to be a library and there's no definition of that it's very loose so in the end at some point we had we had a circular dependency and it just turned out that it's because we didn't package a library properly but we really had to and it's really about you don't have this definition once again it's the kind of thing you have to try you have to experiment and in the end you're never quite sure you're doing the right thing so it's also one complicated thing just to finish so it's maybe a bit confused just yeah so this situation could improve and will improve we're really much waiting for that because golon is going through the language you know it's quite young and the ecosystem is evolving and hopefully in the right direction so we have vgo which is a version go and it's basically go is introducing built in the language the support for versions for libraries which is not there yet but this is really now something that is coming and hopefully it will really improve the ecosystem and the way Debian wants to package things will be much more easier and hopefully it will hopefully be better and better so yeah so we have hope for the future thank you very much and a question if you want you're welcome to ask questions now so it seems to me you know I haven't really poked go a lot it seems to me that when they were setting up language in the environment they've made a lot of terrible decisions that they really that anyone experienced with packaging or the systems or distributions that wouldn't have made was there a reason they made all these terrible decisions have they said or is it just a thing that happened I don't know well I'm probably not the right person to answer this question but I think I think they really iterate on the language and it seems to be kind of open to experimentation because for example at the beginning there's really maybe no support for dependency in the language but I think it looks really like it's on purpose they don't want it's a difficult topic to solve the dependency a lot of languages get it wrong so maybe they just decided we don't do anything and we just let the community find out their own solution and after a while we see what appears, what are the different solutions that people come up with and maybe we start to build now a solution inside the language based on what other communities have done it's kind of open to experimentation and iterating like this that's the feeling I have and yeah so I think it's still a young language and a young ecosystem and yeah Thanks for giving this talk because I'm particularly interested in Docker and Kubernetes and just go apps on stretch so because of the lack of support that your presentation discussed I was kind of pushed to CoreOS because that's a Linux distro that more or less has just a Kubernetes cluster that works out of the box now my question is is this a tenable strategy for packaging you just spin up a CoreOS instance and look at their Docker packages and then essentially like try to copy it what we're doing I just mean is that a viable packaging strategy at least for a starting point what we're doing for Docker yeah essentially like spin up Docker spin up CoreOS or like Red Hat or something that has it sort of pre-installed and then just kind of look at the versions of their dependencies and kind of copy it and see what happens yeah we don't really we don't copy anything that's what Docker does that's the way and it's not only Docker it's in the Golang ecosystem they snapshot their dependency and they bring in tree yeah I don't mean like copy is in CP I mean copy is in like copy paste versions and stuff like that I was thinking about it as essentially a shortcut so you mean the way they do it what do you say about yeah if you just if you just initialize like a CoreOS instance on a Linux on just a random machine and look at the versions that that uses because you know it works and then try to just copy paste some of that versioning information into your package declarations well we I'm not sure to exactly get ok I mean it's definitely kind of hacky, weird sure hi I'm from Ubuntu I'm from Ubuntu and we also have Docker packages and there was our devs so you can take a look at the Ubuntu packaging of Docker as well the problem with CoreOS or Fedora or something else that they have very different policies than Debian but they are probably more likely to match so yeah we can copy and we can share and I'm involved in GoPackaging in Ubuntu and in Debian as well so we don't just take everything away and don't look at anything but the challenges he mentioned should be solved in Debian actually the Ubuntu package was also part of the inspiration et c'est un très bon solution to solve some of the problems we have actually came from the Ubuntu package ok thank you ok well if there's no more questions I think thank you very much for being here and feel free to get in touch later on to keep on discussing all these issues and we have a bird of feather about GoPackaging later on this afternoon if you're interested in so GoPackaging in Debian