<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Michele Sciabarra</title>
    <description>The latest articles on DEV Community by Michele Sciabarra (@sciabarracom).</description>
    <link>https://dev.to/sciabarracom</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F542454%2F2dddfae7-2436-48af-ae70-6efb1edfc027.jpeg</url>
      <title>DEV Community: Michele Sciabarra</title>
      <link>https://dev.to/sciabarracom</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sciabarracom"/>
    <language>en</language>
    <item>
      <title>You can run kubectl from a docker container with Docker Desktop</title>
      <dc:creator>Michele Sciabarra</dc:creator>
      <pubDate>Sat, 11 Dec 2021 18:38:38 +0000</pubDate>
      <link>https://dev.to/sciabarracom/you-can-run-kubectl-from-a-docker-container-with-docker-desktop-5728</link>
      <guid>https://dev.to/sciabarracom/you-can-run-kubectl-from-a-docker-container-with-docker-desktop-5728</guid>
      <description>&lt;p&gt;In the process of setting up the development environment for Nuvolaris, I decided to switch from virtual machines to containers, leveraging the devcontainer feature of VSCode. Then I built a Docker image that is a perfect fit for our needs: there everything is in it to build our project.&lt;/p&gt;

&lt;p&gt;But, I almost went on panic when I realized that, since a key component is an operator, and a cli that interacts with Kubernetes, we need to be able to access a Kubernetes cluster for development FROM a container.&lt;/p&gt;

&lt;p&gt;In my initial plans, I would have setup a cluster Kubernetes in the virtual machine itself. But now, that everything is in a container? I actually felt initially very smart having the idea of setting up a Kubernetes cluster using kind. It is a tool that can build a Kubernetes cluster just using docker. But my plans went immediately awry because kind expects to be able to access to docker using localhost, and this is not the case within a container. &lt;/p&gt;

&lt;p&gt;Even if I was able to access to docker from docker with a non-root user, inside the container there is not the proxy to localhost that is available outside a container. It is probably possible to configure kind to work anyway, but my first attempt failed.&lt;/p&gt;

&lt;p&gt;Then I went in deep investigation mode, and I discovered that with Docker Desktop all the services are available using the domain docker.internal. And this domain is available also outside of the container. Then I thought that maybe it is possible to access to the Kubernetes that Docker itself provides from inside a container. maybe changing the configuration. Actually the situation is much better!&lt;/p&gt;

&lt;p&gt;When you enable Kubernetes with Docker Desktop it creates a configuration file .kube/config that actually uses the domain &lt;code&gt;kubernetes.docker.internal&lt;/code&gt;to talk to Kubernetes from the outside. &lt;/p&gt;

&lt;p&gt;So I just copied the generated kubeconfig inside the container:&lt;/p&gt;

&lt;p&gt;docker cp $HOME/.kube/conf container:/home/nuvolairs/.kube/config&lt;/p&gt;

&lt;p&gt;and kubectl worked from inside the container, talking to Docker's Kubernetes!!!&lt;/p&gt;

&lt;p&gt;Yes, this is a feature already available in Docker Desktop but not documented (or at least I was unable to find specific documentation for it). &lt;/p&gt;

&lt;p&gt;I discovered it by myself and it saved my day and a week of efforts building the development environment that is now perfectly usable for our needs.&lt;/p&gt;

</description>
      <category>nuvolaris</category>
      <category>docker</category>
      <category>kubernets</category>
      <category>serverless</category>
    </item>
    <item>
      <title>Building a multi-architecture development environment</title>
      <dc:creator>Michele Sciabarra</dc:creator>
      <pubDate>Tue, 07 Dec 2021 10:21:25 +0000</pubDate>
      <link>https://dev.to/sciabarracom/building-a-multi-architecture-development-environment-4713</link>
      <guid>https://dev.to/sciabarracom/building-a-multi-architecture-development-environment-4713</guid>
      <description>&lt;p&gt;When you start a project, that is as complex as &lt;a href="//bit.ly/nuvolaris"&gt;nuvolaris&lt;/a&gt; (a new distribution of a Apache OpenWhisk), you need to be very careful in what you do, as your initial choices will be the hardest to change later.&lt;/p&gt;

&lt;p&gt;Whatever you choose now, it will be shared by a number of people, they will learn your procedures, and they won't be happy if you change them. Also, even if you decide later to update them, your changes will disrupt the workflows and create friction in the team.&lt;/p&gt;

&lt;p&gt;I am working hard, but for now is's a solo effort to prepare the development environment. And here I am evolving my decisions on how to develop Nuvolaris.&lt;/p&gt;

&lt;p&gt;First I simply wrote a readme, mentioning the required components. But since there are so many, so I wrote a script &lt;code&gt;setup.source&lt;/code&gt; using also the various &lt;code&gt;nodenv&lt;/code&gt; &lt;code&gt;pyenv&lt;/code&gt; and &lt;code&gt;goenv&lt;/code&gt; to set the correct version of the programming languages to use.&lt;/p&gt;

&lt;p&gt;Then I decided that was also wise to provide a stable environment to run everything, so I considered the option of using a virtual machine to run everything in the same way for everyone. So I spent some time tweaking with multipass to see if I could use this as a standard environment for development, as I mostly develop using VSCode with the Remote-SSH plugin and I use my server.&lt;/p&gt;

&lt;p&gt;In the end my conclusion is that setting up multipass is complex enough to not be worth the effort. But I considered to use VSCode Remote-Container plugin, and it was a great find. I was aware of this but I haven't actually used it in the past, but it is great, as there are provisions to initialize the environments for the various programming languages!&lt;/p&gt;

&lt;p&gt;A perfect fit for my needs. So I decided to use Remote-Containers instead and built a Dockerfile to create the perfect development environment for Nuvolaris with all the development tools inside. So you can develop on Linux, Mac or Windows, and even on the web using CodeSpaces!&lt;/p&gt;

&lt;p&gt;My only regret was that I actually use a Mac with ARM M1. It is not a problem, as I do not develop in it. As I said, I use a remote, Intel based, server with VSCode Remote-SSH. I personally can't use the Remote-Container simply because the image I built is intel based (and please, do not talk of emulating Intel in Docker for ARM as it is considerably slower).&lt;/p&gt;

&lt;p&gt;Then I wondered: why not support ALSO ARM? Actually, we would like to support Nuvolaris on multiple Kubernetes distributions, and yesterday we discussed of building clusters of Kubernetes with Raspberry PIs and it would be awesome to have Nuvolaris running on those!&lt;/p&gt;

&lt;p&gt;So I decided to go with this option too, and I decided to support ALSO arm64 from day one. In the end we are going to build Nuvolaris to work on a variety of Kubernetes environments, both on Intel and ARM architectures. And I am now building the development environment to be multi-architecture so you can work on a Windows PC, on a Mac with M1 chips and even on a Raspberry PI, as long as you have Docker.&lt;/p&gt;

&lt;p&gt;Stay tuned.&lt;/p&gt;

</description>
      <category>nuvolaris</category>
      <category>serverless</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>
Deploy a MicroK8s cluster with cloud-init</title>
      <dc:creator>Michele Sciabarra</dc:creator>
      <pubDate>Wed, 09 Jun 2021 21:21:47 +0000</pubDate>
      <link>https://dev.to/sciabarracom/deploy-a-microk8s-cluster-with-cloud-init-45l7</link>
      <guid>https://dev.to/sciabarracom/deploy-a-microk8s-cluster-with-cloud-init-45l7</guid>
      <description>&lt;p&gt;If you need to run Kubernetes, today very frequently you just pick one managed in some cloud provider. However this option is frequently expensive. A cheaper option is to get a bunch of virtual machines and install Kubernetes in it.&lt;/p&gt;

&lt;p&gt;Creating a Kubernetes cluster actually today is pretty simple, using tools like &lt;a href="https://microk8s.io/"&gt;MicroK8s&lt;/a&gt; but there are still some manual actions to take.&lt;/p&gt;

&lt;p&gt;To make cluster building even simpler, you can use for example &lt;a href="https://cloudinit.readthedocs.io/en/latest/"&gt;cloud-init&lt;/a&gt;, the standard for cloud image initialization. So I decided to write a cloud-init that can automatically build a cluster for you.&lt;/p&gt;

&lt;p&gt;The result is &lt;a href="https://bit.ly/microk8s-init"&gt;here&lt;/a&gt;, you can download it with this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -sL bit.ly/microk8s-init &amp;gt;microk8s-init.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To entirely automate the cluster generation I had to use a couple of tricks.&lt;/p&gt;

&lt;p&gt;First I assigned statically an IP address to virtual machines. I assign ips to virtual machines using a number that is expected to be included in the hostname. Second I generate "programmatically" a token to join the cluster.&lt;/p&gt;

&lt;p&gt;There are hence a couple of parameters you may need to customize before using it. You may need to change the &lt;code&gt;NET&lt;/code&gt; parameter.  All the virtual machines will get an IP in that network according to the host name. For example, the virtual machine  &lt;code&gt;kube1&lt;/code&gt; will get the address &lt;code&gt;10.0.0.1&lt;/code&gt;.  Also note that the &lt;code&gt;1&lt;/code&gt; virtual machine is always the one used to join the cluster&lt;/p&gt;

&lt;p&gt;Also for security you may want to change the &lt;code&gt;PASS&lt;/code&gt; parameter that is the  password used to generate the unique token for joining the cluster.&lt;/p&gt;

&lt;p&gt;The script can be used in many different environments. The low hanging fruit  to use it is wth &lt;a href="https://multipass.run/"&gt;&lt;code&gt;multipass&lt;/code&gt;&lt;/a&gt;, another handy tool from Ubuntu to launch virtual machines in multiple environments.&lt;/p&gt;

&lt;p&gt;Microk8s requires at least 2gb of memory to run and 2 vcpu. You can hence test the script with the following commands to create the first node of a local cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;multipass launch -nkube1 -m3g -c2 --cloud-init microk8s-init.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sometimes it will time out during the initialization so you may need to wait for it to complete with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;multipass exec kube1 -- sudo cloud-init status --wait
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then launch more instances and wait for them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;multipass launch -nkube2 -m2g -c2 --cloud-init microk8s-init.yaml
multipass exec kube2 -- sudo cloud-init status --wait
multipass launch -nkube3 -m2g -c2 --cloud-init microk8s-init.yaml
multipass exec kube3 -- sudo cloud-init status --wait
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can finally extract the configuration file and check for the cluster status with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;multipass transfer kube1:/etc/kubeconfig ~/.kube/config
kubectl get nodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>cloud</category>
    </item>
    <item>
      <title>How to create a REST API in 1 minute</title>
      <dc:creator>Michele Sciabarra</dc:creator>
      <pubDate>Thu, 03 Jun 2021 09:07:18 +0000</pubDate>
      <link>https://dev.to/sciabarracom/how-to-create-a-rest-api-in-1-minute-no5</link>
      <guid>https://dev.to/sciabarracom/how-to-create-a-rest-api-in-1-minute-no5</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DQ01kBcV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sap9bzrxo1vk7lfb9re0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DQ01kBcV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sap9bzrxo1vk7lfb9re0.png" alt="2021-06-03_10-34-00"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;go to &lt;a href="http://www.nimbella.com"&gt;www.nimbella.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;click on Login&lt;/li&gt;
&lt;li&gt;use your GitHub account to sign in&lt;/li&gt;
&lt;li&gt;click on Console&lt;/li&gt;
&lt;li&gt;go to Workbench&lt;/li&gt;
&lt;li&gt;select the playground&lt;/li&gt;
&lt;li&gt;edit your serverless code (or just use an example)&lt;/li&gt;
&lt;li&gt;copy the URL&lt;/li&gt;
&lt;li&gt;curl it!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yO6NTH9a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ubttxkptsl9z90il2zng.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yO6NTH9a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ubttxkptsl9z90il2zng.png" alt="2021-06-03_10-25-48"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Nimbella in a nutshell</title>
      <dc:creator>Michele Sciabarra</dc:creator>
      <pubDate>Tue, 06 Apr 2021 07:39:12 +0000</pubDate>
      <link>https://dev.to/sciabarracom/nimbella-in-a-nutshell-21k8</link>
      <guid>https://dev.to/sciabarracom/nimbella-in-a-nutshell-21k8</guid>
      <description>&lt;p&gt;So you may wonder what is Nimbella.&lt;/p&gt;

&lt;p&gt;Nimbella is a serverless development platform, similar to Amazon Lambda and similar serverless offerings by other cloud providers.&lt;/p&gt;

&lt;p&gt;The distinctive feature of Nimbella is that is based on open-source software, &lt;a href="https://openwhisk.apache.org/"&gt;Apache OpenWhisk&lt;/a&gt; and it is portable among different cloud providers, so you can also install it in your private cloud on-premises.&lt;/p&gt;

&lt;p&gt;Nimbella's goal is to make easy cloud-native development and provide an awesome development experience. Developers are entitled to build their applications with microservices from the ground up.&lt;/p&gt;

&lt;p&gt;Nimbella offerings include the multi-tenant public offering allowing developers to build their applications in the cloud. &lt;/p&gt;

&lt;p&gt;Their applications can then be deployed in a private cloud, either on-premises or in any other public that provides a Kubernetes cluster.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Jump Start with Nimbella</title>
      <dc:creator>Michele Sciabarra</dc:creator>
      <pubDate>Mon, 05 Apr 2021 15:12:07 +0000</pubDate>
      <link>https://dev.to/sciabarracom/jump-start-with-nimbella-3146</link>
      <guid>https://dev.to/sciabarracom/jump-start-with-nimbella-3146</guid>
      <description>&lt;p&gt;I am starting a series of posts, that is going to cover &lt;a href="https://www.nimbella.com"&gt;Nimbella&lt;/a&gt;, an open-source serverless platform.&lt;/p&gt;

&lt;p&gt;We start learning how to do the signup in Nimbella, which offers a free account for development. We are going to install the &lt;code&gt;nim&lt;/code&gt; tool, the command-line interface to interact with Nimbella. Nimbella is also available on-premises in private clouds.&lt;/p&gt;

&lt;p&gt;Then we go through &lt;em&gt;actions&lt;/em&gt;, which are the building blocks of Nimbella applications. We will see how to create and update actions. Furthermore, actions can be invoked. Each invocation leaves a track as an &lt;em&gt;activation&lt;/em&gt;. We are going to see how to check those activations, inspecting logs and results.&lt;/p&gt;

&lt;p&gt;Nimbella also includes event handling, in the form of &lt;em&gt;trigger&lt;/em&gt; and &lt;em&gt;rule&lt;/em&gt;. We complete the chapter going into the details, with an example using slack, and another using timed execution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/sciabarracom/nimbella-in-a-nutshell-21k8"&gt;Nimbella in a Nutshell&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Learn serverless programming playing a game</title>
      <dc:creator>Michele Sciabarra</dc:creator>
      <pubDate>Fri, 18 Dec 2020 06:05:20 +0000</pubDate>
      <link>https://dev.to/sciabarracom/learn-serverless-programming-playing-a-game-4cfo</link>
      <guid>https://dev.to/sciabarracom/learn-serverless-programming-playing-a-game-4cfo</guid>
      <description>&lt;p&gt;FAAS Wars is a free programming game where you have to write the code that controls a "FAAS fighter".  It is available&lt;a href="//bit.ly/nimbots"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The fighter is a spaceship that can move in space and shoot lasers. The goal of the game is to defeat the enemy fighter, hitting it 5 times, and of course avoiding the bullets of the enemy.&lt;/p&gt;

&lt;p&gt;To control a fighter you have to write the control code. The control code itself is a Nimbella serverless action. In the following, there is a tutorial about how to write a progressively smarter control action. &lt;/p&gt;

&lt;p&gt;We are using javascript as the programming language. You can use however any other programming language available in Nimbella, like Python or Go. All the actions receive their input in JSON format and return the output in JSON, too. So the logic described in javascript can be readily translated into any other programming languages.&lt;/p&gt;

&lt;p&gt;Let's start now, discussing how to create your fighter control code with a step by step tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to control your fighter
&lt;/h2&gt;

&lt;p&gt;A serverless action suitable for Faas WARS in its simplest form has this format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function main(args) {
    return {"body": []}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Any Nimbella action returns a map. In our case, we need a web action returning JSON, so you have to use &lt;code&gt;body&lt;/code&gt; as a mandatory field of your object. The resulting answer has to be an array of maps. In the simplest case, it is just an empty array. However, if you implement this action way your fighter will simply do nothing at all. Just sit down waiting to be hit by the enemy.&lt;/p&gt;

&lt;p&gt;You can send commands to the fighter. A command is a map, where the keys are the commands given to the robot and the values are the parameters of the command. For example, you can order the fighter to "yell" something. If you want your robot displays the current time, you can order it with  &lt;code&gt;{ "yell": new Date().toLocaleTimeString()}&lt;/code&gt;. Let's put it in an entire action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function main(args) {
    let msg = new Date().toLocaleTimeString()
    return {"body": [{"yell":msg}]}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you start the battle, you can see not the fighter is telling the current time. As it is not doing anything else, it will not survive for very long if there is a minimally offensive another fighter in the battleground.  Indeed, this example is not very useful, battle-wise, but nonetheless, we see our robot is doing something, now!&lt;/p&gt;

&lt;p&gt;Let's learn how to move around our fighter. As we already pointed out, the action returns an array of commands, so you can give multiple orders.&lt;/p&gt;

&lt;p&gt;Out first step is to  order to the robot to move forward and then turn to the left, as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function main(args) {
    return {"body": [
       {"move_forwards":50},
       {"turn_left":90},
    ]}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you run this code you will note the fighter will move around, following a squared path. Indeed the orders are to move forward 100 pixels and then turn right of 90 degrees, forever. If it is hit, it may change randomly its orientation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reacting to events
&lt;/h2&gt;

&lt;p&gt;If you run the robot this way, is it blind and stupid, but it has not to be this way. Actually, the robot receives information about its environment in the &lt;code&gt;args&lt;/code&gt; parameter. The most important value to check is &lt;code&gt;args.event&lt;/code&gt;.  There are basically 4 events our robot can react to: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;idle&lt;/code&gt;: when the robot is running out of commands and has nothing to do&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;enemy-spot&lt;/code&gt;: when the robot sees the enemy right in front of the turret.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hit&lt;/code&gt;: when an enemy bullet hits the robot&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;wall-collide&lt;/code&gt;: when the robot hits the wall and cannot move forward anymore&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now lets add the ability to shot to the enemy when it sees one. For this purpose we instroduce a swich on the event. Also, we use an array where we push the actions we want to sent. Our revised code is thus:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function main(args) {
    let actions = []
    switch(args.event) {
        case "idle":
            actions.push({"move_forwards":50})
            actions.push({"turn_left":90})
            break;
        case "enemy-spot":
            actions.push({"yell": "Fire!"})
            actions.push({"shoot":true})
            break;
    }
    return {"body": actions}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, another detail. We say command is wrapped in a map, but in a map, there has not to be only one command. It can be multiple commands at the same time. But those have to be something the robot can do at the same time.&lt;/p&gt;

&lt;p&gt;So for example a robot cannot move at the same time forward and backward, or move and turn. So the following actions are "sequential", in the sense, you can put only one at a time in the command maps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;move_forwards &amp;lt;number&amp;gt;&lt;/code&gt;: move forward of the given number of pixels&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;move_backwards &amp;lt;number&amp;gt;&lt;/code&gt;: move backward of the given number of pixels&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;move_opposide &amp;lt;number&amp;gt;&lt;/code&gt;: move in the opposite direction, useful when you hit a wall&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;turn_left &amp;lt;degrees&amp;gt;&lt;/code&gt;: turn the robot to the left of the given degrees&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;turn_right &amp;lt;degrees&amp;gt;&lt;/code&gt;: turn the robot right of the given degrees&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, you can order at the same time to yell and shot, for example. So this is a valid command:  &lt;code&gt;{"yell": "Fire!", "shoot":true}&lt;/code&gt;. Those are parallel actions.&lt;/p&gt;

&lt;p&gt;In addition, you can also move the turret. This is thus the complete list of parallel actions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;yell &amp;lt;message&amp;gt;&lt;/code&gt; show a message&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shot: true&lt;/code&gt;: order to shot, if the value is true&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;turn_turret_left &amp;lt;degrees&amp;gt;&lt;/code&gt;: turn the robot to the left of the given degrees&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;turn_turret_right &amp;lt;degrees&amp;gt;&lt;/code&gt;: turn the robot to the right of the given degrees&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data: &amp;lt;object&amp;gt;&lt;/code&gt;: store the object and return it in every further event&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now let's put it all together, handling also the cases of the robot colliding with the wall or being hit. What it follows is the default control program that is the default when you create a new robot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function main(args){
    let actions = []
    switch(args.event) {
        case "idle":
            actions.push({"turn_turret_left": 45, "move_forwards": 50})
            actions.push({"turn_left": 45})
            break;
        case "wall-collide":
            actions.push({"move_opposide":10})
            actions.push({"turn_left":90})
            break;
        case "hit":
            actions.push({"yell": "Ooops!"})
            break
        case "enemy-spot":
            actions.push({"yell": "Fire!", "shoot":true})
            break
        default:
            console.log(args)
    }
    return { "body": actions}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>serverless</category>
      <category>gamedev</category>
      <category>cloudnative</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
