Defining and using the Actions in a Dagger Script

Using CUE dagger
Reading Time: 3 minutes

Introduction

Dagger is an open source devkit for CICD. It works using two open source tools CUE language and BuildKit from Docker. Dagger uses CUE to script the code and configuration. And Buildkit to provide local containerized environment.

Prerequisite

  1. Dagger installed on local system. The latest version now is 0.2.10
  2. Docker installed on local system. The latest version now is 20.10.16

What are Actions in Dagger ?

Actions in Dagger are definitions that perform a task inside a #Plan. They are repeatable and called in other scripts or actions. Actions can be related to functions used in a programming language. For example, in python, there are modules with multiple functions. These are imported in the program and used. For example, “requests” used to use REST api functions.

In the built-in package, there are predefined actions at dagger.io/. Here we have used the #Pull definition in the image. cue script from dagger.io/dagger/core

image.cue

package core

import (
	"list"
	"dagger.io/dagger"
)

....
....
....
....

// Download a container image from a remote repository

#Pull: {
	$dagger: task: _name: "Pull"

	// Repository source ref

	source: #Ref

	// Authentication

	auth?: {
		username: string
		secret:   dagger.#Secret
	}

	// When to pull the image

	resolveMode: *"default" | "forcePull" | "preferLocal"

	// Root filesystem of downloaded image

	output: dagger.#FS @dagger(generated)

	// Image digest

	digest: string @dagger(generated)

	// Downloaded container image config

	config: #ImageConfig @dagger(generated)
}
 
....
....
....
....

main.cue

package basic

import (
	"dagger.io/dagger"

	"dagger.io/dagger/core"
)

dagger.#Plan & {

	actions: {

		alpineImage: core.#Pull & {

                  source: "alpine:3"
               }
	 }
}
example1 of actions in dagger

In Dagger, there are two types of actions:

  1. Core Actions: They are primary actions defined under dagger.io/core. The dagger development team defines. In addition, they modify and update them on source code for other people.
  2. Composite Actions: These actions derived from core actions. And devops engineer define these actions in project. Above all,these actions are easily used with many CI servers.

The #PULL action defined in the “image” script is a core action. Similarly, the “alpineImage” action in the “main” script is a composite action.

LifeCycle of Actions in Dagger

The composite actions follow a lifecycle in Dagger. It consists of four stages, namely:

Definition –> Integration –> Discovery –> Execution

1. Definition

The Dagger script uses the CUE template for definitions. These Definitions define the input, output, sub-actions, and interconnections fir the project. And each sub-actions can be inter-related. Moreover, CUE runs every related actions for all actions. Exploring the #Pull action of the image script, we find:

  • The “inputs” are simple incomplete fields for input. For example, username and secret are inputs.
  • The “output” produce a value that integrates externally. For example, the output is the output image.
  • The “sub-actions” contain another action definition. For example, #Secret and #FS  are sub-actions.

2. Integration

Integration is the part of lifecycle where actions become usable. The #Plan integrates them with the current project for end-user use. The dagger will now be able to cache the logs and images related to the action. In dagger.io/dagger, the plan script defines the working of #Plan.

example1.cue

package helloworld

import (
	"dagger.io/dagger"

	"dagger.io/dagger/core"
)

dagger.#Plan & {
	actions: {
		_alpine: core.#Pull & {source: "alpine:3"}

		name: string | *"Vaibhav"
		hello: core.#Exec & {

			input: _alpine.output

			args: ["echo", "hello, world! From /(name)"]

			always: true
		}
	}
}

There are two ways of integration in dagger. Firstly, it is direct integration like the core.#Pull action. Secondly, it is indirect integration like the action “#Pull” integrates with the “#FS” . The integrations define:

  1. What can be done by end-user.
  2. The dependencies for those interactions. For instance, the name is the required string required.
  3. The interactions between client and task.

3. Discovery

After integration, end-users discover available actions. They use the “dagger do” command. The output messages provide these actions and options with them. For example, in the example1, in the Available Actions part shows hello action and name in the Options part.

discovery output

4. Execution

The same dagger do command executes the actions. And this can be seen in following:

action output

Conclusion

In this blog , use of actions in Dagger was explored. Moreover, this blog was all about the scripting in Dagger. You can learn a lot about this powerful CI/CD devkit. You can explore the dagger documentations. Further, you may visit the GitHub repository to learn about dagger.

References

footer

Written by 

Vaibhav Kumar is a DevOps Engineer at Knoldus | Part of Nashtech with experience in architecting and automating integral deployments over infrastructure. Proficient in Jenkins, Git, AWS and in developing CI pipelines. Able to perform configuration management using ansible and infrastructure management using terraform. Like to script and do developing in Python. Other than AWS, have an experience in Google Cloud, Azure cloud services. Other than Jenkins, CI/CD in Azure Pipelines, GitHub Actions, Teamcity. Loves to explore new technologies and ways to improve work with automation.