Skip to content

Commit

Permalink
allow specifying a dockerfile to use for a target
Browse files Browse the repository at this point in the history
  • Loading branch information
Emilgardis committed Apr 3, 2022
1 parent 39c4d5b commit be84a9d
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 4 deletions.
53 changes: 53 additions & 0 deletions .github/actions/image-publish/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Publish Image
description: Publishes images from artifact
inputs:
targets:
description: 'Target'
required: true

runs:
using: composite
steps:
- name: Read changelog
id: changelog-reader
uses: mindsers/changelog-reader-action@v2.0.0
with:
validation_depth: 10
version: ${{ (github.ref_type == 'tag' && github.ref_name) || 'Unreleased' }}
path: ./CHANGELOG.md

- name: Download artifacts
id: download-artifacts
uses: actions/download-artifact@v3
with:
path:
${{ runner.temp }}/artifacts

- name: Log into crates.io
if: steps.cargo-toml-publish.outputs.value != 'false' && github.event_name != 'pull_request'
uses: actions-rs/cargo@v1
with:
command: login
args: -- ${{ inputs.cargo-registry-token }}

- name: Create GitHub release
if: >
github.event_name == 'push' && (
github.ref == format('refs/heads/{0}', github.event.repository.default_branch) ||
startsWith(github.ref, 'refs/tags/v')
)
uses: softprops/action-gh-release@v1
with:
tag: ${{ steps.changelog-reader.outputs.version }}
name: ${{ steps.changelog-reader.outputs.version }}
body: ${{ steps.changelog-reader.outputs.changes }}
prerelease: ${{ steps.changelog-reader.outputs.status == 'prereleased' }}
draft: ${{ steps.changelog-reader.outputs.status == 'unreleased' }}
files: |
${{ steps.download-artifacts.outputs.download-path }}/*/*
- name: Publish crate
uses: actions-rs/cargo@v1
with:
command: publish
args: ${{ !startsWith(github.ref, 'refs/tags/v') && '--dry-run' || '' }}
51 changes: 51 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ which = { version = "4", default_features = false }
shell-escape = "0.1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tempfile = "3"

[target.'cfg(not(windows))'.dependencies]
nix = "0.23"
Expand Down
2 changes: 2 additions & 0 deletions docs/cross_toml.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,7 @@ volumes = ["VOL1_ARG", "VOL2_ARG"]
passthrough = ["VAR1", "VAR2"]
xargo = false
image = "test-image"
dockerfile = "./Dockerfile"
context = "."
runner = "custom-runner"
```
28 changes: 28 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ impl Environment {
self.get_target_var(target, "IMAGE")
}

fn dockerfile(&self, target: &Target) -> Option<String> {
self.get_target_var(target, "DOCKERFILE")
}

fn context(&self, target: &Target) -> Option<String> {
self.get_target_var(target, "CONTEXT")
}

fn runner(&self, target: &Target) -> Option<String> {
self.get_target_var(target, "RUNNER")
}
Expand Down Expand Up @@ -152,6 +160,26 @@ impl Config {
self.toml.as_ref().map_or(Ok(None), |t| Ok(t.image(target)))
}

pub fn dockerfile(&self, target: &Target) -> Result<Option<String>> {
let env_value = self.env.dockerfile(target);
if let Some(env_value) = env_value {
return Ok(Some(env_value));
}
self.toml
.as_ref()
.map_or(Ok(None), |t| Ok(t.dockerfile(target)))
}

pub fn context(&self, target: &Target) -> Result<Option<String>> {
let env_value = self.env.context(target);
if let Some(env_value) = env_value {
return Ok(Some(env_value));
}
self.toml
.as_ref()
.map_or(Ok(None), |t| Ok(t.context(target)))
}

pub fn runner(&self, target: &Target) -> Result<Option<String>> {
let env_value = self.env.runner(target);
if let Some(env_value) = env_value {
Expand Down
14 changes: 14 additions & 0 deletions src/cross_toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ pub struct CrossTargetConfig {
volumes: Vec<String>,
xargo: Option<bool>,
image: Option<String>,
dockerfile: Option<String>,
context: Option<String>,
runner: Option<String>,
}

Expand All @@ -55,6 +57,16 @@ impl CrossToml {
self.get_target(target).and_then(|t| t.image.clone())
}

/// Returns the `target.{}.dockerfile` part of `Cross.toml`
pub fn dockerfile(&self, target: &Target) -> Option<String> {
self.get_target(target).and_then(|t| t.dockerfile.clone())
}

/// Returns the `target.{}.context` part of `Cross.toml`
pub fn context(&self, target: &Target) -> Option<String> {
self.get_target(target).and_then(|t| t.context.clone())
}

/// Returns the `target.{}.runner` part of `Cross.toml`
pub fn runner(&self, target: &Target) -> Option<String> {
self.get_target(target).and_then(|t| t.runner.clone())
Expand Down Expand Up @@ -170,6 +182,8 @@ mod tests {
xargo: Some(false),
image: Some("test-image".to_string()),
runner: None,
dockerfile: None,
context: None,
},
);

Expand Down
50 changes: 47 additions & 3 deletions src/docker.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::io::Read;
use std::path::{Path, PathBuf};
use std::process::{Command, ExitStatus};
use std::{env, fs};
Expand Down Expand Up @@ -29,7 +30,6 @@ pub fn docker_command(subcommand: &str) -> Result<Command> {
.with_suggestion(|| "is docker or podman installed?")?;
let mut command = Command::new(ce);
command.arg(subcommand);
command.args(&["--userns", "host"]);
Ok(command)
}

Expand All @@ -45,6 +45,7 @@ pub fn register(target: &Target, verbose: bool) -> Result<()> {
};

docker_command("run")?
.args(&["--userns", "host"])
.arg("--privileged")
.arg("--rm")
.arg("ubuntu:16.04")
Expand Down Expand Up @@ -113,7 +114,7 @@ pub fn run(
let runner = config.runner(target)?;

let mut docker = docker_command("run")?;

docker.args(&["--userns", "host"]);
let validate_env_var = |var: &str| -> Result<()> {
if var.contains('=') {
bail!("environment variable names must not contain the '=' character");
Expand Down Expand Up @@ -248,8 +249,51 @@ pub fn run(
}
}

let image = if let Some(dockerfile) = config.dockerfile(target)? {
let mut docker_build = docker_command("build")?;
docker_build.current_dir(host_root);
docker_build.env("DOCKER_SCAN_SUGGEST", "false");

let iidfile_path = tempfile::NamedTempFile::new()
.wrap_err("could not create a temporary file")?
.into_temp_path();

docker_build.args(["--iidfile".as_ref(), iidfile_path.as_os_str()]);

docker_build.args(["--file", &dockerfile]);

if let Some(image) = config.image(&target)? {
docker_build.args(["--tag", &image]);
};

if let Some(context) = config.context(&target)? {
docker_build.arg(&context);
} else {
// This `.` is techically the host_root, not cwd
docker_build.arg(".");
}
docker_build
.run(verbose)
.wrap_err_with(|| format!("could not build dockerfile `{dockerfile}`"))?;

let image_name = if let Some(image) = config.image(&target)? {
image
} else {
let mut image_name = String::new();
std::fs::File::open(&iidfile_path)?.read_to_string(&mut image_name)?;
image_name
};
if image_name.is_empty() {
eyre::bail!("no image returned from docker build")
}
std::fs::remove_file(iidfile_path)?;
dbg!(image_name)
} else {
image(config, target)?
};

docker
.arg(&image(config, target)?)
.arg(image)
.args(&["sh", "-c", &format!("PATH=$PATH:/rust/bin {:?}", cmd)])
.run_and_get_status(verbose)
}
Expand Down
6 changes: 5 additions & 1 deletion src/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ pub trait CommandExt {
impl CommandExt for Command {
fn print_verbose(&self, verbose: bool) {
if verbose {
println!("+ {:?}", self);
if let Some(cwd) = self.get_current_dir() {
println!("+ {:?} {:?}", cwd, self);
} else {
println!("+ {:?}", self);
}
}
}

Expand Down

0 comments on commit be84a9d

Please sign in to comment.