#Container methods

1 messages · Page 1 of 1 (latest)

woven acorn
#

With container methods like Exec() or Build(), I assume that these methods really only prepare an execution and that no work is done until I call ExitCode() or Directory.ID()?

Can I also re-use a container with multiple exec commands and does the file system contain the mutations from the first command for the second or does it revert to the original prepared state?

soft mural
#

Hey Nic,

Yeah you're exactly right, you can chain together as many exec calls as you want and they'll all be executed in that order with the mutated state

woven acorn
#

Cool thanks, however, this...

#
   33   node.Exec(dagger.ContainerExecOpts{
   34     Args: []string{"npm", "install"},
   35   }).ExitCode(ctx)
   36
   37   node = node.Exec(dagger.ContainerExecOpts{
   38     Args: []string{"npm", "run", "build"},
   39   })
#

Does not work as the install does not exist.

#

Removing the ExitCode, does

#
   33   node = node.Exec(dagger.ContainerExecOpts{
   34     Args: []string{"npm", "install"},
   35   })
   36
   37   node = node.Exec(dagger.ContainerExecOpts{
   38     Args: []string{"npm", "run", "build"},
   39   })
soft mural
#

Ahh, yes, so to clarify, the operation is being "prepared" until you actually execute it, with ExitCode or Directory.ID() as you noted. So in this case. you'd want the ExitCode() on the npm run build exec, or on whatever the "final" command is in the chain

woven acorn
#

I think it might also be the reference, as if I take a reference to node in the first example then call Exec, the second statement works. I guess because I have the mutated reference

#

Just testing that

#

Yes that does seem to be the case

soft mural
#

Yeah that makes sense, although I think it may not behave in an obvious way, because the next time you call ExitCode on node it'll execute all of the operations again

woven acorn
#
   33   node = node.Exec(dagger.ContainerExecOpts{
   34     Args: []string{"npm", "install"},
   35   })
   36
   37   node.ExitCode(ctx)
   38
   39   node = node.Exec(dagger.ContainerExecOpts{
   40     Args: []string{"npm", "run", "build"},
   41   })
   42
#

Oh right

#

I see

#

So when you do say Exec does it mutate node or is it more like go's array append where it returns you a new reference

#

so if i did say

soft mural
#

node.Exec will return a mutated version of node with the exec added on, so in this case if you node = node.Exec... you're reassigning node with the updated version

woven acorn
#
node.Exec(...)
node.Exec(...)
node.Exec(...)
#

and did not grab the returned reference I am basically throwing the operation to dev null.

#

This makes total sense

#

Just one last question then

soft mural
#

yup exactly! or you can even assign it to a new reference if you want to do a bunch of things on the same base that you've built

woven acorn
#

Directory or ExitCode will execute the prepared statement, if I call ExitCode then Directory will it run the statement twice

soft mural
#

Ooh good question. I think so. @earnest tulip @polar plover can you confirm?

woven acorn
#

The last one is not really super important, I am just curious 🙂

soft mural
#

Yeah it's an interesting thing to consider. Since they're both operations on the Container type, which itself is the prepared statement, I would think it would run it twice

earnest tulip
#

not sure I'm following 100%, but even e.g. calling ExitCode twice should actually only run it once, since it'll be cached

#

Container.Directory.ID technically won't even force it to run until you try to access files from it (this is a common source of confusion, will be addressed soon!)

soft mural
#

ah TIL 🙂

earnest tulip
#

yeah, it looks like it will since it has an error return type, but it's actually still a lazily generated value 🙂

soft mural
#

Yeah that totally makes sense

cloud estuary
#

The ID thing is really an implementation detail of the underlying API transport (graphql). Some pipelines can be expressed as a single API request. Others need to be broken down into several calls: this is done by basically ending the first sub-pipeline with a "save" operation, and starting the second sub-pipeline with a "load" operation. The "ID" is really the serialized contents of the first pipeline, being saved then loaded back.

#

Now that we know it's confusing (hindsight 20/20) we're making it a higher priority to hide it (as explained above). Honestly it's not even clear they should be called "IDs" at all..

#

(if you're curious about said underlying API, it's all GraphQL under the hood 🙂

wary halo
wary halo