So I asked my wife what do you mean exactly tell more about myself and she was you know Like I don't know exactly tell them your name your age and the number of kids that you have So I went along and I created a web application in Elm that tells you my name my age and then my the number of kids that I have and You know it took me a lot of time.  You're only 37. So Even though it's biographically incorrect, I'd still like to proceed with the presentation. So Indeed my name is Amitai Burstein. I'm the CTO and co-owner of Gizra. We're a web development shop based in Israel and since the beginning of 2016 we have an official US office so My Twitter handle is Amitai Buu. So if you want to tweet go ahead, it makes me feel important So today I would like to talk about Elm which is basically a different approach to web application But let's start by understanding what problem it solves So you couldn't agree or disagree but one of the problems I call it This is where you might disagree of all JavaScript framework is what they have in comments They they are all written in JavaScript and That's fine. If you're a JavaScript ninja, which nobody is or they are very very few and When I'm going to show you about Elm so often time people say so what's wrong about JavaScript? I think there is a lot of things that are wrong I'm not gonna I'm not gonna get into the argument of the JavaScript Ecosystem and the fact that two two days ago we had grant and yesterday We had gop and today it's cool to use npm script and finding what the real best practices are but rather I want to show you a pragmatic approach or Our own approach in Gizra, which is basically saying We want to build web application the quickest way possible the cheapest way possible Solid web application and also keep our developers moral high So in this in this session, I'll probably be bashing angular one a bit just because you know It's so popular to hate angular one. I have nothing really against it I'm just gonna show it The mindset that I at least know of angular one and how it corresponds In Elm and basically just to show you how I think that Elm provides better tools to deal with front-end development So Elm is a function a functional programming language If you know what's functional programming language is good for you If you don't know will cover some some of the things in general the gist of it I would say that Function the function that we have don't have states and that is immutable. That's probably The two important things that we have so what you can see on the screen. It's the code This is this is Elm. It looks similar to Haskell in case you've you've seen Haskell It's a compound language. It's being compiled into HTML Java and CSS It doesn't mean you cannot use bootstrap or semantic UI you can but if you want to have some inline CSS or stuff like that You can do it so we have the Elm language and Along that we have also the Elm architecture, which is basically a set of best practices on how to How to come and how to structure our application our application how to connect the different components and Basically, we know MVC model view controller in in Elm in the Elm architecture. It's pretty similar We have the model update the view will see a few code example that will explain that and Basically the Elm architecture have a few principles. I just want to share with you the two important art Two important principle So the first principle is saying we have a single source of truth and the entire state Our entire application in health is held in one single record tree in one big object And when I saw that when I saw that for the first time it really resonated with me if that's even a thing that you say in English because in Angola one if I would ask you where is your state you'd probably you know scratch your head a bit and you say well It's in the UI router or in the router But then you remember that you have a few services and each service, you know can have its own internal cash So you don't really know where where you don't really control the entire state of your application Or you cannot control it easily add on top of that the fact that The async nature of JavaScript and again, it's really really hard To know what is the condition of your web application and definitely we're in cases of bugs And we have a lot of bugs in front end just because it's so hard It's really hard to reproduce. It's really hard to reproduce those those problem So this idea this principle of having everything in one single record tree is maybe counterintuitive to the fact that We are thinking well everything should you know separation of concerns everything should be completely separated So yeah, the LM architecture is still saying everything should be There's there's still a separation of concerns But still the entire state is held in one single place just to help us control our web application The second principle is that state is read only and you know folks. It's 2016 We all already understand that the root of all evil in this world is heartwarming positive Non-cynical world is two-way data binding and you know, you probably remember yourself. Thank you just for laughing mission accomplished I Remember yourself myself going into Angola one sites three and a half years ago And you know checking the first example where you fill in the input form and it shows you Your name high and your name and I told myself. Oh my god This is saving me so many jQuery lines and you know that thing that made us love Angola one so much is the thing that we now Hated for this two-way data binding because we have a big problem If we have this model view controller thing with the two-way data binding our review our html is actually Changing our model without necessarily the control and being involved over there And when the model is changing the data changing it might cause A fact of triggering other action other changes and again We are not able to control or understand the state the condition of our web application So back to our award-winning web application, which is basically a glorified counter example I'd like to think that maybe I'm the first that was able to personalize a counter example but it's a counter example my friends and I'd like to show you through I'd like to show you some code and Basically to show you how we are thinking elm so definitely you don't need to understand every single line and command over here And definitely there is a learning curve to elm I know I when I saw the elm syntax for the first time I closed it and I didn't go back to it for For three months because it looks a bit daunting, but I'll show you how things are making sense So even if you don't know elm I'll show you how things, you know fall into there the right place So this is the code that we have and I'll just go over it very quickly There is some boiler code that I'm not showing you I'd just like to show you the essence So we have a model called person We have a bunch of import stuff like you know in JavaScript. We have this Required thing, but let's go to the interesting part. We have here the model our model is basically just a record holding a few stuff Like the age which is an integer now. This is a compile language. It's a statically typed language It means age can only get integers There's no way you will be able to pass a string into into the age Just because the compiler will not will not let you do it This is part of the guarantees that elm brings with itself.  So we have the age which is an integer the kids and the name and In the initial initialized model, I just initialize a bunch of Values watch me as I quickly Completely ignore the init function There we ignored it and we reach this line that fills me with total joy And in effect, maybe I could have stopped the presentation right here And if you're coming for react redux, it might make sense because again Angular 1 I'm looking at you if I would ask you about your fairly big, but not too big angular 1 web application What are all the options? All the actions? Sorry a user can interact With your application and that they will change the data meaning what are all the actions now? If you're a senior developer and you started the project Well, maybe you know you remember everything, but see you wouldn't feel too confident You'll have to go into the code you look some stuff inside the controller You look some stuff inside the view because it might be changing the model and you come with a list and it's not Well, you kind of hope cross your fingers that the list is correct And the beautiful part over here is you know our glorified counter example This is just a counter and example. I can increment and decrement it I've just created a new type called action and I'm giving it this arbitrary words, which are decrement and increment increment And I know exactly where to look for when you'll ask me. Hey, I'm a tile What are the different actions you can do for your web application? I have one single line that tells me not more not not more than that not less than that So below that we have this update function, which is kind of the controller for that we know from Eb me see So let's look at the type signature. So the type signature basically helps us helps us understand that I'm gonna get an action I'm gonna get a model and then I'm gonna return another model So elm is immutable language meaning I got a model. I'm not gonna I cannot reassign values to it I'm actually creating a new model and handing it back. Let's completely ignore the effects that we see below that So now the update function is getting an action and a model and I have a case over here case action off Decrement and increment. I cannot write anything else. I cannot have a type of the compiler will not allow me to have a Typo over here the compiler will not allow me to forget to write the word Increment over here So it's guaranteeing that all the cases are fulfilled and basically inside the case you can see I'm saying take the model and Take the kids property and that's decremented by one or incremented by one All right, that's our view So it might have some certain resemblance to HTML I know that I know that when I saw that for the first time that was like that's when I decided to close elm for the first Time because I said hey Where's my HTML right like it's it's really hard to to read the syntax It has its advantages it has a disadvantages in short I will say you it just syntax deal with it the disadvantages are probably that it's less readable because we're used to reading HTML The advantages are these are function that are compiled so I cannot have a div with it with a typo I cannot have an enclosed tag and so on and so forth. So basically what we are seeing here in the view function we have We have the div which is like the root div and below that we have another div completely ignore the text We don't care about it and then I see I have a name plus plus which is basically just concatenating a String which is the model name and below that I have the same thing which is an age and since age is an integer I'm just casting it into a string and you know I got it and the same thing for kids number below that I have a button which basically we're saying on click Just send one of those actions that we've set already the decrement the increment. We cannot have anything else The HTML the view part isn't changing our model It is basically saying take the action take the model that we have right now sending to the update function Which is like the brain of our web application. This is where all the business logic is being handled We're just sending it and changes should be done there So we have the increment and decrement and then below just some some debug code But even though it's not HTML still it's a bit. It's quite convoluted. We can probably clean it and By clinging it we can actually show that everything in Elm is actually a function So what I've what we've done over here the view name is actually I can declare a view name I have a function. It's getting a string and it's returning an HTML So this is basically just getting the name at it and it knows how to print it So if I'm going up I can see that the view name is now getting the model name Same thing would be with age the view age if I'm looking at the function So the signature will be an integer and I'm just getting an HTML and by the way, I'm writing it When I'm writing the type signature, I don't have to Elm is Inferred typed meaning it can it can understand by itself But this is kind of a best practice for us the humans to understand what's going on So with the view age, basically view age I pass it the model age and here our web application is perfect. It is showing my name. I'm it I my age and my kids number Oh, no How embarrassing I have a bug and in front such a respectable audience The number of kids is wrong and we can see that in the debug if you can see from that far The age is 38 the kids is 3 and the name is Amitai But somehow the kids number is appearing incorrectly if we go back to the code we can actually see That I wasn't very concentrated probably when I created the web application The view kids which is also getting an integer. We are passing it by mistake model age So one of the things that Elm allows us since it's a combined language is a statically type language is to try and Move the runtime mistakes into compiler errors, and I don't call it runtime errors because again There are no runtime errors in Elm What did I mean something That there are no runtime errors, okay, it is but it but it's true So our idea is try to shift as much as possible this this those mistakes that We are so used to pushing into production and just have the compiler You know bark at us and say this is wrong and in order to do that we need to understand types So let's have a quick types one over one here is the types here is the type Boolean This is how it's defined in Elm it can get either a false or a true. That's it If we wanted to extend our Fancy web application, and I wanted to share with you the different vehicles that I'm out I might own and again since I'm the CTO of Gizra. I'm so rich I might have a boat One boat. I don't want to exaggerate. I might have a plane one pay But I might have multiple cars. I Actually have two I want to sell one. I don't know how to do it, but Basically I have this integer of the car the integer is wrapped With a car type. It's not just a simple integer. So now in my model I would say the name and the age and the kids and then I'll have another Vehicle property which is basically a vehicle type from now on So then we can start once we understand types. That's it you understand types We can talk about type safety So once we have the type safety in place We're basically helping the compiler in helping us and preventing those mistakes So again looking looking at our previous example how it looks right now The age and the kids are both integer if I go down I can see that I'm just initializing with normal numbers a Possible solution would be just defining here. I have this new type kids Which is just it's just the kids right? It doesn't get it's not like the vehicle. It's not a plane or A boat it's just kids But what important is we have an integer and that integer is wrapped with the type kids So just for the sake of the example I I kept age as an integer and kids is now of kids type So if I look at the initializing model, then you can see the age is being initialized with a simple integer But the kids is initialized with the integer wrapped with the kids type So the view kids function for example if it used to get an integer up until now This is before the change that we want to add here is the new change If you can see in the type signature you can see that it's no longer gonna get an integer It's gonna get this kids type is it basically again our value wrapped in something So we need to unwrap it in sour our let there is a let block over here basically we are you know reaching inside and yanking out unwrapping the kids and now we have inside this valve inside this valve Variable we have our integer and we can print it we can print it out Just to show that there is a possibility again to keep it a bit shortened and in our argument Over here on top. We actually already unwrapped it. So we keep it a little more readable But the fun part here is once we've done it one we have this type safety in place if I'm looking at the compiler This is actually the integration of the elm compiler inside atom the compiler is actually Telling me hey, you cannot do that You cannot call now view kids with the model age and the compiler is actually telling me I'm expecting the function is expecting a kids type and you are passing me integer And this is beautiful because it will never reach production because you know, it's not it wouldn't it wouldn't compile So the update function very similar to that we're seeing if this is the before change We can see that the kids is treating the model kids as a normal integer is a normal number But it is not that our number is wrapped in that in that type So the change would look like that again I need to unwrap our value and then here the kids you can see maybe you can see there is a small Apostrophe this is quite common in immutable language It's saying I took the value from kids, but I'm doing some kind of computation, right? I couldn't reassign kids itself because it's an immutable language and then I will reassign and then I will reassign it So Basically the update function and that's that's the fun parts I mean our entire business logic is being done here again if we're thinking about angular one when you have bugs suddenly your data Something on the screen is you know not working properly you need to start digging thinking where is this data changing? You don't have to ask yourself that in hell because there is one single place that it can happen and that's in your update function so obviously it makes is it much easier to ping point bugs and fix them and We could have more complicated Requirements I want to show you a more complicated requirement just to I just want to put it in context Just so the next requirement won't sound too harsh It's is a very short video try to notice the sound of the piano in the end. It's I think it's my own favorite part Blenby so the next requirement is putting limits on kids because And by the way, I add that's the name of the girl that was crying she was basically throwing a fit for 30 minutes because She was annoyed by the fact that the the yellow potato had glasses didn't fit her better and like It just won't I'm sorry So we want to put the limits on the kids like logical limits when we hit the decrement So it won't be low below zero and if we Hit increment it won't go beyond a certain lumber now again angular one. How would you how would we do it? Would we disable the HTML just to prevent the clicking that that's like it's kind of signs wrong sounds wrong Right, it's dealing with with the HTML. He doesn't deal with the data How would we do it? Otherwise in the controller? Maybe listen to the model changing and either prevent it or or or revert it We don't have that problem in elm because we all don't have the two-way data binding this is data is flowing through Through a single direction. This is the unidirectional Unidirectional approach like we said earlier the view is just sending the current model with the action And then it's up to the update function to decide what to do with the action if it decides not to do nothing It won't do nothing So indeed this is before the change we can see that you know when we're hitting decrement Then we're just decrementing without checking anything the entire change that we need to do Sorry The only change that we need to do is add an if over here So if the value is reaching a certain amount when then we just return kids zero again Not just a zero a kids zero save thing if we're gonna do it for for the increment so Business logics business logic requires testing right type safety cannot always save us We saw for example the if then for for for putting a limit and it requires testing so For the audience who writes unit tests in JavaScript for their own web application All right Now another trick question who enjoys doing that so for the viewers viewers at home a very few people raise their hands and I cannot blame her Clap back blame them because Writing unit tests for JavaScript. You probably have the same amount of joy and happiness those guys in the back of Kim Jong-un must be feeling right, so Unit test in JavaScript. It is a so much a fun, right? Everybody Everybody hates it, right and And and to understand what makes unit tests really easy in Elm It's probably time to talk about few pure functions and side effects. So Your functions and side effects. Elm is a black box, right? It has no connection to the outside world So if I tell you that an HTTP request it's the outside world. It kind of makes sense, right? I need to call some server. It's more than that even getting reading the URL from the address bar This is the outer even getting the time and date from the browser This is the outside world and this basically all those things we call it effects now Today the new version of Elm was really so from now when we call it comments Those effects or those side effects outside of Elm So if we're looking at this code again back to a simpler counter example Just the integer just you know We could we could have let's say an action saying Sorry to get our information from the server then our action would look like that I will have the type action again, and we have two actions One is calling the HTTP request to get the server and once we've got it, we'll have a second action Nothing happens Together This code So let's say I'm inside the function This is the action code That's What It's List Drunk You know stand up and don't go all the way It's just just just to do basically When When it will reach the previous of code is oh now I need to do the actual request and this is the idea of having this pure function And another another I have all this benefit from that or not all this benefit of having this pure function is one of the things The reason why we had to write writing unit tests in JavaScript is that you need to mock the entire world We need to Jasmine catch HTTP and whatnot You don't need that because there is no HTTP calling when you're gonna unit test those functions So now if we're looking at update data from a server, we can see that again. We have a case over here If everything is fine, then I'm then I'm just updating my model If something is wrong with my HTTP, I'm getting an error and this is where elm It doesn't even encourage us It forces us to be better developers because if I wouldn't add this error case, it just wouldn't compile So honestly if I had to write it in angular one, I would probably cut corners and I say yeah I mean, why would the HTTP request won't work? Why what can possibly go wrong and I will just completely avoid it But elm doesn't let me do it. So just for the simplicity. I'm not to do. I mean my return value is nothing I got a model. I'm returning it but Confronted with the fact that I already had to write this error error handling I would probably tell myself. Well, let's invest a few more minutes a few more hours I don't know in you know providing a better error mechanism showing a message or whatnot All right headless Drupal. So I Literally look looked for the in Google images I looked the word ISIS and that way that's one of the first images that came in and I said like it's perfect It's showing everything that I want to show about headless Drupal. I Not even sure myself. I totally understand it, but it's like it just made sense so Drupal, I mean it provides us, you know Users and permission and content modeling and entity reference and restful and and whatnot So we decided yeah, we want to still use it. We just want to replace our angular. We just want to replace our React with something else. So one of the first experiments was our office time watch pretty simple every this is The Israeli law forces that every every employee that comes to the office They need to write their pin and they're getting you know We're just registering when did they keep came in and when did they come out? nothing too fancy However, what helped us what helped us sorry Decide to transition from Angola and actually to jump over react was Hadley and Elm Hadley so if you're already familiar with our Hadley project We have generator Hadley which basically Scaffold's an entire working headless Drupal installation. So you just write yo Hadley and it just you know drush It it creates your Drupal scaffolded. It is sorry scaffolding Drupal It's installing it npm install bow install creates an angular Application and basically it's a fully working headless Drupal It already comes with be hat test and Travis integration basically everything that that you want So we just told ourselves, okay Let's try to replace the angular one and basically create a typical web application that one that has login and logging with weather We log in with github and a routing system and maps and user interaction to filter the events and an article that I can easily drag and drop Files and upload them and create an article on the fly and the cool thing is that All those application you can already use that in your own existing Drupal site So it doesn't even necessarily need to be a fully, you know headless Drupal It can be a hybrid side that Drupal itself is Serving the page and you have this Elm web application inside inside the pages and First of all, I think it's a pretty cool demonstration of capabilities and If even if you're not wowed that's fine I mean, I won't take it personally and in a in a way. It's okay because this is a typical web application I mean I did we didn't the deliberate try to do something Extreme we wanted to see can we you know get all the nodes and permission and OG and what not everything is like we don't care about it. This is just restful serving the information So if you want to start interacting With Elm and everything that I'm saying is kind of right to Elm 0.16 and today was released 0.17 But still you can you can look at the things obviously you can go to elm that Dashlang.org and I'm pretty happy to say that the second example that appears in the homepage belongs to github Which is this and Hadley Hadley example another thing that we've done in Githra is another yo generator for For elm which basically scaffolds a very simple counter example But it comes with gulp and browse browser sync and sass and you can you know push to gh pages And basically it scaffolds everything that you need and it's already connected to Travis and You can read different blog posts some of our blog post that we are writing we're always trying to provide blog posts blog posts that are Pragmatic not just the crazy stuff But how do you do translation of the web application with type safety meaning how can I translate my web application and Be guaranteed that all the sentences that I put them put there will be Translated so you can do that and Just almost to finish the the the last 60 seconds about my own personal functional programming journey slash what about no JS so About a year ago a bit more than a year ago I started with elm and that was the first time I was touching Functional programming and I must admit that up until then I was looking you know looking at stuff like symphony as the holy grail You know everything is object oriented and it's the couple then composition and whatnot and slowly I started realizing Yeah, it's awesome and great. It's beautiful But the objects are mutable and they are holding states so it doesn't necessarily mean it's wrong It's just a completely different approach to solving to solving the problem and once I got into that I told myself Okay, what about the back end? I'm not about to replace Drupal I have a lot of respect for Drupal also a lack of hatred to parts of Drupal But still it's doing a lot a lot of stuff so on it on a not a typical on a quite complex system We might have like a headless Drupal, so we'll have a fronted in elm will have the Drupal itself acting as the headless Drupal But oftentimes we have also like a no GS proxy server So the same problems I have in JavaScript on the client side I'm I'm starting to have with JavaScript on on no JS. I've started to I've actually and Started to learn Haskell and this is a you saw framework which is really interesting And even if we won't use it in production in the end in Giza and most probably we use it and we'll kick No, yes, there is a real value in learning something that is so completely different because I Really got a kick in my developed prayer Developers brain and this is really shifted the way. I'm looking at at a development It really changed my approach and these were Exactly 35 minutes and 60 seconds about elm and thank you very much questions You want to try the mic or oh? Yeah, and I'll The elm you're asking so elm is pretty stable in the sense that It's still it's still a new project in a sense that no it's not a new project It I think it exists even more than react. It's a small a small project The maintainers are doing a terrific job in you know Not breaking stuff on one hand and be very careful, but on the other hand not being afraid on saying, okay We should change that. I Think what I mean my best argument that I can give you is for my own company I'm using elm form in production. That's my that's my argument. Yeah Thank you. Thank you. Hi, and so I was wondering how How much of the like the time do you spend with like the type checking and the types and at the same time? Like house it for like people which are not familiar with for example Object-oriented code or something in general which is a little bit more high-level than the typical procedural stuff Because I could imagine that like for many people. It's like a high barrier to even work on your projects I'm wondering whether you run into any issues or can give some tips about that So I think in a way you are asking also about the learning curve and bringing like junior developers and I have to admit that this is actually became easier because When we're doing code reviews even for G for junior developers if if it compiled I'm already reassured and it's actually We're seeing it. It's much easier for them and in a way kind of the nice side effect of elm part of our Our job recruiting thing is we are giving people an elm task and it's guaranteed Nobody knows elm so they don't know elm and it's a simple thing usually it's a counter again a glorified counter and they make it so It's possible. It's possible to do it and another another fun thing about it is you know When I was reviewing angular angular web application after two weeks. I lost it I I couldn't review it anymore, you know, I'm banging my head that directive and trans clue than crazy stuff With that even month after that I can still easily review because I really understand the flow of the things Yeah, last question You mean a part of elm using other other stuff. Yeah, so part of headly so headly Basically shows that elm can have interop interoperability with JavaScript Which is kind of again. This is outside of the world of elm elm is a black box So you could think about about it as JavaScript as a service, right? So basically elm has ports so if this entire drag and drop the maps obviously I didn't write All the leaflet maps from scratch. This is basically working from port So headly is really showing you all the use cases that you would that you would probably have Another question. Is there any kind of focus regarding server side rendering of elm? So I know it's I know it's part of the plan. It hasn't been done yet, but Stay tuned. All right. That's there really the last one Make it counted So with JavaScript, we have npm and it's a really giant Ecosystem lots of well-written code. What does elm have to offer for package management? All right. So first of all there is It doesn't it isn't as big as npm with all the advantages and disadvantages so I think in terms of You'd probably find higher quality stuff You wouldn't see all the duplication and a nice thing that since elm is statically typed So the package manager if you try to push a change and you try to do like a minor change It will tell you good You cannot it will it will stop you because it knows how to go through your code and understand the API and will Say this is a major change So this is I mean you have a lot a lot of a lot more guarantees on On the stability and this is one of the important thing you're getting a really really stable web application All right folks. Thank you very much


someone who is autistic means at a certain level. Sometimes it can be very bad, that's different. At a certain level, one thing that's happening is not much input gets into him from outside world. Sometimes it's a blessing. Somebody normal means there's too much external input. So, because of the kind of societies that we have created which are observed and twisted out, if you ask me. Because of that, as you were mentioning a certain time of life as if it's problem, teenage means problem, middle age means problem, old age means problem. So, only death is no problem. Isn't this so? People think teenage is problem, middle age is problem, old age is problem. What is not the problem? Only death. So, the only time they're peaceful and still is when they're dead. Unfortunately, this is not what a human being is made for. But we have structured everything like that that a man can never find rest in his life. Rest does not mean physical rest. There is no one moment of ease simply. Structured societies, where you have a house mortgage which is for 30 years, a car mortgage which is for 10 years, an education loan which is 22 years. You got a life term. You're doing your time in an open prison. So, in such a situation, any sensitive human being will become withdrawn and miserable unless they're heavily equipped or completely insensitive. Yes, we're creating such societies. This is our idea of civilization, unfortunately. So, about the boy, without seeing him, we cannot say what can be done. We do not know what's the level of perception. But if he's happy, what's the problem? Somebody thinks he's not normal, so what? That way, none of you are normally in my perception. So, it's okay if he's happy, it doesn't matter. Maybe he can't do a few things that others do. There are a whole lot of people who cannot do what somebody else does here, isn't it? Isn't it so? Isn't it true with every one of us? So, what? He can't do certain things. Never compare one human being with another. If you compare one with the other, everybody's abnormal. Yes or no? Tell me, show me one normal human being here. If you hold any one person as normal standard, there is nobody else like him. That means everybody else is abnormal. So, do not compare and put these titles on children. This one is autistic, this one is ADHD, that one is XYZ. It's not needed. Different people have different levels of competence and capability. It's okay. If it's causing pain and uncontrolled misery, then we must be concerned about it. If it is not, it's fine. So, don't put any titles on the boy.  It's fine. His capabilities may not be the same as somebody else. That means he cannot be a cog in the larger machine. I'm very happy for that. I would like to see every child grows up like that. Not to grow up as a cog in a large, monstrous machine we have created. But every individual blossoms as an individual human being. Maybe our economy then will not be touching some mad peaks, which are anyway... When I look at the economy touching mad peaks, I know we are heading for destruction straight. Yes, we are. We have created an economic engine into which you have to pre-feed your children as fuel. Yes, I wanted to get this straight. We have built a huge monstrous machine where your children are the fuel. You are anyway burning.  From the age of six, what will you become, what will you become, what will you become? What will I become? What am I supposed to become? No, no, will you become doctor or engineer? Tell me what will you become, what will you become, how much money will you make? What is this rubbish? Have we lost it? We've definitely lost it in terms of life. So, at least one boy will not be a cog in the machine and I'm happy. And it's time every parent thinks straight, whether you want to feed them as fuel into that monstrous machine which is eating of the whole planet. Yes, he's not making anybody happy. He's just burning the whole planet. And if you don't feed your children into this machine, at least it will slow down a bit. You can't stop the monster, but you can slow it down. Your girl, you send her here, we'll make her nice and send her back.


Okay, so my talk today is going to be about how I do ZFS powered magic upgrades. So using ZFS boot environments to replace the operating system of servers in the field in as quickly and as safely as possible. So my name is Alan Jude. I'm on the FreeBSD core team and I'm an open ZFS developer. And then for my day job, I work at Clara, which is a FreeBSD professional services and support company. So a quick overview of what we'll talk about today is first explaining what a boot environment is in case you haven't used them before and how they work. And then we'll talk about how we actually create system images and make golden images of using boot environments and then how we deploy those to various environments including remote machines and appliances and then how we can improve the process even further than what I've come up with so far. So starting in the past looking at how this was done on FreeBSD before the days of ZFS. So this is how things like PF Sense and FreeNAS and so on worked until they switched to ZFS over the last couple years. So we have a system called NanoBSD, which was a build system for building an embedded version of FreeBSD for appliances and images like that. So what it would do is take the hard drive and partition it into two halves. One half you would install the latest version of PF Sense or whatever in and you would run off that and that part of the system is mostly read only and there was a small partition at the end where it kept the configuration files. And then to upgrade you would write the new version into the second partition and you would set a flag in GPT saying next time we boot boot the second partition instead of the first partition. The boot loader would then erase that flag once it had done it once. So even if that image didn't boot just by power cycling again you get back to the working image. So if it's a device like a PF Sense that might not even have a video screen or something to connect to it would allow you to just do the upgrade if it doesn't work power cycle it and it would go back to the working image. If it did work you would stay running off the second image set a flag to make that permanently the default boot and then in the future when you need to upgrade again you would just overwrite the first partition and just ping pong back and forth always being able to go back one revision if something went wrong. And that worked quite well but it has some limitations including you have to partition your storage in half so if your image gets a little bit bigger then you don't maybe have enough room especially if it's like an SD card or something. So comparing that to ZFS boot environments because ZFS is taking all of your available storage and making a pool out of that and then using basically thin provision file systems on top of that where each file system only takes space from the pool as it needs it meaning that all of your free space is available to any one of the file systems or all of them. So what we can do is actually have multiple versions of the root file system so we have a version of slash with the current version of the software we can snapshot and clone that and keep that as the before image and then upgrade the system in place and then if the upgrade doesn't work we just reboot onto the older version. So same idea as nano BSD except for you're not limited to two images you can keep the last 10 or whatever however much space you have available. And the other big difference is you separate out the other file systems. You don't do this in nano BSD because you ended up with so many partitions you would run out of space but with ZFS we can make sure that your home directory lives in a different partition. So for example I updated the OS in my laptop and then when I tried to get my talk earlier today the HDMI didn't want to work. So I rebooted, selected the Thursday image from my laptop and then it worked again. But when I rolled back I didn't lose the changes to my slides that I had done on Friday because they were in my home directory which didn't get rolled back. I only rolled back the operating system and the packages not my log files in my home directory or the database on my server or whatever. And since snapshots are instantaneous and don't actually take any space until you overwrite stuff you have no reason not to keep lots of snapshots in ZFS. So it's easy to go backwards. This way you keep as many working images as you want and so no matter how long ago it turns out you introduced the bug you can always go back to before it. So we basically have multiple versions of the root file system and then you can use the menu in the bootloader to select which one you want to start from. And you can always choose to revert and go back and again you don't lose changes to the rest of the system only the operating system. I have a slide coming up that shows how we lay out the file system to separate the operating system and packages from the rest of the system so that you can achieve this undo the operating system changes but not all the other changes on your system. So because of the flexibility you get from ZFS you get to decide what lives as part of the system image and what stays persistent across upgrades or whatever. So any files that end up in the root file system slash are considered part of the operating system. So you'll see in a second how we actually created data set a file system for slash USR but we don't actually mount it so that all the files in USR bin end up in slash and will be rolled back or forward as part of the boot environment. You do have the choice of whether or not you want to include user local in the boot environment or have it be a separate file system. On my laptop I always include it as part of the operating system because it's more often that x something breaks than previous d breaks and that's what I want to be able to undo. But on some of our servers we actually keep the software separate so that we can update the OS without having to touch the software if we don't want. So we have the layout of the default file system set up if you use the ZFS installer on previous d. So we have the root of the pool which we mount to slash Z root. This is so that when you create a new data set so if you create Z root slash foo it gets mounted to slash Z root slash foo like the default in ZFS and then we have this root which is a container for all your boot environments and we don't mount it at all. And default is the boot environment created by the installer and it's your slash file system as you can see it contains the 1.6 gigs of stuff that exist on my laptop as the operating system. And my temp is empty but you see here slash USR well it actually contains 12.3 gigs of stuff it's empty because we're not actually mounting slash USR so that all the files in user bin and user S bin and user lib and so on fall through into slash. But we can create other directories like user obj if I'm compiling stuff I don't want to lose that progress if I rewind the version of the operating system. If I compile a new kernel and it crashes I want to back up to a not new kernel but I want my next build for the fix to be incremental and only take a couple minutes instead of longer. We use the and then again user home is separate so that when I revert the version of my OS I don't revert the version of my slides because then there would be fewer slides and you would be upset. And we do the same trick with slash far where again it's not mounted so that var db package and so on end up in the boot environment but we keep the audit logs the crash logs and the regular logs and my mail in separate file system so they don't get reverted. So we pick and choose what things are part of the operating system and not and that way we can control what we want to roll back and what we want to persist. So when we want to deploy our servers around the world and upgrade them constantly we wanted to basically replace the entire operating system with a newer version and not have to deal with merging config files. You know ETC update or merge master or previous the updates merging thing made me pull out my hair and I don't have very much. So our goal with the way we were designing the new set up for boot environments was just I'm going to just drop down a new version of FreeBSD and it's going to have all the new config files and I'm not going to have to merge anything I'll just overwrite but you know there are some files in ETC that actually matter like the machine needs to know what its IP address is. They're not using GHCP or anything. So how do I persist the config files I care about and not you know every file in RC.D where the version control header change and FreeBSD update wanted me to merge them all. So I thought we'll just make ETC its own file system and maybe only have to deal with that. Anybody have any idea why that won't work? Yes, you know FSTAB is in ETC and RC is in ETC and so you can't find other file systems to mount or give the thing to give the system the instructions to mount ETC if there's not an ETC directory. So yes, as it turns out lots of things in the boot process depend on ETC being there and having the files in it. So without it you have no FSTAB so you don't get swap or any non-ZFS file systems you might want to mount. No ETC RC means nothing starts. NoRC.conf means the machine doesn't have an IP address or know what what's a VLAN. I don't know. And no TTYs mean your serial console probably doesn't work either. So good luck fixing it. So that's a problem but I still really really don't want to have to merge your master. So I stole an idea from nanoBSD. Because the system images are read only they have ETC actually mounted as an MFS or tempFS and then at boot they copy the persistent files from slash CFG over top of ETC. If you've ever used something that uses nanoBSD you might have gone and changed RC.conf rebooted and wondered why it went away. It's because it actually you have to change the file over here which will get written into the memory file system that just gets blown away every time. But I didn't really want a memory file system. So while digging into it I accidentally came across a variable init underscore script in the freeBSD loader. It was originally designed for a system where you could actually boot the system in a chroot. So in the loader.conf you would set the init chroot to a directory and init script was a script that would run first to set up that chroot to make sure it had slash dev and any other things you needed in there before you boot it. So I'm not using the chroot part but I'm using or abusing this thing which causes the system to run this shell script before it tries to do anything like run RC. And so the script I'm using is on the next slide. So we set up this little script so that mounts slash CFG very early while we're still in single user mode so that when we actually try to boot it'll be able to find the first tab and all the other files. And since we have snapshots and so on we don't have to keep it as a separate file system like an N-O-B-S-D to make sure you don't corrupt it or something. So we have CFG with a couple of important config files in it and then we just replace those same files in ETC with a sim link pointing to CFG. So when we slap down the new image it already has the sim link in it and it knows to read RC.conf slash CFG instead of slash ETC. So the script is pretty simple. It runs the mount command with the parseable flag so it prints out tab delimited instead of trying to line up columns for humans. And then we just use a simple shell script to read the device, the mount point, the type and the rest of the line. If the mount point is slash we keep going otherwise we continue and read the next line. If the type is ZFS then we extract the pool so we get this variable up till the first slash and then we just mount that pool name slash CFG and now the CFG dataset will be mounted before we get to the point where normally all your file systems other than slash for ZFS are mounted by the RC or the ZFS RC service which gets run from RC.conf which obviously if you don't have a CFG where your RC.conf is it won't happen. So we mount the one file system early and the regular process takes care of the rest of the file systems just like a normal boot. So we end up with about ten files that we care about in slash CFG and any other file we ship the version we want as part of the operating system and it's never unique on any one server. So all that we really care about is the network settings. Our servers have a slash 29 of static IPs from each provider. We need certain sysctls we set between the network and so on. The SSH keys the important thing was when we upgrade the system we didn't want our SSH keys to change or to have the same SSH key on every machine. Didn't want that either. So we keep them the FS tab because we have different swap configurations depending how many disks the machine has. It might have more swap or mirrored swap or whatever. And yes the rest of ETC we can just overwrite with the stock files every time. We treat almost all of ETC as if it was the defaults directory. The nice thing about this is you never get left over merge markers in your files causing them not to parse and you don't have to ever think about that again or merge all the rc.d files because of the version, the revision control stuff changing. You don't have your configuration if you are based on stock files. The files we care about go in slash CFG and would stay as a sim link. Because we produce the image that we are replacing the OS with. So it's got the 10 files we care about change the sim links and every other file gets upgraded to the vanilla one from whatever version of FreeBSD we are upgrading to. So the way we used to do this originally was spin up a VM, install FreeBSD then like delete the SSH keys and try to clean up and so on. But that never worked out very well. We'll get to that in a minute. So now that we have created this boot environment how can we deploy it to many servers? So on the virtual machine where we've created our image of the newer version of FreeBSD that we want to use we just take a snapshot of the boot environment and use ZFS send to pipe it into a file and we'll exit it as well just to make it smaller. Then on each of the hundreds of machines we want to upgrade we just run fetch output to standard out the HTTP path to the file we created, pipe that in un-exit and then type it in ZFS receive and give it the name of the new boot environment and that file system will suddenly appear then we use the ZFS boot CFG which is the way you do that one boot thing so you say one boot, one boot only and say boot this dataset so it writes into the ZFS label the name of the dataset you selected the loader will then read that and immediately write it over with zeros and boot the dataset you selected. If it doesn't work or whatever again your power cycle when it comes back up that override is full of zeros so it ignores it and boots the original boot environment from before the upgrade so if something doesn't work you get back your working system which is power cycle but if it does work you're booted up in a newer version of FreeBSD at this point in the process we still had to deal with actually upgrading the packages because we didn't ship on our servers we keep user local separate from the boot environment but you could choose not to do that and then we also had to upgrade each jail again upgrading the packages in it and building images was painful a manual using that VM always forget something whether it was fix one of the sim links or re erase the SSH keys or it regenerated the host ID file again or something so I wanted a much better way to generate these images that I was going to push to all the servers because I needed them to be right every time not slightly wrong in a different way every time and the other problem we had is when we want to actually install the server for the first time we'd still have to do it the whole fashion way and then upgrade it and it was not something anyone other than me could really do and that wasn't useful to anybody so in our environment at Skellengine we have over 100 servers spread across 38 data centers in 11 different countries as you can see from the numbers on average there's 2 or 3 servers in each data center so we don't have the kind of setup where you can pixie boot the machines because there's only a couple in each place and so you kind of have to manually manage them and the team there for sys admins was really myself and one full time sys admin and that was it so anything labor intensive was going to be right out and we weren't using the same version of FreeBSD on everything we finally got rid of the last 11.1 machines so that's good we still have a lot of 11.2 machines that need to get up to 12 and doing FreeBSD update was just too manual and too slow fetching 40,000 patches just doesn't make sense on a server with a gigabit connection when you could just download the whole thing as one big tarpile and it would be done so again we have the process where we just set if as receive one boot, reboot machines back up as fast as it can reboot and if it works we just stamp that boot environment as the default from now on if it doesn't, one more power cycle and it's back to how it was and you figure out what was going wrong later this was very nice especially some of the servers are in remote countries like Singapore and we don't even have console access so really try hard not to break it and so just power cycle and it comes back is really useful so in my investigation of ways to make the images nicer I've actually stumbled across pudrare so pudrare if you don't know is the tool used to build the binary packages for third party programs on FreeBSD so it builds all the ports in the ports tree as packages that you can download it does this in an interesting way it uses a jail to build inside of and it does one jail for each CPU you give it because it turns out that's usually keeps the CPU busy better than trying to do one multi-threaded build at a time because during .slash configure and so on it's not actually using all of your cores so running more build single threaded at once turned out to be better and the jails mean that you're getting a fresh image with no pollution in every time and it can use ZFS to revert the jail back to pristine every time and it does nice things because you can have multiple different ports trees that you build from you can build each of those port trees for every version of FreeBSD that you care about on each architecture that you care about and you can build multiple packages for each one so you can end up with a lot of packages so while I was struggling with some of this I happened to get to sit on a picnic table outside in the nice warm air in Taiwan with Baptiste and he told me about Proudrear image that he had worked on at Gandhi to build VM images for their public cloud and it was specifically designed to build customized VM images with like the cloudware packages pre-installed and stuff or to build USB stick images so I looked at that and saw that it could do most of what I wanted build ISOs, MFS based ISOs USB sticks raw disks tar files, firmware images for things like nanoBSD or for embedded images for like Raspberry Pis or Pine 64s because Manu helped with it so my immediate reaction is alright I will add ZFS send as a file format to this so one of the outputs you can get is the stuff to recreate a ZFS pool so I did that, you get two new options one is ZFS send which will take the entire pool it just created and send that as a replication stream or which is what we would use to do a new install or you can do ZFS send plus BE and you'll get only the boot environment part and you'll ignore the rest and that's the image you would use to do an upgrade I modified the overlay handling so Proudrear image has the ability to say here's a directory full of files I want you to put over top of the image before you package it up but it followed sim links instead of copying sim links so I made the option to do it this way so that it would install all my sim links in ETC pointing to slash CFG and I added support for defining the ZFS layout instead of you being stuck with how I like to do it you write a text file with the list of the data sets you want and the properties you want and it will lay out the pool that it creates that way so you can tweak it to have the data sets you want and pick and choose which files end up as part of the boot environment that you create and it uses the same format as BSD install so if you've already written a customized script for script installs you can just copy and paste that it does data sets but you can recursively do a data set in all its children and if you do that to the top then it's the whole pool so in this mode you basically it sends the whole pool as a stream and in this one it sends only the one data set so you're basically controlling whether it uses dash capital R or not and yes for example you can control whether you want user local the packages to be part of the boot environment or not because the other thing pudware image can do is pre-install all the packages you care about as part of the boot environment so if you make user local not its own file system you can also feed pudware image the list of 100 packages and they'll already be installed and so when you do the upgrades with it by just ZFS receiving it it'll also take care of upgrading the packages even which could be really nice so then our other problem was dealing with the fresh installs so I use pudware images ISO MFS support to write my own installer where it basically prompts for the IP configuration and then just creates a new pool and ZFS receives the full image down to onto it automatically and doesn't ask any other questions so my work in progress for the patches for pudware is up on my github I'm still finishing some of the cleanup there I would like to fix some of the naming for the image formats because there's one called ZFS raw disk but it's not what you think it is you can't just boot it that way we need it to not go away because Gandhi uses it for their the images they create for VMs but it's too easy for someone to think it's the image that they want because the name isn't descriptive enough so you can use this to create your own custom images and upgrade them like that the nice thing is the images when you're trying to build a new image it uses the jails you're already building to build packages with so if you've already compiled your custom version of FreeBSD to compile your packages for it just take the files from that jail which also means that you can tell it to create a jail off of release ISO and not have to compile anything so if you just want to customize FreeBSD by taking the release, adding an overlay of your own files and a list of packages you want to pre-install you can do all that and not have to compile anything it's quite nice and I'd like to look at adding more additional image output formats to it like making our virtual machine images like we do for the install images or the official FreeBSD builds supporting for MBR and GPT and all the other combinations that you might want to build your image with because you could also use this to build hard drive images that you could spot down just DDing on to the hard drive to do your install or whatever some of the enhancements I'd like to look to like I said changing the image types so that it's more obvious what each one does and maybe just spelling those out better in the man page and adding a lot more combinations although maybe we want to actually limit the number of combinations so that it's more obvious which one you probably want to use there's another tool that I helped WarnerLosh write in the source tree under tools boot root gen and it generates a QMU image of every possible combination of images to test the boot loader and it fires each one up in QMU with a telnet console and allows you to run expect or whatever to make sure that each one's actually booting properly and it'd be nice to actually use the pudre image support to do this so that you would have evolved less compiling and so on and it'd be nice to also consider having it better able to just have a flag to automatically bundle the cloudware stuff like BSD cloud in it so that when you spin up an image that you've created like this on a cloud service it automatically configures everything for you or supports the user data stuff where you provide the command you want to run on first boot it'd be interesting to actually look at updating some of the way we build releases on FreeBSD to use this pudre image support since it's so nice and since we're already going to have to build these images for packages and stuff we could save some effort too and make it more easily automated another thing I would like to add is support for post build scripts so after it does the overlay I'd like to see each route into there run a bunch of scripts to set up more complicated stuff and then create the image from it because eventually what I'm going to want to do to the image before I ship it is going to be a bit more complicated than just copy these files over top of these other files and I'd like to look at adding more features for building appliances you know if one of the things that FreeBSD is very popular for building appliances but each appliance vendor is kind of left on their own to come up with an upgrade mechanism and if we can make something a little more solid then every appliance based on FreeBSD will do upgrading correctly instead of their own special way each time but if you're interested in the appliance stuff definitely talk to me and if you have other ideas I'm open to looking at them but I don't know how much free time I'll have so questions so the question was about how ZFS boot CFG writes the next boot environment it wants to boot into the ZFS label it does it in one of the reserved areas so it's not going to confuse Solaris or make it incompatible the way Solaris does it I think uses the they call it non-persistent.conf or whatever and the problem with that is if something goes wrong early enough in the boot process where the file system is still read-only you can't set it back to no and so it can end up booting that way more than once or permanently yeah so the problem with the FreeBSD loader is well it's not really a problem but it purposely only has read-only support for ZFS writing to ZFS is much too complicated to do in the loader and so ZFS boot CFG is actually done in the thing before the loader and it knows the specific offset in the label which is at a fixed position on the disk or in the partition that it's safe to write to and it writes the string in there and then the boot loader sees that reads it and then overwrites it with zeroes with the pre-calculated checksum of what's supposed to be there so the label checksum still always matches that way yes maybe not all four I'd have to double-check but yes it uses the ZFS label code and it puts it in one of the spaces that's safe for us to put that kind of thing in and it updates the checksum correctly so the label is valid Delphics end up doing the same thing on their Illumus images but instead of the boot environment they keep track of how many times they've tried to boot and then they reset it to zero and so what their loader does is after it sees three failed boots it purposely boots into a rescue system that phones home and say I'm having trouble booting come fix me because their appliance runs in Amazon and it has no console so it's the only way they could fix them so they just keep rebooting it until it fails enough times to boot the rescue system I've looked at wanting to extend what ZFS Boot CFG does instead of just writing a string of packed NV list or something we could actually have support for both things like say I want to boot this one next time only or keep a fail counter and if it fails I want to boot this other boot environment called rescue or whatever I think it's like 16 kilobytes so that's more than enough to store a packed NV list of like five or six features like that the minimum file system size is 100 megabytes so no you're going to want something more like nanoBSD if you only have eight or 16 megabytes of space because yeah yes I've done the same thing with the TP-Link that had 16 megabytes and it's awfully hard to squish enough of freeBSD down just to have a useful router with only 16 megabytes depending what you're doing you could actually make a new file system read only if we're using cfg for the config files we actually expect to change and we've moved the log files and so on off you could decide to make it read only yes yeah yeah I don't know there's a good way to solve that to tell people don't create just a directory you have to create a new file system if you want that file to persist or whatever yeah a quota would be a good way to catch the problem early before you write a terabyte of data into the file system forgetting that oh I need to create a file system first put a new freeBSD version upgrading the file system with new features and then rolling back to an older version that doesn't support them we don't do zpool upgrade until we're sure we're not going to want to go back usually I'm not after the newest ZFS feature anyway but yes if you're going to go back quite a few versions or something or if you're going back in time a major version then yes features could be a problem it depends on the features some of them like device removal works as long as you don't use it so as long as you can upgrade the thing but as long as you haven't tried to remove a hard drive you can still boot from it even if you're booting from a version that doesn't support device removal as long as you never actually removed a hard drive it's fine or even if you're going back into older freeBSD you've added the support for the new checksum algorithms as long as you've not created a dataset that uses one of those it's fine or even if you as long as you've destroyed the last dataset that was still using the new algorithm you can still import it on an older version that doesn't support the feature so the feature tracking in ZFS a feature becomes enabled once you can use it but it's safe as long as it's not active which means there's a file system that has used it at some point any file system is using it or a file system was and hasn't been destroyed yet FreeBSD does not have a good union file system that doesn't crash union FS or oh yeah well, 8 we're running FreeBSD 13 yeah so on FreeBSD we have support for booting from Gehli encrypted disks I wrote that in the loader and I presented it at FOSDEM a year or two ago ZFS native encryption hasn't landed yet and when it does I don't expect the bootloader to support it right away yeah, it's not really full disk encryption anyway it's the point of it is you have specific data sets so most likely it wouldn't be your boot environment because that's FreeBSD bye if you want to know more Michael Lucas and I wrote two books FreeBSD mastery ZFS and advanced ZFS they're not really that FreeBSD specific so if you're using ZFS on a Lumos or Linux or Mac OS or Windows thing the ZFS commands are the same across all of them some of the things like partitioning might be a little different for each operating system but the content of those books is good for all the operating systems and you can get it as a DRM free ebook at ZFSbook.com or you can buy it in print on Amazon or whatever what's the other big European one and every week I do the BSDnow.tv video podcast and we answer questions about all the BSDs and ZFS so if you have more questions you can write them into feedback at BSDnow.tv and we'll answer them in some future week on the podcast thank you


Come to a new vlog I am so so so excited because this is our cruise vlog number one I don't know how I'm gonna edit this number two I don't know if I'm gonna break it into different sections But I'm going to make sure that you guys know what is day one two three four So today is getting on the ship. Oh my gosh. Look how cute Valerie looks. I am so cute. I am so cute look at the hat Yes, this is my normal cruise hat. I only wear it for the cruise and there's sherry Sporting some stripes finally. Yes. Well, it's nice, but this is my little Mickey shirt I'm obviously wearing this a rose gold spirit jersey because it's kind of chilly here and it's gonna be kind of chilly on the boat I was gonna wear a different outfit, but this is the best fit for me So it's just the usual Sporty outfit that I wear a lot of the time off we go ship ahoy This is the most exciting part guys. We see the ship We are here we are here that's where you enter the ship, which we'll look at later There's Mickey Mouse, okay, so we got our gold lanyards and we got our little stateroom keys I've been posting on Instagram to you go under my Instagram and look at my profile I have like all the stories like saved and stuff check it out. We're about to get our pictures taken Hello, what's your family now? Blankenship grab tree family We just got on the ship as you guys saw they have this place called Cabana. What is it? Cabanas. I was gonna say Cabana Bay I'm like wrong park wrong park. So these are new since we've been on the wonder We haven't had sinks before but this is awesome. Did I get Valerie? Oh my god. This is wonderful This is the buffet at Cabanas Sherry, what did we get? Say it again. Look how realistic that carrot is. It's not miss like a what is that fondant fondant Okay, so we have our Bahama mamas and These are souvenir mugs and we can get them refilled Okay, so we've made it into our room we are in room 85 70 I think so We are going to take a little tour. So here is the bathroom everything is super super small But we have the sink and this is just the toilet area Then we have the shower and we have another sink. This is such a nice room. Oh my goodness We have the closet area. We have the life vests. Then we have this little drawer thing here We have a little seat here, but Sherry's using it for her bags. Oh my gosh We got a little backpack. How cute. I think the Floridians life. I watched their vlog not too long ago They got one of these that's pretty cool We got some luggage tags and because I think we're the gold now I don't know if those are like extra or whatever, but we have a big bed and then we have this is probably gonna be my Bed, I'll probably just like sleep here. We all got pina coladas. So that's what we're sipping on right now We have this little desk area Vanity thing. We have some more drawers, but we're only here for three nights and we have a view Look at our view And this is our little balcony veranda thing. Anyway, that is a murphy bed So we can like pull out and everything which is really cool, but this room sleeps five people ladies. Are you happy? Oh, yes, absolutely We are just pulling out of Cape Canaveral or as Valerie said I bet I'll say it I'll say it. She said Canaveral Hey ladies outfit of the night sherry sport and her black and white. Look how good Valerie looks nice jacket there So this is what I'm wearing. I'm wearing this dress. This is animators palette. It's so cool Yes, it's all black and white I don't know why the lights are causing this like strobe effect, but this is one of sherry and i's favorite things here Look at the little butter knife. It's so cute.  I don't what is this supposed to be? Oh, it's just the number. So for an appetizer. I got a Caesar salad and Valerie and sherry got Butternut squash soup butternut squash soup. All right. So sherry got this stick Valerie got a steak and a potato and I got some salmon a potato and then they also Put veggies so what's really cool about this restaurant is it slowly starts to turn into colors Perfect. Yeah, he's so nice. He always asks to make sure our dinner's okay But um see over there you can see dory and everything's still black and white So it gets a little bit of color. Oh, there's a little rat from ratatouille.  Can we do this? I wish I could share this cake with all of you guys, but as you can see the chocolate How cute that is it says happy birthday. All right, so mothers don't be a card A daughter's love lightens every corner of your heart For being such a beautiful part of our lives for giving us both so much happiness and so many reasons to be proud We love you and happy birthday. Love you so much. Sweetie pie. Happy belated 21st birthday sherry Happy belated 21st birthday, baby kids. G am loves you all. Thanks, Valerie I want to guess Valerie. It's such a Valerie car. Thank you guys To top off the birthday celebrations. Not only did I get a cake I ordered a mickey bar because nothing. Oh, whoops nothing beats a good mickey bar around the disney cruise All right, so they left us a little swan here with some chocolate Oh, I could either choose to sleep here or here look at how beautiful the sky is Sherry can answer any questions you might have Yeah, I want to know that But that's how we take these cruises is because of dvc. We use our points I was going to show you what adults can do on the cruise So there's this whole part of the ship that is dedicated like bars and stuff So if i'm allowed to i'm gonna like film at least some clips so you guys can see So this is after hours and it's like a whole section of the boat So these are the bars. So there's a zero or however you say that the Cadillac And the crown and fin pub. Here's the Cadillac, which this is a place that I want to check out because it just looks so like Cool also in this ship. There is a cute little gift shop here sea treasures. Ooh Oh, this is the crown and fin cherry. There's a spirit jersey for disney cruise It's kind of like a different fabric over here. We have some really cute scarves and different things Oh, I like that bag. That's actually really cute So this is one of the bars one of the little hangout places look at that how cool Wow Look at that So he brought it out on a cart. It's awesome And then the portion Okay, so sherry got a beer. It's a specialty beer. I really want to try it Um, I got a daiquiri urnist hemmingway style. That's what he said Valerie got a sidecar and this is just a glass of water. Tell us how big this is It's 23 23 ounces two beers. Welcome to day two I'm wearing this lily romper sherry's wearing her lily over here But we're eager to get breakfast. This is sherry's favorite thing in the world. It's my favorite thing sherry. Is it everything you've dreamed? So I got cereal I'm not a big breakfast person. I honestly don't like breakfast We are headed to nasa because we're gonna go gamble I seriously love how they always work on the ships every time we dock They're always like cleaning or painting like that guy's doing So this is really cool because the sister ship of our ship We're on the wonder and that's the magic and they're both almost identical ships with disney And they're parked right next to each other. How cute sherry And we have been on both so that's really cool. And then over here we have the carnival liberty We have the carnival Conquest and then that big ship over there is the norwegian Okay, so we just made it to atlantis and look at all of this. Whoa This is like a high-end mall. So there's a max store Rolex, michael kors john bull Look at that. I really wanted to show you guys and then there's the casino right back there So we have come out to look for some food But I just wanted to show you guys some of these yachts that are out here like yo Dream life there. So for lunch because I chose to not have a big Meal of breakfast. I got this Caesar salad and some Doritos. This costs us like a 20-something dollars 17 dollars crazy. So we are leaving the Bahamas. It was great. We went to Atlantis and we gambled and we had so much fun, right ladies What are we doing? We always play bingo family bingo It's just kind of like a tradition here on the cruise. So that's what we're doing right now We kind of are late because we were at the Bahamas gambling, obviously Wait a minute. Are we standing already at the back of the room? We are heading to dinner. It's called tiana's place. We're moving I was going to say that the buildings are moving that are on the shore or we are moving We are moving. Oh my gosh. This is so pretty Welcome everybody Look at how cute this is. Sherry's giving up on pirate night already Look at the little lily pad. How cute is that and we have the best spots in the house. We got some bread Okay, so I also wanted to show they gave us these little beads. What are you thinking about having Valerie? Uh, I'm thinking about having the private I'm still thinking about having the private Tiana So I got some chicken as you guys can see. What do you get Sherry? I got um sea bass What did you get Valerie? Oh my gosh, look at how cute this is they used my sunglasses. They tried to make it look like a human Anyway, I also wanted to you guys. This is a body mirror. This is the first time we've had a body mirror In a room It is pirates night here on the disney wonder and everyone dresses like a pirate I normally don't dress up last year at least two years ago I did dress up and it was kind of embarrassing because I was wearing a dance costume And I met these people in the costume. Yeah this year Yo, it's about two years ago. It's 2018. I was 2016 Yeah, I dressed up during Christmas Yeah, I chose to not dress up this year as you guys can see Adults do dress up. Look at this cute tiny backpack. Oh my gosh. Look at this total cruise theme We just saw it's a wrinkle in time or wrinkle in time. It was like Your your opinion Yeah, it's like You guys welcome to day three of the cruise. Here's mother other mother And I wanted to get a quick little clip of my cute new bathing suit This is from forever 21. Like I said in my other thing I'm also taking my cute sunglasses with my cover up, which I'll show you guys in point one second And this my friends is the cover up. It is so cute. I paid way too much money for this I think it's cute. And I think it was a wise investment. I never have had like a actual pool cover up I'm bringing these because we're going to try to recreate the aspen photo because I'm in like an old fashion looking Type of bathing suit sherry needs to be on her orange cutting game this morning I do but let's go. Okay. Okay. I'm going. Oh and I forgot to add my hat Oh my gosh. Look you can see sherry in the mirror only this floppy hat's pretty floppy I've had this thing since like senior year. I should just turn around like this Flamingos I'm keeping that in the footage. Look at beautiful castaway key What a sight to be seen So pretty we all got some breakfast. Valerie got hers. I got toast. There is a big buffet Cookout on the island. So that's why I'm only having this corn and rips. Don't we baby? Yes, we do They do have really good chicken and then sherry got her locks and bagels sherry. This is what she lives for look at our view We have a table right in front of the island So we have made it to castaway key and I actually got some good pictures So that's good, but we're gonna get on the tram and I think we are going to the adult beach So that's going to be super fun We've never been to the adult beach and we didn't know in the past that you can take a tram To the beach and then we're gonna have lunch and sherry's gonna read by the ocean I am I'm gonna and Valerie's gonna do some shopping Yep, I'm here for lunch. She's here for lunch. This is a map of disney's castaway key So I just wanted to include that because I don't know why so came into the gift shop Perfect only child water bottle for you. Yes mine mine mine mine. There you go And we have to get two of them one for you one for me because you'd have mine mine mine mine mine And I'd have mine mine mine mine mine So this is the little gift shop at castaway key. Look at all the lanyards. There's a castaway key one Oh, I like that one They have like exclusive stuff. That's why I like this gift shop one of my favorite exclusive pens I really like that one, but I also really like this passport with the ship on it And look you can actually open it up and it's like mickey's passport. Valerie really likes this one I actually really like that one too. It's like steamboat willy. There's all of these cool pens. Look at this little ship in a bottle one So we have made it to the adult beach Looky here sherry. Oh, look at how crystal blue the ocean is. This is amazing So quiet No children. This is our current view. Look how beautiful. It is so quiet here Sherry's fallen So I would want to take pictures here, but I don't have anyone to take it for me. Sherry's not the best photographer. No offense And I honestly just want to relax so I might get some clips of the water I Adult beach review. I was happy that I saw it, but I wouldn't go back We all agree that the kitty beach the regular beach is like really fun.  How excited are you? Okay, I feel it Because it's st. Patrick's stick they included shamrock cookies I got a lot of corn as you guys can see corn's like my favorite food. I got some barbecue chips I got some chicken legs. I'm gonna try the pork rib. I think that's what it's called Don't know and a hot dog Valerie and I always stuff our faces because their food is just so good here Alrighty, so Valerie and I got our ice cream How fun mine kind of looks like the ice cream emoji. I tried to Yeah hers is a mess. I try to be creative, but you know this officer only goes so far comment Sherry We did what we wanted to do is so now we're just heading it back to this ship There's a lot to do on the island, but like we just like to chill out and stuff and not really do all the other stuff Now we are headed to the hot tub. Sherry and I are headed to the adult beach not adult beach. Oh my gosh. I have such a Sherry and I are going to the adult pool on the ship We are back on the ship as you guys can see and we're gonna just chill out tan Get in the pool and relax Super quiet around here. I love it And here we are at the adult pool Sherry's gonna try to find a spot in the shade So this was truly my happy time because we went in the pool for a little bit. We soaked up the sun I edited pictures. It was just so magical Very cherry Yeah, so make sure to check out my instagram, which is alex underscore blanket ship It's always linked down below so you guys can see the pictures I'm talking about and I'll follow you back. So Don't forget to check out the instagram. I work hard on that Mother and I have come out to the top so we can enjoy this view and relax for just a little bit Oh, wow. Thank you. Okay. I guess I'll sit around here then Thank you So we are in tritons right now. It is our sea restaurant surprise surprise. It got a salad Sherry got some escargot Okay, escargot Valerie got some onion soup Look at her go. All right, Valerie. What soup did you get? Potato soup. Oh It's cherry And then cherry got the french onion soup as well It's duck. Oh And what did Valerie get? Oh, I think Valerie also got duck I got butter pasta. I was seriously in the mood for this and I just asked and they're like, yeah, sure Sherry got strawberry shortcake sundae and I got a cran brulee The real cran brulee forgot to get the mother's outfits of the night Sherry is sporting the black and white and Valerie is sporting the burgundy jacket with black pants I am sporting my birthday lily dress, which is really really cute and These little heels. We are looking at Ornaments because we like to buy the 2018 every year We get an ornament and this one is super cute. So Valerie is looking for the perfect one. It just says Disney cruise line Exactly the same. That's good I was joking to my mom saying that this should be my 21st birthday present because it's a shot glass And it's like of the engine thing and I think that's really funny. All right I have said every year that they need to sell these We gotta buy one for Alice. I need one. I need this butter knife in my life Every time we're on the cruise. I say they should sell these because I want to steal one one time My souvenir is a butter knife Don't laugh at me I know I have I wanted to document how cute this little bag was From the disney cruise line. They made their own special little bags. We're still trying to find sherry's birthday present She still hasn't found anything. Okay, so we're going to see a production of frozen I just want to show you guys the stage. This is such a big theater on the boat. She found her present Oh my gosh, look at how cute it is I wanted to I've been wanting a crossbody bag And then I wanted my birthday present to be something from the cruise special You couldn't get any place on so it's a special duny and berk. See it's a duny and berk bag And scott, it is all disney cruise stuff on it. See see there's mini and niki and a little wheel anchors Pluto it just couldn't be any cute and it's perfect because it fits all of sherry's qualifications Look at him. He's so cute. I love the little animals. They make we actually have to get all packed and put our luggage out because They come and pick it up because tomorrow at 7 a.m. We have to be down at breakfast And then we're getting off the boat sadly. Look at how cute. It's like a little It's a little jacket there. We are back at tritons for breakfast for our final meal on the cruise ship We have our breakfast. Valerie has that And sherry has that look at that for me. I'm having fruit loops with some milk Well, I'm gonna pour it in you know Some toast well done. We are on our road back home On our way not road Yes sherry Yes, I know sad sad day back home We had a great time leave a comment down below telling me if you've ever been on a cruise because I'd love to know And I think that's about it.  Bye