Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
resolves #8 Very experimental Linux containers support
Browse files Browse the repository at this point in the history
slonopotamus committed Feb 14, 2022

Verified

This commit was signed with the committer’s verified signature.
leninmehedy Lenin Mehedy
1 parent 4bd139e commit a02a942
Showing 7 changed files with 408 additions and 11 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
@@ -7,10 +7,11 @@ For a detailed view of what has changed, refer to the {uri-project}/commits/main

== Unreleased

* Automatically attempt to restart service in case startup fails https://github.com/slonopotamus/stevedore/issues/22[#22]
* Automatically attempt to restart service in case startup fails. https://github.com/slonopotamus/stevedore/issues/22[#22]
* Make service depend on EventLog
* Fix event text not shown properly in Windows Event Viewer
* Workaround failure to install under SYSTEM account https://github.com/slonopotamus/stevedore/issues/10[#10]
* Workaround failure to install under SYSTEM account. https://github.com/slonopotamus/stevedore/issues/10[#10]
* Add experimental support for Linux Containers. https://github.com/slonopotamus/stevedore/issues/8[#8]

== 0.0.5 (2022-02-08) - @slonopotamus

11 changes: 11 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -8,9 +8,20 @@ homepage = "https://github.com/slonopotamus/stevedore"
repository = "https://github.com/slonopotamus/stevedore.git"
license = "Apache-2.0"

[dependencies]
directories = "4.0"
msgbox = "0.6"
named-lock = "0.1"
trayicon = { version = "0.1", features = ["winit"] }
winapi = { version = "0.3" }
winit = "0.25"
wslapi = "0.1"

[build-dependencies]
bytes = "1.1"
const_format = "0.2"
flate2 = "1"
reqwest = { version = "0.11", features = ["blocking"] }
sha2 = "0.10"
winres = "0.1"
zip = "0.5"
8 changes: 5 additions & 3 deletions README.adoc
Original file line number Diff line number Diff line change
@@ -14,13 +14,14 @@ This project aims to be a frictionless Docker distribution for Windows.

Stevedore can be used as a replacement for `DockerMsftProvider`, Docker Desktop or Mirantis Container Runtime.

Only Windows containers are supported currently.
Linux containers support is https://github.com/slonopotamus/stevedore/issues/8[under development].
Windows Containers are fully supported.

Linux Containers support is in _experimental mode_.

== Supported OSes

* Windows 10, 11
* Windows Server 2016, 2019, 2022
* Windows Server 2016, 2019, 2022 (no Linux containers due to lack of WSL2)

== Installation

@@ -64,6 +65,7 @@ If you only want to install specific Stevedore features, use `/ADDLOCAL=Feature1
It allows running containers with https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/hyperv-container#process-isolation[process isolation].
* `FeatureHyperV` installs Hyper-V support.
It allows running containers with https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/hyperv-container#hyper-v-isolation[Hyper-V isolation].
* `FeatureLinuxContainers` installs Linux Containers support.

You can also pass custom installation properties to Stevedore installer using `/PROPERTY=value` syntax.

113 changes: 113 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -3,8 +3,11 @@ use std::fs::{create_dir_all, File};
use std::io;
use std::io::{Cursor, Write};
use std::path::{Path, PathBuf};
use std::process::Command;

use const_format::formatcp;
use flate2::write::GzEncoder;
use flate2::Compression;
use sha2::{Digest, Sha256};
use zip::ZipArchive;

@@ -14,6 +17,13 @@ const DOCKER_WIN64_URL: &str =
formatcp!("https://download.docker.com/win/static/stable/x86_64/docker-{DOCKER_VERSION}.zip");
const DOCKER_WIN64_SHA: &str = "bd3775ada72492aa1f3c2edb3e81663bd128b9d4f6752ef75953a6af7c219c81";

const DOCKER_LINUX_URL: &str =
formatcp!("https://download.docker.com/linux/static/stable/x86_64/docker-{DOCKER_VERSION}.tgz");
const DOCKER_LINUX_SHA: &str = "ee9b5be14e54bf92f48c82c2e6a83fbdd1c5329e8f247525a9ed2fe90d9f89a5";

const ALPINE_URL: &str = "https://dl-cdn.alpinelinux.org/alpine/v3.15/releases/x86_64/alpine-minirootfs-3.15.0-x86_64.tar.gz";
const ALPINE_SHA: &str = "ec7ec80a96500f13c189a6125f2dbe8600ef593b87fc4670fe959dc02db727a2";

const DOCKER_COMPOSE_VERSION: &str = "2.2.3";
const DOCKER_COMPOSE_URL: &str = formatcp!("https://github.com/docker/compose/releases/download/v{DOCKER_COMPOSE_VERSION}/docker-compose-windows-x86_64.exe");
const DOCKER_COMPOSE_SHA: &str = "7ed35698f85d2d67855934b834845461cd454d40f9a07ee72deb88085af0890e";
@@ -22,6 +32,11 @@ const DOCKER_SCAN_VERSION: &str = "0.17.0";
const DOCKER_SCAN_URL: &str = formatcp!("https://github.com/docker/scan-cli-plugin/releases/download/v{DOCKER_SCAN_VERSION}/docker-scan_windows_amd64.exe");
const DOCKER_SCAN_SHA: &str = "d6e19957813f28970c5552aa2683277e187a1b7327b3af90194e8f04f1d04021";

const DOCKER_WSL_PROXY_VERSION: &str = "0.0.1";
const DOCKER_WSL_PROXY_URL: &str = formatcp!("https://github.com/slonopotamus/docker-wsl-proxy/releases/download/{DOCKER_WSL_PROXY_VERSION}/docker-wsl-proxy.exe");
const DOCKER_WSL_PROXY_SHA: &str =
"8df71c496052427787cbf8df37fa9aff625086702990a74a1864e11700bfee02";

fn get_dest_dir() -> PathBuf {
//<root or manifest path>/target/<profile>/
let manifest_dir_string = env::var("CARGO_MANIFEST_DIR").unwrap();
@@ -81,12 +96,110 @@ fn build_docker_scan_plugin(dest_dir: &Path) {
download_file(DOCKER_SCAN_URL, DOCKER_SCAN_SHA, &dest_path);
}

fn build_docker_wsl_proxy(dest_dir: &Path) {
let dest_path = dest_dir.join("docker-wsl-proxy.exe");
download_file(DOCKER_WSL_PROXY_URL, DOCKER_WSL_PROXY_SHA, &dest_path);
}

fn run_cmd(cmd: &mut Command) -> String {
let output = cmd.output().unwrap();
assert!(
output.status.success(),
"{:?} returned {:?}\nSTDOUT:{}\nSTDERR:\n{}",
cmd,
output.status,
std::str::from_utf8(&output.stdout).unwrap(),
std::str::from_utf8(&output.stderr).unwrap(),
);
String::from(std::str::from_utf8(&output.stdout).unwrap().trim())
}

/**
1. You can't use Docker in this function because GitHub Actions doesn't support nested virtualization
2. You can't use WSL2 in this function because Windows Server only has WSL1
*/
fn build_wsl_tarball(dest_dir: &Path) {
const DISTRIBUTION_NAME: &str = "stevedore";
const STAGING_DISTRIBUTION_NAME: &str = formatcp!("{DISTRIBUTION_NAME}-staging");

// Download Alpine Linux rootfs
let alpine_tgz = dest_dir.join(formatcp!("alpine.tar.gz"));
download_file(ALPINE_URL, ALPINE_SHA, &alpine_tgz);

// Download Linux Docker binaries
let docker_tgz = dest_dir.join("docker.tar.gz");
download_file(DOCKER_LINUX_URL, DOCKER_LINUX_SHA, &docker_tgz);

// Remove WSL distribution in case it already exists
let _ = Command::new("wsl")
.arg("--unregister")
.arg(STAGING_DISTRIBUTION_NAME)
.output();

// Import Alpine Linux rootfs into WSL
run_cmd(
Command::new("wsl")
.arg("--import")
.arg(STAGING_DISTRIBUTION_NAME)
.arg(dest_dir)
.arg(alpine_tgz),
);

// Add docker into WSL
// TODO: Instead, use Docker binaries we just downloaded
run_cmd(
Command::new("wsl")
.arg("--distribution")
.arg(STAGING_DISTRIBUTION_NAME)
.arg("--")
.arg("apk")
.arg("add")
.arg("--no-cache")
.arg("docker")
.arg("socat"),
);

let uncompressed_tarball_path = dest_dir.join(formatcp!("{DISTRIBUTION_NAME}.tar"));
let compressed_tarball_path = dest_dir.join(formatcp!("{DISTRIBUTION_NAME}.tar.gz"));

// Export tarball from WSL
run_cmd(
Command::new("wsl")
.arg("--export")
.arg(STAGING_DISTRIBUTION_NAME)
.arg(&uncompressed_tarball_path),
);

// Compress tarball
// TODO: pipe directly from wsl --export
{
let mut uncompressed_tarball = File::open(uncompressed_tarball_path).unwrap();
let compressed_tarball = File::create(compressed_tarball_path).unwrap();
let mut encoder = GzEncoder::new(compressed_tarball, Compression::default());
std::io::copy(&mut uncompressed_tarball, &mut encoder).unwrap();
}

// Cleanup WSL
run_cmd(
Command::new("wsl")
.arg("--unregister")
.arg(STAGING_DISTRIBUTION_NAME),
);
}

fn main() {
let dest_dir = get_dest_dir();

build_wsl_tarball(&dest_dir);
build_docker(&dest_dir);
build_docker_compose(&dest_dir);
build_docker_scan_plugin(&dest_dir);
build_docker_wsl_proxy(&dest_dir);

let mut res = winres::WindowsResource::new();
res.set_icon("resources/stevedore.ico");
res.compile().unwrap();

println!("cargo:rerun-if-changed=resources/stevedore.ico");
println!("cargo:rerun-if-changed=build.rs");
}
6 changes: 5 additions & 1 deletion choco/stevedore.nuspec
Original file line number Diff line number Diff line change
@@ -8,7 +8,11 @@
<projectUrl>https://github.com/slonopotamus/stevedore</projectUrl>
<tags>containers docker foss</tags>
<summary>Docker distribution for Windows that Just Works</summary>
<description>Stevedore aims to be a frictionless Docker distribution for Windows. Stevedore currently only supports Windows containers.</description>
<description>
Stevedore aims to be a frictionless Docker distribution for Windows.
Windows Containers are fully supported.
Linux Containers support is in EXPERIMENTAL mode.
</description>
<licenseUrl>https://github.com/slonopotamus/stevedore/blob/main/LICENSE</licenseUrl>
<releaseNotes>https://github.com/slonopotamus/stevedore/releases/tag/{{ version }}</releaseNotes>
<packageSourceUrl>https://github.com/slonopotamus/stevedore/tree/main/choco</packageSourceUrl>
Loading

0 comments on commit a02a942

Please sign in to comment.