#Simplify code with custom type

1 messages · Page 1 of 1 (latest)

paper fjord
#

Sorry if I misunderstood what you want to do. For maximum simplicity, personally I would do this:

type RedhatMinimal struct {}

func (*RedhatMinimal) Container(base *Container, packages []string) *Container {
  return base.
    WithExec(append([]string{"microdnf", "install", "--nodocs", "--setopt", "install_weak_deps=0", "--assumeyes"}, packages...)).
    WithExec([]string{"microdnf", "clean", "all"})
}
#

For maximum convenience, you can add default values for both base and packages.

type RedhatMinimal struct {}

// Build a minimal Red Hat container
func (*RedhatMinimal) Container(
  // Custom base image
  // +optional
  base *Container,
  // System  packages to install
  // +optional
  packages []string,
) *Container {
  if base == nil {
    base = dag.Container().From("docker.io/redhat/ubi8")
  }
  if packages == nil {
    return base
  }
  return base.
    WithExec(append([]string{"microdnf", "install", "--nodocs", "--setopt", "install_weak_deps=0", "--assumeyes"}, packages...)).
    WithExec([]string{"microdnf", "clean", "all"})
}
tall robin
#

Hi @paper fjord, thanks for your detailed answer! That’s the approach I tested first, but I found it not that flexible for what I’d like to do. For a better view of what I’m currently doing, here is my Daggerverse: https://github.com/camptocamp/daggerverse. I’ve a Redhat module to get UBI images and customize them, a Nodejs module to install Node.js on an UBI image, a Golang module to install Go on an UBI image, and a Documentation module which uses the Nodejs and Golang modules to install Node.js and Go on an UBI image. My current approach allows me to use chaining: https://github.com/camptocamp/daggerverse/blob/0eee0f9a9db5df12b7900819d9b4df83cb39c8a7/documentation/main.go#L51-L58 and https://github.com/camptocamp/daggerverse/blob/0eee0f9a9db5df12b7900819d9b4df83cb39c8a7/nodejs/main.go#L24-L30. However, I don’t know if this is good nor idiomatic Dagger code.

GitHub

Contribute to camptocamp/daggerverse development by creating an account on GitHub.

GitHub

Contribute to camptocamp/daggerverse development by creating an account on GitHub.

paper fjord
#

Two things here:

  1. It's fair to say we're all still figuring out best practices for this platform, so as long as your approach works for you, that's enough to call it good 🙂

  2. Speaking for myself: in your situation, where you want to carry a little more state around, and not just pass everything as arguments every time (like I did in my example): I think I would create custom types wrapping a Container, one for each specialized container. Then when I need to access the raw container object, simply have a function return that.

I'm busy right now, but later today I'll try to write a quick example of what I mean

#

I personally try to avoid relying on With(), because it doesn't actually use the Dagger API, it's an SDK-specific convenience. I find that with Functions, I no longer feel the need for it