Hello everyone. Welcome to Cloud Native Live, where we dive into the code behind Cloud Native. I'm Annie Talvasto, and I'm a CNCF ambassador, as well as a Senior Product Marketing Manager at Camunda, and I will be your host tonight. So every week, we bring a new set of presenters to showcase how to work with Cloud Native technologies and they will build things and they will break things, and they will answer all of your questions. So join us every Wednesday to watch live. So this week, we have two amazing speakers here with us to talk about enhancing your GitOps experience with flux tools and extensions. And as always, this is an official live stream of the CNCF and as such, it is subject to the CNCF Code of Conduct. So please do not add anything to chat or questions that would be in violation of that Code of Conduct. Basically, please be respectful of all of your fellow participants as well as presenters. But now I'll hand it over to the speakers to kick off today's presentation. All right, I guess we'll introduce ourselves. I'm Priyanka Ravi. I am a Developer Experience Engineer at WeaveWorks. And I'm Kingdon Barrett. I'm an open source support engineer. Also, I'm a Developer Experience Team at WeaveWorks. And I'm a flux maintainer. Yeah, okay. So I don't know if y'all can see my screen yet. I was just going to talk a little bit about WeaveWorks real fast. Okay, so like we said, we both work at WeaveWorks. And all the tools we're going to show you today are open source tools that are created by WeaveWorks to enhance your flux experience. So WeaveWorks is founded on open source. We've donated a few projects, including flux to the CNCF. And we are the GetOps company. Our CEO, Alexis Richardson coined the term back in 2017. And we've been helping DevOps teams with their cloud-native journey ever since. So that's a little bit about us. And I'm going to talk a little bit about what is GetOps if you are not familiar with it. So GetOps is a, sorry. GetOps is an operating model for cloud-native applications such as Kubernetes. It utilizes a version-controlled system most commonly get as the single source of truth. It enables continuous delivery through automated deployment, monitoring, and management by a version-controlled system. You manage your infrastructure and applications declaratively. And there is an awesome group called the GetOps Working Group. And they manage the site called opengetops.dev. And in here you can find a lot of information, including the GetOps principles that were developed by talking to a lot of users. And so these are kind of, if you don't meet all of these, don't think that you can't be using GetOps right away. These are kind of just what it should be in an ideal state. So you can get started using it and then add some of these in later too. The first one is that a system managed by GetOps must have its desired state expressed declaratively. The second is desired state is stored in a way that enforces immutability versioning and retains a complete version history. Software agents automatically pull the desired state declarations from the source. So something like flux, like we're going to be talking about. And then software agents continuously observe actual system state and attempt to apply the desired state. So you get away from things like configuration drift and because things are written declaratively. So a lot of benefits from that, including, oh, including increased developer and operational productivity, enhanced developer experience, getting away from manual steps. You maybe aren't there on a weekend if someone did something wrong manually and you can't trace what was done. There's an improved stability. There's higher reliability. There's consistency and standardization and stronger security guarantees as well. So that's a little bit about GetOps. What we are going to be talking about is flux. And this is the repo for flux. And basically what flux is, is it is a set of Kubernetes controllers. And if you're not familiar with the concept of a controller in Kubernetes, it handles the lifecycle of objects, what should be done when an object is created, deleted, updated, et cetera. And so it's a tool for, it's a Git centric package manager for your applications. And it's a set of continuous and progressive delivery solutions for Kubernetes that's built with Kubernetes in mind with a lot of the tools that are already existing in Kubernetes. So it's really just kind of drops in place in your already existing ecosystem very easily. And it really reduces developer burden because it removes the need for manual deployment processes. You don't have to worry about being on the right Qt control version, whatever, right? You don't have to do all those. Yeah, so if you want to check that out, there's also fantastic documentation here at fluxcd.io slash docs as well. Then let's see. Okay. Do you want to add anything? And if you want to add anything, can you just like jump in? Please give us a star on GitHub if you haven't yet. Yes, yes, go here and give us a star for sure. We'll drop a link to these as well. Okay, so one thing I want to mention because I'm going to be doing a demo to show, the first one is we're going to show we've GitOps which is a UI that you can put on top of your flux installation that you've already bootstrapped. And yeah, so it's a dashboard web UI and then we're going to show and to install that we're actually going to be using a home chart which is exciting to be able to show how easy it is to set up a home chart with flux as well. And then I'm going to be using the VS Code extension which is a really new feature as well. And I'm going to show that. So that's what I wanted to start with just to, because you're going to be seeing me use it in VS Code even to set up the we've GitOps UI. So you can find it in here. This is our new VS Code extension. It is still being updated and stuff. So if you do notice anything when you're using it just let us know, feel free to give us feedback. We love that. Kingdon actually works on it. So yeah. Yes, this is what I'm working on primarily these days. Yeah. So if you do use it, please, please let us know what you think. And we're happy to, like, we're constantly making changes as well. So all right. So let's go ahead and do this. So I'm going to open VS Code. So I already, let me back up for a second. I already went ahead and created a kind cluster. And one second, sorry. Just a while. Yeah. So I created a kind cluster. And I ran a bootstrap command. So there's a, Flux has a CLI. And it's really awesome. Super user-friendly, very, very helpful as well. So if you need hints and you just do help commands for any of the subcommands, it's great. It gives you exactly what the command's going to do. And then it also gives you suggestions for any flags that has examples too, which is awesome. Can you increase the resolution? Or maybe zoom in? Yeah, let me zoom in. Does that help? Does that work better? If it, maybe more. I think it's just the video quality. I'm not sure if it's your internet or if there's anything we can do about it at this point. But it's readable to me, I guess. OK. If anyone else is experiencing issues, let us know. Right. And I'll try to scroll slow if that helps too. OK, so this is the command I ran earlier. This Flux bootstrap command and go more. And this is from the getting started guide. If you follow the get started with Flux guide on our Flux CD docs that was pointed out earlier, this will get you through, these are the basic things that we usually show in every presentation. We're going to skip over some of these because we've got a lot to cover in more advanced topics. Yeah, so yeah, it's what this bootstrap command is doing is if the repository doesn't exist. So in this case, I'm saying cncf-demo under my GitHub. And so what it's going to do if the repository doesn't exist, it's going to create it. And OK, cool. And if it does exist, then it's fine. It'll just bootstraps into it. So what that means is it installs the Flux components, but it also puts all those files into that repo. So I can show that with us. Yes, so bootstrap is Flux Managing Flux. And that's what we want. We want everything on the cluster to be managed by Flux. Ultimately, that will give you the best coverage for disaster recovery and drift protection. Yeah, so what that's done here is it's created three different files in here. But the first one is this GOTK components. And so this is creating the Flux system namespace. That's the default namespace that everything gets put in. All those controllers that I mentioned earlier, things like cluster role bindings, anything that's needed for Flux. All of those manifests are in here. And then in the GTK sync, the way that Flux works, there's multiple controllers, one being the source controller. And the source controller is actually listening to a source. In this case, it's a Git repository source. And you can have different things like a Helm repo source. There's multiple different sources. But in this case, Git repo source. And you tell it the URL. And what it does is every minute in this case, it goes and checks for any art of manifest that are there. And it pulls those. And then the customization controller actually goes in and applies those manifests. And in this case, it's going to apply it in a 10-minute interval sync. And it's pointing to the Git repo source above it. So just to point something about the intervals out, the Git repository intervals one minute. The customization interval is 10 minutes. But the customization, because it has a reference to the Git repository, is actually subscribed. So when the Git repository detects changes, they go out immediately through the customization. I just saw something about my mind when I was doing that. Okay, so yeah, and along with that too, the 10-minute thing is nice because if something happens, like if some configuration drift happens, some bad actor comes in and deletes one of the deployments or whatever, right? This customization every 10 minutes will ensure that that stands back up. So that's really awesome as well. Okay, so there's that. I'm just gonna add it to this. So there's that. So now I'm going to go into VS Code and do this getting started back, okay. So this, we've GitOps expects that you've already bootstrapped Flux. It's going to then be installed on top of it. And it's gonna be listening to your Flux stuff. So what I'm gonna do now is I'm gonna use this terminal. So maybe I'll, no, I'll use the other one. So it's bigger, keep using this one, okay. So I am going to, let me make sure I'm in the right. I'm going to create a password first for the, for we've GitOps for like actually logging in. So I'm gonna do password equals, I'm just gonna do test or something. Not the best password to have, but yeah. So, and then I'm gonna run this command. And so you can find all these steps on that doc that I showed briefly here. So it's this getting started with we've GitOps doc and you can follow along in here too. So. Perfect. And then there's an audience question coming in. Keep them coming everyone by the way. Ask your questions already now or during the Q&A in the end. So Laurentinus asks, is that code for configuring flux, configuring cluster or both for? So we've already configured flux with the bootstrap. Configuring cluster was done before that off stream. That's, it's a kind of cluster. So there's not really much to configure. We'll get back to that later because there's some configuration, but it's. And I'm assuming they're talking about this, this code, right? Yeah. Yeah. The Git repository and the customization are the underpinning of flux. Those two work together to deliver resources to the cluster. And what we're about to demonstrate now is how you can deliver slightly more advanced software package that requires some configuration itself through Helm and do that in a declarative way with flux. So this is really two part, two payoffs we get from this demo. We get to show you, we've get ops and we get to show you how to install any software package that's distributed through Helm. Yeah, perfect. Is this a good time to take another audience question? Yeah, yeah, go ahead. Yeah. Daniel asks, what is your recommendation on onboarding a service to flux? For instance, from centralized cluster that has flux installed, what is a good way to onboard a service to a particular environment? Well, we're going to show two strategies today. After we get through with our we've got ops installation here, which is really about installing a piece of software for my vendor. So that's onboarding in a way. Then there are two scenarios that we're going to show. One is I'm a developer and I'm building software using Docker build in CI. And I want that image to be deployed automatically. And then the further scenario that we'll show after that is a more production oriented scenario where we're going to have, we don't really just want the image to be updated. We might have some manifests that need to change too because it's a new release of the app and who knows what is going to change from one release to the next. So we'll talk a little bit about semantic versioning too while we're in here. Yeah. So what I did real quick was, I don't know if y'all can see this. Let me get rid of the least that maybe. This is good. Okay. So what I did is I added a, oh wait, I did it twice. One second. So I added a, no wait, that's one more. No, I think you just deleted the file. Yeah, yeah. Let me leave that alone. Yeah. So this file says do not edit. That's because it's created by Bootstrap. Oh, did I open? Oh, here it is. Here we go. Yes, it goes in here. So we're computing resources together in the same file as, you can do it that way or you can put them in separate files. That's okay. Yes. So I used the Fluct CLI real quick to just create the source and the customization. So there's multiple ways you can do that. Obviously the CLI is a really good way to do it. And then I did the export command which then doesn't actually create the source. What it does is it actually creates the YAML and that way you can push it to get and let it manage itself. And then I created like, I'm gonna grab this password robust. So, and then I'm gonna put it replace this one in here. So these values are copied from the example in the getting started guide for Weave GetOps. If that wasn't clear. So what this is doing is, I said that the source controller can also listen to a Helm repo. So this is actually pointing to a Helm repository, the Weaveworks one. And then what the Helm release is saying is stand up this chart but then also with these specific values. So this is a really cool way to override your values and everything. And then, yeah. So it's specifically the Weave GetOps chart. And yeah, sorry, got distracted. Okay. So I'm gonna save this and then I'm going to push it to get. So I saw you put this in the flex system directory and there's a customization YAML file here. You know me. You know me so well. We have to add it here because this file is, if this file is here, it needs to have the whole list of all the manifests to apply. If this file is missing, flux will just slurp up everything that's in the directory and that's fine too. But we're gonna show some of the functionality of customize in terms of resources and bases. And you can connect. I'm not sure how much of that we're actually gonna show today but we have a few things that do use that. So there, just skip one error. Perfect. That wasn't your intention, was it? You're aware of it. No, no, no, it's, you know how I am. I always forget to add it to the customization file and then I don't like to have it. Yeah, that's why I stopped you. I figured it would be. Thank you. It's like, I can't, I just, I don't know. Numerous demos and I always forget. Okay, so the neat thing about the VS Code extension is, well, one of the neat things. There's several neat things, but the fact that you can see the sources, you can see the workloads in here and then you can actually go in, reconcile them and so force them to actually go and fetch and then suspend them. So let's say you were making a change in Git but you didn't actually want it to be realized in your cluster yet. You can suspend either the sources, you can also suspend the workloads and that way it won't actually realize that change until you resume it again. So I am a really big fan of this extension. I think it's really neat to be able to just code and then also apply these changes right away. So, and then you can see it in the output that it did fetch that. It's all about minimizing context, which if you have to go find a terminal in order to figure out if it worked or not, you're already host. You lost it. Yeah, and if it has failed, it would be a red X as well. So hopefully something will go wrong sooner or later Maybe I should have left that. Well, it wouldn't have failed, but it would have just not applied it. And I would have been like, why? Okay, so now if we go in here. There's two more audience questions by the way. We want to take them now. We can always just take them in portions as well. But there's, for example, Sankara asks, can the Git repository configured in the Fox Bootstrap be local clone? That is, can these be used in a test environment where a developer has pushed changes in local repo and wants to deploy the update in some cluster for testing? That's a good question. So the Git repo has to be addressable from the Kubernetes cluster. So it has to be hosted somewhere. It cannot be a local repository on your hard drive that doesn't live on a network anywhere. But there are examples. We've had, I host a weekly meetup called the FluxBugsgrub and we have a YouTube channel where you can see sometimes we have a presenter. We did have one presenter who wanted almost exactly what you just described who added DNS entry through Core DNS and it was a really neat presentation to show how local you can make it if you can host. Like, can I host a Git repository in Docker adjacent to the kind cluster? Yes, and we have examples of that. So we're logged in here. Then there was another one as well. If you leave off the dash-dash-export flag is the change made immediately? Yes. So if I left off the dash-dash-export flag when I was creating a source, it would just create a source. Directly in the cluster without putting it in the Git repository. Which isn't really in the spirit of Git. So you do want to do the export and push it. But you can also create it and then, yeah. So it's not like, yeah. And all of that. There's also FluxExport. If you do it in the opposite order, just because you'd like to know that it works before you commit it to the Git repo, that's a really helpful workflow too. So you can FluxExport a Git repo or anything else that you create through the Flux CLI. Yeah. Great. There was one more question, or do we want to move a bit more forward in the demo? Let's queue a couple up here and let's see if we can make some progress. We have a lot of points to cover. Yeah, okay. Yeah, let me just show this UI real fast. Yeah. So in this, we getups UI, you have the application. So this is showing, in this case, the customization for Flux system, the one that we bootstrapped and then the we've getups Helm release itself. And if you go to sources, then you can actually see all the sources that are created. And so these are the ones that we've created in the Flux system namespace. And then Flux runtime actually shows all of the different controllers that are part of the Flux runtime. One thing I didn't mention really quickly is that if you do bootstrap, just base bootstrap command, then it won't install the image controllers. So there is a little extra flag to add, as you can say, add these additional controllers as well. So I did that when I bootstrap, so that's why they're here. And then- Components extra if you caught it or if you didn't, that's how it's called. Components extra is the name of the flag. Yeah. And then if I click on these, I can actually see the different components that are in this managed application. And then in events, you can actually see the events that have been going on. There's a graph to see the breakdown. I think it's better if I show this in later when I do the pot info example. But so I'll come back to that and then YAML. And then as I mentioned earlier about being able to sync and suspend in the as code extension, you can also do it in here as well. You can hit the sync button to force a reconciliation or you can suspend and resume it here as well. So that's the UI in a nutshell. Now I'm going to deploy. Well, we'll answer these questions first, but basically what I'm gonna do in a second is I'm going to deploy a pod info application using the image automation controllers as well. And then I'll briefly show it in here what it looks like. And that way you can kind of see how the image automation controller works. And then I'll pass it off to Kingdon. So we'll answer some questions real fast. So we have one question about, two questions about declarative principles. Is it okay to use external secrets? And is it okay to use templating tools like Helm and customize to template your YAML and then apply from the YAML? So Flux itself has customized built in. So we obviously don't think that it's against declarative principles. Flux customized controller is limited in what it can use in terms of external plugins, since those involve a shell out. And that's where we found the vast majority of security issues creep in. We don't support that type of behavior. So we'll sort of limit you to the more declarative things that you can do and shun you away from the imperative things that you could do with customize in a different scenario. Templating a Helm chart is something that you can do. No one will stop you, but the question is, what do you do with the template and will it break your Helm charts? Because that's how some other Helm tools work and they'll template out Helm and Helm has these hooks that are lifecycle hooks for when a chart is installed or upgraded for things like we need to migrate a database. And those things have to happen in a certain order. Sometimes the way that templating shakes out, they don't happen in that order. So the point of Helm controller is to be as close to Helm as possible and to do things the Helm way everywhere. So we wouldn't recommend usually to do templating in Helm because we support Helm on the metal, I guess. It's the best way to say it. And as far as external secrets, no, I don't think that's against declarative principles. There are some guides on how to do secrets with flux. You can use SOPs, for example, that's the one we support the most. But we also have integrations with HashiCorp Vault and there are a lot of docs supporting how you can do GitOps and declarative secrets that way. Other tools like KMS that are not necessarily open source for various cloud vendors. Those are also supported through SOPs. Yeah, I think that's all right. Was the Daniels question about monitoring the Fox GitOps deployment status? Are you there already? So there are... I haven't looked at myself yet. I've heard that's very good. Yeah. Yeah, so there's a flux monitoring guide that will show you how to set up flux with CUBE Prometheus stack and all of the flux related graph on a dashboards. We always wanna mention this too when we're talking about flux UIs broadly because this is the original flux UI as the graph on a dashboard. There is one dashboard for flux controller status or control plane and another dashboard for fluxes workloads to show you if any Git repositories have failed to sync, for example, there's an alert manager configuration that will help you see if any flux resources are not reconciling for longer than 10 minutes. Those are definitely key for production flux deployments. Yeah. Yeah. Yeah, so if there was like a helm chart or anything like that, you could set up, like you said, notifications to let you know. Yeah, and at the base level, when you're having issues with flux, you wanna go in and start describing resources because every resource that flux has will raise events as things are happening. So if you have an error with a helm release, it may say helm chart did not exist or was not ready.  Was it an authentication failure? And you'll get those details in events. They show up at the bottom of the described block or if you have another system like Loki for consuming Kubernetes events, they'll show up in that. Okay, I think we'd better try to... Yeah, okay. So one thing I wanted to mention real fast is that we're about to use this pod info application that probably a lot of people, like I know a lot of people are familiar with already, but we, Kingdom made a couple of changes. And so we basically just added an Ingress so that I don't have to do port forwarding and all that stuff. So we discovered this whole thing and we just wanted to show it to y'all real fast. So in kind, when you are heading up the cluster, you can actually create the cluster with this and with these settings. And then if you install one of these, you can actually just use an Ingress normally. So this was just like a cool thing that we... So yeah, why do you use an Ingress instead of port forwarding? The main reason is port forwarding is a clunky, very devish solution for getting access to a pod. And it gets you access to exactly one pod. So for a demo like Flux or Flagr, if we were doing a Flagr demo especially, when you want to be able to access multiple pods and see the transition between them, it's not really a great way to do a demo. So we wanted to have Ingress. And fortunately, kind has these great documentation now about exactly how to do an Ingress controller in a kind cluster. There are about three steps to get it working. It's really easy compared to a year or more ago. Yeah. So I have already said the CMO, so I'm just gonna copy and paste it, but then I'm gonna walk through it real fast. So this is pointing to a... So the original pod info project is under Stiffon and Kingdon's forked that and then I forked Kingdon's project. So the one that I'm pointing to is a fork of a fork. And so mostly because we were just testing out image automation stuff. So that's what the source is pointing to. And then what we've done is we have two separate customizations in this case that are pointing to the same source. And the first one is pointing specifically to this, like this path within that repo. And then the second one is pointing to this.customize path. So what those are real quick is... Oh, wait, sorry. The deploy overlays on my... Okay, so in here it's actually setting up the... We have our image policy, our image repo or image automation set up. So if I start with our... So I'll start with the image auto.yaml. This is... Whoa, I'm lost. Oh, I'm lost, I'm sorry. Okay, so this is actually setting up our image automation, like image update automation stuff. So these are all the parameters for the thing that actually writes a commit. Right. There are three parts to the flux image automation. There's image update automation, this resource. There's an image policy resource that says what image, how do we know which image is the latest and which images to select from? So that's a regular expression there. We'll see what kind of image tag that matches in a sec. And then the third thing is an image repository for the image reflector controller. This just reflects a tag list. So it goes and looks at that public OCI repository with images in it and says, this is a list of images. They get filtered through the image policy. The image update automation looks for the latest, if it's different than what's in the repo already, it will write a commit and update the repo with that new image. So that's what we'll see. And then one thing in here just to point out is this. So what we're doing is we have a dev branch. And King and I wanted to show what it would look like to just have a dev branch that's continuously being updated regardless of what version it is, right? Major, whatever, because it's a dev branch. And so what we came across is an accidental loop where in the actions, we have it actually set to build an image if there's a change made. And then also this is gonna make a change to all the image versions in here. So every time they made a change, it would kick off the action. And yeah, so it's back and forth. So this is to actually tell it to see I skip when it is doing the image automation. So yeah. And these parameters for the dev branch, maybe we should explain those as long as we're in here. One points at the branch to check out and the other is the branch to pull to push to. So those can be the same or they can be different. The idea being maybe you want a main branch to be the starting point and you wanna create a pull request from that. There are those examples in the docs. This is just a single branch to keep things simple imagine it's a dev branch. And this is where all of our changes go. I added it to the customization this time. Okay. So now if we're going here and we reconcile. And like Kingdom said, when the source finds a new version, it will also kick off the customization. So that's why I'm not like also then going in and reconciling the customization as well. All right, let's see. I think it might just be running. Well, I made a note of this and then I, okay. So I have to also create a secret because it needs to have access to write to the repo as well, right? So let me go do that real fast. Yeah. So the bootstrap steps only create a read only deploy token in the cluster by default. You can bootstrap with a read write token if you want, but this is the point where we always point out how potentially dangerous it is to have a read write deploy key anywhere. And one of the reasons why we wanted to highlight the difference between how you might do this in dev versus how you do it in production. But obviously branch protection policies are something you should consider if you're using something like this so that you don't have the possibility that you will, your deploy key is compromised somehow. And then your main branch is overwritten with whatever the hackers put in there. It's this one, right? Yeah, that looks right. Okay. But I mean, I just have to change the. There's been a few audience questions as well. I have a good time to go through them at some point, but we can also, you know, power through a sections of the demo if that works better. So I just ran that command to create a deploy key and then I'm going to go into my project and put it in there. You can ask the question, I think it's okay. Okay. So we had share asking according to the declarative principle, there should be no processes between the desired and actual state. So doesn't decrypting secrets go against that? So I think the question is really about hermiticity. The question is, is the cluster reaching outside of itself to find anything? And the answer is yes, it is always all the time. If we're doing GitOps, the Git repo almost certainly does not live inside the cluster. It will live on GitHub or it will live on a remote server somewhere that can survive a disaster that downs the cluster. That's the point. So it's not a violation of declarative principles or GitOps principles to reach outside of the cluster for something and it is not really a violation to do something functional in between, something without side effects. That's I guess, I guess that's what we're talking about. So I mean, you can have a side effect that could be we've rotated the secrets outside of Git. And now we don't have a way to recover the cluster into the exact state that it was before. So yes, this is a way that you can shoot yourself in the foot, be careful. There are two different models. You can have secrets in the Git repo which has its own set of drawbacks. Those secrets obviously have to be encrypted. Those encryption keys have to be protected. And then the possibility that they are ever compromised, you need to have a plan in place to rotate them. Those things are also all true if you keep the secrets outside of the Git repo. So it is complicated to handle secrets. That's really the nutshell version of the answer. And you don't want secrets in the open or there won't be secrets for long, especially if there are secrets that can compromise critical parts of your deployment infrastructure like your Git repository or your cluster admin credentials. Those are all possibilities that you need to be aware of and engineer around. So Flux does the most conservative thing by default. That's one of the design principles of Flux. Okay, sorry, that was a, I don't know if you'll notice the pumbling, okay? So I forgot that we named the secret very specifically. So, but I just adapted that. So now this is running. So the image automation is also running and the pod info stuff is deployed as well. So if I was podinfo.local, right? So we can see here, it's deployed. And we can see that the version is 6.15-alpha.one. In the podinfo project, we have this, did I not have that one? I did. Handed in the make file, right? Yeah, yeah. We have this make file. So if I go down here, in this make file, there's a command called version set. And we can use that to basically show y'all how the image update would be. I'm going to run a command request, so. So there's a chicken and the egg problem that this version set represents. And Flux, we've been talking about how Flux can update manifests to point at the latest version of the image. Here we're doing it in the make file. And imagine that this is part of your CI or your release process. We'll do it manually instead. And that is to avoid the chicken and egg problem that Flux can only tell you about images that have already been built. And we'd like for this version number to be correct in the image. It shouldn't refer to the previous image in a new image. So for in the tag, maybe those manifests don't actually go into the image itself. All right, so we updated the source code and the manifests to have this new version number in it. We're going to push a new commit here. And that's going to trigger a Docker build. Yeah, we've got to commit that we have to rebase over because automation is also working in the background. All right, this is going to trigger a Docker build. And this Docker build is based on a new example that was added to the Flux docs very recently in the... Oh, yeah, here. Use cases section. It's a... By the way, while we see this, a VK asks, is there recording? This is not a recording. This is live. And we're going to get to the audience questions soon. So don't worry VK, your question will be answered. I had it somewhere. Yes, the Git repo that we're working out of right now is github.com slash Priyanka Ravi, Priyanka-Ravi slash PodInfo. And there's another fork at Kingdom B slash PodInfo that I've been working on. So we'll see that at the end if we get all the way to the end. We're doing a dev deployment now from this dev image. We'll do a slightly different deployment at the end with a Helm chart. That's pushed to an OCI repo. So the reason why we're working out of several different forks is to have what we really wanted to show was like this concept that you would have... Some people are working in their own forks and then there's a main fork that the org owns. So pretend that I'm the org because we don't have Stefan here today. It's his original work, but we basically hollowed out the github workflows just to demonstrate this really simple workflow because PodInfo is really a staging ground for all sorts of new and advanced features. If you go and look at what Stefan Prodan has done in his original PodInfo repo, there are a lot of really advanced github workflows in there and there are some that go back quite a ways. There's one to publish a Helm chart to a Helm repository. There's one to do a cosine trustless artifact verification. I don't really know the details about how that works, but it's an example that's in there and there are details on the Flux blog about how you can do cosine verification and what we're building around cosine in the Flux project now. But we wanted... I really wanted to have an example in the Flux docs of what is the simplest builder that you need? You don't, you know, because we've got a lot of people that come for support who have big involved CI pipelines and they wanna know if they can use them with Flux. And the answer is usually yes. If it produces a container image, then yes, you can use it with Flux. But we get pretty unsatisfactory results from answering the question that way. It's probably better to show people what's the minimum viable answer. So even though Flux considers CI completely outside of its own responsibilities, we did add a document showing how to do CI with GitHub Actions and a few other GitHub Actions related docs. Also other CI platforms like Jenkins. So our build succeeded. There's a new image out there now. Flux may not have seen it yet, but any moment now we should see a response from the new one with alpha.2, I think, right? You did very well. Yeah, that's where I put it, I assume. Sure, just asked a question about OCI Helm repositories and renewing the token when pulling the chart. There is documentation about how to renew a token. I think that there's our new app. All right, yay, it worked. So we didn't have to update any manifests. Flux did that. If you go find the commit that it made, you can get pull that commit and see exactly what it changed or you can check it out here. Excuse me. So back to the question about renewing the token. This is kind of a specific question. We have examples in the docs about how to interact with ECR. They're not specifically focused on Helm yet because this is a new feature and we're building more features around it. But yes, there is support in the docs for if you search for ECR in the Flux docs, you'll find a lot of information including how to write a job that will renew the token. There is an auto login feature. I'm not sure that that has made it all the way to the Helm repository OCI feature yet. So if not now, then soon, you will also be able to use leverage cloud credentials like IAM roles to connect to an ECR and you won't have to manage renewing the token yourself. Great, then there was another question for sure, which was, are there any features that Flux has compared to ARCO CD? There are certainly a lot of features that these two projects track each other pretty closely in terms of new features. When ARCO CD comes out with a new feature, we are always hearing about it and we have people coming and asking, can we get this in Flux too? Application stats is a great example of that. And so Flux has this native Helm support. That's one thing that's definitely has over ARCO CD, in my opinion. Is there anything else that we can highlight about the difference between Flux and ARCO CD? I know that there are blog posts out there about the specific topic, but they are always getting out of date because it's a big competition. We'd love to be able to say that Flux does all these things that ARCO CD doesn't and it never shakes out that way because everybody's trying to keep up with everybody else and it's great. The telephone controller is a cool one, I guess. The telephone controller is one of the features but it's built on, I think that architecture is the most unique feature of Flux. So performance based on that architecture is also something to call attention to. Flux has a very low footprint on the cluster. It can run in a few hundred megabytes. Helm itself is not very, it wasn't architected to run as a server. It was architected to run as a CLI. So it doesn't have the same focus on low memory usage and performance in terms of stateful workloads. But all right, so we wanted to talk a little bit about semantic versions and what does the version number mean? We have a semantic version number here with a pre-release tag. So the dash suggests that this is not a release version but a pre-release with some information after the dash. And if you want the details about semantic versioning there, semver.org but rather than read the spec, I thought we could talk about semver and how you compare it to another versioning strategy that's not semper like marketing versions. If everyone's ever heard of marketing version, this is not really a scheme so much as just a way that things are done. This is the version, the number go up approach to versioning where when you have new features and you want to highlight some particular release, you make the first number bigger and it's great news because we have a new version number. This is totally different than semantic versioning where the new number in the major place means you need to watch out because something is going to break when you do the subgrade and it's a different type of versioning. So when we're using semantic versions, we'll, Helm charts, for example, are semantically versioned. That's one of the requirements of Helm chart. And maybe this is a good time to share my screen here so I can show the Helm version of this in production here. So, okay, so I have a few namespaces here. I have one pod info helm OCI namespace where I've installed using a Helm release. Let's see if I have the right editor window owner. Can everyone see my screen? By the way, this is okay. In our deploy directory, in the overlays directory, this is where we were looking before. We have this example, Helm OCI that we have deployed as cluster. And we'll show a Helm release and a Helm repository that make up this Helm OCI. So this has a lot less in it than the Helm release we saw before. I haven't specified a version number. I haven't specified any values. We're just installing this chart with the default values. And we're gonna put it into this target namespace pod info helm OCI. And here's our Helm repository. This is the new feature, this type OCI. If you'd like to take advantage of an OCI Helm repository, you can point at something like this. This one happens to be public. And so there's no secret required. If I go to my pod info directory where I had released version 6.1.18, I'm gonna release new version. So I need to update the source code to reflect that new version. You saw that happening already once. And think these example. Signing my commit. Don't have to, but you can. And then I'm going to tag that and push that tag. And that is going to trigger the Docker build workflow similarly. Here's our pod. Quick question from the audience. I hope quick. Does it support internal repos, something like Artifactory? Yes. Yes, Artifactory is definitely on the supported list. We have support for any kind of Helm repos that are out there now, I think. We also support GitLab. What else are people using off the top of my head? I can't think of another one besides Chart Museum. But there's definitely, the Helm repository format itself is really simple. There's an index.yaml at the root that has a list of every version of every chart. And this is the reason why it doesn't scale particularly well. This is why OCI is such a big advancement for us and why we're so excited about it. Because fetching a list of tags is very efficient compared to fetching a YAML file that's full of metadata above and beyond just the tag number itself. So I wanna make sure that we don't miss this deployment here. You see, 51 minutes ago, we had a deployment. And like I said, it's just gonna select the latest release based on this manifest. So there's no version number. So it's just using semantic versioning to determine which one is the latest with no restrictions and it'll install that. Did we have any other questions? Yeah, a basic web server is all that's needed for a Helm repository. You don't have to have anything special. Okay, so this is finished. And let's go and take a look in here at exactly what we did. I wanna call out this step here because this is different than what's in the docs. We used Helm push. So in a previous step, we did Helm Lint and Helm Package and then Helm push from the artifact. This is just pushing a targed GZ file to an OCI target. And this is a built-in feature of Helm. And I wanted to call this out because next month I'll be showing a brand new feature in Flux, which is this rehashed for customizations. So instead of requiring you to use a Helm chart to get this behavior and this behavior, by that I mean atomic releases where we see this happening. All the configuration comes with the new image and they get released at the time that you say, not necessarily at the time that the new image is first available. This is better because you like to test your artifacts before you put them in production and you simply can't use Flux's original image update automation in that way. It only monitors for new images and pushes them out immediately. So you can add a Cluj so that there's a pull request between this point and that point, but really what you'd probably like is to separate build publish from release. And that's what this accomplishes. We get to publish our artifact, test it out and then release it at our leisure later or automatically through Flux. So that's what's just happened here. We have a few minutes left. So if anyone has any super quick questions from the audience, you can leave them to the Q and A chat now, but we have to start wrapping up soon as well. I did want to just mention the Terraform controller real fast. So it's a like another one of we've worked as created tools and it's kind of the newest one. It's the, what it is is you can do manual approvals or auto-approves. So basically you can manage all your Terraform resources regardless of whether they're in Kubernetes or not, but it is kind of like a nice marrying with GitOps and Terraform. So it's still using the GitOps workflow. There is a TFC TL CLI that's really awesome. It also most recently has integration with Terraform Cloud and Terraform Enterprise which is really cool. And you can even set the outputs into a Kubernetes secret as well. So I do have a demo already out there on that that you can find on our Weaveworks YouTube channel. So if you are interested in learning how to get off to find your Terraform deployments, you can go check that out as well. Perfect. So we had a few questions, really quick answers hopefully. When referencing a third-party Helm chart, can I use values file in my GitHub repo? Yes, there is a feature, you can select a different values file. So like values production, you can do that. There's, if you have different values files, you can select them, you can group them together and merge them, those things are all possible. Perfect. So then further diving into flux and Argo, so how does flux compare to functionality in Argo like sync wave and phases? I'm not familiar with phases, but I heard of sync waves before, and my understanding of how they work is that you sort of give everything a number and they sync in that order. The way that we do it in flux is more explicit. There's a depends on statement, you can say this customization depends on another one. And then in each customization or Helm release, you have an option of whether it should do health checking or not. So sometimes you just wanna like, I need the CRD to be installed in the cluster. I don't care if anything's ready. You can have dependency that doesn't wait and works that way, or you can have a dependency that waits where say you have some admission controllers and we really wanna be sure that they're firing before we let any of our tenants try to put anything on the cluster because they're bad people and they're gonna break it if we allow them to. So that way you enable wait and then there's health checking that gets performed and that's part of the dependency check too. Perfect. Then final question, hopefully with a quick answer again, related to the third party Helm chart question before, if the values file is from a different workflow than the chart question mark. So you can incorporate values from config maps on the cluster. You can incorporate values from other sources. The values are composed in the Helm release itself. So wherever the Helm release comes from, you can bring in values from where that is. You can also, there's a feature we didn't show today where Git repositories can be composed together. So if you have resources that are in two different Git repositories, it kind of works like sub module, but it's a little bit better in some ways. It has better performance characteristics and caching. So if you do have things that are in separate repos and they need to be brought together, yeah, Flux can do that as well. Perfect. That wraps it up. Thank you so much to our amazing speakers. Really nice quick answers in the end as well. Love it. So thank you everyone for joining the latest episode of Cloud Native Live. It was really great to have a session about enhancing your GitOps experience with Flux tools and extension and really love the audience interaction this time as well. Thank you so much everyone for your questions and comments. Yeah, and next week we will have a session on using Litmus, KOS Engine and microservices demo app to demonstrate automated RCA. So thanks for joining today and hope to see you next week. Super.


What is up everyone? Happy Thursday, December 14th really nice green day today plus 1242 for winning trades we had that big uptick yesterday in the markets and kind of played off that so Had three longs and one short. They were all winners. So Apple Small winner there kind of scratch trade didn't really go anywhere for me plus 42 Roku though Good winner there 435 Actually gave some back towards the end Oh, I should have been really huge and Tesla had a nice add to Tesla plus 510 and then this was a Downside continuation runner That was a nice winner. So Apple so I took Apple as an upside continuation runner pretty quickly Right out of the gates here had nice push up and some some stocks were pushing down and it was just holding right here So I went ahead and got long right in here and It ended up somewhere in here I think it would have came up to here I got out of half and then I just started to chop so when it came down here I just cut it and it just hasn't gone anywhere. So that's why I was a scratch trade Roku See kind of same thing, you know, you look at like Microsoft Netflix Amazon, they were all pushing down Well Roku was holding so right here. I got I got long right here as It pulled back into these pivots and then rode it up and just was scaling out Then I had a few contracts left and when it came back down Here to the pivots. I just cut it down here at the bottom So looked like it was gonna push through the pivots and it did So definitely a good out there Tesla Tesla pushed up Pulled back to right here and right at this first red bar again Other other tech stocks and things were pushing down. So I got along right here because it was really holding it came down some more and I added to it right here and boy, was that a great ad because It pushed up and I scaled out and then when it started coming back down. I got out of it I think I think I got out of it as it pushed back through this pivot right here So Just didn't want to you know, I had this great ad right here and I didn't want I didn't want to lose any profits Like I did in Roku And then Microsoft Microsoft had this pushed down a little bounce Pushed down on this little bounce here. I got short and wrote it down scaled out And then had a few contracts left it started to bounce and I I got out of it like right in here where it looked like it wasn't Gonna roll over anymore. So Just bailed on it there right in there. So I'll take it nice nice winner plus 1242 always love four-figure days Then for the week, let's pull my Spread sheet over here for the week 13 total trades Only seven and six a little over 50 percent But plus 1,729 dollars for the week on three days of leading the livestream So pretty pretty Even in terms of number of trades per strategy One and two for the mighty 90 So basically scratched there Two and one for the volume runners. I had that Big volume runner in square yesterday So took some profits there four and three and continuation runners plus five seventy two For seven twenty nine keep your losers small. That's the goal. So Hope everybody has a good weekend. I'll see you by next week. Peace


I hope you had a wonderful weekend. Got to see something fun, maybe? Maybe on Sunday, maybe Saturday is a little rainy. Today, yes. Yes, that's right. That's right. OK, so hopefully you see this. Yes, that's right. All right, so today I'm going to skip a lot of some of this because we've had a lot of the same stuff. So actually repetition may be good, so you can really learn it. So some of it will go over very quickly. Basically, Sam did a very good job talking about this. If we have some sort of a target that's funny shaped, if we want to do 3D conformable, we can do a nice uniform dose distribution when we add the beams. But if we want to get a concave shape and shape the dose around some structure, then we really need IMRT, we need some sort of intensity modulation. So for example, in this case, you can modulate intensity with one field. You combine it with other fields. You can have some area in the middle, has low dose, and get high dose around that. Here's an example from a paper. Same thing. They have this C shape, and they have this intensity modulation for multiple beams. You get some nice, beautiful things that you can do that you can't do with just normal 3D conformable. And here's another example showing these are different. This is the intensity map for each beam. And so you have higher intensities, lower intensities. You combine that all the way around with multiple beams. You get this beautiful distribution. All right, so difference between forward and inverse planning. So actually, you can do IMRT with forward planning and inverse planning. And Yakov had some slides there showing kind of this breast plan where he had 110%, 105%, so on and so forth. That would be like a forward plan where you decide everything. You decide which beams you want to use, the geometry, collimators. You decide these MLC positions.     You say, I want this dose. And now you give me what I need to get that dose. And so you do decide the geometry for those beams, but you do not decide the fluence.  And it gives you the fluence to get that. All right, so here's some examples of you have one segment, two segment, three segments. You add those together. You get multiple dose levels from multiple segments. And that's in modulated intensities. So you have different intensities in the same beam. So forward-planned IMRT, that can be done by defining the fluence. So you actually have some planning systems where you can draw kind of like a paintbrush, very simply an add fluence, takeaway fluence. And you can do it that way. The other way is you create these multiple subfields. So you have one subfield, two subfields, three subfields, so on and so forth. So these are both ways to do forward-planned IMRT. So inverse-planned IMRT, we already talked about this, basically divided into those beamlets. So one thing to note for inverse planning, for the optimization, so first off, each voxel, the dose to that voxel can be described as the sum of the dose from all of the beamlets. And so each beamlet has some contribution to that voxel. And so you get this kind of linear addition of the beamlet doses to get your dose to that voxel. So often in many of these planning systems, that dose calculation, the dose to this voxel, that is added ahead of time. And then you're just changing the weights so that you can change those rapidly in the optimization algorithm. So it does some calculation ahead of time, and then it just changes the weights to get different doses to try to achieve your dose distribution. So that dose calculation is done up front. And then once again, the criteria that we put in is done in the DVH space. So we have a dose volume histogram, and we define the criteria, and this can be for the target, this can be for the OER. Sam already talked a little bit about this optimization algorithms. There's gradient descent, and there's also simulated annealing. Some methods are faster than others, and then some, for example, simulated annealing is usually maybe a little more robust, especially for when you're looking at the optimizing the machine parameters directly instead of the fluence. Most of those algorithms will use that. So most modern planning systems typically will use the fast optimization algorithms such as gradient descent for like a fluence optimization, for direct machine or direct aperture optimization simulated annealing it's typically used. That's right, yeah. So yeah, what he's saying there is, if you have a gradient descent, you can get caught in this local minima and not make it down to a better solution. And so that can be a problem, especially for this, where you have all these different MLCs. It may find something it thinks is good, but there may be a much better solution. Simulated annealing, it has this kind of statistical noise level that it lowers over time. So it gives you, so even if some, it may find, sorry, it may tell it to come here, which it may be here and it may tell it to come up here and it has some probability of accepting a worse solution. And it may accept that, especially early on in the optimization, so that it can get above these local minima and get down to the global, to the global minimum. Let's see if Sam is a good one to answer that. Monte Carlo. Often you have those separate. That's right, so yeah. So you have a separate algorithm for your optimization and separate algorithm for your dose distribution. Often you can have a planning system, you can select, I want this dose calculation algorithm, it will use the same optimization regardless of what dose calculation you will use. Does that answer that? All right, so once for traditional IMRT where you decide the fluence or the actually the inverse plan, the inverse optimization decides the fluence, then you have to deliver that fluence somehow. So there's a few different ways you can do that. Physical compensators is one way. Multi-leaf collimator motion is another way. And so that can be done with a leaf sequence or this can be created directly. And so in this case, you're actually skipping the fluence step, you are deciding the motion, you can actually calculate what fluence you would get from those parameters, from those segments that was optimized. So this is basically the difference between these two here is which one does the inverse optimization decide? Does it decide the fluence or does it decide the leaf motion? And then you can calculate the other one after the fact. All right, so physical compensators, this is an example, some company that sells these, basically this is something that can be done without having an MLC. You just have some type of a attachment that goes on there and it will basically, you have a primary fluence that comes through and you're attenuating that.  So this is a very simple idea that you can create an intensity modulated field. You would need one of these for every field that you're going to deliver. You can imagine that's a lot of work, that's a lot of overhead just to create this intensity modulated field. You need one of these for every single field, for every patient. And this type, for example, may not be, you can't really reuse this. It's milled for each patient. Here's another example. This is a group that was doing this. They have some, these powder or granule fields. They put in a tin, a little tin powder and they have a styrofoam milled compensator mold. And then so this goes with that and so it creates a different thickness of the compensator as you go across. So this is a, this has some advantages in that this is reusable. You can reuse this powder. You just need a new styrofoam portion and then you can get in modulated field that way. It's something also very unique. Not many places are doing this as very kind of academics, one in kind of an old technique, but it got over that this way you didn't have to have a separate compensator for every field. You just, you could reuse those materials. All right, so some of the advantages of physical compensators, there's no need for the MLCs. They can be delivered static so that you don't have this interplay of the motion of these leaves and your organs if you have, for example, something that's moving and you're moving your leaves, you have some sort of interplay there where some areas can get large dose and others low dose potentially that could potentially be an issue. That's not a problem with this because you have your, your modulated field is delivered all at the same time. Some of the disadvantages is this is not very automated. In each field requires a custom compensator. You need to, you have to go in and out of the room for every patient to put these in, take these out. And then the modulation can be limited for these because these have a thickness, a maximum thickness of your compensator. So you can't attenuate the beam to zero so it's actually a little bit less than that. For, here's an example of that. So max compensator thickness typically is around five centimeters. If you're for a 10 compensator that equates to your minimum fluence you can get through there's about 40%. So that's the minimum, maximum's 100%. So you, so you can't get to zero. Here's an example of a modulated field where this is, this is what the planning system would like. So it would like to get very low fluence here. This is what was, they were able to make physically. So here they were not able to get a zero fluence through here. So there's some fluences that you can't actually deliver using the, using a compensator.  For some other types of materials, some sort of thicker, higher denser materials that can get a little better. And then, so just some of the ideas behind those, what makes a good compensator, if it gives a good range of modulation like it can attenuate the beam a lot, high spatial resolution, something that's not hazardous, so on and so forth. So here's some, just some of the benefits of different materials for compensators. All right, so most IMRT is done by MLCs. And so as Sam talked about, there's two ways here. One is you have a fluence, you get the leaf sequencing algorithm. The other one is this directly determine the positions of the leaves, so on and so forth. So for the leaf sequencing algorithm, there's many solutions to create the desired fluence. And some of those may or may not be deliverable. And you have to put a lower bound on the transmission that you can deliver. And so when you calculate this leaf sequencing algorithm, it has to take into account the limitations of those leaves, how fast they can move, if they cannot abut or you'll come together or so on and so forth. And so some of these algorithms may optimize the number of segments, the monitor units, the leaf travel time and the tongue and groove effect where you have leaves, they'll try to keep the leaves relatively close together to avoid this tongue and groove effect. The other thing is that very complicated intensities can often lead to more complicated leaf sequences need more segments. So often in your inverse optimization, there'll be an option to smooth that fluence. And so you're not getting some very complicated fluence. And that can help to minimize differences between what the leaf sequencing algorithm gives you and your ideal fluence. So the other thing to keep in mind is that the final dose calculation from the treatment planning system, that may be reported in different ways. That may be the ideal fluence or the final fluence from the leaf sequence. So it's important to know what is your treatment planning system giving you and is that going to be representative? Often, for example, with ARIA, what it gives you is, it gives you during the optimization, it gives you kind of a simplified dose calculation and it's based off the fluence. And then afterwards, it recalculates the dose and it gives you dose based on the leaf sequence and there's gonna be a difference there. So you have to expect that. You may be very close on some criteria and you're very happy you met that. Then you go to recalculate the dose and you say, what happened? And that may be because there's some differences in the dose calculation and in the leaf sequence. All right, so ways to deliver this that we already talked about. Basically, you're just adding up intensities and so this would be a field, different openings of your MLCs as you go along and you get these different intensity levels. So there's two different ways of doing this. One is your leaves can close in, so you have a leaf here, here, deliver this intensity, move your leaf in and then deliver this one. Or this can be a sweeping across the field where your leaves only move in one direction and you can deliver the same fluence either way. So your leaf sequencing algorithm may do one of these two methods and this way obviously works much better if you're doing a dynamic delivery where your leaves are moving the entire time. That way you can deliver those in one motion across going the same direction. So here's just an example from a paper showing the method to create this dose distribution and turn it into a sweeping algorithm where your leaves are just moving in one direction. And one thing to note is this method can work for both a step and shoot method and for a dynamic delivery where it's basically the same process it's just instead of having set positions you have a motion so you're creating a more smooth curve along that path. So here's an example. Here you have this dynamic motion so you have lots of different points and basically you want your leaves to meet these points where here's your beam on time and here's your position of your leaves, the motion's in one direction and then here's your step and shoot. You move the leaves, they stop, they deliver. So basically it's going up and over, up and over whereas this one has just positions that you're meeting as you go across. So Sam already talked about this, we can skip this. Basically here you're specifying a few things, you're disallowing things that can't happen, leaves that, you know, small MU so on and so forth and then you're just getting the positions and then you can calculate the fluence from those leaf positions. So here's the, this is the sum of, this is the fluence that's the sum of the different leaf positions, the different segments. So segments, those can be, these segments, these could be defined by forward planning or inverse planning and if they're from inverse planning those can be derived from a leaf sequence or from DMPO. So you could have these segments and they could be, you know, those could come from many different types of, there's many different ways of getting those. So basically in the treatment planning process we start with simulation so on and so forth.  I'm gonna skip some of this. Here, this is similar to another one you guys have already seen. Basically this is your optimization window. Here's your dose criteria, your DVH space that has all, this kind of puts these criteria on a DVH graph. This is your objective function and how this changes over time. You have your beam fluence that you can see and your penalty, this is a penalty that you can put in to smooth that fluence. So if this fluence has some hot spots here and you didn't like that, you didn't, you thought that was gonna create a problem with your high monitor units or very complicated leaf sequence. You can put in some, you can increase these numbers and that would penalize any smooth, any, you know, unsmooth dose, or fluence in that field or in those fields. And then also there's an option, this is for ARIA, up here for a normal tissue constraint. So you can say, all right, everything that is not my PTV, the target that I wanna treat, I want to create just, you know, a general criteria to say, I don't want dose there. So this here can help with that where you could just have, in theory you would have, you could have one here for your PTV and you could have one for your normal tissue and you just say just conform to it. But then if you care about other organs and certain numbers, that's where these come in handy. All right, and so then we already talked about this, the differences that you can get in the dose distribution. There's great things you can do, you can create a smiley face, you can create a frowny face, you can do all kinds of things with IMRT that you can't really do with 3D. Yes, yeah, that's a good question. All of these are relative because there's this weighting, right? So you have some numbers that are for the PTV, you have numbers that are for the normal tissue structures and you have, for these structures, you also have this number for the normal tissue objective and you have these numbers for the smoothing. In theory, you could double all of them and you'll be doing the same thing. So relative to, it's a sort of thing, it's kind of hard to tell mathematically it's just a number, right? And you just kind of change it and you see what happens. It has a number here that's, it defaults like 40, 40, 50 or 40, 30. So for X and Y, I typically don't change those. I do change that actually. I typically, well, I'll use like 200 here and I'll use 150 here, which is probably the same as what they're doing here, 180, about the same. Yes, there's some numbers there. There's a couple of parameters. And today in the, when we do the, we'll go over that because I don't have a window showing that, but we can go over that there. Oh, that's, yeah, that's a good, good point. So here we have, here we have this resolution, right? Oh wait, no, that's priority. Yeah, so you see this revolution here and you can change those numbers. The number to look at is there's this volume. So for each one you have the, you have the structure, you have a volume that's in cubic centimeters and then you have number of points. So as you change that resolution, if you make that resolution smaller, your number of points is gonna go up. So if it's an organ that you care about, especially if you care about the hotspots, then you want that number to be fairly high so that you can, it will calculate a lot of points within that structure. If it's a, you know, if it's a structure that you just care that the mean dose is low or something or it's low priority, you can keep the resolution pretty high and it's just gonna calculate a few points within that organ. So that's the number of points that it's calculating within that organ and that's calculating dose for, and it's doing its DVH based on that. So it's the resolution of the DVH for that organ. And so what number is good? If it's bad, it may complain. So here like the numbers range between 1,000 to very, very high for the body. So 4,000. This is not the number of iterations. This is the resolution. So it's like the spatial resolution of this organ and how many points it's calculating dose to within that. So it's not actually doing, normally when you do the dose calculation afterwards, you basically have a uniform dose, maybe one millimeter or two and a half millimeters, something five millimeter spacing. This is actually calculating dose for that organ. In each organ has its own resolution because some organs are gonna be small. If you had a very large dose volume, they may only have one, two points, but it's gonna calculate a lot more than that. Here's your iterations. You have a max time, max iterations. I typically have not had a problem with it going to max iterations.  But you could put that number in. The other thing here is now newer versions of ARIA here have this kind of intermediate dose calculation. So they actually kind of, they do an intermediate dose calculation to kind of improve your accuracy. And then it kind of re-optimizes based on that. Any other questions? So you're talking about the fluence and whether you can see it? You mean here or? So when you do the image, like when you do a verification afterwards? Well, so that high resolution is in the dose space and it's just for the optimization. Can you get that high resolution you're saying in the, okay, okay, sorry. Okay, so yeah, once again, very beautiful distributions that you can do with IMRT. DVH space, this is just some difference between 3D and IMRT, so this is very similar to the 3D plan we did last time. And here's our IMRT and our 3D for the PTB, spinal cord and larynx. And then this is a comparison with Quantek, which is some papers that look at what's the normal tissue complication probability, so on and so forth. For this one, with changing the resolution mean, what it will mean if you change the resolution there is that you will have more or less number of samples for that organ. So if you could imagine, your mean dose may be pretty accurate. If you're looking at a hotspot or a low spot, minimum dose, maximum dose, those numbers may, those might be in a larger volume or something, so maybe those are gonna get averaged out and not be as accurate. But that's gonna be here in your optimization space. When you go to calculate dose afterwards, you're gonna get a uniform dose matrix. So it's not gonna have this resolution here, it's gonna have a very different resolution that's gonna be uniform. So that is, even if you were to have this not be very, if you had two little points here, you should see that after the fact if you have a high enough dose resolution for your entire grid. 4.5, yeah, for the body. Actually, I have in some cases made that number smaller or actually larger, larger, so less resolution. Just if I run into problems with memory for the computer, if I have a computer problem and some sort of very complicated case, and I am not using a maximum dose constraint for the body, I may make that number smaller, I don't need that high of number. Okay, so if you have, let's say we have a case and they're definitely are cases where you have an IMRT case and a 3D case and they look very similar. Yeah, I would agree, any other comments on that? So he says that because the 3D conformal would be preferred because we're gonna be using less monitoring units, the time of the treatment, and also the work, right, if you're gonna be verifying these fields, everything's more complicated with IMRT. It's a great tool, but it doesn't have to be used every time. There are definitely cases where a 3D case will do just as good. And even if you see, let's say you see a slight difference between IMRT and 3D, is that gonna make a clinical difference? That's a good question. And I think you have to, if you see a clinical difference and a head and neck case is probably as good of an example as any, as where you might, then IMRT makes sense. And if you're not gonna see a clinical difference, then 3D is just fine. It's worked for a long time. And it's a very good technique. Any other questions? Moving on, I like this slide. So this is an IMRT field. You can see the fluence. And this is on the head. So you can see the fluence there, the hair loss, and it's proportional to the fluence. So IMRT works. And you gotta be careful. I mean, this is, if you think about what we're doing here, we're increasing the monitor units a lot. And we have this very complicated shape. And it's a great tool, but it's complicated. And we're increasing the complication to do some things. So it requires a little more safety. It's a tool that just needs to be used strategically. So here's just an example showing, I don't know if prostate's the best example for IMRT, but this is showing how in this case, we have a hotspot for the 3D case. And the hotspot is in the area of the PTB that's overlapping with the organ at risk. So you can, with IMRT, you may be able to shape the areas where your hotspot is to areas that are only within the PTB. So just kind of some subtle changes here that can happen. For example, here's your hotspot, it's going here into the rectum. You can maybe kind of push that hotspot over outside of the organ at risk. So you're still getting the dose, the full dose to the PTB, but the area that's most likely to be near your organ at risk, you can shape that with IMRT. So there's subtle things that you can do with your planning system. And this may require creating a structure, right? Of your, in your optimization algorithm, you can create a structure that is PTB minus rectum, or PTB minus bladder or whatever. And so then you can kind of optimize these and throw some, you know, there's fun things you can play around with to kind of shape your dose distribution the way that you want to. So just some comments on IMRT, it's, you know, this more conformal, I think Yaakov mentioned, that also means it's much better at missing the target if you're not careful. Since you have a conformal dose, you know, if we have a large dose, it doesn't matter how well you set the patient up, you're gonna hit it. But if you have a very, you know, if you have a very conformal dose, you have to be more accurate in setting that patient up. So it's important first to make sure that your margins that you're using when you're, when you're looking at uncertainties, make sure those are correct and then use IMRT. Beam selection is a little non-intuitive in that way we use, you know, more, maybe more beams instead of less and maybe equally spaced. A lot of this is done by the optimization, it's not done by beam selection. So typical monitor units are three to five times higher and there's a tendency to use lower energy to minimize neutrons because we're using higher monitor units for these cases. So there's a tendency to overstress IMRT planning. Just let it do its thing and you don't try to make it, achieve something that it can't do, basically. So some of the advantages, you know, it's able to create these conformal doses. You can escalate the dose if, you know, by shrinking your margins, maybe the dose can go up that you're delivering and you can decrease dose to normal tissues. Disadvantages is it's a little more labor intensive as far as planning goes. Although I think now a lot of modern dose algorithms or treatment planning systems, that's debatable. Sometimes I think a 3D case is actually more work than IMRT because it's doing all the work for you. You know, it does the fluence instead of me manually going through and adding a wedge here, taking one out there. So some of that's debatable, but there is more involved as far as, you know, verification and so on and so forth. The delivery time's a little bit longer. It has the danger of being too conformal potentially if you're not, if you don't adequately adjust your margins. Generally more inhomogeneous dose distribution, although that I think depends on the way you're optimizing. I think you can also get a uniform dose with IMRT if you are not trying to overstress the optimization. And increased, MU equals increased whole body dose and increased room shielding. Here's some references that might be useful. And I think that is everything I have. Thank you.