Skip to content

Commit

Permalink
Support for --add-host (railwayapp#1119)
Browse files Browse the repository at this point in the history
* Add example

* Attempt to add tests

* Add hosts works, validated by tests

* Add test to validate that the build does not work when there are no hosts attached

* Fix naming conventions

* Use the same argument as Docker

* Use the same argument as Docker

* Clean up after tests

* Clean linting

* Fix clippy linting

* add snapshot test for node fetch network

* remove build command from node-fetch-network

* update snapshot

* add back build command

* Fix package.json

* Fix build, make sure to use --network=host when providing add hosts

* Fix clippy

---------

Co-authored-by: Jake Runzer <[email protected]>
  • Loading branch information
Thijmen and coffee-cup authored Jul 26, 2024
1 parent 50711c6 commit 0e71646
Show file tree
Hide file tree
Showing 13 changed files with 587 additions and 4 deletions.
4 changes: 4 additions & 0 deletions Cargo.lock

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

169 changes: 169 additions & 0 deletions examples/node-fetch-network/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore

# Logs

logs
_.log
npm-debug.log_
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)

report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json

# Runtime data

pids
_.pid
_.seed
\*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover

lib-cov

# Coverage directory used by tools like istanbul

coverage
\*.lcov

# nyc test coverage

.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)

.grunt

# Bower dependency directory (https://bower.io/)

bower_components

# node-waf configuration

.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)

build/Release

# Dependency directories

node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)

web_modules/

# TypeScript cache

\*.tsbuildinfo

# Optional npm cache directory

.npm

# Optional eslint cache

.eslintcache

# Optional stylelint cache

.stylelintcache

# Microbundle cache

.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history

.node_repl_history

# Output of 'npm pack'

\*.tgz

# Yarn Integrity file

.yarn-integrity

# dotenv environment variable files

.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# parcel-bundler cache (https://parceljs.org/)

.cache
.parcel-cache

# Next.js build output

.next
out

# Nuxt.js build / generate output

.nuxt
dist

# Gatsby files

.cache/

# Comment in the public line in if your project uses Gatsby and not Next.js

# https://nextjs.org/blog/next-9-1#public-directory-support

# public

# vuepress build output

.vuepress/dist

# vuepress v2.x temp and cache directory

.temp
.cache

# Docusaurus cache and generated files

.docusaurus

# Serverless directories

.serverless/

# FuseBox cache

.fusebox/

# DynamoDB Local files

.dynamodb/

# TernJS port file

.tern-port

# Stores VSCode versions used for testing VSCode extensions

.vscode-test

# yarn v2

.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.\*
23 changes: 23 additions & 0 deletions examples/node-fetch-network/fetchData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import fetch from 'node-fetch';

const url = process.env.REMOTE_URL;

if (!url) {
console.error('REMOTE_URL is not defined in the environment variables.');
process.exit(1);
}

fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(`Network response was not ok: ${response.statusText}`);
}
return response.statusText;
})
.then(data => {
console.log('Fetched data:', data);
})
.catch(error => {
console.error('Fetching data failed:', error);
process.exit(1);
});
17 changes: 17 additions & 0 deletions examples/node-fetch-network/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"type": "module",
"name": "your-project-name",
"version": "1.0.0",
"description": "A project to fetch data from a remote URL",
"main": "index.js",
"scripts": {
"build": "echo $REMOTE_URL && node fetchData.js",
"start": "node fetchData.js"
},
"dependencies": {
"dotenv": "^10.0.0",
"node-fetch": "^3.0.0"
},
"author": "Your Name",
"license": "MIT"
}
59 changes: 59 additions & 0 deletions examples/node-fetch-network/pnpm-lock.yaml

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

6 changes: 6 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ enum Commands {
#[arg(long)]
docker_host: Option<String>,

/// Adds hosts to the Docker build
#[arg(long, global = true)]
add_host: Vec<String>,

/// Specify if Docker client should verify the TLS (Transport Layer Security) certificates
#[arg(long)]
docker_tls_verify: Option<String>,
Expand Down Expand Up @@ -255,6 +259,7 @@ async fn main() -> Result<()> {
cache_from,
docker_host,
docker_tls_verify,
add_host,
inline_cache,
no_error_without_start,
cpu_quota,
Expand Down Expand Up @@ -288,6 +293,7 @@ async fn main() -> Result<()> {
no_error_without_start,
incremental_cache_image,
cpu_quota,
add_host,
memory,
verbose,
};
Expand Down
59 changes: 59 additions & 0 deletions src/nixpacks/builder/docker/docker_helper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::error::Error;
use std::process::Command;
use std::str;

#[derive(Serialize, Deserialize, Debug)]
struct ContainerInfoFromDocker {
#[serde(rename = "Name")]
name: String,
#[serde(rename = "IPv4Address")]
ipv4_address: String,
}

pub struct ContainerInfo {
pub name: String,
pub ipv4_address: String,
pub ipv4_address_without_mask: String,
}

type Containers = HashMap<String, ContainerInfo>;

pub struct DockerHelper {}

impl DockerHelper {
pub fn containers_in_network(network: &str) -> Result<Containers, Box<dyn Error>> {
let output = Command::new("docker")
.arg("network")
.arg("inspect")
.arg(network)
.arg("-f")
.arg("{{json .Containers}}")
.output()?;

if output.status.success() {
let containers_string = str::from_utf8(&output.stdout)?;
let containers: HashMap<String, ContainerInfoFromDocker> =
serde_json::from_str(containers_string)?;

let mut vec = Vec::new();
for info in containers.values() {
let ipv4 = info.ipv4_address.split('/').next().unwrap();
let container_info = ContainerInfo {
name: info.name.clone(),
ipv4_address: info.ipv4_address.clone(),
ipv4_address_without_mask: ipv4.to_string(),
};
vec.push(container_info);
}

return Ok(vec
.into_iter()
.map(|info| (info.name.clone(), info))
.collect());
}

Err("Docker command failed".into())
}
}
10 changes: 9 additions & 1 deletion src/nixpacks/builder/docker/docker_image_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,22 @@ impl DockerImageBuilder {
.arg("build")
.arg(&output.root)
.arg("-f")
.arg(&output.get_absolute_path("Dockerfile"))
.arg(output.get_absolute_path("Dockerfile"))
.arg("-t")
.arg(name);

if self.options.verbose {
docker_build_cmd.arg("--progress=plain");
}

if !self.options.add_host.is_empty() {
for host in &self.options.add_host {
docker_build_cmd.arg("--add-host").arg(host);
}

docker_build_cmd.arg("--network").arg("host");
}

if self.options.quiet {
docker_build_cmd.arg("--quiet");
}
Expand Down
Loading

0 comments on commit 0e71646

Please sign in to comment.