<?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: Tyson Lawrie</title>
    <description>The latest articles on DEV Community by Tyson Lawrie (@tysonlawrie).</description>
    <link>https://dev.to/tysonlawrie</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%2F459440%2F27bfd624-e64f-47cf-8689-f565794e08de.png</url>
      <title>DEV Community: Tyson Lawrie</title>
      <link>https://dev.to/tysonlawrie</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tysonlawrie"/>
    <language>en</language>
    <item>
      <title>Creating a GitHub stale repositories cleanup bot with Boomerang Flow</title>
      <dc:creator>Tyson Lawrie</dc:creator>
      <pubDate>Tue, 01 Jun 2021 01:53:02 +0000</pubDate>
      <link>https://dev.to/tysonlawrie/creating-a-github-stale-repositories-cleanup-bot-with-boomerang-flow-1hbl</link>
      <guid>https://dev.to/tysonlawrie/creating-a-github-stale-repositories-cleanup-bot-with-boomerang-flow-1hbl</guid>
      <description>&lt;h2&gt;
  
  
  Why Boomerang Flow?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://useboomerang.io/"&gt;Boomerang Flow&lt;/a&gt; is a no-code event-driven cloud native workflow automation tool and is an open-source project. &lt;/p&gt;

&lt;p&gt;There are a number of tools that you can use to create a GitHub bot; GitHub Actions, Netlify, Heroku, or any functions hosting cloud, with various skill levels required.&lt;/p&gt;

&lt;p&gt;The following will give you a view on doing the same with no-code automation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a repositories bot?
&lt;/h2&gt;

&lt;p&gt;This particular bot is useful to identify if new repositories are being created and you want to make sure to keep a clean GitHub Organization. Its possible that repositories get created for testing purposes and forgotten about, or are created and now need to be managed with issue templates or a license.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the Workflow
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P8gtdOmo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rzqf9c26dp9auehwjjh1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P8gtdOmo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rzqf9c26dp9auehwjjh1.png" alt="Creating the Workflow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The default landing page is the Workflows screen and in your space will be the ability to create a new workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wiring together the bot
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GK13asd_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1bg6qloqwwc34f0vx50c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GK13asd_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1bg6qloqwwc34f0vx50c.png" alt="Wiring together the bot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the Workflow Editor screen you can drag and drop a number of tasks from the palette providing a great end user experience. For advanced management these tasks are Tekton defined YAML and can be managed via the Task Manager.&lt;/p&gt;

&lt;h3&gt;
  
  
  Find Repositories in Org
&lt;/h3&gt;

&lt;p&gt;Drag on the &lt;strong&gt;Find Repositories in Org&lt;/strong&gt; Task and add the required specifics.&lt;/p&gt;

&lt;p&gt;Custom Task Name: &lt;code&gt;Find Repositories&lt;/code&gt;. &lt;br&gt;
&lt;em&gt;This will be used later on to get the result parameters.&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;URL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://github.com/api/v3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Token&lt;/td&gt;
&lt;td&gt;&lt;em&gt;You can get this value on github.com from your profile under Settings &amp;gt;  Developer settings &amp;gt; Personal Access Tokens.&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Org&lt;/td&gt;
&lt;td&gt;The org you want to scan, in this demo I chose the boomerang-io org&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Visibility&lt;/td&gt;
&lt;td&gt;The types of repositories you want returned. &lt;em&gt;Default: All&lt;/em&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repositories to Skip&lt;/td&gt;
&lt;td&gt;This is a newline delimited list of repositories to ignore based on repository name&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Number of Repositories to Retrieve&lt;/td&gt;
&lt;td&gt;Helpful to retrieve more or less based on the GitHub API paging.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Send Simple Slack Message
&lt;/h3&gt;

&lt;p&gt;Drag on the &lt;strong&gt;Send Simple Slack Message&lt;/strong&gt; Task and add the required specifics.&lt;/p&gt;

&lt;p&gt;We make use of the prior tasks result parameters to output the repositories of note.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Webhook URL&lt;/td&gt;
&lt;td&gt;You create this in Slack App for your workspace as an Incoming Webhook and will be similar to &lt;code&gt;https://hooks.slack.com/services/&amp;lt;id&amp;gt;/&amp;lt;id&amp;gt;/&amp;lt;id&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Channel&lt;/td&gt;
&lt;td&gt;This can be a channel or direct message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Icon&lt;/td&gt;
&lt;td&gt;I usually go for a bot or Github logo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Username&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Boomerang GitHub Bot&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Message&lt;/td&gt;
&lt;td&gt;
&lt;em&gt;This is a weekly reminder announcement from your friendly GitHub Bot&lt;/em&gt;\n\nThe following repositories are currently in the &lt;em&gt;Boomerang&lt;/em&gt; org and need to be cleaned up:\n$(task.Find Repositories.results.repositoriesPrettyPrint)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Wire the Tasks together
&lt;/h3&gt;

&lt;p&gt;Drag and drop the lines between the tasks. You can make use of the Task state as well by changing it to only proceed on success.&lt;/p&gt;

&lt;p&gt;Find out more information about &lt;a href="https://www.useboomerang.io/docs/boomerang-flow/3.2.0/how-to-guide/workflow-editor/#links"&gt;Link and Tasks states&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure Schedule Trigger
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3pU8ubAp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sgb01xs6r172xw80vjkd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3pU8ubAp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sgb01xs6r172xw80vjkd.png" alt="Configure Schedule Trigger"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We want this to run on a weekly or monthly schedule. On the Configure tab under Triggers, enable the Scheduler and then click Change Schedule.&lt;/p&gt;

&lt;p&gt;In the basic view you can set a weekly schedule or you can switch to the advanced view and set any cron based schedule.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Activity
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j53vF1Uu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g6psrfjhr4rsquthzkhg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j53vF1Uu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g6psrfjhr4rsquthzkhg.png" alt="Screen Shot 2021-06-01 at 11.42.10 AM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Boomerang Flow provides an activity view where you can see whats running, dynamically tail logs, and view a Tasks Result Parameters.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uMtlvtU---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s7mg038secti5xfxr77g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uMtlvtU---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s7mg038secti5xfxr77g.png" alt="Screen Shot 2021-06-01 at 11.42.20 AM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Result Parameters are important in this Workflow as it is how we passed information from the repositories listing Task that connected to GitHub, to the Slack messaging Task.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5PMGkUs2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dd5kwn3s5tvlc5wotda6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5PMGkUs2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dd5kwn3s5tvlc5wotda6.png" alt="The slack message"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And as you can see, the workflow resulted in a message post to a Slack channel. This is a really easy, no-code way of creating a bot.&lt;/p&gt;

&lt;h2&gt;
  
  
  What did we achieve
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A no-code workflow&lt;/li&gt;
&lt;li&gt;No configuration of setting up a function running in a cloud&lt;/li&gt;
&lt;li&gt;No YAML!&lt;/li&gt;
&lt;li&gt;Easy to use interface for providing information&lt;/li&gt;
&lt;li&gt;A bot that can keep on running and be refined with a filterable list.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Future Steps
&lt;/h2&gt;

&lt;p&gt;If you are confident that the bot is now finding the correct repositories, you can implement a repository deletion mechanism or raise a GitHub issue to close the repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Show your support
&lt;/h2&gt;

&lt;p&gt;Show your support if this helped you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/boomerang-io/flow.client.web"&gt;⭐️ the GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/useboomerangio"&gt;💬 Follow us on Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.useboomerang.io/docs/boomerang-flow/installing/installing"&gt;Install the project&lt;/a&gt; on your own Kubernetes cluster&lt;/li&gt;
&lt;li&gt;🙏 &lt;a href="https://github.com/boomerang-io/roadmap"&gt;Join us and help contribute&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>automation</category>
      <category>github</category>
      <category>workflow</category>
      <category>bots</category>
    </item>
    <item>
      <title>Canceling a Tekton TaskRun with Fabric8 Kubernetes Java Client</title>
      <dc:creator>Tyson Lawrie</dc:creator>
      <pubDate>Thu, 13 May 2021 00:16:04 +0000</pubDate>
      <link>https://dev.to/tysonlawrie/canceling-a-tekton-taskrun-with-fabric8-kubernetes-java-client-2bng</link>
      <guid>https://dev.to/tysonlawrie/canceling-a-tekton-taskrun-with-fabric8-kubernetes-java-client-2bng</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This work is being done as part of my open-source contribution to &lt;a href="https://useboomerang.io"&gt;Boomerang Flow&lt;/a&gt;, a low-code cloud-native workflow automation project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Fabric8 Java Kubernetes Client helps you integrate with Kubernetes and it has an extension for integrating with Tekton. &lt;/p&gt;

&lt;p&gt;It makes building out Java code extremely easy, however, you still need to know what or how to update the objects. This is where examples and references really help and is a great place to start as a contributor!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Code
&lt;/h2&gt;

&lt;p&gt;As the name says, this article is all about how to Cancel TaskRuns in Tekton using the Fabric8 Tekton client. You can see the &lt;a href="https://github.com/fabric8io/kubernetes-client/blob/master/extensions/tekton/examples/src/main/java/io/fabric8/tekton/api/examples/TaskRunCancel.java"&gt;latest example code here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  But there is no Cancel action
&lt;/h2&gt;

&lt;p&gt;Unlike &lt;code&gt;create()&lt;/code&gt;, &lt;code&gt;list()&lt;/code&gt;, &lt;code&gt;delete()&lt;/code&gt;, etc there is no corresponding action for cancel instead you need to use &lt;code&gt;updateStatus()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This comes down to the fact that Kubernetes itself doesn't understand Cancel, and in fact you are inserting a new Status for the Kubernetes object.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's update the Status
&lt;/h2&gt;

&lt;p&gt;In reading the &lt;a href="https://tekton.dev/docs/pipelines/taskruns/#cancelling-a-taskrun"&gt;Tekton TaskRun documentation&lt;/a&gt; all you have to do is stick "TaskRunCancelled" in the Status object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: tekton.dev/v1alpha1
kind: TaskRun
metadata:
  name: go-example-git
spec:
  # […]
  status: "TaskRunCancelled"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Seems easy enough, right?&lt;/p&gt;

&lt;p&gt;🚧 ...not so fast!&lt;/p&gt;

&lt;p&gt;This doesn't actually work...or at least I could not get it to work.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what does work?
&lt;/h2&gt;

&lt;p&gt;What worked for me was updating the Condition block in the Status.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Retrieve the particular TaskRun&lt;/li&gt;
&lt;li&gt;Build up a Condition block and set the type, status, reason, and message.&lt;/li&gt;
&lt;li&gt;Replace all existing Conditions. &lt;em&gt;If you don't replace the existing conditions, you will receive a message back saying "Not all Steps in the Task have finished executing".&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TaskRun taskRun = client.v1beta1().taskRuns().inNamespace("default").list().getItems().get(0);

List&amp;lt;Condition&amp;gt; taskRunConditions = new ArrayList&amp;lt;&amp;gt;();
Condition taskRunCancelCondition = new Condition();
taskRunCancelCondition.setType("Succeeded");
taskRunCancelCondition.setStatus("False");
taskRunCancelCondition.setReason("TaskRunCancelled");
taskRunCancelCondition.setMessage("The TaskRun was cancelled successfully.");
taskRunConditions.add(taskRunCancelCondition);

taskRun.getStatus().setConditions(taskRunConditions);

client.v1beta1().taskRuns().updateStatus(taskRun);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a really great table in the &lt;a href="https://tekton.dev/docs/pipelines/taskruns/#monitoring-execution-status"&gt;Tekton TaskRun documentation&lt;/a&gt; for the different execution statuses you can expect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Show your support
&lt;/h2&gt;

&lt;p&gt;Do not hesitate to support us if this helped you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/boomerang-io/flow.client.web"&gt;⭐️ the GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/useboomerangio"&gt;💬 Follow us on Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.useboomerang.io/docs/boomerang-flow/installing/installing"&gt;Install the project&lt;/a&gt; on your own Kubernetes cluster&lt;/li&gt;
&lt;li&gt;🙏 Join us and help contribute&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>fabric8</category>
      <category>tekton</category>
      <category>workflow</category>
    </item>
    <item>
      <title>Converting to Tekton in Boomerang Flow using Fabric8</title>
      <dc:creator>Tyson Lawrie</dc:creator>
      <pubDate>Fri, 07 May 2021 05:32:07 +0000</pubDate>
      <link>https://dev.to/tysonlawrie/converting-to-farbic8-and-tekton-in-boomerang-flow-1dbi</link>
      <guid>https://dev.to/tysonlawrie/converting-to-farbic8-and-tekton-in-boomerang-flow-1dbi</guid>
      <description>&lt;p&gt;Recently, as part of work on version 3 of &lt;a href="https://useboomerang.io"&gt;Boomerang Flow&lt;/a&gt;, we undertook a decision to migrate from Kubernetes Jobs to &lt;a href="https://tekton.dev/"&gt;Tekton&lt;/a&gt; Tasks and TaskRuns.&lt;/p&gt;

&lt;p&gt;As we stepped back and looked at the how and after many deep conversations late at night (thanks &lt;a href="https://twitter.com/marcusdroy"&gt;Marcus&lt;/a&gt;), we decided that it was also the right time to migrate from the existing Kubernetes Java Client to the Fabric8 Kubernetes Java Client.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Boomerang Flow
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://useboomerang.io"&gt;Boomerang Flow&lt;/a&gt; is an open-source event-driven cloud-native workflow automation tool that runs on Kubernetes and provides a no-code drag and drop editor for workflow creation. We focus first on the end user experience and then the technical features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Tekton
&lt;/h2&gt;

&lt;p&gt;It was a big decision to make, one that had been in the works for a while with over 9 months of healthy discussions, and so at the start of 2021 we commenced the changes.&lt;/p&gt;

&lt;p&gt;Whilst we had done a lot of great work in our internal controller to orchestrate and manage Kubernetes Jobs, there were a number of areas that we lacked features or had alternative ways of achieving the same result, but without the broader community. We were also starting to see cracks in our error handling&lt;/p&gt;

&lt;p&gt;We also wanted to make sure that by adopting Tekton we would not be sacrificing any end-user experience. In the following comparisons you'll see that in majority of the cases we could actually build out new functionality to help our users.&lt;/p&gt;

&lt;p&gt;For now, we are only adopting the Tekton Task/TaskRun and working in with our existing Workflow DAG, it opens up a huge range of benefits;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Leverages the community of a popular open-source system&lt;/li&gt;
&lt;li&gt;Provides additional Task functionality with steps and script blocks&lt;/li&gt;
&lt;li&gt;Provides a wider range of Tasks built by community&lt;/li&gt;
&lt;li&gt;Allows us to focus less on adding new functionality to the engine, and spending this time on enhancements with the community.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Tasks
&lt;/h3&gt;

&lt;p&gt;We had Tasks, Tekton has Tasks. The models were relatively the same. &lt;em&gt;Fantastic! Alignment would not be a pain.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We defined our Tasks in JSON, Tekton Tasks are in YAML. The great &lt;strong&gt;JSON vs YAML&lt;/strong&gt; debate took place and we settled on YAML as this is only for the advanced user and does not take away from the end-user experience. &lt;em&gt;Plus, everything is YAML!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We did however have metadata and elements needed for the UI and as such we have followed the Kubernetes approach and stored this metadata in the &lt;em&gt;annotations&lt;/em&gt; and default it when importing a straight Tekton Task YAML without the optional annotations.&lt;/p&gt;

&lt;p&gt;We did not support multi-step or script blocks so it was a win-win to be able to bring this to our users. Whilst the typical user does not see any of this, they drag and drop a task from a Palette onto the Workflow Editor and provide inputs, it allows us to provide more powerful and complex tasks and task management, abstracted by a powerful experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nkIRFzKP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3w6fzntigf91mok2dqau.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nkIRFzKP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3w6fzntigf91mok2dqau.png" alt="Task Manager YAML Editor"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Outcomes
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;New YAML editor as part of Task Management&lt;/li&gt;
&lt;li&gt;Experience metadata stored in the annotations&lt;/li&gt;
&lt;li&gt;Additional Task features with script, working directory, environment variables, result parameters, and multi-step (coming soon).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Parameters
&lt;/h3&gt;

&lt;p&gt;We had Properties, Tekton has Parameters. We had &lt;code&gt;${p:property}&lt;/code&gt; as the syntax, Tekton has &lt;code&gt;$(params.parameter)&lt;/code&gt;. We passed in all properties to a task, with Tekton you have to explicitly define the parameters wanted.&lt;/p&gt;

&lt;p&gt;The biggest difference was in how we approach the layering and &lt;a href="https://tekton.dev/docs/pipelines/variables/"&gt;substitution&lt;/a&gt; of Parameters. Boomerang Flow offers additional layers for the user to have greater control as to how to store and re-use information. &lt;/p&gt;

&lt;p&gt;Boomerang Flow also provides powerful inheritance and full recursive substitution, this means that if you define a Parameter at the Team layer and then also at the Workflow level, the Workflow Parameter will win out, this is all resolved as part of using &lt;code&gt;$(params.&amp;lt;parameter&amp;gt;)&lt;/code&gt;. Or if you have a Workflow Parameter that references another Parameter this will also be resolved and substituted.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Boomerang Flow&lt;/th&gt;
&lt;th&gt;Tekton&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;System&lt;/td&gt;
&lt;td&gt;Content&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Global&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Team&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workflows&lt;/td&gt;
&lt;td&gt;Pipelines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tasks&lt;/td&gt;
&lt;td&gt;Tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Outcomes
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Retained the same great experience and powerful inheritance and recursive substitution with all existing layers kept.&lt;/li&gt;
&lt;li&gt;Adjusted to the Tetkon &lt;code&gt;$( )&lt;/code&gt; syntax&lt;/li&gt;
&lt;li&gt;Explicitly define the parameters that are sent through to a task.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Result Parameters
&lt;/h3&gt;

&lt;p&gt;We had Output Properties, Tekton has Result Parameters.&lt;/p&gt;

&lt;p&gt;We utilized a watcher side car to scrape a folder and turn all files into Output Properties by posting these back using a HTTP Post and then patch a ConfigMap.&lt;/p&gt;

&lt;p&gt;Tekton on the other hand requires explicitly defining the result parameters and&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scrapes a folder for files named that match the explicitly defined expected results&lt;/li&gt;
&lt;li&gt;Stores them in the container termination message. This is thus limited to 4096 bytes&lt;/li&gt;
&lt;li&gt;relies on alternate resources for larger outputs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What we lose in this instance we gain in other areas, including in not having a custom implementation that required patching ConfigMaps that sometimes failed. We will also be submitting a TEP to the community on hopefully adjusting how parameters are stored to remove the size restriction.&lt;/p&gt;

&lt;p&gt;We also were able to update the UI to now provide auto complete when reference the result parameter of another task. &lt;em&gt;Isn't that neat!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vsjIVK3C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s14smofnyb51317y2yas.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vsjIVK3C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s14smofnyb51317y2yas.png" alt="Workflow Editor Result Parameter Auto Prompt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z1KjTvv1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rha06ymrwqikdsx4mxz6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z1KjTvv1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rha06ymrwqikdsx4mxz6.png" alt="Workflow Activity View Tasks Result Parameters"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Outcomes
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Explicitly defined Result Parameters in Task Manager&lt;/li&gt;
&lt;li&gt;Deprecation of our bespoke Watcher and related code&lt;/li&gt;
&lt;li&gt;A more stable well tested implementation&lt;/li&gt;
&lt;li&gt;Auto prompt reference of result parameters when in the Workflow Editor&lt;/li&gt;
&lt;li&gt;New description when viewing results in the Workflow Activity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Error handling
&lt;/h3&gt;

&lt;p&gt;Another big win was solving a number of our error handling concerns. Tekton provided a structured Task error object and error handling, and watching for these errors was made a lot simpler with the Fabric8 client.&lt;/p&gt;

&lt;p&gt;We could then capture and translate these to nice user based messages to return to the user and provide greater visibility and detail at both the Task and Workflow level. This was a &lt;strong&gt;powerful&lt;/strong&gt; enhancement for our user experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ha6j3pCU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/flu6f6oqmyezvnm6fjtr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ha6j3pCU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/flu6f6oqmyezvnm6fjtr.png" alt="Workflow Activity View Task Error"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h4&gt;
  
  
  Outcomes
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;More structured and detailed errors&lt;/li&gt;
&lt;li&gt;Better ability to watch and handle the errors&lt;/li&gt;
&lt;li&gt;New Task and Workflow error viewing in the Workflow Activity for greater visibility.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why change Java clients
&lt;/h2&gt;

&lt;p&gt;Technically we did not have to move from the vanilla Kubernetes Java Client to the Fabric8 Kubernetes Java client. We could have achieved the required CRDs (Custom Resource Definitions) in the existing client... that being said, it was much easier with the Fabric8 Tekton extension.&lt;/p&gt;

&lt;p&gt;The Fabric8 community itself has also been very helpful and its these experiences that help provide the level of examples and references for advanced implementations such as a Custom Watcher for TaskRun execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Acknowledgments
&lt;/h2&gt;

&lt;p&gt;This migration would not have been possible without the blogs and information from the community, in particular&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://itnext.io/difference-between-fabric8-and-official-kubernetes-java-client-3e0a994fd4af"&gt;Difference between Fabric8 and Official Kubernetes Java Client&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://itnext.io/access-tekton-pipelines-in-java-using-fabric8-tekton-client-bd727bd5806a"&gt;Access Tekton Pipelines in Java using Fabric8 Tekton Client&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/fabric8io/kubernetes-client/blob/master/doc/CHEATSHEET.md"&gt;Fabric8 Kubernetes Client Cheat Sheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.programcreek.com/java-api-examples/?code=eclipse%2Fche%2Fche-master%2Finfrastructures%2Fkubernetes%2Fsrc%2Fmain%2Fjava%2Forg%2Feclipse%2Fche%2Fworkspace%2Finfrastructure%2Fkubernetes%2Fnamespace%2FKubernetesPersistentVolumeClaims.java#"&gt;Code from the Che project&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And my fellow contributors: Ben, Marcus, and Costel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Show your support
&lt;/h2&gt;

&lt;p&gt;Do not hesitate to support us if this helped you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/boomerang-io/flow.client.web"&gt;⭐️ the GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/useboomerangio"&gt;💬 Follow us on Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.useboomerang.io/docs/boomerang-flow/installing/installing"&gt;Install the project&lt;/a&gt; on your own Kubernetes cluster&lt;/li&gt;
&lt;li&gt;🙏 Join us and help contribute&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>automation</category>
      <category>workflow</category>
      <category>tekton</category>
    </item>
    <item>
      <title>CICD Evicted: exceeded ephemeral storage</title>
      <dc:creator>Tyson Lawrie</dc:creator>
      <pubDate>Fri, 28 Aug 2020 02:53:10 +0000</pubDate>
      <link>https://dev.to/tysonlawrie/cicd-evicted-exceeded-ephemeral-storage-4n2h</link>
      <guid>https://dev.to/tysonlawrie/cicd-evicted-exceeded-ephemeral-storage-4n2h</guid>
      <description>&lt;p&gt;&lt;em&gt;I am a Software Engineer enjoying the journey to a Cloud Native landscape. You can find my previous posts on &lt;a href="https://medium.com/@tysonlawrie"&gt;Medium&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Pod ephemeral local storage usage exceeds the total limit of containers
&lt;/h2&gt;

&lt;p&gt;Recently we hit a major issue with the builds for some of our AI based components in our DevOps pipeline. Due to either storage or memory limits. As with all the new modern DevOps tools, a task (essentially a Kubernetes Job) is spun up to complete the commands required to build and package.&lt;/p&gt;

&lt;p&gt;In can be complex to pinpoint exactly what the issue is and what reaching these limits mean, at what point in the task are these limits reached.&lt;/p&gt;

&lt;h2&gt;
  
  
  ephemeral-storage = emptyDir &amp;amp;&amp;amp; medium = memory
&lt;/h2&gt;

&lt;p&gt;In kubernetes ephemeral-storage can be mapped to an emptyDir, essentially a scratch space for the duration of the pod which is then terminated. Unfortunately on our clusters, each Node only has a maximum disk space of 100Gb so it very quickly fills up.&lt;/p&gt;

&lt;p&gt;Ok so let's use this cool medium feature and set the storage to use memory. Bonus the task sped up, we saw an increase in performance of about 20%. Unfortunately we still reached a maximum for the task with the memory resource limit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Volumes:
  cicd-vol-data:
    Type:    EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:  Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Visibility = New Relic infrastructure
&lt;/h2&gt;

&lt;p&gt;We really needed to get a realistic view of what all these CICD tasks were doing, we could no longer just sail through with blind trust in tasks and pipelines. Time for a real deep analysis.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jNaDDYML--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tx0ypb3ryzzqb9xa2raw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jNaDDYML--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tx0ypb3ryzzqb9xa2raw.png" alt="Memory"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TFKIM21A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gtcbn6zlnnpaxyjmvgn8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TFKIM21A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/gtcbn6zlnnpaxyjmvgn8.png" alt="CPU"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With new relic infrastructure agents on our kubernetes nodes we put together a dashboard that would show us a breakdown of the memory, storage, and CPU thats being consumed by our tasks.&lt;/p&gt;

&lt;p&gt;In this dashboard you can see the spikes specifically for the AI related worker are outliers compared to all the other tasks. As you can see they reach the limits previously applied for disk and memory (16Gb Ephemeral + 16Gb of Memory as Disk) and just abruptly terminate. CPU is fine.&lt;/p&gt;

&lt;p&gt;It seems we have just transferred the issue from storage to memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unpacking the layers
&lt;/h2&gt;

&lt;p&gt;In analyzing the memory usage, the task would consume a total of 21.6Gb of memory. Essentially the working scratch directory in memory was ~18Gb by completion. Well thats HUGE!&lt;/p&gt;

&lt;p&gt;In breaking down the 18GB, we have;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After Clone = 1.7Gb&lt;/li&gt;
&lt;li&gt;After Image Build &amp;amp; Export we have = ~16Gb. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Image build includes the build context, tempfs, and output archive. The build context &lt;br&gt;
**Whenever there is a Dockerfile command (&lt;code&gt;COPY . .&lt;/code&gt; or &lt;code&gt;RUN xyz .&lt;/code&gt;) its copying the context into different layers. Every command in the container forms layers.&lt;/p&gt;

&lt;p&gt;The key was to understand the various layers being built to see we were starting to copy the file contents around the place making multiples of 1.7Gb&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;To get this going for our team, we increased the memory limit to 24Gb, which was easier for us than disk (plus we wanted the speed increase). Hooray, it built!&lt;/p&gt;

&lt;p&gt;And now we focus on the Dockerfile and code structure to try and make it more efficient and bring this back down to within normal range.&lt;/p&gt;




&lt;p&gt;Thanks go to my whole team, in particular, key members of that team: &lt;a href="https://twitter.com/glenhick"&gt;Glen Hickman&lt;/a&gt; and Ionut Palada for the help in solving this issue.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>boomerang</category>
    </item>
  </channel>
</rss>
