From 3e8ca8d86eafdc1f9d5e8b69f14fb60509549e0f Mon Sep 17 00:00:00 2001 From: kjuulh Date: Sat, 25 Feb 2023 00:01:18 +0100 Subject: [PATCH] feat: update to dagger-v0.3.13 https://github.com/dagger/dagger/releases/tag/v0.3.13 --- crates/dagger-core/src/cli_session.rs | 11 +- crates/dagger-core/src/downloader.rs | 9 +- crates/dagger-core/src/engine.rs | 14 +- crates/dagger-sdk/examples/caching/main.rs | 3 +- .../examples/existing-dockerfile/main.rs | 3 +- .../examples/first-pipeline/main.rs | 3 +- .../examples/publish-the-application/main.rs | 3 +- .../examples/test-the-application/main.rs | 3 +- crates/dagger-sdk/src/gen.rs | 653 +++++++++++++++--- 9 files changed, 590 insertions(+), 112 deletions(-) diff --git a/crates/dagger-core/src/cli_session.rs b/crates/dagger-core/src/cli_session.rs index 63882d0..c260f84 100644 --- a/crates/dagger-core/src/cli_session.rs +++ b/crates/dagger-core/src/cli_session.rs @@ -1,9 +1,4 @@ -use std::{ - fs::canonicalize, - path::PathBuf, - process::Stdio, - sync::Arc, -}; +use std::{fs::canonicalize, path::PathBuf, process::Stdio, sync::Arc}; use tokio::io::AsyncBufReadExt; @@ -105,7 +100,9 @@ impl InnerCliSession { } }); - let conn = receiver.recv().await.ok_or(eyre::anyhow!("could not receive ok signal from dagger-engine"))?; + let conn = receiver.recv().await.ok_or(eyre::anyhow!( + "could not receive ok signal from dagger-engine" + ))?; Ok((conn, proc)) } diff --git a/crates/dagger-core/src/downloader.rs b/crates/dagger-core/src/downloader.rs index 1858bf6..d825ccc 100644 --- a/crates/dagger-core/src/downloader.rs +++ b/crates/dagger-core/src/downloader.rs @@ -129,7 +129,8 @@ impl Downloader { if !cli_bin_path.exists() { cli_bin_path = self - .download(cli_bin_path).await + .download(cli_bin_path) + .await .context("failed to download CLI from archive")?; } @@ -238,7 +239,11 @@ mod test { #[tokio::test] async fn download() { - let cli_path = Downloader::new("0.3.10".into()).unwrap().get_cli().await.unwrap(); + let cli_path = Downloader::new("0.3.10".into()) + .unwrap() + .get_cli() + .await + .unwrap(); assert_eq!( Some("dagger-0.3.10"), diff --git a/crates/dagger-core/src/engine.rs b/crates/dagger-core/src/engine.rs index a4e8283..53e2e9a 100644 --- a/crates/dagger-core/src/engine.rs +++ b/crates/dagger-core/src/engine.rs @@ -1,5 +1,3 @@ - - use crate::{ cli_session::CliSession, config::Config, connect_params::ConnectParams, downloader::Downloader, }; @@ -12,14 +10,17 @@ impl Engine { } async fn from_cli(&self, cfg: &Config) -> eyre::Result<(ConnectParams, tokio::process::Child)> { - let cli = Downloader::new("0.3.12".into())?.get_cli().await?; + let cli = Downloader::new("0.3.13".into())?.get_cli().await?; let cli_session = CliSession::new(); Ok(cli_session.connect(cfg, &cli).await?) } - pub async fn start(&self, cfg: &Config) -> eyre::Result<(ConnectParams, tokio::process::Child)> { + pub async fn start( + &self, + cfg: &Config, + ) -> eyre::Result<(ConnectParams, tokio::process::Child)> { // TODO: Add from existing session as well self.from_cli(cfg).await } @@ -35,7 +36,10 @@ mod tests { #[tokio::test] async fn engine_can_start() { let engine = Engine::new(); - let params = engine.start(&Config::new(None, None, None, None)).await.unwrap(); + let params = engine + .start(&Config::new(None, None, None, None)) + .await + .unwrap(); assert_ne!( params.0, diff --git a/crates/dagger-sdk/examples/caching/main.rs b/crates/dagger-sdk/examples/caching/main.rs index c2c9b36..862ecbe 100644 --- a/crates/dagger-sdk/examples/caching/main.rs +++ b/crates/dagger-sdk/examples/caching/main.rs @@ -35,7 +35,8 @@ async fn main() -> eyre::Result<()> { .container() .from("nginx") .with_directory("/usr/share/nginx/html", build_dir.id().await?) - .publish(format!("ttl.sh/hello-dagger-rs-{}:1h", rng.gen::())).await?; + .publish(format!("ttl.sh/hello-dagger-rs-{}:1h", rng.gen::())) + .await?; println!("published image to: {}", ref_); diff --git a/crates/dagger-sdk/examples/existing-dockerfile/main.rs b/crates/dagger-sdk/examples/existing-dockerfile/main.rs index 7cb0e26..05384a9 100644 --- a/crates/dagger-sdk/examples/existing-dockerfile/main.rs +++ b/crates/dagger-sdk/examples/existing-dockerfile/main.rs @@ -13,7 +13,8 @@ async fn main() -> eyre::Result<()> { let ref_ = client .container() .build(context_dir.id().await?) - .publish(format!("ttl.sh/hello-dagger-rs-{}:1h", rng.gen::())).await?; + .publish(format!("ttl.sh/hello-dagger-rs-{}:1h", rng.gen::())) + .await?; println!("published image to: {}", ref_); diff --git a/crates/dagger-sdk/examples/first-pipeline/main.rs b/crates/dagger-sdk/examples/first-pipeline/main.rs index 192cf6e..3fc09d3 100644 --- a/crates/dagger-sdk/examples/first-pipeline/main.rs +++ b/crates/dagger-sdk/examples/first-pipeline/main.rs @@ -6,7 +6,8 @@ async fn main() -> eyre::Result<()> { .container() .from("golang:1.19") .with_exec(vec!["go", "version"]) - .stdout().await?; + .stdout() + .await?; println!("Hello from Dagger and {}", version.trim()); diff --git a/crates/dagger-sdk/examples/publish-the-application/main.rs b/crates/dagger-sdk/examples/publish-the-application/main.rs index ba80ad1..4d96d24 100644 --- a/crates/dagger-sdk/examples/publish-the-application/main.rs +++ b/crates/dagger-sdk/examples/publish-the-application/main.rs @@ -39,7 +39,8 @@ async fn main() -> eyre::Result<()> { "/usr/share/nginx/html", client.host().directory(output).id().await?, ) - .publish(format!("ttl.sh/hello-dagger-rs-{}:1h", rng.gen::())).await?; + .publish(format!("ttl.sh/hello-dagger-rs-{}:1h", rng.gen::())) + .await?; println!("published image to: {}", ref_); diff --git a/crates/dagger-sdk/examples/test-the-application/main.rs b/crates/dagger-sdk/examples/test-the-application/main.rs index c758763..af15d15 100644 --- a/crates/dagger-sdk/examples/test-the-application/main.rs +++ b/crates/dagger-sdk/examples/test-the-application/main.rs @@ -23,7 +23,8 @@ async fn main() -> eyre::Result<()> { let out = runner .with_exec(vec!["npm", "test", "--", "--watchAll=false"]) - .stderr().await?; + .stderr() + .await?; println!("{}", out); diff --git a/crates/dagger-sdk/src/gen.rs b/crates/dagger-sdk/src/gen.rs index 2984260..fffdeb0 100644 --- a/crates/dagger-sdk/src/gen.rs +++ b/crates/dagger-sdk/src/gen.rs @@ -34,7 +34,7 @@ pub struct CacheVolume { impl CacheVolume { pub async fn id(&self) -> eyre::Result { - let query = self.selection.select("id"); + let mut query = self.selection.select("id"); query.execute(&graphql_client(&self.conn)).await } @@ -49,7 +49,7 @@ pub struct Container { #[derive(Builder, Debug, PartialEq)] pub struct ContainerBuildOpts<'a> { /// Path to the Dockerfile to use. - /// Defaults to './Dockerfile'. + /// Default: './Dockerfile'. #[builder(setter(into, strip_option))] pub dockerfile: Option<&'a str>, /// Additional build arguments. @@ -60,17 +60,26 @@ pub struct ContainerBuildOpts<'a> { pub target: Option<&'a str>, } #[derive(Builder, Debug, PartialEq)] +pub struct ContainerEndpointOpts<'a> { + /// The exposed port number for the endpoint + #[builder(setter(into, strip_option))] + pub port: Option, + /// Return a URL with the given scheme, eg. http for http:// + #[builder(setter(into, strip_option))] + pub scheme: Option<&'a str>, +} +#[derive(Builder, Debug, PartialEq)] pub struct ContainerExecOpts<'a> { - /// Command to run instead of the container's default command. + /// Command to run instead of the container's default command (e.g., ["run", "main.go"]). #[builder(setter(into, strip_option))] pub args: Option>, - /// Content to write to the command's standard input before closing. + /// Content to write to the command's standard input before closing (e.g., "Hello world"). #[builder(setter(into, strip_option))] pub stdin: Option<&'a str>, - /// Redirect the command's standard output to a file in the container. + /// Redirect the command's standard output to a file in the container (e.g., "/tmp/stdout"). #[builder(setter(into, strip_option))] pub redirect_stdout: Option<&'a str>, - /// Redirect the command's standard error to a file in the container. + /// Redirect the command's standard error to a file in the container (e.g., "/tmp/stderr"). #[builder(setter(into, strip_option))] pub redirect_stderr: Option<&'a str>, /// Provide dagger access to the executed command. @@ -100,41 +109,55 @@ pub struct ContainerPublishOpts { } #[derive(Builder, Debug, PartialEq)] pub struct ContainerWithDefaultArgsOpts<'a> { + /// Arguments to prepend to future executions (e.g., ["-v", "--no-cache"]). #[builder(setter(into, strip_option))] pub args: Option>, } #[derive(Builder, Debug, PartialEq)] pub struct ContainerWithDirectoryOpts<'a> { + /// Patterns to exclude in the written directory (e.g., ["node_modules/**", ".gitignore", ".git/"]). #[builder(setter(into, strip_option))] pub exclude: Option>, + /// Patterns to include in the written directory (e.g., ["*.go", "go.mod", "go.sum"]). #[builder(setter(into, strip_option))] pub include: Option>, } #[derive(Builder, Debug, PartialEq)] pub struct ContainerWithExecOpts<'a> { - /// Content to write to the command's standard input before closing. + /// Content to write to the command's standard input before closing (e.g., "Hello world"). #[builder(setter(into, strip_option))] pub stdin: Option<&'a str>, - /// Redirect the command's standard output to a file in the container. + /// Redirect the command's standard output to a file in the container (e.g., "/tmp/stdout"). #[builder(setter(into, strip_option))] pub redirect_stdout: Option<&'a str>, - /// Redirect the command's standard error to a file in the container. + /// Redirect the command's standard error to a file in the container (e.g., "/tmp/stderr"). #[builder(setter(into, strip_option))] pub redirect_stderr: Option<&'a str>, - /// Provide dagger access to the executed command. + /// Provides dagger access to the executed command. /// Do not use this option unless you trust the command being executed. /// The command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST FILESYSTEM. #[builder(setter(into, strip_option))] pub experimental_privileged_nesting: Option, } #[derive(Builder, Debug, PartialEq)] +pub struct ContainerWithExposedPortOpts<'a> { + /// Transport layer network protocol + #[builder(setter(into, strip_option))] + pub protocol: Option, + /// Optional port description + #[builder(setter(into, strip_option))] + pub description: Option<&'a str>, +} +#[derive(Builder, Debug, PartialEq)] pub struct ContainerWithFileOpts { + /// Permission given to the copied file (e.g., 0600). + /// Default: 0644. #[builder(setter(into, strip_option))] pub permissions: Option, } #[derive(Builder, Debug, PartialEq)] pub struct ContainerWithMountedCacheOpts { - /// Directory to use as the cache volume's root. + /// Identifier of the directory to use as the cache volume's root. #[builder(setter(into, strip_option))] pub source: Option, /// Sharing mode of the cache volume. @@ -143,14 +166,23 @@ pub struct ContainerWithMountedCacheOpts { } #[derive(Builder, Debug, PartialEq)] pub struct ContainerWithNewFileOpts<'a> { + /// Content of the file to write (e.g., "Hello world!"). #[builder(setter(into, strip_option))] pub contents: Option<&'a str>, + /// Permission given to the written file (e.g., 0600). + /// Default: 0644. #[builder(setter(into, strip_option))] pub permissions: Option, } +#[derive(Builder, Debug, PartialEq)] +pub struct ContainerWithoutExposedPortOpts { + /// Port protocol to unexpose + #[builder(setter(into, strip_option))] + pub protocol: Option, +} impl Container { - /// Initializes this container from a Dockerfile build, using the context, a dockerfile file path and some additional buildArgs. + /// Initializes this container from a Dockerfile build. /// /// # Arguments /// @@ -168,7 +200,7 @@ impl Container { }; } - /// Initializes this container from a Dockerfile build, using the context, a dockerfile file path and some additional buildArgs. + /// Initializes this container from a Dockerfile build. /// /// # Arguments /// @@ -196,11 +228,16 @@ impl Container { } /// Retrieves default arguments for future commands. pub async fn default_args(&self) -> eyre::Result> { - let query = self.selection.select("defaultArgs"); + let mut query = self.selection.select("defaultArgs"); query.execute(&graphql_client(&self.conn)).await } - /// Retrieves a directory at the given path. Mounts are included. + /// Retrieves a directory at the given path. + /// Mounts are included. + /// + /// # Arguments + /// + /// * `path` - The path of the directory to retrieve (e.g., "./src"). pub fn directory(&self, path: impl Into) -> Directory { let mut query = self.selection.select("directory"); @@ -212,13 +249,49 @@ impl Container { conn: self.conn.clone(), }; } + /// Retrieves an endpoint that clients can use to reach this container. + /// If no port is specified, the first exposed port is used. If none exist an error is returned. + /// If a scheme is specified, a URL is returned. Otherwise, a host:port pair is returned. + /// + /// # Arguments + /// + /// * `opt` - optional argument, see inner type for documentation, use _opts to use + pub async fn endpoint(&self) -> eyre::Result { + let mut query = self.selection.select("endpoint"); + + query.execute(&graphql_client(&self.conn)).await + } + + /// Retrieves an endpoint that clients can use to reach this container. + /// If no port is specified, the first exposed port is used. If none exist an error is returned. + /// If a scheme is specified, a URL is returned. Otherwise, a host:port pair is returned. + /// + /// # Arguments + /// + /// * `opt` - optional argument, see inner type for documentation, use _opts to use + pub async fn endpoint_opts<'a>(&self, opts: ContainerEndpointOpts<'a>) -> eyre::Result { + let mut query = self.selection.select("endpoint"); + + if let Some(port) = opts.port { + query = query.arg("port", port); + } + if let Some(scheme) = opts.scheme { + query = query.arg("scheme", scheme); + } + + query.execute(&graphql_client(&self.conn)).await + } /// Retrieves entrypoint to be prepended to the arguments of all commands. pub async fn entrypoint(&self) -> eyre::Result> { - let query = self.selection.select("entrypoint"); + let mut query = self.selection.select("entrypoint"); query.execute(&graphql_client(&self.conn)).await } /// Retrieves the value of the specified environment variable. + /// + /// # Arguments + /// + /// * `name` - The name of the environment variable to retrieve (e.g., "PATH"). pub async fn env_variable(&self, name: impl Into) -> eyre::Result { let mut query = self.selection.select("envVariable"); @@ -228,7 +301,7 @@ impl Container { } /// Retrieves the list of environment variables passed to commands. pub fn env_variables(&self) -> Vec { - let query = self.selection.select("envVariables"); + let mut query = self.selection.select("envVariables"); return vec![EnvVariable { proc: self.proc.clone(), @@ -242,7 +315,7 @@ impl Container { /// /// * `opt` - optional argument, see inner type for documentation, use _opts to use pub fn exec(&self) -> Container { - let query = self.selection.select("exec"); + let mut query = self.selection.select("exec"); return Container { proc: self.proc.clone(), @@ -287,16 +360,17 @@ impl Container { /// Exit code of the last executed command. Zero means success. /// Null if no command has been executed. pub async fn exit_code(&self) -> eyre::Result { - let query = self.selection.select("exitCode"); + let mut query = self.selection.select("exitCode"); query.execute(&graphql_client(&self.conn)).await } - /// Writes the container as an OCI tarball to the destination file path on the host for the specified platformVariants. + /// Writes the container as an OCI tarball to the destination file path on the host for the specified platform variants. /// Return true on success. + /// It can also publishes platform variants. /// /// # Arguments /// - /// * `path` - Host's destination path. + /// * `path` - Host's destination path (e.g., "./tarball"). /// Path can be relative to the engine's workdir or absolute. /// * `opt` - optional argument, see inner type for documentation, use _opts to use pub async fn export(&self, path: impl Into) -> eyre::Result { @@ -307,12 +381,13 @@ impl Container { query.execute(&graphql_client(&self.conn)).await } - /// Writes the container as an OCI tarball to the destination file path on the host for the specified platformVariants. + /// Writes the container as an OCI tarball to the destination file path on the host for the specified platform variants. /// Return true on success. + /// It can also publishes platform variants. /// /// # Arguments /// - /// * `path` - Host's destination path. + /// * `path` - Host's destination path (e.g., "./tarball"). /// Path can be relative to the engine's workdir or absolute. /// * `opt` - optional argument, see inner type for documentation, use _opts to use pub async fn export_opts( @@ -329,7 +404,22 @@ impl Container { query.execute(&graphql_client(&self.conn)).await } - /// Retrieves a file at the given path. Mounts are included. + /// Retrieves the list of exposed ports + pub fn exposed_ports(&self) -> Vec { + let mut query = self.selection.select("exposedPorts"); + + return vec![Port { + proc: self.proc.clone(), + selection: query, + conn: self.conn.clone(), + }]; + } + /// Retrieves a file at the given path. + /// Mounts are included. + /// + /// # Arguments + /// + /// * `path` - The path of the file to retrieve (e.g., "./README.md"). pub fn file(&self, path: impl Into) -> File { let mut query = self.selection.select("file"); @@ -341,12 +431,13 @@ impl Container { conn: self.conn.clone(), }; } - /// Initializes this container from the base image published at the given address. + /// Initializes this container from a pulled base image. /// /// # Arguments /// /// * `address` - Image's address from its registry. - /// Formatted as [host]/[user]/[repo]:[tag] (e.g. docker.io/dagger/dagger:main). + /// + /// Formatted as [host]/[user]/[repo]:[tag] (e.g., "docker.io/dagger/dagger:main"). pub fn from(&self, address: impl Into) -> Container { let mut query = self.selection.select("from"); @@ -360,7 +451,7 @@ impl Container { } /// Retrieves this container's root filesystem. Mounts are not included. pub fn fs(&self) -> Directory { - let query = self.selection.select("fs"); + let mut query = self.selection.select("fs"); return Directory { proc: self.proc.clone(), @@ -368,9 +459,21 @@ impl Container { conn: self.conn.clone(), }; } + /// Retrieves a hostname which can be used by clients to reach this container. + pub async fn hostname(&self) -> eyre::Result { + let mut query = self.selection.select("hostname"); + + query.execute(&graphql_client(&self.conn)).await + } /// A unique identifier for this container. pub async fn id(&self) -> eyre::Result { - let query = self.selection.select("id"); + let mut query = self.selection.select("id"); + + query.execute(&graphql_client(&self.conn)).await + } + /// The unique image reference which can only be retrieved immediately after the 'Container.From' call. + pub async fn image_ref(&self) -> eyre::Result { + let mut query = self.selection.select("imageRef"); query.execute(&graphql_client(&self.conn)).await } @@ -384,7 +487,7 @@ impl Container { } /// Retrieves the list of labels passed to container. pub fn labels(&self) -> Vec