#daggernauts

1 messages ยท Page 3 of 1

spiral whale
#

1password on Zenith ๐Ÿฆค . I really love how easy to create a module and integrate it into my workflows.

sharp zealot
spiral whale
#

Good old โ€˜sedโ€™ ๐Ÿ™‚ itโ€™s not expanded ( dagger query --progress=plain container < <(sed "s/$OP_SERVICE_ACCOUNT_TOKEN/$OP_SERVICE_ACCOUNT_TOKEN/g" examples/examples.gql) )

sharp zealot
#

I just ran my first Zenith function from a stable dagger build ๐Ÿ™‚ 0.8.8

#

@kind carbon how do I play with the latest and greatest of CLI invocation?

kind carbon
sharp zealot
thorn moat
spiral whale
#

This is like a trailer for the final episode of your favorite TV show. ๐Ÿ˜ต

strong ingot
#

Can you share an mtr daggerverse.dev -rwnbc 10 via DM? Would like to dig into this one.

BTW, I suspect that it's the same reason that registry.dagger.io doesn't work for you.

FWIW, this is a temporary setup, I expect us to migrate it over the next few weeks.

sonic vessel
#

Learning Zenith - Jenkins DSL ๐Ÿ‘€

restive shore
restive shore
kind carbon
sharp zealot
#

When you want to try @kind carbon 's CLI awesomenedd, but are too lazy to fetch his PR into your local dev environment...

echo '{dagger{engine{dev(repository:"https://github.com/helderco/dagger", branch:"helder/dev-2744-pass-arguments-to-functions-as-subcommands"){cli(operatingSystem:"darwin", arch:"arm64"){export(path:"./superdagger")}}}}}' | dagger -m github.com/shykes/daggerverse/dagger query
./superdagger call --help

(Requires Dagger 0.8.8)

upbeat herald
#

Is there a way to update the dagger.json to not publish a package? I'll create a module to tests my other modules but it's not something that should be used by anyone else than me

#

It's kind of a replacement of a possible mage file, with a method integration-test, lint etc...

kind carbon
#

You can check the query that's executed in debug mode.

thorn moat
#

@sonic vessel Small local dev requesst for the Elixir SDK - when sdk:elixir:generate fails, it seems to leave my local state with the entire sdk/elixir/... removed, which I have to git checkout before I can try again. Haven't had time to look into why it's happening, it's not a big deal just slightly annoying. If you can find time to fix that I'd appreciate it ๐Ÿ™

rocky harbor
#

You can check the query that s executed

sharp zealot
#

Starting a quick "project management" thread to talk about Kubecon countdown...

bleak nest
#

I need some help creating and testing Node and Python examples for the services v2 guide...Helder/Tom/JF, can you please have a look whenever possible at https://github.com/dagger/dagger/pull/5557 where I've put inline comments for the snippets I need your help with? Thanks!

rocky harbor
#

debug module tests

sharp zealot
#

@rocky harbor linear bikeshedding, if you don't mind I'm going to move dagger shell and dagger serve under call functions from the CLI since that's the big killer feature and in my mind, each verb we want to ship on top of call should be part of it

rocky harbor
sonic vessel
thorn moat
#

thanks! โค๏ธ

rose hinge
#

Hi, I'm trying the module feature but I have an issue.
It seems when a ref of my object is send to a children, private attributes are not transfered.
If I try to put in public the attribute (secretManagerClient) I have a graphql schema error related to the type: secretmanager.Client where the Client type seems to create a conflict.
I don't really understand what I'm doing wrong or how to deal with that, someone have an idea ? (the code is available here: https://github.com/Dudesons/daggerverse/tree/main/gcp-secrets-manager)

upbeat herald
#

Hello guys, I made 3 modules (Golang, Golangci-lint, Node) to test some dependencies capabilities of Zenith and explore way to test module through a ci module (that should be private, it's not usable in another context)

https://github.com/quartz-technology/daggerverse

I'll also add tests for Golang and a python Module soon, it's pretty fun to play with Dagger Zenith ๐Ÿš€
Using concurrency definitely helps for tests btw ๐Ÿ˜„

GitHub

Daggerverse modules made by Quartz. Contribute to quartz-technology/daggerverse development by creating an account on GitHub.

rose hinge
rose hinge
obtuse lion
#

the dagger playground localhost CORS approach is super cool ๐Ÿ™‚

#

for playground modules should be able to have examples, like godocs does. Or the same in daggerverse

#

i'm having a lot of fun with modules, i'm doing some really stupid things, but I will say it's pretty hard to understand how to create modules that don't suck. Like what's a good pattern. I'm sure since this is all so new yall are still figuring out the best style. But in general, adding methods to container I think is a difficult to understand model. I've seen over and over again that people really really struggle with the idea of CI tasks running from a containerized context. Add things to directory makes more sense to be. Like Host().Directory(".").Gobuild(). Then the consumer just feels like they are "running a command." I'm building something with dagger that is a bit off the wall and hope to be able to share it soon (not convinced it's a good idea, but it's fun).

upbeat herald
sharp zealot
#

@obtuse lion yeah I no longer extend core types personally

#

My favorite pattern is straightforward but awesome: my own structs with their own state and methods

obtuse lion
#

i'm trying to rewrite one of my projects CI pipelines using zenith, so fooling around with different approaches. I struggle with the idea of "what should the output be". For example, gobuild is the core thing I need to do. Should the result of that function be a that it wrote the binary back to the host, or should it return a directory that has the binary in it. The later is definitely cooler, but it's hard to understand how to use it. I'm doing this all from the perspective of it I rewrite everything with zenith whats the chances my engineers don't get confused.

sharp zealot
#

if it helps i started doing this for our own ci ๐Ÿ™‚

obtuse lion
#

I really struggle with the concepts of things existing in a parallel containerized/cached universe. I saw this with gh action where they started with a dockerized model, but then what took off is the javascript approach where everything runs in the same context.

obtuse lion
#

I hope there's some happy medium where it can look like things are all running in the same context, but really they do fancy things on the side and don't have to pollute the host like GH actions do.

sharp zealot
obtuse lion
#

This is cool, but I still struggle with complexity that you are basically creating a virtual workspace. It exists "somewhere" in dagger. That's hard to grok unless everything you are doing is in that virtual space. Like if your dagger "script" is "first checkout, do stuff" Then it's fine because everything is in one virtual place. But if your starting from the perspective that you already have everything checked out locally on disk (how all CI flows start). It's hard to mentally reconcile what you have locally with what is happening virtually elsewhere. Sorry if that confusing to explain. Like the full mental model of how to best use dagger hasn't quite clicked with me in a way that I can easily explain it to someone. Everything I do with it so far is super fun and cool, but I just know I can't easily give it to someone else, they will be so confused. Not that it's a flaw of dagger, just that I don't understand the right way to hold the phone ๐Ÿ™‚

obtuse lion
#

I would vote to not allow extending core types. It still doesn't seem right to me. My two cents. I think the method chaining approach really makes sense from the perspective that you are essentially doing a fluent api builder pattern. But I don't think it should be abused to the point that try to do everything in one chain. So self referencing method are nice, but adding to other types not so much.

wintry prism
#

experimented with goplantuml

#
go get github.com/jfeliu007/goplantuml/parser
go install github.com/jfeliu007/goplantuml/cmd/goplantuml@latest

goplantuml -show-compositions -show-connection-labels -show-aliases -show-aggregations -show-implementations -show-options-as-note  ./supergit > supergit.puml

Then pasted contents of supergit.puml in https://www.plantuml.com/plantuml/ and hit submit.

latent trellis
#

Now that zenith is merged, do I still need a local dev engine? Or can I enable it with an environment variable?

latent trellis
sharp zealot
wintry prism
obtuse lion
#

The WithX style doesn't really represent cardinality well. What I mean is the ambiguity of a method WithFoo, is that replacing Foo or appending Foo. I'm trying to understand the style where it seems like WithX function should be used to build an object, essentially aggregate state.

#

Is there a public version of querybuilder somewhere? Not the generated one in ./internal?

rocky harbor
#

we could most likely split it out to its own quicker PR if helpful

obtuse lion
kind carbon
rocky harbor
obtuse lion
#

I'd vote for WithFoo for replacing as that seems like the default behavior and WithAppendFoo for appending

#

Is it intentional that dagger mod --help doesn't show any help about init/use

obtuse lion
kind carbon
obtuse lion
rocky harbor
obtuse lion
kind carbon
obtuse lion
rocky harbor
#

Is it intentional that dagger mod help

obtuse lion
#

I'm trying to do a multicall type thing where I want this code to run in the context of a module or not. The only way I seem to know if I'm in a function call is if CurrentFunctionCall().Name() blows up. Could there no a better flow that doesn't result in an error to know if I'm in a function call?

rocky harbor
# obtuse lion I'm trying to do a multicall type thing where I want this code to run in the con...

There definitely could be, it would be trivial to add an API that just returns a bool based on whether you are in a module or not. That just wasn't really a use case we've thought about before ๐Ÿ˜„ Curious about the details whenever you have time. In general, we want users to execute while containerized as much as possible, so we just want to be careful to not rush into making these sorts of use cases too easy necessarily (though happy to be proven wrong)

obtuse lion
rocky harbor
obtuse lion
rocky harbor
#

Thoughts on extending core types (and generally types from outside your module)โ€ฆ

Conceptually, itโ€™s all total sugar. In terms of functionality,query{container{foo(arg:โ€abcโ€)}} has the same effect as query{foo(container:โ€<container id>โ€, arg:โ€abcโ€)}

func(c *Container) Foo(arg string) has the same effect as func Foo(c *Container, arg string)

etc.

So, by that argument, it does feel like our raw graphql API doesnโ€™t need to support extending other types. Sugar is not very important on that level.

In terms of our codegen across various languages, sugar does matter though. I have a million thoughts on the cases where extending other types is genuinely useful vs when itโ€™s an anti-pattern. But it just devolves into the same arguments programmers have been having with each other for decades about programming styles, the best language, the best API, etc. Itโ€™s honestly just kind of boring at this point.

Whatโ€™s more interesting IMO is that whatever choice Dagger makes for our official SDKs in terms of whether methods can be added to core types, it would still be possible for someone else to say โ€œthatโ€™s awfulโ€ and then go make their own SDK that encodes their own opinions. Thatโ€™s possible because of our โ€œconsumer-centricโ€ model where codegen is done client-side and because of the work over the last month to allow SDKs to be implemented as modules and then published+consumed by anyone.

#

So to be concrete, if we didnโ€™t allow core type extensions in the graphql schema or in our Go SDK, someone else could still implement a AltGo SDK that does codegen with methods extending core types. Using the example above, they could find what would have been methods like func Foo(c *Container, arg string) and instead codegen them as func(c *Container) Foo(arg string). There would be some interesting heuristics there, but definitely possible.

obtuse lion
#

Is the point your making is that sugar can be added after the fact by a consumer and therefore that is reason to possibly delay allowing it? My general approach is just that when it comes to UX, conservative is better. Once it's proven it can be added later. So it seems like having the ability to bake the feature a bit more outside of core might be good.

rocky harbor
# obtuse lion Is the point your making is that sugar can be added after the fact by a consumer...

Yes exactly, I'm sort of thinking out loud so sorry that the point wasn't clear, I'm still figuring it out ๐Ÿ˜…

Basically, the first important point is that it's not needed at all in terms of graphql schema, no utility there. The second important point is that I realized even if we don't implement this ability in the raw graphql schema, then it's still possible for codegen'd clients to choose to do it. Basically, I'm realizing whatever choice we make isn't really a one-way door, which is great.

I've heard dramatically different opinions on the feature, so we'll upset someone no matter what. So since all else is equal, 100% agree that just starting more conservative is probably the better option.

obtuse lion
rocky harbor
obtuse lion
#

but I'll definitely read through this PR.

rocky harbor
rocky harbor
latent trellis
rose hinge
#

Hi, is it possible to have a list as an input for a method in a module ?

#

I tried something like that: func (f *Foo) WithBars(e []Bar) *Foo { // ... return f }

#

but I have this error: ```dagger mod sync
โ€ข Engine: ceb73106b135 (version v0.8.8)
โง— 3.75s โœ” 51 โˆ… 7 โœ˜ 2
Error: failed to automate vcs: failed to get vcs ignored paths: input:1: host.directory.asModule failed to call module to get functions: failed to get function output directory: process "go build -o /runtime -ldflags -s -d -w ." did not complete successfully: exit code: 1

oblique reef
rose hinge
ocean escarp
#

Is it possible to pass environment variable from the host to the dagger module?

bleak nest
#

I need some help creating and testing

kind carbon
# ocean escarp Is it possible to pass environment variable from the host to the dagger module?

You can send the value as you're calling, like dagger call deploy --token $API_TOKEN. But... we could also interpret a function's EnvVariable parameter to interpret the value of the flag as the key to fetch the OS var from. Like dagger call deploy --token API_TOKEN . You'd then need to token.Value(ctx). Not sure when that would be preferred over just sending the value though. And it may be worse for reusability, when consumed by other functions (having to instanciate an EnvVariable).

kind carbon
ocean escarp
#

ok, so I need to pass as an argument to the function. Now, if my function needs several optional parameters?

kind carbon
#

Just keep passing flags ๐Ÿ™‚

#

Python module runtime unlocked! ๐ŸŽ‰ Thx @rocky harbor!

rocky harbor
rocky harbor
deft rain
#

e.g., variadic params also don't generate compileable code

kind carbon
ocean escarp
rose hinge
#

Hi I have a question when using modules, is it possible to use modules in a code which is called with dagger run ... or I have to use another command or doing something different ?

deft rain
rose hinge
wintry prism
#

Getting this after new module creation with v0.8.8

#

I remember seeing advice of changing the go.mod to match suggested format. Is there an issue for this already?

kind carbon
#

Not sure. In this case it should be changed to 1.21, not 1.23.

wintry prism
#

My module has other complaints about secrets and such, so maybe that caused something to go wrong...not sure.

kind carbon
#

Python runtime

obtuse lion
#

I realize now that if my first step of my dagger pipeline is to git clone, dagger makes so much more sense to me. Which leads me to two observations:

  1. It's surprising difficult to do an good git clone for CI, just look at all the crap actions/checkout does
  2. If you are using GH action, you have to do a checkout to get the dagger to then run the checkout... kind of weird.
warped canyon
rocky harbor
# obtuse lion I realize now that if my first step of my dagger pipeline is to git clone, dagge...

Yes agreed on both points.

What @warped canyon said, with the dagger CLI you can run e.g. dagger query -m github.com/org/repo/subpath@commit .... When you do that, the git repo holding the module is pulled in the dagger engine (not to your local fs), so it's all nice and cached and efficient. I almost think of it as the equivalent of being able to specify a remote docker image in a docker run command, except our equivalent in dagger are remote git repos ๐Ÿ™‚

Also, a few Zenith iterations ago I did some early experimentation w/ an updated Dagger Github Action that basically just installs the dagger CLI for you and then parses the GH env vars to figure out what repo you want to checkout and uses that as your module. So I ended up being able to run my CI steps w/out including the standard actions/checkout@v3 step first. Ultimately just a marginal performance improvement, but pretty nice still.

thorn moat
# wintry prism Getting this after new module creation with v0.8.8

you need to bump to go 1.21, which frustratingly changed the default go.mod version format in a backwards-incompatible way, and the message is pretty confusing. your local pre-1.21 Go is unhappy seeing a full MAJOR.MINOR.PATCH semver number that 1.21 produces, where it previously only supported MAJOR.MINOR

sharp zealot
wintry prism
#

regarding passing secrets around from GraphQL or CLI, what's the best strategy for now? I was trying out a HelloSecret module which is just Solomon's HelloWorld with a greeting that's a Secret. I realized I might need generics or something since my naive approach was to overload the function name with different arg types. Since I figured I might want to pass a Secret from code and a SecretID from GraphQL. But does Secret() not get an existing secret in an engine by ID? Or are they scoped to a session? Saw another discussion about introducing a GetSecret(), but maybe the solution is just adding the ability to pass a Secret from the dagger cli, eh?

type HelloSecret struct {
    Greeting *Secret
    Name     string
}
...
// Change the greeting
func (hello *HelloSecret) WithGreeting(greeting *Secret) *HelloSecret {
    hello.Greeting = greeting
    return hello
}

// Change the greeting
func (hello *HelloSecret) WithGreeting(greetingID *SecretID) *HelloSecret {
    s := dag.Secret(greetingID)
    return WithGreeting(s)
}
kind carbon
# wintry prism regarding passing secrets around from GraphQL or CLI, what's the best strategy f...

With https://github.com/dagger/dagger/pull/5882 you can pass by the CLI: dagger call with-greeting --greeting $MY_SECRET. The CLI will make the c.SetSecret for you with that value, before passing it to the query.

GitHub

Warning
Thereโ€™s a failing check due to the changes in Goโ€™s runtime, but should be fixed by #5900.
Summary
This brings several improvements to the way you call functions from the CLI.
Background
The...

wintry prism
#

Improve cli for calling module functions...

plucky ermine
#

I have a dumb question that I feel was already answered but I cant seem to find it.

It seems like none of the modules actually import the dagger SDK - I dont fully understand how this part works.

The reason I ask is because I am not sure if its possible to get your text editor to show the dagger SDK definitions and do autocomplete type things without importing the dagger SDK?

deft rain
#

Codegen ๐ŸŽ‰
So instead of importing a library, we generate code in dagger.gen.go.
If you run "dagger mod sync" then the generated code is created, and then copied locally so your ide picks it up ๐Ÿ™‚

kind carbon
#

And that's done locally only because of the IDE in fact, otherwise it wouldn't need to.

warped canyon
#

If you're having trouble with autocomplete in Go and you have a monorepo of modules, open the module directly in your editor rather than the parent directory

#

or setup a go.work, but I don't have instructions handy to help with that

deft rain
#

Jinx @warped canyon ๐Ÿ˜‚

plucky ermine
#

Thanks everyone โค๏ธ I feel like I get bit by this once a week haha, I will get the hang of this soon.

plucky ermine
wintry prism
quick wind
#

I notice all mods are written in Go so far and I recall seeing something about Go being the only supported SDK for now? Is there a timeline for other SDK support? Waiting on Python to demonstrate this internally

kind carbon
deft rain
thorn moat
thorn moat
#

@rocky harbor do you have a moment to greentick https://github.com/dagger/dagger/pull/5557? Looking to get this finally merged, tired of dealing with merge conflicts ๐Ÿ˜ตโ€๐Ÿ’ซ - docs are "done enough," better to just continue in a separate PR at this point

rocky harbor
wintry prism
#

Going to build a quick staticcheck module.

#

If I did something like WithStaticcheck(*Container) (*Container) I could install via go install but that would mean I need to assume the container provided has golang. Otherwise, I could do a dance to get a binary in there. Or I could instead do something like Staticcheck(*Directory) ... that assumes a directory with a golang project (though it will return 0 in a random directory, which is :/)

What makes most sense for linters (or other checks) in general? Did the previous dagger checks work yield lessons?
(disclaimer, my brain/body are still on UTC+1 though I'm supposedly here in UTC-7 land)

rocky harbor
#

If I did something like `WithStaticcheck

thorn moat
#

services v2 is merged elmofire

wintry prism
#

services v2 is merged :elmofire:

deft rain
#

What are people's thoughts on being able to query "the constructor" for an object?

#

e.g. I have a GitRepository - I want the remote that it comes from, but it feels like a specific case of something more general (I want the http URL that a File came from, etc)

#

I think it's slightly more apparent with Zenith - e.g. I have a github module that takes "git urls", but I'd love to be able to just take core git objects, and grab the url from there (I didn't construct the input type, so I don't have access to the constructor). Although mayyybe that's against the spirit of things ๐Ÿ˜„

rocky harbor
#

I think it's slightly more apparent with

wintry prism
rocky harbor
#

It won't come into full fruition until we add more cache control (which isn't scoped for Kubecon); so right now the only downside is that it will be uncached when first invoked in a session (cached on any subsequent calls in the session). But once we add the full cache control, you should be able to make even that code fully cached based on the inputs

spiral whale
#

I just discovered that I can use a local path for module dependency. It's baffling to me that I haven't noticed it until now. ๐Ÿ˜… ๐Ÿ˜ฌ

rocky harbor
wintry prism
#

Hi All! zenith Project Zenith Community Call happening in the โ #911305510882513037 channel right now! ๐Ÿ™‚

spiral whale
warped canyon
#

failure on sync/init on 0.9.0: Error: failed to automate vcs: failed to get vcs ignored paths: input:1: host.directory.asModule failed to create module from config ::.: failed to get runtime: failed to import go module sdk tarball: no manifest for platform linux/arm64 and tag

#

maybe I'm too early ๐Ÿ™‚

spiral whale
rocky harbor
#

failure on sync/init on 0.9.0: `Error:

kind carbon
#

@rocky harbor, I seem to have a limit on 12 functions in a module. 13 and it breaks:

Error: query module objects: returned error 502 Bad Gateway: http do: Post "http://dagger/query": net/http: HTTP/1.x transport connection broken: EOF

That's on the query for fetching the module's objects. You think that's returning a response that's too large? I'll probably have to cut down and make more queries.

#

Nope it's not the query. ๐Ÿ˜…

#

Even if I select only name, it's the same thing.

spiral whale
#

I just created this issue https://github.com/dagger/dagger/issues/5937 and it seems it exists in 0.9.0 as well. Do I making something wrong?

{
  "name": "gale",
  "sdk": "go",
  "root": "../.."
}

Shouldn't this dagger.json needs to import parent directory as dag.Host().Directory(".") it's kinds blocker for me to convert gale since I'm not able to access source code

GitHub

What is the issue? When configuring dagger.json with a parent directory that uses ".." to access repository code using dag.Host().Directory("."), it still returns the directory ...

rocky harbor
#

@Erik Sipsma, I seem to have a limit on

spiral whale
#

I'm not able to use my module remotely at the moment. I'm unsure if this is a bug or I couldn't do it properly. What is the correct way to call a module repository using subpath daggerverse/gale

ocean escarp
#

so since dagger version 0.9.0, sdk runtimes will all be included in the dagger engine container, no more need to pull an external sdk runtime image?

upbeat herald
kind carbon
#

But only for built-in ones.

wintry prism
#

dagger shell -m github.com/quartz-technology/daggerverse/redis cli --entrypoint /bin/sh

kind carbon
#

Fyi, I'm about to push several fixes for the cli.

upbeat herald
#

Unpublished because it's not usable except for testing dagger shell, but it shouldn't be imported, feel free to clone the repo to try it ๐Ÿ˜„

wintry prism
#

Fyi, I'm about to push several fixes for

rocky harbor
# kind carbon Yes, thatโ€™s right.

@ocean escarp We did the initial setup required to support including the built-in SDKs w/ the image, but it started getting way out of scope of the original purpose of the PR it was included in (which was just to get the Python SDK Module working), so it's not complete yet.

Issue for finishing removal of internet deps to run builtin SDKs here: https://github.com/dagger/dagger/issues/5913

quick wind
kind carbon
#

Codegen? I think so.

restive shore
#

Where can I find the zenith getting started guide? It would be a useful pin on his channel.

rocky harbor
rocky harbor
warped canyon
#

Playing around with module DX without extending core types. Here's how that looked over a couple of iterations:

Original DX with the Golang module extending the Container type for GoTest:

func (g *Greetings) UnitTest(ctx context.Context) (string, error) {
    b := dag.
        Golang().Base("1.21").
        WithDirectory("/src", project()).
        WithWorkdir("/src").
        GoTest([]string{"./..."})

    return b.Stdout(ctx)
}

First update to the module to keep the API about the same but without extending core types:

func (g *Greetings) UnitTest(ctx context.Context) (string, error) {
    base := dag.
        Golang().Base("1.21").
        WithDirectory("/src", project()).
        WithWorkdir("/src")
    b := dag.Golang().Test(base, []string{"./..."})

    return b.Stdout(ctx)
}

Didn't like the look of that much, so I updated the module's API to embrace a world without extending core types:

func (g *Greetings) UnitTest(ctx context.Context) (string, error) {
    return dag.
        Golang().
        WithProject(project()).
        Test([]string{"./..."}).
        Container().Stdout(ctx)
}
rocky harbor
# warped canyon Playing around with module DX without extending core types. Here's how that look...

Looks good, I am curious to see how annoying the wrapping/unwrapping pattern gets once we have modules with lots of deps that require wrapping/unwrapping all over the place, but that's sort of par for the course at least in Go, so not that big of a concern.

One nitpick: this is currently encoding an assumption that .Test() is implemented by running a single Exec on a Container, which is why .Container().Stdout() works as expected.

That's not too crazy an assumption in this particular case, but you could imagine that the implementation changes to use multiple execs or even do something else entirely like running go test direct in the module container (once the runtime container is more easily customizable).

So I think it might be better to encourage patterns where you return objects with the intended API, with the unwrapper methods like .Container only used as an escape hatch. So in the Golang module it would be more like:

type TestResult struct {
   // fields...
}

func (mod *Golang) Test(...) *TestResult {
   // ...
}

func (res *TestResult) Output() string {
   // ...
}

That way if the implementation of Test updates, the implementation of Output can also be updated and callers don't ever need to change anything.

warped canyon
#

I added a WithContainer() function to the golang module too, so there's potential to break in/out of the module multiple times

spiral whale
#

A noobie question, how do we export files and directories to host machine using dagger call?

rocky harbor
#

Has same behavior in terms of flags and calling conventions as dagger call, just a different verb to indicate you want to export what the function returns rather than just call it and see the output

spiral whale
rocky harbor
spiral whale
#

please don't read my previous message. I forget to remove my own flag ๐Ÿ˜„

spiral whale
sharp zealot
sharp zealot
rocky harbor
rocky harbor
# sharp zealot Iโ€™ve actually wondered if we should make `Container.StdX` return the concatenati...

There's times where you'd want that and times where you wouldn't, so it's hard to say. I guess the more general issue I am getting at there is just that users shouldn't need to make any assumptions about the Container being operated on internally. So that includes Std* apis but also pretty much all of the other ones too. Instead, modules should create their own types that expose exactly the APIs they support (i.e. TestResult w/ a Output field)

#

Another example might be a future update to Golang.Test that splits test execution across multiple container Execs in order to get better parallelization/caching. At that point, there isn't even a single Container to call Stdout on.

warped canyon
#

For the Golang.Test function specifically, I'd probably either grab the stdout in the function and store it in a struct in the module, or redirect the stdout/stderr into a file and reference that. In a case where my whole pipeline executes in one container, I could see some value in having an easy way to get all of the stdout, but I don't know how common that will be

spiral whale
#

tried shell first time with kind and k9s and loved it daggerfire

export DAGGER_MODULE=github.com/aweris/daggerverse/kind
dagger call cluster --name  kind-with-dagger create
โœ” build "dagger call" [1.71s]
โ”œ [1.45s] loading module
โ”œ [0.26s] loading objects
โœ” running "dagger call cluster create" [12.53s]
โ”ƒ cluster kind-with-dagger created
โ€ข Engine: 61b34bf9d33e (version v0.9.0)
โง— 15.23s โœ” 79 โˆ… 13
dagger shell k-9-s --name kind-with-dagger
โœ” build "dagger shell" [1.69s]
โ”œ [1.43s] loading module
โ”œ [0.26s] loading objects
โœ” running "dagger shell k-9-s" [32.21s]
โœ” shell [29.68s]
โ€ข Engine: 61b34bf9d33e (version v0.9.0)
โง— 34.95s โœ” 100 โˆ… 10
wintry prism
#

Doing a quick docs refresh!

wintry prism
#

translating examples from GraphQL and dagger query to dagger call (leaving both in for now)

#

Do we need two calls to dagger call to handle the multiple values returned by this gql query?

dagger call hello-world --message "I am a potato" message
dagger call hello-world --message "I am a potato" from
echo '{potato{helloWorld(message: "I am a potato"){message, from}}}' | dagger query
rocky harbor
thorn moat
rocky harbor
#

I want the tmux thing specifically to be able to reimplement bincastle someday ๐Ÿ˜„

#

But yeah, to start just being able to distinguish trivial resolver fields from โ€œexpensiveโ€ ones would be helpful here

sharp zealot
#

I think itโ€™s reasonable to print all the scalar fields if the query ends in a struct. I wouldnโ€™t worry about โ€œexpensiveโ€ fields until that actually becomes a problem

#

Also we should talk about dagger print as a more specialized version of dagger call with less noisy output and perhaps more formatting options

rocky harbor
deft rain
#

Have we considered putting the main contents of the go codegened dagger.gen.go into the internal package? There's a lot of private fields on objects now, including querybuilder things, and it would be nice if we could have the boundary properly defined.
For accessing dag easily, we could still generate a top-level dagger.gen.go that creates a little helper.

kind carbon
#

Main thing is it was just faster to do it this way, but we know we want to put as little as possible in the user's host. We still need to be compatible with non zenith runs so the current codegen in zenith just adds a bit to the dagger.gen.go that's generated by mage and shipped with the SDK releases. At one point the querybuilder package was moved into internal but I had to move it back out to use it in the CLI. The zenith codegen can improve for sure, we just thought it's a lesser priority for now. Still, ideas on how to make it better are welcome at any time. As a reminder, codegen on the host is only needed for the IDE, and having LSP work correctly. It'll still be generated on the fly inside the runtime container so it works without those files locally.

sharp zealot
#

Hey now that there is a Service type, would it make sense to support passing it from the zenith CLI as a URL? ๐Ÿ˜

#

I can't think of a specific killer use case (yet) but it feels like it could unlock a bunch of powerful stuff

#

dagger call integration-tests --db localhost:4242

wintry prism
#

Broke up into a Drupal Base(), a MariaDB AsService(), and a Drupal Test Run()

#
{
  "name": "drupalTest",
  "sdk": "go",
  "dependencies": [
    "github.com/jpadams/daggerverse/drupal@552d439f15073b62054c46f5e072be6d18b74c90",
    "github.com/jpadams/daggerverse/mariadb@552d439f15073b62054c46f5e072be6d18b74c90"
  ]
}
#

One bit I found confusing was that in Drupal().Base(ctx) the Container().Sync(ctx) returns (*Container, error) https://github.com/jpadams/daggerverse/blob/main/drupal/main.go

But by the time you go to use it in DrupalTest().Run() it doesn't want you to use Drupal().Base(ctx) but instead Drupal().Base() and drops error from the return of Base() too. If you try to use it in the original form, you get an error:

#

cc @manic lynx ๐Ÿ‘† Instant Dagger demo with dagger call -m github.com/jpadams/daggerverse/drupalTest run

manic lynx
#

Hello. ๐Ÿ™‚

#

So dagger call is for remote urls? And ragger run is for local?

wintry prism
#

dagger call, dagger up, dagger shell, etc are part of the new Project Zenith experience for running Dagger from the CLI and creating reusable, composable, multi-language modules ๐Ÿ™‚

manic lynx
#

Got it!

wintry prism
#

Another fun example above: #daggernauts message

export DAGGER_MODULE=github.com/aweris/daggerverse/kind
dagger call cluster --name  kind-with-dagger create
dagger shell k-9-s --name kind-with-dagger
manic lynx
#

Sweet!

wintry prism
#

As folks create modules, we're starting to put them here: https://daggerverse.dev/ (some early docs there).

dagger run is still great for running your Dagger pipelines written in the current mode as it gives you the TUI and makes it easy to connect to Dagger Cloud, etc.

whole maple
#

Is there any option to print log statements inside a module? Sometimes it would very useful to print out additional infos during a dagger call ...

spiral whale
whole maple
spiral whale
# wintry prism Another fun example above: https://discord.com/channels/707636530424053791/11205...

I made changes in the KinD module and to this example no longer valid for main branch. it needs to use following DAGGER_MODULE to work correctly

export DAGGER_MODULE=github.com/aweris/daggerverse/kind@66c7436dbc296e319bfa9d27236b8e9d5da2015c
dagger call cluster --name  kind-with-dagger create
dagger shell k-9-s --name kind-with-dagger

Updated README for anyone interested: https://github.com/aweris/daggerverse/tree/dc1c6d7de0aed058a9e5c32fc32c6d84a847569b/kind#commands

wintry prism
# wintry prism One bit I found confusing was that in `Drupal().Base(ctx)` the `Container().Sync...

@rocky harbor @warped canyon @kind carbon am I confused or is this the way that the machinery works to make module authoring easier in the Go SDK by making context and error optional in some cases? Seems to only be affecting me in the "main" module that uses the two "utility" modules. It seems like I'm being required to drop context and error in my "main" module in this case (not an option to keep them).
https://docs.dagger.io/labs/project-zenith/

kind carbon
wintry prism
#

So it keeps things lazier?

#

To leave it off?

kind carbon
#

No, it's never needed if that's what you finish the function with.

wintry prism
#

hmmm

thorn moat
#

Maybe a good rule of thumb: if you don't know whether you should Sync you probably don't need to - especially when building a module to be consumed by someone else

thorn moat
# wintry prism <@949034677610643507> <@135620352201064448> <@768585883120173076> am I confused ...

What you're running into with Base() vs Base(ctx) is the fact that the client code doesn't reflect the server-side implementation's signature; it'll always be "lazy" just like the rest of the SDK. This is 100% intentional, and the same way the existing SDK codegen works. All those methods like Container.WithMountedDirectory are backed by resolvers that take a context.Context and return an error, but that's invisible through the GraphQL API

wintry prism
#

Ok, now I'll drop that and push it.

warped canyon
wintry prism
#

now to try to dagger mod sync on drupalTest and see what happens

#

err

#

dagger mod use the latest version of drupal

thorn moat
#

try setting "root": ".." and "dependencies": ["../drupal", "../mariadb"]

wintry prism
#

but I want to simulate the experience of building a "main" module from "utility" modules I don't control

thorn moat
#

ah ok ๐Ÿ‘

wintry prism
#

mod use and mod sync ok!

warped canyon
#

when you sync from your "main" module it should update your dependency as well, right? so you don't have to use the new version

wintry prism
wintry prism
#

Working in simpler form! Thanks all! ๐Ÿ™Œ

dagger call -m github.com/jpadams/daggerverse/drupalTest run
#

I was really pleasing to break up the (small) wall of code in the example into three tiny modules, I must say ๐Ÿ˜„
Just a toy example at this point, but can imagine growing the utility modules up to their final form.

wintry prism
#

One bit of confusion was during initial module creation. I wanted to have a cool name for my MariaDB module so I used
dagger mod init --name=mariaDB --sdk=go but I put it in a directory on disk, that I subsequently commited to git, named mariadb, and then the name of the module in Golang is MariaDb.
So I need to dagger mod use github.com/jpadams/daggerverse/mariadb to keep consistent with GitHub and then use MariaDb in my code:
https://github.com/jpadams/daggerverse/blob/main/mariadb/main.go#L3
The original "cool" name is known only to me...๐Ÿ˜‚

warped canyon
wintry prism
restive shore
warped canyon
restive shore
restive shore
sharp zealot
#

good catch

rocky harbor
sharp zealot
#

First attempt at using 0.9 Zenith commands, getting a cryptic new error:

% dagger version
dagger v0.9.0 (registry.dagger.io/engine) darwin/arm64

% dagger -m github.com/shykes/daggerverse/helloWorld functions
โ–ถ init
  โœ˜ connect ERROR [0.33s]
  โ”œ [0.33s] starting engine

โง— 0.36s  โœ” 1 โœ˜ 1
Error: new client: remote is not a valid dagger server (expected "github.com/dagger/dagger", got "4d7c9f1e8edf")
sharp zealot
#

I really feel the need for dagger print (or equivalent). When I call a function with the primary goal of getting output to the terminal, I find dagger call very noisy and frustrating. I struggle to find the actual output in the noise; if I pipe it to another command, it's unclear if it works reliably

#
% dagger -m github.com/shykes/daggerverse/helloWorld call message
โœ” build "dagger call" [1.86s]
โ”œ [1.72s] loading module
โ”œ [0.14s] loading objects
โœ” running "dagger call message" [0.18s]
โ”ƒ Hello, World!                                                                                                 
โ€ข Cloud URL: https://dagger.cloud/runs/2cbfe452-872b-4d58-9670-d2207c051260
โ€ข Engine: 1b8f5d0852ba (version v0.9.0)
โง— 3.35s โœ” 44 โˆ… 10
% 
#
% dagger -m github.com/shykes/daggerverse/helloWorld call message | cat -e
โœ” build "dagger call" [1.75s]                                              
โœ” build "dagger call" [1.75s]
โ”œ [1.61s] loading module
โ”œ [0.14s] loading objects
โœ” running "dagger call message" [0.31s]
โ€ข Cloud URL: https://dagger.cloud/runs/60441005-4870-471d-9822-23bc878d7931
โ€ข Engine: 1b8f5d0852ba (version v0.9.0)
โง— 3.48s โœ” 44 โˆ… 10
% 
kind carbon
#

Use --silent.

kind carbon
sharp zealot
#

Nice ๐Ÿ™‚ thanks

#

I still would love a command that still shows me some TUI goodness while it's running, but then it all disappears once it's completed

#
  • formatting options, and the ability to print as much as possible as text
#

ie. if I dagger print a container, maybe it could information about the container; etc

warped canyon
#

getting a codegen error using Optional on dagger@main ๐Ÿงต

sharp zealot
#

Bikeshedding alert... dagger mod use ... shouldn't we change that verb to something more standard like add or install?

warped canyon
#

What's the dagger verb for H2C? serve? or is it not in yet?

sharp zealot
#

up?

warped canyon
#

yup that's the one, thanks

sharp zealot
#

Is it possible to tag a field to be serialized but not exposed in the API?

#

In other words, a struct field that is public in Go (so saved in the object state) but not public in GraphQL.

#

Example of the problem:

$ dagger -m github.com/shykes/daggerverse/helloWorld greeting
Error: input:1: helloWorld.greeting Cannot return null for non-nullable field HelloWorld.greeting.
#

I would love a way to either:

  1. register a constructor function for my module (then I could initialize my fields, and wouldn't need to hide them in shame,

or

  1. hide fields I can't properly initialize (then I can wrap them in accessors)
#

Has anyone seen this one before?

Error: query module objects: returned error 502 Bad Gateway: http do: Post "http://dagger/query": rpc error: code = ResourceExhausted desc = trying to send message larger than max (16799505 vs. 16777216)
#

It's like somehow the same code in the same module became very expensive to run in the latest version

#

Here's the code of the tags function:

// Query the remote for its tags
func (r *Remote) Tags(ctx context.Context, opts RemoteTagOpts) ([]*RemoteTag, error) {
    var (
        filter *regexp.Regexp
        err    error
    )
    if opts.Filter != "" {
        filter, err = regexp.Compile(opts.Filter)
        if err != nil {
            return nil, err
        }
    }
    output, err := container().WithExec([]string{"git", "ls-remote", "--tags", r.URL}).Stdout(ctx)
    if err != nil {
        return nil, err
    }
    lines := strings.Split(output, "\n")
    tags := make([]*RemoteTag, 0, len(lines))
    for i := range lines {
        commit, name := tagSplit(lines[i])
        if filter != nil {
            if !filter.MatchString(name) {
                continue
            }
        }
        tags = append(tags, &RemoteTag{
            Name:   name,
            Commit: commit,
        })
    }
    return tags, nil
}
#

The query does return, with what looks like double-digit number of tags as result

#

It kind of looks like the module runtime is re-executed as many times as there are tags in the result?

#

That does seem to be the case... Filtering the tags so that the returned is shorter, seems to shorten the run time (and I believe the number of re-execs) in a way that feels proportional

rocky harbor
#

fixing sdk module generated code

rocky harbor
rocky harbor
# sharp zealot That does seem to be the case... Filtering the tags so that the returned is shor...

The module shouldn't be re-exec'ing when resolving "trivial" fields like name (it only execs for functions), but due to the problem fixed in that commit above, I wouldn't be surprised if we were copying so much data while running requests that it became noticeably slow proportional to the amount of tags just because metadata in the context was getting copied around.

So worth another try tomorrow (or w/ ./hack/dev if brave)

main jewel
#

Hello, quick question regarding code organization. Should I create one module per job (like lint, test, etc) or I can create only one module for my project and expose multiple methods?

kind carbon
#

Iโ€™d create one module with multiple functions but itโ€™s up to you really ๐Ÿ™‚

#

Easier to manage.

main jewel
#

That was my first guess also, and here comes the naming ๐Ÿ˜„

spiral whale
#

Hey, I was trying to test dagger main to see what is changing for gale and I'm a little bit confused about the passing configuration. Did we remove passing Opts Struct support completely?

deft rain
#

yes, pretty much - the idea is that we want to eventually have all structs that the module declares be IDable (like container, directory, etc)

spiral whale
#

This is what I'm getting when I try to sync at the moment

dagger mod sync
โœ˜ asModule(sourceSubpath: "daggerverse/gale") ERROR [1.51s]
โ€ข Engine: 04daf1dd8578 (version devel ())
โง— 2.94s โœ” 153 โˆ… 2 โœ˜ 1
Error: failed to automate vcs: failed to get vcs ignored paths: input:1: host.directory.asModule failed to install module dependencies: failed to install dependency "repo": failed to install module schema: schema validation failed: input:2029: Undefined type RepoOptsID.

      | ...
 2026 |         
 2027 |         
 2028 |         """
 2029 |         opts: RepoOptsID!
 2030 |     ): Directory!
 2031 |     """
 2032 |     
      | ...

deft rain
#

there is the potential to add opts structs back one day, but with a much more explicit way (instead of detecting if it's possible using pointers, etc)

spiral whale
#

ohh ๐Ÿ˜ข , then what about the default values?

deft rain
#

But, the problem is, there's no way in go to do proper default values - the problem gets worse when you imagine having default Container values, etc
To do default values, you need to use code - if you use an Optional, then you can do option.GetOr("defaultvalue"). The only difference is that this isn't understood at the engine level (so auto-docs generation won't pick up on it), but you can still have the default value.

spiral whale
#

I understand the reasoning and it makes sense. ๐Ÿ™ Thanks for the explanation.

deft rain
#

I'm half hoping someone can come up with a good way that makes default values make sense in go ๐Ÿ˜ฆ
But we couldn't think of something that felt natural for go programmers, and wasn't "too magical". One of the issues is we can't enforce the default values for intra-module function calls, so it does feel a bit confusing to have different behaviour inside and outside the module.

thorn moat
latent trellis
#

I'm trying to convert an existing project still using mage to plain dagger call .

Currently, most of my (Go) projects have a ci submodule (an actual module) that I'm replacing with a new one generated using dagger mod init.

When I'm trying to run one of my build targets (dagger call --mod ci lint), the workspace becomes the ci subdirectory though and I don't have access to my actual project root.

I considered moving the dagger module to the project root which may work for application type projects (though I very much dislike the querybuilder package in the project root), it may not work well for libraries (I don't want dagger dependencies in my go.mod).

There is of course a chance that I'm missing something obvious. Any ideas?

kind carbon
#

This decouples the app code from the pipeline code, so you can run that from anywhere.

latent trellis
kind carbon
#

Another option is to use "root": ".." in your dagger.json. Then the module will have the parent dir's files, but that ties the module to the repo.

latent trellis
#

Or even better, set DAGGER_MOD=ci in an env var and just call dagger call build

kind carbon
#

Yeah, than use "root".

latent trellis
# kind carbon Yeah, than use `"root"`.

One problem with that is it's gonna upload the entire directory as build context which I don't want (I have some large nix generate files in there). Is there an exclude option as well?

kind carbon
#

You can add exclude and include to dagger.json.

latent trellis
#

Nice!

latent trellis
kind carbon
#

Relative to root.

latent trellis
#

So dag.Host().Directory(".") should be the root, right?

#

Because....it's not

spiral whale
rocky harbor
#

We need to rename root I think. Ultimately I think the actual model is pretty understandable, but I feel like the naming throws people off (feel free to disagree):

  1. Your current working directory in the Module is always the same as the one containing dagger.json
  2. By default, that's all that matters and all you need to be aware of
  3. In the exceptional case where you need to load local paths that are "out-of-tree" (i.e. not a subdir of your current working dir), then you have to set what's currently called root
  4. If you set root, your current working directory doesn't change in that it's still the directory containing dagger.json; the only difference is that the whole root gets loaded and your current working directory is now a subdir of that.
    • This results in the exact same directory structure you see on your local disk (up to the root path)
#

Would it help if we changed root to be named something like loadedParentDir? Maybe that would make it more clear that it's always going to be a parent dir rather than the "root" you are executing in or something

latent trellis
#

Couple ideas: projectRoot, contextDir

#

Context is already familiar from the container build terminology

rocky harbor
deft rain
#

could we just map Directory(".") to the root? to me, that feels the most obvious behaviour.

rocky harbor
# deft rain could we just map `Directory(".")` to the `root`? to me, that feels the most obv...

I think that results in more mental gymnastics ultimately, and potentially some technical problems. When I'm writing the code for my module, it's very simple if the paths I'm writing are actually relative to the file. So if I have a file foo.txt next to my main.go, I want to access it at ./foo.txt. I don't want to think about where I set my root and then do the path arithmetic to figure out what I need to reference in my code (and then update all my code if I have to change root)

warped canyon
#

That problem predates zenith, right? With the SDKs today you'd typically reference files relative to the workdir rather than where the dagger code is

#

Not saying we shouldn't change that, though. People trip on it all the time

rocky harbor
#

Yeah, I think Zenith gives us the opportunity to fix it since we now are actually loading that code into a container and have control over this sort of aspect

#

Basically, I want the Module container to mirror what I see on the host as closely as possible. I think that means that your workdir in the module container has to be the dir containing your module code.

For example, I have an IDE plugin that adds autocomplete suggestions based on files available relative to the source code file I'm editing. That wouldn't work if we set the workdir to be root. And obviously I don't care that deeply about one dumb IDE plugin ๐Ÿ˜„ It more just feels like evidence that the assumption of workdir being where your module source code is (rather than root) is on the right track.

If no one else agrees then obviously we should change it though ๐Ÿ™‚

thorn moat
#

Agree with above - it's also very common for go test for example; tests always run from their package dir, making it easy to reference testdata etc.; making it a moving target is a pain in the arse

restive shore
#

Silly Q, I have an SDK i'm wrapping dagger Go SDK with. My plan is to slowly move sub components to a zenith module within the same repo. To access those external modules do I have to make my SDK a module as wel? I tried doing dagger mod use -m mymodule but that didnt' do anything (although it succeeded).

tldr: Can I access dagger modules from a non-module regular go module? I want to use the dag construct to call my module functions.

latent trellis
kind carbon
#

Or the abs path to it.

latent trellis
#

It works! Thanks!

kind carbon
#

direnv it ๐Ÿ™‚

latent trellis
rocky harbor
#

Silly Q, I have an SDK i'm wrapping

latent trellis
#

dagger call test

sharp zealot
#

Oh wait I just realized we removed optional arguments? ๐Ÿ˜ฆ

thorn moat
sharp zealot
#

Oooh I understand now - thought that was only for fields. Thanks

sharp zealot
#

I got a little further with 0.9.1... But still stuck ๐Ÿ˜ฆ

% dagger -m github.com/shykes/daggerverse/supergit functions repository with-remote
โœ˜ load functions ERROR [1.99s]
โ”œ [1.99s] loading module
โ”ƒ Error: failed to get loaded module ID: input:1: git.commit.tree.directory.asModule failed to cal
โ”ƒ module "supergit" to get functions: failed to get function output directory: process "/usr/local
โ”ƒ in/codegen --module . --propagate-logs=true" did not complete successfully: exit code: 1        
โœ˜ asModule(sourceSubpath: ".") ERROR [1.03s]
โœ˜ exec /usr/local/bin/codegen --module . --propagate-logs=true ERROR [0.62s]
โ”ƒ Error: generate code: template: module:56:3: executing "module" at <ModuleMainSrc>: error callin
โ”ƒ ModuleMainSrc: runtime error: index out of range [1] with length 1                              
โ”ƒ Usage:                                                                                          
โ”ƒ   codegen [flags]                                                                               
โ”ƒ                                                                                                 
โ”ƒ Flags:                                                                                          
โ”ƒ   -h, --help             help for codegen                                                       
โ”ƒ       --lang string      language to generate (default "go")                                    
โ”ƒ       --module string    module to load and codegen dependency code                             
โ”ƒ   -o, --output string    output directory (default ".")                                         
โ”ƒ       --propagate-logs   propagate logs directly to progrock.sock                               
โ”ƒ                                                                                                 
โ”ƒ Error: generate code: template: module:56:3: executing "module" at <ModuleMainSrc>: error callin
โ”ƒ ModuleMainSrc: runtime error: index out of range [1] with length 1                              
โœ˜ generating go module: supergit ERROR [0.25s]
โ”œ [0.10s] go mod tidy
โ”ƒ writing dagger.gen.go                                                                           
โ”ƒ writing go.mod                                                                                  
โ”ƒ writing go.sum                                                                                  
โ”ƒ creating directory querybuilder                                                                 
โ”ƒ writing querybuilder/marshal.go                                                                 
โ”ƒ writing querybuilder/querybuilder.go                                                            
โ”ƒ needs another pass...                                                                           
โ€ข Cloud URL: https://dagger.cloud/runs/4e245e34-2e29-4e50-8a95-c17814c7d583
โ€ข Engine: 778c2c78e68a (version v0.9.1)
โง— 3.38s โœ” 35 โˆ… 4 โœ˜ 4
#

Hard to debug because I'm not getting a filename or line

deft rain
#

Yeah the lack of filenames and stack traces is insanely annoying - I have a local thing to work around this, but go templates recover from panics without giving any useful info as to how to recover.

sharp zealot
#

It looks like we had a few regressions over the last 1-2 weeks, is that right?

deft rain
#

There's been a couple I think - part of it is that some of the paper cut fixes require more structural changes, and these affect the code in unexpected ways. And then we didn't have a super wide range of integration tests, that we've been adding as we fix those regressions to make sure it doesn't do it again.

#

Though, I think I'd have preferred to land the big opts change a bit less close to the release - I think that's just a bad timing thing from my side, sorry.

rocky harbor
# deft rain Though, I think I'd have preferred to land the big opts change a bit less close ...

Not your fault at all, that's just how the timing worked out. This is just gonna happen when we're moving quickly and iteratively. Like you said, we're expanding our set of integ tests every fix we make, but the amount of cases there are to cover is enormous; small differences here and there can be easily missed and require follow ups to fix and add coverage for.

I think the fundamental problem is that working fast+iteratively like we are is contradictory w/ being reliant on waiting for official releases to get everything out to users who are also working fast+iteratively on stuff.

The thing is, we build+publish both engine images and CLIs on every push to main. There's improvements to be made here, but let me see how hard it is for someone to use those. It might be a one-liner (much easier than ./hack/dev stuff)

rocky harbor
# sharp zealot I got a little further with 0.9.1... But still stuck ๐Ÿ˜ฆ ```console % dagger -m ...

To use the engine w/ Justin's fix in place, you can use the engine built off main like this:

export _EXPERIMENTAL_DAGGER_RUNNER_HOST=docker-image://registry.dagger.io/engine:main@sha256:80be3e5462f52fd2203265ee019c7b6f36071c71ca5c8b1d85bd872866475742
dagger -m github.com/shykes/daggerverse/supergit functions repository with-remote

Not ideal, but it's at least just a single env var. Maybe it's worth doing another patch release tomorrow; I'll ping Gerhard (just don't want to here atm since he just logged off for the night a little bit ago).

rocky harbor
# sharp zealot I got a little further with 0.9.1... But still stuck ๐Ÿ˜ฆ ```console % dagger -m ...

Either way, running that command I get an actual expected error due to the updates we made to remove the special opts type from the Go SDK. I think you'll need to just update this code to directly accept Filter as an arg rather than wrapping it in the struct: https://github.com/shykes/daggerverse/blob/main/supergit/remote.go#L49-L83

The updated docs have an example: https://docs.dagger.io/labs/project-zenith/#creating-your-first-module (search for For example, to take multiple parameters (some of which can be optional))

restive shore
#

Found out that you can't name the module "go"

~/G/g/F/P/go โฏโฏโฏ dagger mod init --name Go --sdk go                                                                                                         bugfix/prevent-stack-smashing โœฑ โ—ผ
โœ˜ asModule(sourceSubpath: ".") ERROR [0.92s]
โœ˜ .....
โœ˜ generating go module: Go ERROR [0.09s]
โ”œ [0.02s] go mod tidy
โ”ƒ writing dagger.gen.go
โ”ƒ writing go.mod
โ”ƒ writing go.sum
โ”ƒ writing main.go
โ”ƒ creating directory querybuilder
โ”ƒ writing querybuilder/marshal.go
โ”ƒ writing querybuilder/querybuilder.go
โ”ƒ panic: go: internal error: missing go root module
โ”ƒ
โ”ƒ goroutine 1 [running]:
โ”ƒ cmd/go/internal/modload.mustHaveGoRoot(...)
โ”ƒ         cmd/go/internal/modload/buildlist.go:104
โ”ƒ cmd/go/internal/modload.newRequirements(0xe0?, {0x4000218b40?, 0x543be0?, 0x40001720f0?}, 0x5aedc0?)
โ”ƒ         cmd/go/internal/modload/buildlist.go:118 +0x584
โ”ƒ cmd/go/internal/modload.updateUnprunedRoots({0x71df30?, 0xab31e0?}, 0x0?, 0x40000f20a0, {0x0, 0x0, 0x3d0f40?})
โ”ƒ         cmd/go/internal/modload/buildlist.go:1465 +0x820
โ”ƒ cmd/go/internal/modload.updateRoots({0x71df30?, 0xab31e0?}, 0x0?, 0x40000a80c0?, {0x0?, 0x2?, 0x40000a80c0?}, {0x0?, 0x0?, 0x40000a80d0?}, ...)
โ”ƒ         cmd/go/internal/modload/buildlist.go:781 +0x6c
โ”ƒ cmd/go/internal/modload.loadModFile({0x71df30, 0xab31e0}, 0x40000fe280)
โ”ƒ         cmd/go/internal/modload/init.go:939 +0x134c
โ”ƒ cmd/go/internal/modload.LoadPackages({0x71df30?, 0xab31e0}, {{0x0, 0x0}, 0x4000119ef0, 0x1, {0x0, 0x0}, 0x1, 0x1, ...}, ...)
โ”ƒ         cmd/go/internal/modload/load.go:345 +0x31c
โ”ƒ cmd/go/internal/modcmd.runTidy({0x71df30, 0xab31e0}, 0x40000ea4c8?, {0x400009e1a0?, 0x54c8e0?, 0x10edbc?})
โ”ƒ         cmd/go/internal/modcmd/tidy.go:127 +0x204
โ”ƒ main.invoke(0xa70ea0, {0x400009e1a0, 0x1, 0x1})
โ”ƒ         cmd/go/main.go:268 +0x4f0
โ”ƒ main.main()
โ”ƒ         cmd/go/main.go:186 +0x754
โ”ƒ needs another pass...
โ€ข Engine: c8919d4606c0 (version v0.9.1)
rocky harbor
restive shore
#

One more.. the generated go.mod is go 1.21.2. But I am using go work and it sets the workspace version to my local go version which is go 1.21.3. Now when i do a dagger mod use ../mymodule I get the following. This is with engine and go SDK 0.9.1

#

Only thing that worked was downgrading my go.work. I tried upgrading the module go.mod to 1.21.3 but that didn't work. Is that because the go SDK the engine is using is 1.21.2?

rocky harbor
# restive shore Only thing that worked was downgrading my go.work. I tried upgrading the module ...

Yeah we are using 1.21.2, so that seems correct. I'll update us to 1.21.3 (we should anyways + it's a one line change), but in general I'm not sure there's a ton of great options here.

We don't want to override the users version of course.

We do want to support configurable go versions (and SDK parameters in general), but that is going to require we pull Go toolchains at runtime (we can't plausibly pre-package every patch version of Go in our engine image), which obviously can become problems for users who are contending w/ stringent corporate firewalls.

rocky harbor
restive shore
#

let me try that with a dummy module

#

hmm that sort of worked? But not really. I manually set go.work to 1.21. But the dagger mod get failed with

~/G/g/F/P/dummy โฏโฏโฏ dagger mod use ../docker                                                                                                                bugfix/prevent-stack-smashing โœฑ โ—ผ
โœ˜ asModule(sourceSubpath: "dummy") ERROR [0.49s]
โœ˜ exec /usr/local/bin/codegen --module . --propagate-logs=true ERROR [0.15s]
โ”ƒ Error: load package ".": err: exit status 1: stderr: go: module .. listed in go.work file requires go >= 1.21.0, but go.work lists go 1.21; to update it:
โ”ƒ         go work use
โ”ƒ go: module . listed in go.work file requires go >= 1.21.2, but go.work lists go 1.21; to update it:
โ”ƒ         go work use
โ”ƒ go: module ../go listed in go.work file requires go >= 1.21.2, but go.work lists go 1.21; to update it:
โ”ƒ         go work use

After I did go work use

It set my go.work to

go 1.21.2

toolchain go1.21.3

use (
        .
        ./docker
        ./dummy
        ./go
)
thorn moat
# rocky harbor That's good to know, creating an issue. I'm actually not immediately sure exactl...

Haha I ran into this exact same thing yesterday. You just can't have a go.mod with module go - it's a really cryptic error, would be fun to figure out what wires that's crossing in the Go stack. cc @restive shore - this could be avoided by not naming the go.mod after the module though. I mainly did that because it looks nice, and the name doesn't really matter, so we could maybe just decide on a static one

#

You can also just change the go.mod directly to have a different name, if you want to have the module named "go"

rocky harbor
thorn moat
#

Either way you can literally just change the go.mod if you don't like it, since the codegen will pick up from an existing go.mod and use that for existing imports like the querybuilder

rocky harbor
latent trellis
#

Anyone saw this error before?

3: build "dagger call" ERROR: failed to get loaded module ID: input:1: host.directory.asModule failed to call module "ci" to get functions: failed to get input file: failed commit on ref "layer-sha256:46995db4b389b894d512d6d1114535e02adf710a54ca68837fead903aef5c022": "layer-sha256:46995db4b389b894d512d6d1114535e02adf710a54ca68837fead903aef5c022" failed size validation: 162 != 24: failed precondition

3: loading module [8.36s]
3: build "dagger call" ERROR: failed to get loaded module ID: input:1: host.directory.asModule failed to call module "ci" to get functions: failed to get input file: failed commit on ref "layer-sha256:46995db4b389b894d512d6d1114535e02adf710a54ca68837fead903aef5c022": "layer-sha256:46995db4b389b894d512d6d1114535e02adf710a54ca68837fead903aef5c022" failed size validation: 162 != 24: failed precondition

Error: failed to get loaded module ID: input:1: host.directory.asModule failed to call module "ci" to get functions: failed to get input file: failed commit on ref "layer-sha256:46995db4b389b894d512d6d1114535e02adf710a54ca68837fead903aef5c022": "layer-sha256:46995db4b389b894d512d6d1114535e02adf710a54ca68837fead903aef5c022" failed size validation: 162 != 24: failed precondition
#

GHA

rocky harbor
deft rain
latent trellis
#

I have DAGGER_CLOUD_TOKEN set, I have a few cache mounts if that's what you mean. I did not set. _EXPERIMENTAL_DAGGER_CACHE_CONFIG

Seems to be a one off (or rather happens inconsistently), but basically immediately after I merged my dagger module rewrite, it started happening.

Here is the workflow run for reference: https://github.com/openmeterio/openmeter/actions/runs/6659370631/job/18098290440?pr=362

GitHub

Usage Metering for AI, DevOps, and Billing. Built for engineers to collect and aggregate millions of events in real-time. - [bot] Re-generate Node.js client ยท openmeterio/openmeter@59c57de

#

Another weird thing I see on Dagger cloud is that basically all builds timeout. I do have the docker stop thing in the GHA workflows though.

#

From what I can tell, it's always this step.

ember walrus
#

@latent trellis which engine of the version are you running? Are you using services in your pipeline?

rocky harbor
#

[bot] Re-generate Node.js client ยท openm...

wintry prism
#

This happening for anyone else who is updating a module's dependencies?

drupalTest โžค cat dagger.json                                                                                                                                      git:main
{
  "name": "drupalTest",
  "sdk": "go",
  "dependencies": [
    "github.com/jpadams/daggerverse/drupal@687eda1df9ec2e72187365d6142adfec4e8b4485",
    "github.com/jpadams/daggerverse/mariadb@552d439f15073b62054c46f5e072be6d18b74c90"
  ]
}
drupalTest โžค dagger mod use github.com/jpadams/daggerverse/drupal                                                                                                 git:main
โœ˜ stdout ERROR [0.58s]
โœ˜ git://github.com/jpadams/daggerverse#687eda1df9ec2e72187365d6142adfec4e8b4485 ERROR [0.57s]
โ”ƒ fatal: Not a valid object name 687eda1df9ec2e72187365d6142adfec4e8b4485^{commit}
#

Turns out that after a brutal rebase on my part that wiped out the SHAs I was using, now drupal@687eda1df9ec2e72187365d6142adfec4e8b4485 doesn't exist any more.

#

My intent is to update this to the current ref via dagger mod use github.com/jpadams/daggerverse/drupal or dagger mod use github.com/jpadams/daggerverse/drupal@e5470174bfd86b9858dd5fd3db381835b579a5b4

#

I can re-create the module of course as one option.

#

I move my go code out. Delete all the mod contents. dagger mod init, dagger mod use my deps, copy back my go code, dagger mod sync. That works.

#

But it seems I should be about to force an update even if the old module dep doesn't resolve. If the NEW module ref doesn't resolve, it should prob stop me or warn me ๐Ÿ™‚

rocky harbor
# wintry prism But it seems I should be about to force an update even if the old module dep doe...

Yeah it shouldn't fail like this, making an issue. There's definitely some corner cases here... like in theory it's possible to have completely different modules at different commits in a single git repo + subpath. That would imply calling dagger mod use github.com/jpadams/daggerverse/drupal could actually be expected to just append the newest commit to the list of dependencies rather than update the existing entry in the list of deps.

But that's probably such an obscure thing to want to do that maybe we should just ignore it and have the behavior be to replace the existing github.com/jpadams/daggerverse/drupal dep with the latest version.

sharp zealot
# rocky harbor To use the engine w/ Justin's fix in place, you can use the engine built off mai...

Following up...

 % export _EXPERIMENTAL_DAGGER_RUNNER_HOST=docker-image://registry.dagger.io/engine:main@sha256:80be3e5462f52fd2203265ee019c7b6f36071c71ca5c8b1d85bd872866475742
% dagger -m github.com/shykes/daggerverse/supergit functions
โœ˜ load functions ERROR [18.62s]
โ”œ [18.62s] loading module
โ”ƒ Error: failed to get loaded module ID: input:1: git.commit.tree.directory.asModule.serve failed 
โ”ƒ  install module schema: schema validation failed: input:2270: Undefined type SupergitRemoteTagOp
โ”ƒ ID.                                                                                             
โ”ƒ                                                                                                 
โ”ƒ       | ...                                                                                     
โ”ƒ  2267 |                                                                                         
โ”ƒ  2268 |                                                                                         
โ”ƒ  2269 |                 """                                                                     
โ”ƒ  2270 |                 opts: SupergitRemoteTagOptsID!                                          
โ”ƒ  2271 |         ): [SupergitRemoteTag!]!                                                        
โ”ƒ  2272 | }                                                                                       
โ”ƒ  2273 | """                                                                                     
โ”ƒ       | ...                                                                                     
โœ˜ checkVersionCompatibility(version: "0.9.1") ERROR [0.00s]
โœ˜ serve ERROR [0.00s]
โ€ข Cloud URL: https://dagger.cloud/runs/d6d62873-7cb3-40ee-b4a9-14fff58d7e21
โ€ข Engine: 656c662afeb1 (version main)
โง— 1m15.6s โœ” 166 โœ˜ 3
%
sharp zealot
rocky harbor
#

That one is an intentional backwards incompatible change

rocky harbor
sharp zealot
#

Is the checkVersionCompatibility actually an error? Or just a warning maybe?

#

But thanks, I suspected it was related to optional args, I'll switch focus to fixing it ๐Ÿ™‚

#

(It looks like we have error message / debugging experience polish work in our future)

rocky harbor
sharp zealot
#

Unfortunately I'm still getting the compat check error even after fixing the code

#
 % export _EXPERIMENTAL_DAGGER_RUNNER_HOST=docker-image://registry.dagger.io/engine:main@sha256:80be3e5462f52fd2203265ee019c7b6f36071c71ca5c8b1d85bd872866475742
% dagger mod sync
โœ˜ asModule(sourceSubpath: ".") ERROR [21.06s]
โœ˜ exec /usr/local/bin/codegen --module . --propagate-logs=true ERROR [7.27s]
โ”ƒ failed to check version compatibility: input:1: checkVersionCompatibility failed to parse engine version as semver: No Major.Minor.P
โ”ƒ ch elements found                                                                                                                   
โ”ƒ                                                                                                                                     
โ”ƒ Error: generate code: template: module:56:3: executing "module" at <ModuleMainSrc>: error calling ModuleMainSrc: failed to convert m
โ”ƒ hod Tags to function def: failed to convert param type: invalid type: invalid type                                                  
โ”ƒ Usage:                                                                                                                              
โ”ƒ   codegen [flags]                                                                                                                   
โ”ƒ                                                                                                                                     
โ”ƒ Flags:                                                                                                                              
โ”ƒ   -h, --help             help for codegen                                                                                           
โ”ƒ       --lang string      language to generate (default "go")                                                                        
โ”ƒ       --module string    module to load and codegen dependency code                                                                 
โ”ƒ   -o, --output string    output directory (default ".")                                                                             
โ”ƒ       --propagate-logs   propagate logs directly to progrock.sock                                                                   
โ”ƒ                                                                                                                                     
โ”ƒ Error: generate code: template: module:56:3: executing "module" at <ModuleMainSrc>: error calling ModuleMainSrc: failed to convert m
โ”ƒ hod Tags to function def: failed to convert param type: invalid type: invalid type                                                  
โœ˜ checkVersionCompatibility(version: "0.9.1") ERROR [0.00s]
โœ˜ generating go module: supergit ERROR [5.38s]
โ€ข Cloud URL: https://dagger.cloud/runs/49ffd002-50f8-4b44-b499-453e75e677dc
โ€ข Engine: d88eaa6d1c7b (version main)
โง— 28.96s โœ” 18 โœ˜ 4
Error: failed to automate vcs: failed to get vcs ignored paths: input:1: host.directory.asModule failed to call module "supergit" to get functions: failed to get function output directory: process "/usr/local/bin/codegen --module . --propagate-logs=true" did not complete successfully: exit code: 1
rocky harbor
#

Also, I'm going to copy paste your code into our integ test suite since it seems to be catching quite a bit ๐Ÿ˜„

deft rain
#

There's something weird going on with how we do go package parsing I think

sharp zealot
#

ok I'll remove

#

Ah, not I get real go errors ๐Ÿ™‚

#

with real line numbers etc

#

Question! How do I check for an unset Optional[string]? Just empty string?

deft rain
#

If you call Optional.Get then it returns the string and a bool that's true if it was set and false if it wasn't - there's also a helper .GetOr that returns the provided default if it wasn't set.

#

These need doc comments actually, I'll do that ASAP tomorrow

sharp zealot
#

Oh!

#

OK, thanks

#

How do I provide the default?

deft rain
#

Optional.GetOr(default) should do it

sharp zealot
#

dagger functions could use a little polish... Is anyone already working on that? Otherwise I might make it my stretch goal contribution

rocky harbor
thorn moat
#

Out of curiosity: has anyone had any use cases for an interactive module? Specifically prompt-style request-responses; cases where dagger shell doesn't quite cut it. I'm planning to implement support for prompts in Progrock so that we can do basic interactive things on the CLI, and supporting it at the protocol level is interesting to think about, but it might be a terrible idea.

sharp zealot
#

Lots of workflows require eg. a manual approval step, which may take days to secure. Not having a primitive for that leaves some Dagger pipelines doomed to being forever sliced up within some other system that does

ember walrus
#

Agree with you

sharp zealot
#

Are we sure the .gitignore works? I feel like my changes to generated files are not being ignored, and are in fact being committed and pushed. Or is that the idea?

#

Is it possible to pass an array of strings as an argument?

#

do I json-encode it?

wintry prism
warped canyon
#

Can anyone think of a more clever way to expose 2 services to the host with dagger up other than creating a proxy module that forwards both services on different ports?

wintry prism
#

here's an example I haven't tried

rocky harbor
#

So I was adding what I thought would be a very simple integ test where we init+call a module with a dependency, change the dependency, and then call again to verify we get the new output from the updated dep.

Turns out this doesn't work in the current module integ tests because of the way ExperimentalPrivilegedNesting works. That flag gives the exec dagger API access back to the engine, but it specifically also does it back to the same session as the original client.

This means that even when our integ tests do dagger query/call/mod/etc. calls across execs, it's all back to the same session. This breaks in the test case I'm adding (and all the more complicated ones we need to add) because you are trying to re-load modules back into the same session, which expectedly doesn't work.

Two relatively quick options to fix:

  1. We can run the dev engine as a service inside the dev engine and use service bindings to point to it rather than using the ExperimentalPrivilegedNesting flag. I tried and while it works it's stupendously ugly and makes retaining cache across runs while not creating conflicts between parallel tests very difficult.
  2. We can change the behavior of ExperimentalPrivilegedNesting to not connect back to the same session but instead create its own new one.
    • We still internally need the ability to have execs connect back to the same session in order for modules to work, but that can be a completely internal flag.

I'm currently going with 2 since it's fastest and best long term IMO, but it is technically a breaking change. It's such an obscure thing that I would be extremely surprised if any user even notices, but want to double check now if anyone has any objections or notices any flaws. @thorn moat @sharp zealot @deft rain (also IIRC the playground uses this flag but shouldn't be impacted by the behavior change, right @dense canyon?)

sharp zealot
#

otherwise you canโ€™t really โ€œvirtualizeโ€ zenith

thorn moat
#

I might be mostly thinking of the module use case, which it sounds like we'd keep, so ๐Ÿ‘

rocky harbor
rocky harbor
#

Pushed as a commit here since it's needed in order to write tests for that PR: https://github.com/dagger/dagger/pull/5964
(also finished updating the description to help reviewing, gonna squash remaining TODOs now)

restive shore
sharp zealot
rocky harbor
#

PrivilegedNesting is specifically needed when the exec wants access back to the dagger api serves by the engine its running in

sharp zealot
#

I think the daggerverse crawler is hitting the same error I did earlier... ๐Ÿ˜ญ

thorn moat
#

(assuming it's in the engine / SDK runtime / codegen)

sharp zealot
#

That would be amazing thank you. Yes it is fixed in main.

thorn moat
#

@sharp zealot ok, now it's just not happy that there's no LICENSE ๐Ÿ˜›

#

you can just put one in the root of your repo, it'll find it for all of them

sharp zealot
#

Ha ha thanks ๐Ÿ™‚

#

@thorn moat I'm also stuck on another module which depends on supergit. It keeps erroring on a version of supergit that it doesn't match the latest (I think) but I can't fix it..

thorn moat
#

which module is that?

sharp zealot
#
 % dagger mod sync
โœ˜ asModule(sourceSubpath: ".") ERROR [0.84s]
โœ˜ exec go build -o /runtime . ERROR [0.40s]
โ”ƒ # dagger                                                                                           
โ”ƒ ./engine.go:59:19: dag.Supergit undefined (type *Client has no field or method Supergit)           
โ”ƒ ./engine.go:59:63: undefined: RemoteTagsOpts                                                       
โ”ƒ ./worker.go:223:34: cannot use registrySvc (variable of type *Container) as *Service value in argum
โ”ƒ t to worker.WithServiceBinding                                                                     
โ”ƒ ./worker.go:224:41: cannot use privateRegistry() (value of type *Container) as *Service value in ar
โ”ƒ ment to worker.WithServiceBinding("registry", registrySvc).WithServiceBinding                      
โ”ƒ ./worker.go:231:26: worker.Endpoint undefined (type *Container has no field or method Endpoint)    
โ”ƒ ./worker.go:231:40: undefined: ContainerEndpointOpts                                               
โ”ƒ ./worker.go:266:39: cannot use worker (variable of type *Container) as *Service value in argument t
โ”ƒ w.GoBase.WithExec([]string{โ€ฆ}).WithMountedDirectory("/app", dag.Host().Directory(".")).WithMountedD
โ”ƒ ectory(utilDirPath, testEngineUtils).WithEnvVariable("_DAGGER_TESTS_ENGINE_TAR", filepath.Join(util
โ”ƒ rPath, "engine.tar")).WithWorkdir("/app").WithServiceBinding                                       
โ”ƒ ./worker.go:267:34: cannot use registrySvc (variable of type *Container) as *Service value in argum
โ”ƒ t to w.GoBase.WithExec([]string{โ€ฆ}).WithMountedDirectory("/app", dag.Host().Directory(".")).WithMou
โ”ƒ edDirectory(utilDirPath, testEngineUtils).WithEnvVariable("_DAGGER_TESTS_ENGINE_TAR", filepath.Join
โ”ƒ tilDirPath, "engine.tar")).WithWorkdir("/app").WithServiceBinding("dagger-engine", worker).WithServ
โ”ƒ eBinding                                                                                           
โ€ข Cloud URL: https://dagger.cloud/runs/94ebf59c-0a98-4e9d-af17-0903aa689849
โ€ข Engine: 2ff796165b11 (version main)
โง— 1.22s โœ” 13 โˆ… 4 โœ˜ 2
Error: failed to automate vcs: failed to get vcs ignored paths: input:1: host.directory.asModule failed to call module "dagger" to get functions: failed to get function output directory: process "go build -o /runtime ." did not complete successfully: exit code: 1
thorn moat
#

some of it is also the removal of Opts struct support

sharp zealot
#

sorry wrong command

#

that was after manually removing the supergit dependency

#
 % dagger mod use github.com/shykes/daggerverse/supergit
โœ˜ asModule(sourceSubpath: ".") ERROR [3.04s]
โœ˜ checkVersionCompatibility(version: "0.9.1") ERROR [0.00s]
โœ˜ exec go build -o /runtime . ERROR [0.22s]
โ”ƒ # dagger                                                                                           
โ”ƒ ./dagger.gen.go:4277:12: dag.LoadSupergitCommitFromID undefined (type *Client has no field or metho
โ”ƒ LoadSupergitCommitFromID)                                                                          
โ”ƒ ./dagger.gen.go:4277:37: undefined: SupergitCommitID                                               
โ”ƒ ./dagger.gen.go:4517:12: dag.LoadSupergitRemoteTagFromID undefined (type *Client has no field or me
โ”ƒ od LoadSupergitRemoteTagFromID)                                                                    
โ”ƒ ./dagger.gen.go:4517:40: undefined: SupergitRemoteTagID                                            
โ”ƒ ./engine.go:59:63: undefined: RemoteTagsOpts                                                       
โ”ƒ ./worker.go:223:34: cannot use registrySvc (variable of type *Container) as *Service value in argum
โ”ƒ t to worker.WithServiceBinding                                                                     
โ”ƒ ./worker.go:224:41: cannot use privateRegistry() (value of type *Container) as *Service value in ar
โ”ƒ ment to worker.WithServiceBinding("registry", registrySvc).WithServiceBinding                      
โ”ƒ ./worker.go:231:26: worker.Endpoint undefined (type *Container has no field or method Endpoint)    
โ”ƒ ./worker.go:231:40: undefined: ContainerEndpointOpts                                               
โ”ƒ ./worker.go:266:39: cannot use worker (variable of type *Container) as *Service value in argument t
โ”ƒ w.GoBase.WithExec([]string{โ€ฆ}).WithMountedDirectory("/app", dag.Host().Directory(".")).WithMountedD
โ”ƒ ectory(utilDirPath, testEngineUtils).WithEnvVariable("_DAGGER_TESTS_ENGINE_TAR", filepath.Join(util
โ”ƒ rPath, "engine.tar")).WithWorkdir("/app").WithServiceBinding                                       
โ”ƒ ./worker.go:266:39: too many errors                                                                
โ€ข Cloud URL: https://dagger.cloud/runs/c83d2d5d-fbd0-4339-9b90-c9235ee82c0f
โ€ข Engine: 2ff796165b11 (version main)
โง— 1m19.1s โœ” 158 โˆ… 3 โœ˜ 3
Error: failed to automate vcs: failed to get vcs ignored paths: input:1: host.directory.asModule failed to call module "dagger" to get functions: failed to get function output directory: process "go build -o /runtime ." did not complete successfully: exit code: 1
#

mmm maybe it is the same

#

sorry I've been juggling a bunch of different error states, might be confusing myself

#

let me fix the legit stuff & see what's left

thorn moat
#

all good, there's some interesting other errors there too, could be something notsureif

sharp zealot
#

how do I pass a value to an Optional[...] argument when calling the function directly?

thorn moat
#

I think there's a constructor for it in dagger.gen.go

#

yep - Opt(foo)

sharp zealot
#

@thorn moat something's weird, it's like it's still using an old version of supergit ?

#
./engine.go:59:63: cannot use Opt("^v[0-9\\.]+") (value of type Optional[string]) as SupergitRemoteTagsOpts value in argument to dag.
โ”ƒ pergit().Remote(engineUpstream).Tags  
#

(side note some of that output is getting truncated in a weird way)

#

Just realized what time it is for you... Sorry for pinging!

thorn moat
#

dumb question: is it bumped? e.g. dagger mod use github.com/shykes/daggerverse/supergit@e46c35c682d1a94f2ff867aa6439e9ac298a8f25

thorn moat
sharp zealot
#
 % grep -r SupergitRemoteTagsOpts * | wc -l
       0
sharp zealot
#

So I'm assuming it's getting the last commit from github?

thorn moat
#

should be yeah (just saw the first line of the output)

#

maybe run with --focus=false to see which commit it's fetching?

#

(i will likely randomly disappear soon though, good luck if so)

sharp zealot
#
โ—€โ”€โ”€โ”ค CACHED exec git ls-remote --symref https://github.com/shykes/daggerverse HEAD
โ–ˆ   โ”‚ [0.45s] git://github.com/shykes/daggerverse#main
โ”ƒ   โ”‚ e46c35c682d1a94f2ff867aa6439e9ac298a8f25        refs/heads/main                                                                                             
โ–ˆโ—€โ”€โ”€โ•ฏ CACHED exec git rev-parse HEAD

oooooh

#

It's not a core llb Git, it's an exec of git... and it's cached ๐Ÿ˜ซ

#

looks like the right commit though

#

Giving up for tonight. Thank you for you help ๐Ÿ™ and have a safe flight

rocky harbor
thorn moat
#

might not even be needed now that you can get the commit from a ref

#

this code was originally in Daggerverse where it made more sense to YOLO, should definitely be fixed

rocky harbor
#

Yeah that's what I was wondering at first, but i saw the code was for getting the default branch, which I thought was different, unless there's some way of using ref->commit to determine default branch

thorn moat
#

oh, yeah, we'll need that too. at least the ref => commit part is done (those are the two places alpine/git is used)

#

i've wanted a 'default branch' API before, it's awkward having to specify one all the time

#

I wonder if we should just start using the git CLI directly in the Git APIs at this point. We already need it in there for when Buildkit shells out to it. ๐Ÿ˜›

rocky harbor
#

I think buildkit has a TODO to migrate to a go implementation of a git porcelain iirc, but just shelling out sounds more robust honestly

thorn moat
#

yeah I agree, would rather be looking at git man pages than a bespoke API tbh (go-git is nice, its API surface area is huge)

rocky harbor
wintry prism
#

Anyone seen this error for dagger mod sync? Error: module sync is not supported for git modules

trivyScan โžค ls -al                                                                               git:main*
total 264
drwxr-xr-x  11 jeremyadams  staff    352 Oct 27 06:57 .
drwxr-xr-x  13 jeremyadams  staff    416 Oct 26 16:56 ..
-rw-r--r--   1 jeremyadams  staff     39 Oct 26 15:04 .gitattributes
-rw-r--r--   1 jeremyadams  staff  10758 Oct 26 15:04 LICENSE
-rw-r--r--   1 jeremyadams  staff     93 Oct 26 15:04 README.md
-rw-r--r--   1 jeremyadams  staff  95241 Oct 26 15:04 dagger.gen.go
-rw-r--r--   1 jeremyadams  staff     51 Oct 26 15:04 dagger.json
-rw-r--r--   1 jeremyadams  staff    192 Oct 26 15:04 go.mod
-rw-r--r--   1 jeremyadams  staff   2788 Oct 26 15:04 go.sum
-rw-r--r--   1 jeremyadams  staff    753 Oct 27 06:57 main.go
drwxr-xr-x   4 jeremyadams  staff    128 Oct 26 15:04 querybuilder
trivyScan โžค cat .gitattributes                                                                   git:main*
/dagger.gen.go linguist-generated=true
trivyScan โžค dagger mod sync                                                                      git:main*
โ€ข Engine: 64bf1cf27353 (version v0.9.1)
โง— 2.89s โœ” 16 โˆ… 1
Error: module sync is not supported for git modules
deft rain
#

do you have DAGGER_MODULE set by any chance

wintry prism
#

That was it, thanks @deft rain !

#

(yeah the majority of the error message or bits to build it, didn't seem to be in our code base)

deft rain
#

which is why you probably couldn't find it ๐Ÿ˜ข

restive shore
#

Tell me if this is the wrong place to ask questions like this.

A module's private fields will not be persisted.

As I understand (and seeing in practice) I can't use the WithFunction* pattern in go to set private fields of a module. Is there a different/preferred pattern for fields that I don't want to expose via a module? It's not clear in current docs.

#

One more question. Is this still true? (from the doc)

When referencing another module as a local dependency, the dependent module must be stored in a sub-directory of the parent module.

I was able to refer to a local dependency from a parent folder by setting root: .. in dagger.json. Maybe I'm understanding it wrong or more likely doing something wrong.

deft rain
restive shore
#

Thank you! I am not sure I fully understand where that conversation landed in the end. It's probably because my lack of understanding of certain core decisions. I'll try to summarize what I understand,

All fields of the module need to be public to be used with the API. There is no way to hide certain fields and initialize them with initializer functions. Use Optional for defaults.

deft rain
#

yup, today all fields must be public - you can't hide them.
you also can't initialize them to defaults, there are two things here:

  • we could maybe have a "constructor" thing for this, which we don't have
  • you just can't do defaults elegantly in go, so it's difficult to do neatly
restive shore
warped canyon
#

What's the latest on python modules? Do we have any docs on how it differs from Go today?

rocky harbor
kind carbon
#

Yeah, sorry about that, I'm taking longer than expected ๐Ÿ™‚

warped canyon
#

I guess I'll start with mod init --sdk=python and see what I trip over ๐Ÿ™‚

rocky harbor
warped canyon
warped canyon
#

oh I guess I need to think about how to do this one without objects lol

kind carbon
#

You'll be able to use classes if you need to. Many users won't. So the top level functions are a convenience for a class with the name of the module and no fields.

#

You can also have both. Top level functions for the main module's "object", but also classes for additional objects.

warped canyon
#

Nice, yeah just thinking about the modules I've worked on so far, probably 70% wouldn't need them and 30% would

kind carbon
#

There's already support for default values and descriptions everywhere.... just not documented.

#

You can also chose a different name than the function/field/class:

@function(name="from")
def from_(address: Annotated[str, "The address to pull from"]) -> dagger.Container:
    """Pull a container image."""
    ...

This way you're not limited by reserved/soft keywords.

restive shore
#

When I run dagger call module, shouldn't it print the Pipeline() labels by default? I am not seeing them. I can do --focus=false but that's messy.

wintry prism
restive shore
#

oh man! I am in the office today so don't have access to my PC, let me try to join.

sharp zealot
restive shore
#

I may have hit a blocker with modules. I am able to do dagger call module from my local machine but when I try it in CI, it times out when it tries to pull the go modules because of proxy. How do I make my corp proxies available to the engine spawned off of dagger call? It fails when it tries to do the codegen for the modules initially.

#

The env that dagger call is executing in has the proxies set.

#

I don't have the same issue when I do run non-zenith dagger code with go run main.go

rocky harbor
#

I may have hit a blocker with modules

latent trellis
#

Would be nice to have a "Go to source" button on the daggerverse UI. Since most modules are actually subpaths of a repository, just copying and pasting the URL doesn't work. (Also, I would still have to go to the specific commit).

sharp zealot
latent trellis
warped canyon
latent trellis
warped canyon
latent trellis
sharp zealot
#

Is this failing for anyone?

dagger -m github.com/shykes/daggerverse/dagger functions

latent trellis
#

I wonder if it makes sense to write defensive APIs. For example: WithSource can only be called after a container is set (this would require a second struct that is returned by WithContainer).

The alternative is a flat API (WithContainer and WithSource on the same struct) and storing intermediary inputs and compiling the final container when Run/Lint/Test whatever is called.

The first one is more work, but makes it less likely and extra WithContainer somewhere messes something up. The second one is probably easier to write.

#

This:

type Spectral struct{
}

func (m *Spectral) WithVersion(version string) *SpectralContainer {
    return &SpectralContainer{dag.Container().From(fmt.Sprintf("%s:%s", defaultImageRepository, version))}
}

func (m *Spectral) WithImageRef(ref string) *SpectralContainer {
    return &SpectralContainer{dag.Container().From(ref)}
}

func (m *Spectral) WithContainer(ctr *Container) *SpectralContainer {
    return &SpectralContainer{ctr}
}

func (m *Spectral) WithSource(src *Directory) *SpectralContainerWithSource {
    return &SpectralContainerWithSource{
        &SpectralContainer{
            dag.Container().From(defaultImageRepository).
                WithWorkdir("/src").
                WithMountedDirectory("/src", src),
        },
    }
}
#

Versus this

type Spectral struct {
    Container *Container
    Source    *Directory
}

func (m *Spectral) WithVersion(version string) *Spectral {
    m.Container = dag.Container().From(fmt.Sprintf("%s:%s", defaultImageRepository, version))

    return m
}

func (m *Spectral) WithImageRef(ref string) *Spectral {
    m.Container = dag.Container().From(ref)

    return m
}

func (m *Spectral) WithContainer(ctr *Container) *Spectral {
    m.Container = ctr

    return m
}

func (m *Spectral) WithSource(src *Directory) *Spectral {
    m.Source = src

    return m
}
#

The more defensive API can also protect against accidentally calling a function without the necessary state (eg. source).

rocky harbor
#

Also in terms of consumers, I think it would pretty much be the same end DX

latent trellis
#

The happy path would certainly be the same.

The error path would be slightly easier on both sides: you would get an early warning that you are trying to do something invalid. On the module development side, you don't have to check if a source has been set for example. The type system takes care of that by eliminating invalid states.

Thanks for the feedback!

I asked, because I haven't seen this style in modules yet. Most modules implement a flat API.

rocky harbor
#

I asked, because I haven't seen this style in modules yet. Most modules implement a flat API.
Totally, we're still all figuring it out, so these sorts of questions+discussions are super helpful. Appreciate it

latent trellis
#

Is there an example for running multiple containers?

Here is what I did:

func (m *Lint) All(ctx context.Context) error {
    var group errgroup.Group

    group.Go(func() error {
        _, err := m.Go().Sync(ctx)
        if err != nil {
            return err
        }

        return nil
    })

    group.Go(func() error {
        _, err := m.Openapi().Sync(ctx)
        if err != nil {
            return err
        }

        return nil
    })

    return group.Wait()
}

Ideally, I'd like to have the same behavior as returning a container (fail if errors, print stdout). Sure, I can do it manually...but I just don't want to. ๐Ÿ˜„

upbeat herald
#

Idk what happened to Zenith but all my ci in my daggerverse is broken, and I only have this as output:

Error: make request: input:3: ci.lint failed to call function "Ci.lint": failed to get function output directory: process "/runtime" did not complete successfully: exit code: 2
latent trellis
upbeat herald
#

Ohhh okay

#

That's strange because the goSDK is generated so I shouldn't have to update it... I also use dagger binary from main

latent trellis
#

Is it possible to define a "default" action for a command?

For example:

  • dagger call lint go -> run golangci-lint
  • dagger call lint -> run all linters
#

(For the moment I have an "all" action that runs all actions.

warped canyon
# rocky harbor Based on the error message you most likely hit the bug that was fixed here 2 day...

I think I'm hitting this on main right now.

Getting a mix of:
ERROR: query module objects: returned error 502 Bad Gateway: http do: Post "http://dagger/query": net/http: HTTP/1.x transport connection broken: EOF
and
Error: query module objects: returned error 502 Bad Gateway: http do: Post "http://dagger/query": rpc error: code = ResourceExhausted desc = grpc: received message larger than max (7264280 vs. 4194304)
https://dagger.cloud/runs/c709d9da-d809-4475-9d80-845c0c4ccb5e

Looking at my log output, the ID for [0.53s] [DEBUG] dagger.mod._module: output => '"core.Module:eyJzb3... is crazy long. Like 5 screens long

latent trellis
#

I noticed types in a module are prefixed with the module name which is weird when I already add the prefix.

For example, I have a KafkaContainer type in there that's called KafkaKafkaContainer in the module docs.

I can't call it just Container, because there is already a Container type in there. ๐Ÿ˜„

Any ideas?

#

Also: I'm testing these Dagger modules with Dagger. ๐Ÿ˜„

while(usingDagger) {
    mind.blown = true
}
upbeat herald
#
type Kafka struct {}

func (k *Kafka) Container() {...} 
latent trellis
upbeat herald
#

I see, maybe call it Instance then?

latent trellis
#

I was thinking Context but it's such an overloaded term (like Manager ๐Ÿ˜› )

#

Maybe Node when thinking about the graph context.

upbeat herald
#

Node make sense

sharp zealot
#

FYI @wintry prism I am getting a LICENSE file from dagger mod init but not NOTICE file

#

@warped canyon are you still getting module errors on main?

#

I'm getting this on a brand new module:

 % dagger mod sync
โœ˜ generatedCode ERROR [0.49s]
โœ˜ exec /usr/local/bin/codegen --module . --propagate-logs=true --introspection-json-path /schema.json ERROR [0.44s]
โ”ƒ Error: generate code: template: module:56:3: executing "module" at <ModuleMainSrc>: error calling ModuleM
โ”ƒ nSrc: cannot define methods on objects from outside this module                                          
โ”ƒ Usage:                                                                                                   
โ”ƒ   codegen [flags]                                                                                        
โ”ƒ                                                                                                          
โ”ƒ Flags:                                                                                                   
โ”ƒ   -h, --help                             help for codegen                                                
โ”ƒ       --introspection-json-path string   optional path to file containing pre-computed graphql introspect
โ”ƒ n JSON                                                                                                   
โ”ƒ       --lang string                      language to generate (default "go")                             
โ”ƒ       --module string                    module to load and codegen dependency code                      
โ”ƒ   -o, --output string                    output directory (default ".")                                  
โ”ƒ       --propagate-logs                   propagate logs directly to progrock.sock                        
โ”ƒ                                                                                                          
โ”ƒ Error: generate code: template: module:56:3: executing "module" at <ModuleMainSrc>: error calling ModuleM
โ”ƒ nSrc: cannot define methods on objects from outside this module                                          
โœ˜ generating go module: ttlsh ERROR [0.19s]
โ”œ [0.04s] go mod tidy
โ”ƒ writing dagger.gen.go                                                                                    
โ”ƒ writing go.mod                                                                                           
โ”ƒ writing go.sum                                                                                           
โ”ƒ needs another pass...                                                                                    
โ€ข Cloud URL: https://dagger.cloud/runs/2c31f105-2075-490b-a2af-abd6a47f1356
โ€ข Engine: d0277984c27c (version devel ())
โง— 1.38s โœ” 18 โˆ… 3 โœ˜ 3
Error: failed to automate vcs: failed to get vcs ignored paths: input:1: host.directory.asModule.generatedCode failed to get modified source directory for go module sdk codegen: process "/usr/local/bin/codegen --module . --propagate-logs=true --introspection-json-path /schema.json" did not complete successfully: exit code: 1

% go vet
go: errors parsing go.mod:
/Users/shykes/dev/shykes/daggerverse/ttlsh/go.mod:3: invalid go version '1.21.3': must match format 1.23
wintry prism
sharp zealot
wintry prism
#

I wonder if we could do something to smooth that out for folks ๐Ÿค” Otherwise we should document a minimum required go version

warped canyon
sharp zealot
#

I'm still getting an error on dagger mod sync (first part of that snippet) which I'm guessing is unrelated to go version on the host (I'll still update of course).

wintry prism
#

I'll clone your repo and try

sharp zealot
#

On the go version front: if everyone is going to run into this issue, should we hold off on upgrading to the latest Go?

warped canyon
sharp zealot
#

To be clear I'm getting this even when initializing a brand new module

wintry prism
#

cannot define methods on objects from outside this module

sharp zealot
#

Oh you're right, there's actually a real error message in there

warped canyon
wintry prism
sharp zealot
#

It's probably because I'm overloading a core type in there

#

This part confused the hell out of me:

Usage:                                                                                                   
โ”ƒ   codegen [flags]                                                                                        
โ”ƒ                                                                                                          
โ”ƒ Flags:                                                                                                   
โ”ƒ   -h, --help                             help for codegen                                                
โ”ƒ       --introspection-json-path string   optional path to file containing pre-computed graphql introspect
โ”ƒ n JSON                                                                                                   
โ”ƒ       --lang string                      language to generate (default "go")                             
โ”ƒ       --module string                    module to load and codegen dependency code                      
โ”ƒ   -o, --output string                    output directory (default ".")                                  
โ”ƒ       --propagate-logs                   propagate logs directly to progrock.sock                        
โ”ƒ                                                                                          
#

I assumed it was another regression

#

We need to work on those error messages

warped canyon
#

yeah that's been leaking through with any codegen errors for some reason

sharp zealot
#

(I know I'm stating the obvious)

wintry prism
wintry prism
kind carbon
#

GraphQL casing

sharp zealot
#

@warped canyon where can I find your proxy module? I'm going to try using it for my tailscale module

warped canyon
#

that's it ๐Ÿ‘†

wintry prism
warped canyon
sharp zealot
#

Nice

#

How about HTTP routing? ๐Ÿ˜‡

warped canyon
#

should be totally doable

sharp zealot
#

I'm trying to fit GraphiQL into a single port (otherwise you have to leak host networking information - specifically hostname - into the module)

warped canyon
sharp zealot
#

Would love to get consensus on this so we can ship something in the next patch release ๐Ÿ‘† It doesn't have to remove use right away, can co-exist for now

#

If I wanted to add support for passing a new type by the command-line (like secret, directory, etc) where in the source code should I go to do that (I'd like to try adding service)

#

Also, how do I pass a secret as argument from the command-line when calling a function? Zenith docs don't mention calling functions from the CLI at all, as far as I can tell

warped canyon
sharp zealot
sharp zealot
warped canyon
sharp zealot
#

It would have marginal security benefits, and importantly, it would leave the door open to pluggable secrets providers

#

If we set it up like this, for example:

dagger call --token env:NETLIFY_TOKEN

The env: could be optional:

dagger call --token NETLIFY_TOKEN would be sugar for env:NETLIFY_TOKEN

wintry prism
#

Just a string today that gets converted internally.

sharp zealot
warped canyon
#

Would be nice. In that world, secrets providers would be some sort of special extension to dagger and not modules I guess. Or at least not modules as they exist today

#

more of a middleware

sharp zealot
#

They could still be modules. We have a TBD design discussion on that part. But we've been designing secrets interfaces deliberately to leave space for that future design

#

would be a shame to waste it now

#

I'll create an issue to track this

sharp zealot
#

I apologize for filing / communicating issues that are not accessible to non-employees. That is definitely not ideal, and it's temporary. We're dealing with the complications of Linear and Github co-existing in our stack.

#

@kind carbon while you're around, I'm looking for the special --help logic that introspects available functions etc. I'm going to try making functions more like that ๐Ÿ™‚

#

(at the moment --help is more helpful than functions)

kind carbon
#

That was ported from dagger do, the difference is it lists all functions in a module. With --help you'll only see the main object's functions, and then you need to continue chaining.

#

The --help logic comes from cobra. Nothing custom.

sharp zealot
kind carbon
#

Yes

sharp zealot
#

Then I guess what I'm really looking for is the generation of the command hierarchy

kind carbon
#

That's built by the arguments you pass in.

#

I.e., before parsing an argument, we add all subcommands for current command. Then make cobra.Find a command based on arguments. If it doesn't find one, it errors. If it does, it's a valid argument and does the same thing for next argument until the end.

#

In functions, that is circumvented, but you already have all the module's functions in a data structure.

sharp zealot
#

Thank you ๐Ÿ™

#

I can see the value of listing all functions from all types, but it's not what I'm looking for most of the time. I was thinking of moving that to a functions --all flag or equivalent

#

With functions being the standard entrypoint for discovering what can be done at the selected path

#

So, similar to --help but without the other baggage of --help (I dont care about various flags, just want a list of functions I can call at this path)

kind carbon
#

Being able to know which verbs can be used at a selected path is a todo. That was one of the main points about functions. Without it, any verb will show the same sub-commands when adding --help.

#

The verbs only do something different on the leaf command, to do something with the result. They can add extra flags to help with that but up to that point they all work the same.

sharp zealot
#

That's fine with me, I understand what you mean and also look forward to that improvement, but orthogonal to what I'm looking for here (I'm fine with a list of functions that is not "verb-aware", just all available functions)

sharp zealot
#

I'm getting a segfault in codegen on my tailscale module ๐Ÿ˜ญ

sharp zealot
#

Just got my tailscale working with dagger up ๐Ÿ™‚

#
dagger -m github.com/shykes/daggerverse/tailscale up gateway --key "$TAILSCALE_AUTHKEY" --hostname hello-nginx

Note that there is a --backend SERVICE argument, which cannot yet be specified from the CLI (I am working on fixing that). In the meantime, this will spin up a nginx service container as a default backend.

#

Another bug report (I'll open an issue later): dagger up refuses to run a service with no exposed ports. But sometimes, services only connect out. Case in point: my tailsale service ๐Ÿ™‚ I had to expose a bogus port for it to work

restive shore
#

I am trying to use the validator module but dagger mod sync throws this.
I did go mod tidy. Do I have to do something else besides that?

rocky harbor
#

I am trying to use the validator module

sleek nest
#

Does anyone have a module you'd like to show off during the Community call this week? I have room for one more demo ๐Ÿ™‚ If you are interested, please DM me!

spiral whale
#

I'm unable to read anything from the following code if the container fails. All output details return with error. Am I missing something?

stdout, _ := c.container.Stdout(ctx.Context)
stderr, _ := c.container.Stderr(ctx.Context)
``
wintry prism
#

Super baffled by https://github.com/jedevc/daggerverse/tree/main/hugo
anything I do with it seems to result in

โœ˜ load functions ERROR [0.62s]
โ”œ [0.62s] loading module
โ”ƒ Error: failed to get loaded module ID: input:1: host.directory.asModule failed to instal
โ”ƒ module dependencies: failed to install dependency "github": failed to install module sch
โ”ƒ a: schema validation failed: input:2173: Cannot redeclare type GithubAsset.
โ”ƒ
โ”ƒ       | ...
โ”ƒ  2170 |
โ”ƒ  2171 |
โ”ƒ  2172 | """
โ”ƒ  2173 | type GithubAsset {
โ”ƒ  2174 |         """
โ”ƒ  2175 |
โ”ƒ  2176 |
โ”ƒ       | ...
โœ˜ asModule(sourceSubpath: ".") ERROR [0.57s]
#
hugo โžค cat dagger.json                                                           git:main
{
  "name": "hugo",
  "sdk": "go",
  "dependencies": [
    "./github"
  ]
}
#

uses a github module in a subdir

#
hugo โžค grep -r GithubAsset *                                                     git:main
main.go:func getMatchingAsset(ctx context.Context, assets []GithubAsset, keywords []string) (GithubAsset, error) {
main.go:            return GithubAsset{}, nil
main.go:    return GithubAsset{}, fmt.Errorf("could not find asset matching keywords %s", keywords)
#
github โžค grep -ri type                                                           git:main
./api.go:type release struct {
./api.go:type asset struct {
./api.go:    ContentType string `json:"content_type"`
./main.go:type Release struct {
./main.go:type Asset struct {
./main.go:    ContentType string `json:"contentType"`
./main.go:type Github struct{}
./main.go:            ContentType: tmp.ContentType,
sharp zealot
#

@rocky harbor I'm trying to add support for service arguments in the CLI, I think I accurately duplicated the logic for other types (seemed pretty straightforard), but getting this error:

panic: reflect.Value.Interface: cannot return value obtained from unexported field or method

Does that ring a bell?

warped canyon
#

Getting the hang of the Optional pattern in Go and I think it's pretty nice. That's all. ๐Ÿ™‚

warped canyon
#

๐Ÿš€

sharp zealot
#

@warped canyon do you find that you sometimes forget to publish your modules each time you push a new version to github?

#

(I do... Since nothing actually changes when I forget)

warped canyon
obtuse lion
#

Is there info somewhere on how to create a custom sdk?

warped canyon
#

@wompfox I tried publishing but nothing

rocky harbor
# obtuse lion Is there info somewhere on how to create a custom sdk?

It's very new, mostly untested and undocumented, so no not really ๐Ÿ˜„ If you're feeling brave:

  1. Write a module that has a Codegen function (which returns a directory containing the generated code for a module based on the user's source) and a ModuleRuntime function (which returns the container that a module executes in in dagger)
  2. To use the SDK, manually edit dagger.json to set "sdk" to a module ref that points to the sdk module you wrote above
#

We are going to flesh this out a lot more, we just have been focusing on getting our first 2 "official" SDKs in place, we'll have more time to polish+document the 3rd party sdk support post-KubeCon

rocky harbor
#

Getting the hang of the Optional

sharp zealot
#

I kind of wish I could connect my daggerverse repo to my daggerverse account, then instead of this:

dagger shell -m github.com/shykes/daggerverse/wolfi base container

I could do this:

dagger shell -m shykes/wolfi base container

(that first command works by the way ๐Ÿ™‚

sharp zealot
#

It looks like the calls made by the CLI to pass arguments of type secret/directory/container etc don't show up in Dagger Cloud.

Is that right?

sharp zealot
#

I am developing a module that involves figuring out by trial and error which packages to install on a container. I am LOVING the devloop for that, module source on the left, dagger shell on the right, insanely productive and fun

spiral whale
sharp zealot
#

request @spiral whale : can the generator itself be distributed as a module?

spiral whale
#

Yes, generator and runtime(lightweight wrapper around gale) also a dagger module.

quick wind
#

Having a first look at Zenith, but hitting an error with calling modules from github - Error: no module specified and no default module found in current directory - The github url is of the same format found here: https://github.com/dagger/dagger/blob/main/docs/current/labs/project-zenith.md (e.g. github.com/<user>/<repo>@<branch>) and the repo has a dagger.json at the root from dagger mod init --name=<name> --sdk=python. Am I missing something or is this not expected to work yet?

#

I'm using the 0.9.2 release if that matters, not specifically the current main branch of Dagger

warped canyon
quick wind
#

Or not, it was but is now loading fine, ignore that!

warped canyon
#

what command is giving you that message?

quick wind
#

dagger call <function-name> -m <github.com/<user>/<repo>@main

kind carbon
#

@quick wind Put -m before the function. On call or before.

warped canyon
quick wind
#

Oh I already had that, just missed it when typing it out

#

Still not working however

kind carbon
#

Surely you get another error though.

quick wind
#

Nope:

โœ˜ load call ERROR [0.00s]
โ”œ [0.00s] loading module
โ”ƒ Error: no module specified and no default module found in current directory                                                                
โ€ข Engine: 35cbe9a91354 (version v0.9.2)
โง— 1.07s โœ” 3 โœ˜ 1
kind carbon
#

That suggests it's not parsing -m. Where in the command do you have it?

quick wind
#

Is this possibly because I overwrote the generated pyproject.toml with a Poetry copy

quick wind
kind carbon
quick wind
#

Oh I misunderstood, I've been using this format

#

So that does change the error:

โœ˜ load call ERROR [0.00s]
โ”œ [0.00s] loading module
โ”ƒ Error: failed to load module config: failed to read local config file: open pytest/dagger.json: no such file or directory                  
โ€ข Engine: 35cbe9a91354 (version v0.9.2)
โง— 0.68s โœ” 3 โœ˜ 1
kind carbon
#

Atm it won't parse the whole args, only until the first positional argument after call.

kind carbon
#

Can you check if your dagger.json is well formatted?

quick wind
# warped canyon Just opened a PR to correct the docs: https://github.com/dagger/dagger/pull/6036...

This format seems to progress further:

โœ˜ load call ERROR [10.89s]
โ”œ [10.89s] loading module
โ”ƒ Error: failed to get loaded module ID: input:1: git.commit.tree.directory.asModule.serve failed to load module types: failed to call module
โ”ƒ pytest" to get functions: failed to get function output directory: process "python -m pip install ." did not complete successfully: exit co
โ”ƒ : 1                                                                                                                                        
โœ˜ serve ERROR [3.39s]
โœ˜ exec python -m pip install . ERROR [1.53s]
โ”ƒ Processing /src                                                                                                                            
โ”ƒ   Installing build dependencies: started                                                                                                   
โ”ƒ   Installing build dependencies: finished with status 'done'                                                                               
โ”ƒ   Getting requirements to build wheel: started                                                                                             
โ”ƒ   Getting requirements to build wheel: finished with status 'done'                                                                         
โ”ƒ   Preparing metadata (pyproject.toml): started                                                                                             
โ”ƒ   Preparing metadata (pyproject.toml): finished with status 'error'                                                                        
โ”ƒ   error: subprocess-exited-with-error                                                                                                      
โ”ƒ                                                                                                                                            
โ”ƒ   ร— Preparing metadata (pyproject.toml) did not run successfully. 
quick wind
kind carbon
#

That's it, it's the pyproject.toml. Can you show what you have?

quick wind
#

I've overwritten the generated pyproject.toml with a Poetry version

#

Guessing that's unsupported at this stage

#

Going to generate another and try that, one minute

kind carbon
#

Not tested but should be supported as long as it's simple enough. That's why I asked to see.

#

Basically needs to be installable by pip install .. Poetry supports that.

quick wind
#
[project]
name = "main"
version = "0.0.1"

[tool.poetry]
name = "pytest-ci-module"
version = "0.1.0"
description = ""
authors = ["Mb141"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.11"
dagger-io = "^0.9.2"
anyio = "^4.0.0"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
#

Dependencies are so my editor autocomplete works, they're not actually in use

#

Just had a load of squigly red lines

kind carbon
#

Oh, for editor autocomplete, you just need to activate some virtualenv and install the sdk with pip install -e ./sdk (after dagger mod sync). Notice the editable install.

#

Don't add dagger-io as dependency.

#

The editable install is so you don't have to do it again after another mod sync.

quick wind
#

That appears to have worked. The module errors but for a module reason (cannot return null...) but it runs

#

Thanks for helping me figure that out!

kind carbon
#

Yeah, def needs documentation. It's very recent.

quick wind
#

On the off chance it's of any interest, being able to use Poetry over pip would be cool

kind carbon
#

But you should be able to do that.

#

Because of the [build-system].

quick wind
#

I made a brief attempt at it, I got some poetry errors and left it alone. I'll re-try, just wanted to get a basic module running and callable from elsewhere first

kind carbon
#

If you also want to editable install it via poetry you can. Just add a dev dependency for the local dir "./sdk".

#

And add editable argument to the dependency.

#

I think it's develop = true

quick wind
#

Ok, got the callable module working:

โœ” dagger call pytest [1.48s]
โ”ƒ README.md                                                                                                                               
โ”ƒ main.py                                                                                                                                
โ”ƒ myapp                                                                                                                                   
โ”ƒ pytest.ini 
โ”ƒ tests      
#

I'll re-try Poetry now

restive shore
# rocky harbor Pushed as a commit here since it's needed in order to write tests for that PR: h...

Hey @rocky harbor , The above change may have introduced a regression. ExperimentalPrivilegedNesting doesn't seem to be pass through docker auth to the underlying dagger-in-dagger. I am not sure that's the exact cause though, but with 0.9.0 I can use it to run my tests and the nested dagger session is able to pull docker images from the private registry. Trying to upgrade to 0.9.2 that is failing saying docker image not found. So I am assuming that is because the docker auth is not passed through. I don't fully understand the change that went in with the above.

quick wind
#

So Poetry testing:

Adding dagger.io = { path = "./sdk", develop = true } to [tool.poetry.group.dev.dependencies] worked for autocomplete as you said

Calling the module doesn't work if I just change pyproject.toml:

โ”ƒ   Preparing metadata (pyproject.toml): finished with status 'error'                                                                    
โ”ƒ   error: subprocess-exited-with-error   
...
FileNotFoundError: [Errno 2] No such file or directory: '/src/README.md'                                                             
โ”ƒ       [end of output]          

There is definitely a README.md in src/:

โ•ฐโ”€ ls src/
main.py  README.md
rocky harbor
#

It looks like the calls made by the CLI

warped canyon
#

with the python object support in 0.9.2, can anyone give me an example of what it looks like to add/use fields on the main class? The two examples in the PR are awesome but they're both dealing with secondary classes

rocky harbor
#

with the python object support in 0.9.2

warped canyon
#

This surprised me

@object_type
class Proxy:
...
    ctr: Annotated[
...
    ] = field(default=init())

...

def init() -> dagger.Container:
...

doesn't work

NameError: name 'init' is not defined

rocky harbor
warped canyon
rocky harbor
warped canyon
#

and with the implicit class definition I had before it was probably loaded a different way (maybe?)

rocky harbor
warped canyon
warped canyon
#

Is there any way to do some introspection to see how my python code is getting called by the runtime? I can see the graphql query that looks correct, but the error I'm getting sounds like it's not getting called properly

#

I suspect the root of it may be that it's an async function, but in the generated Go code it doesn't take in a context

rocky harbor
# warped canyon Is there any way to do some introspection to see how my python code is getting c...

If you provide both --debug and --progress=plain on dagger cli commands you'll get a ton of info, including e.g.

157: [0.62s] [DEBUG] dagger.mod._module: resolver => Test.foo
157: [0.62s] [DEBUG] dagger.mod._resolver: input args => {}
157: [0.62s] [DEBUG] dagger.mod._resolver: structured args => {}
157: [0.62s] [DEBUG] dagger.mod._module: result => 'yo'
157: [0.62s] [DEBUG] dagger.mod._module: unstructured result => 'yo'
157: [0.62s] [DEBUG] dagger.mod._module: output => '"yo"'

Which it sounds like is what you're looking for?

warped canyon
#

still broken ๐Ÿ˜ž let me see if I can get a simple repro to share

latent trellis
#

Daggerverse seems to be down or at least struggling to load for me.

sharp zealot
#

I am getting some very surprising cache misses in my zenith runs today. Some very straightforward runs that have no opportunity to miss cache - but still do, on the very next run. Very strange.

kind carbon
rocky harbor
#

Daggerverse seems to be down or at least

kind carbon
sharp zealot
#

also: shell is amazing

kind carbon
#

Custom entrypoints?

#

Like WithEntrypoint?

kind carbon
rocky harbor
#

^ Can confirm because I'm working on examples for docs right now and just called dagger shell expecting sh but ended up dropping into an node shell because I used that as my base image and never reset the entrypoint ๐Ÿ™‚

Dropping right into interpreters like that is going to be a cool use case for debugging+playing-around though

sharp zealot
#

will send a repro later tonight

rocky harbor
rocky harbor
upbeat herald
#

I also need to update my other modules, Iโ€™ll take care of that today ๐Ÿš€

sharp zealot
#

dagger mod publish still not publishing anything for me, as far as I can tell

sharp zealot
# kind carbon It does support it, but only if you don't set `--entrypoint` yourself. By defaul...

Then I think there's a bug somewhere. Here's a repro:

  1. dagger shell -m github.com/shykes/daggerverse/tmate tmate
  • Expected behavior: open a shell running tmate
  • Actual behavior: it works โœ…
  • Implementation: WithDefaultArgs. This is a hack, not what I actually want (can't pass arguments to tmate) โŒ
  1. dagger shell -m github.com/shykes/daggerverse/tmate tmateWithEntrypoint
  • Expected behavior: open a shell running tmate
  • Actual behavior: silently exits without an error โŒ
  • Implementation: WithEntrpoint. This is what I want, and what supposedly works for everyone except me? โœ…
  1. dagger shell --entrypoint tmate -m github.com/shykes/daggerverse/tmate tmateWithEntrpoint
  • Expected behavior: open a shell running tmate
  • Actual behavior: this actually works
  • Implementation: WithEntrpoint + explicit entrypoint in the CLI. I expect this to work, but I don't expect it to be required to work โš ๏ธ

I would be grateful to anyone who can reproduce and share their thoughts ๐Ÿ™

kind carbon
#

tmate works because by using default args, you're replacing /bin/bash with tmate which is what you want.

#

Age old dance of ENTRYPOINT & CMD ๐Ÿ™‚

#

If you run shell --focus=false you can see what's the actual command that ran btw.

sharp zealot
sharp zealot
#

I would consider that a bug though. Errors should always be visible, having to type --focus=false is a UX bug in my opinion

#

Also: IMO WithEntrypoint should clear default args by default, perhaps with an option to not do that.

spiral whale
#

I was going to write I had same issue with kind module. WithDefaultArgs(nil) it's nice to know this command will do the trick ๐Ÿ™

kind carbon
sharp zealot
sharp zealot
#

@kind carbon I'm not getting any error from dagger shell -m github.com/shykes/daggerverse/tmate tmateWithEntrypoint, with or without --focus=false thinkspin

#

Just silent failure in both cases

kind carbon
#

Yeah I know. I was agreeing with you that it's a bug. Not sure if it's on the services side or shell. Not familiar with that code.

#

Can't access that run btw.

#

With --focus=false I just meant that I saw the command and it looked obviously wrong, it's not that it correctly errored out.

kind carbon
#

This doesn't fail as well: --entrypoint wat. Returns exit 0.

sharp zealot
wintry prism
#

whoops. You mean the default container args facepalm

sharp zealot
#

Still cool to see your latest version ๐Ÿ™‚

#

It actually makes me wonder: how hard would it be to support a *Container argument instead of a ref?

#

Then you can inject scanning inline to any pipeline, without being forced to push to a registry

sharp zealot
#

I'm guessing that version is a little slower

#

If that becomes a problem, we could rig a private registry, I could see that being cheaper

wintry prism
sharp zealot
#

I got sidetracked building tmate from source ๐Ÿ™‚ But ready to play with tmate for our battle ๐Ÿ™‚ @warped canyon

sharp zealot
#
 % dagger mod publish
โœ˜ dagger mod publish ERROR [0.03s]
โ€ข Cloud URL: https://dagger.cloud/runs/399e9d2e-a92a-4058-bb8d-78170155f779
โ€ข Engine: f663ba1ab6a9 (version devel ())
โง— 0.43s โœ” 3 โœ˜ 1
Error: failed to get module path: failed to parse git remote origin URL: ssh://git@github.com/shykes/daggerverse does not match "^(git@|https://)(github.com)[:/]([^/]+)/([^/]+)"
sharp zealot
#

@kind carbon @rocky harbor @deft rain I'm trying to implement dagger print, I really find myself needing an "object inspector" tool often in my dogfooding.

Implementation question: I can't use OnSelectObjectLeaf because it's too limited (I need to access more than one field, for example upon receiving a Container I want to expect many fields and print their contents.

So I have to use AfterResponse, which only has a result any.

Is there a way for me to introspect the type of that result argument?

sharp zealot
sharp zealot
wintry prism
#

Hmmm...
Not sure how to proceed with python module. Seeing error mentioned by others, but they were messing with Poetry and such.

The "main" module could not be found. Did you create a "src/main.py" file in โ”‚
โ”ƒ โ”‚ the root of your project?
#

Got something working in thread

#

I tried with object type (with function under/within it) and then without.

sharp zealot
#

I'm trying to implement dagger print, and really struggling to get the behavior I need from the TUI engine. Is anyone reasonably familiar with how to use it?

rocky harbor
#

@Helder Correia @Erik Sipsma @jedevc I'm

sharp zealot
#

Basically, I want to:

  1. call the specified pipeline of functions (same as the other zenith functions)
  2. inspect the result
  3. print a bunch of useful text about the result, on standard output

It's fine (and useful) for the TUI to show progress information while the functions are running, BUT once dagger print returns, I want to see the actual output that dagger print has written to standard output. I don't want the output of the TUI to overwrite it.

Technically, the correct content is written to standard output: if I pipe dagger print into another unix command, the behavior is correct. But, visually that is not reflected in the terminal

#

The second problem is that the cobra output is overwritten to go through the TUI writer. Not a problem in itself.. Except that does break what is written to stdout (adds decorative characters, color etc). The only way to disable this is to use --silent, but that disables all TUI display, which is not what I want.

At the moment I have to bypass the cobra output feature altogether, and fmt.Printf directly. But that might have other side effects I'm not aware of.

kind carbon
#

dagger print

rocky harbor
sharp zealot
#

@rocky harbor @void widget @warped canyon FYI tomorrow for my community call demo slot, I want to setup a collaborative shell (via tmate), them invite whoever has a module to show off, to grab the keyboard and run a command to show off their module.

Like the above

sharp zealot
#

Iโ€™m starting to think that 1) interactive dagger shell needs a non-interactive counterpart, and 2) interactive and non-interactive could be collapsed into the same command, kind of like docker run [-i]. But possibly even better so that interactive/non-interactive can be auto-detected based on local tty being present or not . Basically like ssh [-tT].

I think dagger run [-i] would be a good candidate ๐Ÿ˜

latent trellis
#

How would someone implement live reload (or rather watch and reload) with Dagger today?
Letโ€™s say I have a bunch of services that I want to build and run in Dagger (instead of building and running them on the host machine with a docker compose setup).
I can certainly solve the watch part, but how would that work with Dagger. I donโ€™t necessarily want to restart all services.

strange arch
#

Hello, Iโ€™m playing again with Dagger after a long pause and Iโ€™m excited to see the progresses done on project Zenith so far, congrats! Iโ€™m trying to adapt the CI code I had to make it work with newer versions of Dagger. For example, I have a Hugo package (see attached file) and I have two questions:

  • If I turn it into a Dagger module, how can I handle the WithCustomizations() which takes functions mutating a container as arguments? I guess that functions canโ€™t be serialized to be passed through GraphQL, right?
  • If I canโ€™t turn my package into a Dagger module, how can I access the Dagger client, should I pass it to every functions? (As a bonus question, whatโ€™s the rationale behind the removal of dagger.Context?)
wintry prism
#

Hello, Iโ€™m playing again with Dagger

restive shore
#

How would someone implement live reload

warped canyon
sharp zealot
#

@warped canyon @dense canyon @rocky harbor @void widget @upbeat herald @wintry prism (and anyone else who has a cool module to show off). My tmate setup isn't ready (yay childcare). So instead I'm just going to run one-liners to show off as many modules as possible in my terminal.

If you want me to show off your module, prepare some one liners ๐Ÿ™‚

rocky harbor
#

dagger -m github.com/sipsma/daggerverse/yamlinvaders shell play (press space once on the menu screen to start)

dense canyon
sharp zealot
#

@dense canyon can you have a function to download the samples please

warped canyon
#

dagger -m github.com/kpenfound/dagger-modules/golang download build-remote --remote github.com/dagger/dagger --ref main --module "./cmd/dagger" --platform darwin

dense canyon
rocky harbor
hexed flume
#

typo ?

#

oups sorry

#

my bad

rocky harbor
hexed flume
#

works like a charm

spiral whale
#

dagger call -m github.com/aweris/gale/daggerverse/gha/trufflesecurity/trufflehog@1dee85484cbfba12c609ba114839977547e94c7a run --repo dagger/dagger --branch main --with-path "."

wintry prism
#
dagger call -m github.com/jpadams/daggerverse/drupalTest run

Zenith version of this Service Container example:
https://docs.dagger.io/757394/use-services/#example-mariadb-database-service-for-application-tests
Using drupal and mariadb modules.

Trivy two ways

dagger call -m github.com/jpadams/daggerverse/trivy scan-image --image-ref alpine/git:latest
dagger call --progress=plain -m github.com/jpadams/daggerverse/trivy scan-image --image-ref alpine/git:latest --format json | jq '.Results[].Vulnerabilities[] | {Title, Severity}'
#

@sharp zealot ๐Ÿ‘†

sharp zealot
#

This is just a rehearsal, while I'm live I'll check the amphitheater chat

#

๐Ÿ™‚

sharp zealot
#

@sleek nest @bleak nest do you want to jump on #911305510882513037 to go over zenith docs together? Now or later?

bleak nest
sharp zealot
sleek nest
bleak nest
#

In dev-audio @sharp zealot

hexed flume
sleek nest
sharp zealot
#

Fun fact there is an official implementation of the docker-compose spec in Go, and it's terrible

#

(or at least terribly frustrating to use)

sharp zealot
#

Context: I'm making a basic docker-compose module (not surprising I'm sure)

upbeat herald
sharp zealot
#

I'm trying to add support for git sources in directory arguments. But not sure what encoding to use. git:// makes sense, but then I don't know where to put the https/ssh distinction. Are git+ssh://... and git+https://... considered valid and good? wdyt?

#

The other possibility is just making it ssh:// and https://, but then it would close the door to eg. tarball-over-https which is another interesting source to support

warped canyon
#

running with dagger -s seems normal. Just can't see anything

wintry prism
#

{"count":11,"value":"Uri expired"}

warped canyon
rocky harbor
#

Fun fact: sorting the results returned for introspection queries to our graphql server makes fully cached load time 3x faster in one of Kyle's demos ๐Ÿš€ https://github.com/dagger/dagger/pull/6056

In general anyone running modules that have lots of deps will probably greatly benefit from that (will go out in release tomorrow)

warped canyon
#

trying out a little thing for my demo on github actions

    steps:
      - name: Dagger
        uses: kpenfound/dagger-action@main
        with:
          args: ci-remote --commit $GITHUB_SHA
          module: github.com/kpenfound/greetings-api/ci
          cloud-token: ${{ secrets.DAGGER_CLOUD_TOKEN }}
#

no more actions/checkout ๐Ÿ™‚ If there's no .git/ dir, the action does a git clone -b ${GITHUB_REF_NAME} --no-checkout https://github.com/${GITHUB_REPOSITORY} . to get the git metadata for dagger cloud

sharp zealot
sharp zealot
#

also:

if thereโ€™s no .git dir

didnโ€™t understand that part

#

very interested in this ๐Ÿ™‚

warped canyon
#

overcomplicating it. At first I just dropped the actions/checkout since I'm executing the remote module. But the my cloud runs didn't have any metadata. So now the kpenfound/dagger-action will do a --no-checkout clone if there's no .git dir just to get the metadata for cloud. I check for .git in case there was a actions/checkout, maybe for some other steps

sharp zealot
#

oh I got it

#

โ€œitโ€ is your gh action

warped canyon
#

yeah it's just a little composite action to trim down yaml

sharp zealot
#

canโ€™t wait to F&F the telemetry & viz stack

#

lots of low hanging fruits

#

really you should be able to get all git metadata just by inspecting directories flowing in between functions

warped canyon
#

maybe there could be some api to set the metadata

sharp zealot
#

better for cloud to get it from raw telemetry IMO

warped canyon
#

for sure. just trying to think of how we'd know where to get the metadata in this kind of scenario where I have no repo locally

dense canyon
#

๐Ÿ‘‹ what's the recommended approach for devs trying to lint their module's code in CI? They should run dagger mod sync beforehand generate all the types that are generally not commited?

kind carbon
#

My module (dev module for the python sdk) can lint itself actually, no need for dagger mod sync: ๐Ÿ™‚

dagger call -m dev lint --src dev check

And to fix (not CI):

dagger call -m dev lint --src dev format -o dev
#

But in general terms you can use a module that can lint your SDK's language:

dagger call -m <module with linter> lint --src .

Or use a git ref instead of local dir.

#

For mod sync you may need it for the linter to be able to go through the code paths. I don't need that in the dev module because the generated sdk in the module matches the one outside which is already installed before the linter runs. Curious to explore that in a more isolated case.

dense canyon
#

dagger call -m <module with linter> lint --src .

this will still fail if my querybuilder and dagger.gen (talking about the SDK which is the one I know at least) stuff is not present, right?

#

since src will mostly copy my *. go files into the linting module and it will run lint on them

#

and since I'm missing some types (unless I call dagger mod sync first), both compiling and linting the module will fail. cc @kind carbon since I haven't replied

kind carbon
dense canyon
kind carbon
dense canyon
wintry prism
#

So fun hacking from 35,000 feet on Zenith!

wintry prism
#

I fought the law of the sky...and the sky won. Joining Zenith Community call denied ๐Ÿ˜ญ

sharp zealot
#

Another issue on my list, that I forgot to mention on the call:

  • I wish I could invoke core functions with dagger call
#

dagger shell -m core container from --address alpine

#

A lot of very simple but very useful commands would be unlocked without having to develop wrapper modules

#

Which brings me to another issue: namespace conflict with core types is becoming a problem for me.

For example, it makes it basically impossible to develop a wrapper module for exposing core, because by definition, 100% of the types I want to expose, already exist in the core! Container, Service, Secret etc. I can't define any of them.

Of course that's an extreme example, but even in regular modules, it's common for me to hit a "reserved" type name and be mildly annoyed.

What's worse is that, by introducing new core types in the future, we may break a bunch of modules.

kind carbon
#

Dagger Python SDK plus Infisical Python

whole maple
#

I currently struggling with one of my modules here
https://github.com/schlapzz/dagger-modules/blob/main/git/main.go
When I call dagger call push --url git@ssh.gitlab.puzzle.ch:cschlatter/clone-test.git --username foo --email foo@bar.ch --branch main --key ./id I get following error

โœ˜ dagger call push ERROR [0.08s]
โ”ƒ Error: response from query: input:1: Cannot query field "push" on type "GitRepository".                                                                       
โ”ƒ input:1: Field "git" argument "url" of type "String!" is required but not provided.                                                                           
โ€ข Engine: ec863c0c2634 (version v0.9.1)

I have no clue what I'm doing wrong. I code two other modules, and they worked as expected.... but on this one I'm a bit lost....

GitHub

Contribute to schlapzz/dagger-modules development by creating an account on GitHub.

sharp zealot
#

Could I interest anyone with a tailscale account in trying my module, to reproduce an issue?

#

dagger up -m github.com/shykes/daggerverse/tailscale gateway . You will need a tailscale API key

kind carbon
#

GitRepository

sharp zealot
#

In Go SDK, is there a way to call my own functions without actually specifying a value for optional arguments? Do I just call Opt() with no argument? EDIT: that doesn't work

#

Still struggling to get dagger shell to work properly...

#

Could anyone reproduce this?

$ dagger shell --entrypoint /bin/sh -m github.com/shykes/daggerverse/tmate tmate --base ubuntu
sharp zealot
#

I'm peeling the layers of the onion that is dagger shell behavior...

  1. CLI-side cmd/dagger/shell.go has some logic to interpret --entrypoint (which doesn't actually set the entrypoint), and introspect the container's actual entrypoint and default args. Generally this seems to add an extra layer of WithExec

  2. Core-side, there's a semi-private API call ShellEndpoint

  3. Below that, there's Container.runShell`

  4. Below that, there's Container.Service. This is where the extra layer of WithExec is actually used.

So the source of my confusion is becoming more clear: there is entanglement between logic all the way at the top (CLI handling of a command) and all the way at the bottom (what happens when you spawn a service from a container, and how exactly it's decided what to exec)

sharp zealot
#

If I understand correctly, Container.Service doesn't honor the container's entrypoint & default args? Only the last WithExec? Or a combination of the two?

#

I feel like the answer to that question should be added to the reference doc of Container { asService }

#

Giving up for now

spiral whale
#

but you're trying to pass image address to container id

sharp zealot
#

the CLI interprets the string as an image address and makes the conversion automatically

spiral whale
#
โ”ƒ Error: response from query: input:1: Argument "base" has invalid value {address: "ubuntu"}.
โ”ƒ Expected type "ContainerID", found {address: "ubuntu"}.
โ”ƒ Error: unexpected resourceid.ID[github.com/dagger/dagger/core.Container] literal type: *ast.ObjectValue

this is the error I'm getting

sharp zealot
#

You may need to run it in main

spiral whale
#

ahh, I'm on 0.9.2. Hmm, that should be it.

sharp zealot
#

I've tracked down my mysterious tmate shell issue to this line:

 ctr = baseCtr.WithFile("/bin/tmate", r.StaticBinary())

If I replace it with:

ctr = baseCtr

Then dagger shell works

#

I can't see the actual error encountered by executing the shell, nor can I inspect the contents of the container, so I can only guess. But it seems that Container.WithFile() causes the container to break, somehow

#

side quest: just discovered this in the top-level graphql namespace:

sharp zealot
#
dagger shell -m github.com/shykes/daggerverse/containers \
  from --address alpine \
  state
#
dagger shell -m github.com/shykes/daggerverse/containers \
  from --address alpine \
  with-entrypoint --args=/bin/sh \
  without-default-args \
  state
obtuse lion
#
When using dagger call, all names (functions, arguments, struct fields, etc) are converted into a shell-friendly "kebab-case" style.

When using dagger query and GraphQL, all names are converted into a language-agnostic "camelCase" style

FWIW we were doing the same kebab/camelCase translation in a feature in acorn and just recently reverted. camelCase in a CLI is very yucky, but it got to confusing and was a source of frustrating when working with users to tell them to switch styles in different context. Too many, "oh yeah, sorry, it's not working because here you use kebab case, not camelCase." Other dumb things like "grep ARG" doesn't work because you are using the wrong case style. Just our own experience. Our use case could have been different, but just something to think about.

sharp zealot
obtuse lion
#

yes, camelCase is what we prefer

sharp zealot
#

Itโ€™s even worse in our case because thereโ€™s a third layer: the Go or Python functions behind the GraphQL scheme ๐Ÿซ 

#
  • Go: HelloWorld
  • Graphql: helloWorld
  • CLI: hello-world
obtuse lion
#

we have warts too because we prefer camelCase but because of k8s and DNS names we are forced to kebab-case for some keys. Not pretty.

#

this is also why we moved away from translating kebab to camel is that technically our system doesn't enforce or assume a case style. It's just convention. But by doing the translation we ran into weird corner cases where people put kebab in the DSL and then it was super confusing because from the CLI you'd expect the DSL to have camelCase, but that's not what the user did. So in the end we just dont assume anything but tell people we like camelCase.

#

I've been fooling with zenith in weird ways, but just realized now I don't actually know how to use it in the most basic way. If I write a module, how do I consume the module from a regular dagger pipeline, like the basic go example in dagger.io home page but call my custom module. I didn't know how to generate the client code. Like a module calling another module, I can do that. Just a not module calling a module. I feel like I'm overlooking something really obvious.

sharp zealot
obtuse lion
#

I really want to be able to attach a debugger to a running module. Any tips on how you can do this?

warped canyon
obtuse lion
#

This probably makes no sense, but I got the following to work. It's using AML as dagger a module. So the below

// Fancy hello
define Hello: {
    Greeting: "Hello"
    Name: "World"

    // Say hi
    Message: function string {
        return: "\(self.Greeting) \(self.Name)"
    }

    // Say hi, but loudly
    Shout: function string {
        return: std.toUpper(self.Message()) + "!!!!!!"
    }
}

You can run dagger call with-name --name dagger shout and it will output HELLO DAGGER!!!!!!

You can do real stuff by just writting expressions like dagger.container().from("alpine").withExec(["apk", "add", "curl"]).withExec(["curl", "https://dagger.io"]).stdout()

#

I'm still working on rounding out the edges, specifically I need to write a custom sdk for this.

#

The simplest hello world module in AML looks like

HelloWorld: function string {
  return: "Hello World"
}
obtuse lion
#

seems like there could be some UX improvement for with-foo --foo bar That seems like a pattern to set a field, but it's verbose

#

For the internal state fields there seems to be an assumption that they are lower case for example. WithField("Foo") is assuming the json returned from the module is {"foo": ...}, not {"Foo": ...} So it's weird in AML because I need to define the field as WithField("Foo") so the that CLI arg becomes --with-foo, but then I have to internally treat the field as foo. But AML is basically just json so there not really a notion of marshaling tags to change the case. What I'd prefer that I could just return {"Foo": ...} from the module and it works.

obtuse lion
warped canyon
obtuse lion
warped canyon
latent trellis
#

What's going on with those timers?

warped canyon
#

Is there a better approach? What would

obtuse lion
#

Writing an sdk was ridiculously simple.

#

My first module: dagger call -m github.com/ibuildthecloud/daggerverse/hello with-greeting --greeting "OMG," with-name --name "this works" shout

Of course I couldn't just do a hello world, so this is using my custom AML SDK which integrates dagger and AML. Lots of broken stuff, but now that I go the end to end scaffolding I'm going to start using it to run the actual CI of AML itself. Because of course the CI for AML should be in AML ๐Ÿ™‚

obtuse lion
#

I'm taking a break now, but I'll get to AML CI inception tonight.

obtuse lion
#

looks like daggerverse is say "dagger mod use " when i looks like the CLI is "dagger mod install" now

rocky harbor
rocky harbor
rocky harbor
#

I've tracked down my mysterious tmate

rocky harbor
#

Which brings me to another issue:

obtuse lion
#

it would be nice if ./vendor was supported in modules. You end up with an error like ```exec /usr/local/bin/codegen --module . --propagate-logs=true --introspection-json-path /schema.json ERROR [0.57s]
Error: load package ".": err: exit status 1: stderr: go: inconsistent vendoring in /src/amlsdk:
github.com/99designs/gqlgen@v0.17.34: is marked as explicit in vendor/modules.txt, but not explicitly required in go.mod

    To ignore the vendor directory, use -mod=readonly or -mod=mod.                                                                          
    To sync the vendor directory, run:                                                                                                      
            go mod vendor                                                                                                                   
obtuse lion
sharp zealot
#

on a plane the dagger CLI takes a LONG time to exit, after it has completed its call and printed everything to the screen. I suspect cache flushing or other dagger cloud communication

#

cc @dense canyon