Skip to content

Commit

Permalink
Use volume_mounts as binds rather than mounts (#566)
Browse files Browse the repository at this point in the history
* Use 'binds' interface to mount host directories

* tests pass
  • Loading branch information
paulgb committed Jan 22, 2024
1 parent 0ea14a9 commit a77959c
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 27 deletions.
13 changes: 12 additions & 1 deletion cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ enum Command {
/// instead of spawning a new one.
#[clap(long)]
lock: Option<String>,

/// Optional volume to mount, in the form `host_path:container_path`.
#[clap(long)]
mount: Option<String>,
},
Status {
backend: Option<String>,
Expand Down Expand Up @@ -353,6 +357,7 @@ async fn main() -> Result<()> {
port,
env,
lock,
mount,
} => {
let env: Result<HashMap<String, String>> = env
.iter()
Expand All @@ -366,6 +371,12 @@ async fn main() -> Result<()> {
.collect();
let env = env?;

let volume_mounts = if let Some(mount) = mount {
vec![mount]
} else {
Vec::new()
};

let result = nats
.request(&ScheduleRequest {
backend_id: None,
Expand All @@ -379,7 +390,7 @@ async fn main() -> Result<()> {
resource_limits: ResourceLimits::default(),
pull_policy: Default::default(),
port,
volume_mounts: Vec::new(),
volume_mounts,
},
require_bearer_token: false,
lock: lock.map(|lock| lock.try_into().unwrap()),
Expand Down
3 changes: 1 addition & 2 deletions controller/src/http_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ use plane_core::{
Never,
};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::{collections::HashMap, net::SocketAddr, sync::Arc, time::Duration};
use tower_http::cors::{Any, CorsLayer};

Expand Down Expand Up @@ -56,7 +55,7 @@ struct HttpSpawnRequest {
#[serde(default = "HashMap::default")]
env: HashMap<String, String>,
#[serde(default = "Vec::default")]
volume_mounts: Vec<Value>,
volume_mounts: Vec<String>,
}

impl HttpSpawnRequest {
Expand Down
6 changes: 2 additions & 4 deletions core/src/messages/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use bollard::container::{LogOutput, MemoryStatsStats, Stats};
use chrono::{DateTime, Utc};
use plane_core_nats_macros::{self, TypedMessage};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use serde_with::serde_as;
use serde_with::{DurationMicroSeconds, DurationSeconds};
use std::{
Expand Down Expand Up @@ -316,10 +315,9 @@ pub struct DockerExecutableConfig {
/// Port to serve on. If this is not set, Plane uses port 8080.
pub port: Option<u16>,

/// Volume mounts to add to the container.
/// Schema: https://pkg.go.dev/github.com/docker/docker@v20.10.22+incompatible/api/types/mount#Mount
/// Volume mounts to add to the container, as a list of <host path>:<container path> strings.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub volume_mounts: Vec<Value>,
pub volume_mounts: Vec<String>,
}

impl DockerExecutableConfig {
Expand Down
11 changes: 2 additions & 9 deletions dev/tests/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ use plane_dev::{
};
use plane_drone::{agent::AgentOptions, database::DroneDatabase, ip::IpSource};
use plane_drone::{agent::AgentSupervisors, config::DockerConfig};
use serde_json::json;
use std::net::IpAddr;
use std::time::Duration;
use tokio::time::Instant;
Expand Down Expand Up @@ -766,10 +765,7 @@ async fn attempt_to_spawn_with_disallowed_volume_mount() {

let mut request = base_spawn_request().await;
request.drone_id = drone_id.clone();
request.executable.volume_mounts = vec![json!({
"source": "/foo",
"target": "/bar",
})];
request.executable.volume_mounts = vec!["foo:bar".to_string()];

let mut state_subscription = BackendStateSubscription::new(&connection, &request.backend_id)
.await
Expand Down Expand Up @@ -806,10 +802,7 @@ async fn attempt_to_spawn_with_allowed_volume_mount() {

let mut request = base_spawn_request().await;
request.drone_id = drone_id.clone();
request.executable.volume_mounts = vec![json!({
"Type": "tmpfs",
"Target": "/bar",
})];
request.executable.volume_mounts = vec!["/tmp/foo:/bar".to_string()];

let mut state_subscription = BackendStateSubscription::new(&connection, &request.backend_id)
.await
Expand Down
15 changes: 4 additions & 11 deletions drone/src/agent/engines/docker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use bollard::{
},
image::CreateImageOptions,
models::{HostConfig, ResourcesUlimits},
service::{DeviceRequest, HostConfigLogConfig, Mount},
service::{DeviceRequest, HostConfigLogConfig},
system::EventsOptions,
Docker, API_DEFAULT_VERSION,
};
Expand Down Expand Up @@ -190,19 +190,12 @@ impl DockerInterface {
None
};

let mounts = if self.allow_volume_mounts {
let c: std::result::Result<Vec<Mount>, serde_json::Error> = executable_config
.volume_mounts
.iter()
.map(|value| serde_json::from_value(value.clone()))
.collect();

Some(c?)
let binds = if self.allow_volume_mounts {
Some(executable_config.volume_mounts.clone())
} else {
if !executable_config.volume_mounts.is_empty() {
return Err(anyhow::anyhow!("Spawn attempt named volume mounts, but these are not enabled on this drone. Set `allow_volume_mounts` to true in the `docker` section of the Plane config to enable."));
}

None
};

Expand All @@ -226,6 +219,7 @@ impl DockerInterface {
.collect(),
),
host_config: Some(HostConfig {
binds,
network_mode: self.network.clone(),
runtime: self.runtime.clone(),
memory: executable_config.resource_limits.memory_limit_bytes,
Expand Down Expand Up @@ -264,7 +258,6 @@ impl DockerInterface {
.collect()
}),
device_requests,
mounts,

log_config: self.syslog.as_ref().map(|d| HostConfigLogConfig {
typ: Some("syslog".to_string()),
Expand Down
33 changes: 33 additions & 0 deletions sample-config/auth/ca-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
-----BEGIN CERTIFICATE-----
MIIFoTCCA4mgAwIBAgIUQQ0ocElIKKyXUAUGX9ZeKKAlu68wDQYJKoZIhvcNAQEL
BQAwYDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMREwDwYDVQQHDAhOZXcgWW9y
azEOMAwGA1UECgwFUGxhbmUxDDAKBgNVBAsMA09yZzETMBEGA1UEAwwKcGxhbmUu
dGVzdDAeFw0yNDAxMjExMzQ2NTFaFw0zNDAxMTgxMzQ2NTFaMGAxCzAJBgNVBAYT
AlVTMQswCQYDVQQIDAJOWTERMA8GA1UEBwwITmV3IFlvcmsxDjAMBgNVBAoMBVBs
YW5lMQwwCgYDVQQLDANPcmcxEzARBgNVBAMMCnBsYW5lLnRlc3QwggIiMA0GCSqG
SIb3DQEBAQUAA4ICDwAwggIKAoICAQDtxqX3Z5cNJkS/3iFuNx56pKR8H+qAEMSj
S3Bln1SrOSUd3E5xRev1udoY0lmETpaMfjOcy4A4sojfYCLrVmqZfw8J1t3RlGrJ
kmH1oOu5t+G0wMIx8l6QsBWCst+cHfRQRbYxfTO1Q14XcDR0xmxeFBkrPt0/Kv0P
zjXCQJE+tLfoo8L2ZaHjqbYR9xHuN21UhA8re6C144ldulJ/a4lTZNA+DP7rDa+R
UZcKLEcahPcNMpabdT1VGsQoCYOPhrOu8ZqEdzHL4kiuLSSi1LKUs/UNxtiAYTlC
N+ytTGlVII1Xg6Q/ZTArbAcfj8M669SUGdkA+UzuwH3bkpx2euRgLVoi3b/j39h1
cBkyefD1gPlZ6aEXW2t4yBMePTtdeYpgPa7EiCRgHyqESDvu2CilvgWMuRg5rpTE
Or57deiXSfnOcDX0TfGv5WtZo0fcYmpN8MxVnSZeon15XY4XgS9hSpJysy/kP6OB
mm3FESEKdyAmpq9LNZJoF3evcpE2s6pUlTpaRdc3h9yQfeKFfeiZWuPWqXN9WcAU
pFLEytuHsWDhHUOeNxt/MRp17ha/lhih0/6PWctbcRmrxp5diqJ9/38WcgjaLPws
xm9vHWCAMaJXgnFMCVdR1mSNNWDmbBy2L5Q95QqP44bnxXdZgkD7PU/pN7n54Emb
cC5ODL4ZXQIDAQABo1MwUTAdBgNVHQ4EFgQUQbUgamW3bAvEAKspUvdN6D2IBF8w
HwYDVR0jBBgwFoAUQbUgamW3bAvEAKspUvdN6D2IBF8wDwYDVR0TAQH/BAUwAwEB
/zANBgkqhkiG9w0BAQsFAAOCAgEAdu6j6heE2H3CvSIGq/E+NJtaf9pS3RKfMVPR
s/9Ce5/jakFQeaKqnpHIboSWSXzDk7htr+6QgtwSQIUDUzscXfToQB+JJKOR4/Ke
Banz4SlRCi1qPKxVh6+E/9lfLUN9ux7xl+n9NNr8zydpFSUODyJlWXBjPyoELTxX
NsOTSwZSlDQrPSaYHDmpavG6otTDFStUgiPjnCj2iofUP+wgw9pSNQSZ5qbyhyw2
XvWqVYBbYUR16Z5+56ANYXpTAMg22Senn9/ZLas6zimtNJ/jde4ccRTAKBXoYU8m
8tUUsGGe6bpNhqadBWKDiNtsyAHAPJom4aPEgkpAv9nIlMhC6XPvJ2tnwpqI0pF1
lLWF5U68WaQ8xWhIg/QEXIrgUxudv7t66GO5dDVsj4jTF9H1Nlr4f4VD0vLXbdyu
DqM+n3zuNWq1ifonqdpcpf+LDt6ierk8YrUWu2PLT72PgeyZ1W+b0PbQaLFSmppE
//ZbiA0y5qLT7mKaTXzbnrBJ3tFXV+J9+cLFDOBUIAPu/97Z3OUbzVcWG0NhdIw1
RhIKnsYnDb7nJhqaKzjMX234rc23AU65IUrVGidlIAvIBXHIwXeIeg+GjPN35Cdx
RIk45ljPyGJWpLxSxFaErCwVbDokD2hmzdNXy0zCVwrc3EpdB7+LGMb9Lw90AesB
DQgpzeo=
-----END CERTIFICATE-----
41 changes: 41 additions & 0 deletions sample-config/auth/gencert.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/sh

# Create CA key + cert
openssl req \
-nodes \
-x509 \
-newkey rsa:4096 \
-keyout ca-key.pem \
-out ca-cert.pem \
-sha256 \
-days 3650 \
-subj "/C=US/ST=NY/L=New York/O=Plane/OU=Org/CN=plane.test"

# Create a certificate signing request.
openssl req \
-nodes \
-new \
-newkey rsa:4096 \
-keyout site-key.pem \
-out site-cert.csr \
-subj "/C=US/ST=NY/L=New York/O=Plane/OU=Org/CN=plane.test"

echo "subjectAltName = DNS:*.plane.test" > extfile

# Sign the certificate.
openssl x509 \
-req \
-in site-cert.csr \
-days 365 \
-CA ca-cert.pem \
-CAkey ca-key.pem \
-CAcreateserial \
-out site-cert.pem \
-extfile extfile

# Clean up
rm \
extfile \
ca-cert.srl \
ca-key.pem \
site-cert.csr
31 changes: 31 additions & 0 deletions sample-config/auth/site-cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFaTCCA1GgAwIBAgIUb8CYy3ceAE4STmZfmwAjMkZ52VcwDQYJKoZIhvcNAQEL
BQAwYDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMREwDwYDVQQHDAhOZXcgWW9y
azEOMAwGA1UECgwFUGxhbmUxDDAKBgNVBAsMA09yZzETMBEGA1UEAwwKcGxhbmUu
dGVzdDAeFw0yNDAxMjExMzQ2NTJaFw0yNTAxMjAxMzQ2NTJaMGAxCzAJBgNVBAYT
AlVTMQswCQYDVQQIDAJOWTERMA8GA1UEBwwITmV3IFlvcmsxDjAMBgNVBAoMBVBs
YW5lMQwwCgYDVQQLDANPcmcxEzARBgNVBAMMCnBsYW5lLnRlc3QwggIiMA0GCSqG
SIb3DQEBAQUAA4ICDwAwggIKAoICAQDLH12JBRzP2+duSh+4jfbchdL12+bpk1Db
TMo7WeWyEuw3TiyFc16uN8gYun/VbaS6KIKPGl8rEg5Z4b10kb4vVNKdk2xVAVra
gRlGIwpOGliwxivibrjbWsraUJGyY+CqfxCK9p8wW81Ucoyo65teH/dtDb+xySNC
iV9vWGl0pgSPD1n3vQyX+mUzyGcdvEt50eCr9Omqqe3OWp+E++MhBAAc+ZrIc5LA
iLchdGxJifewCHcslCWIBybn/Z03HDNAtlRsovblgKAN+8soqIDBk5uFui4nl0h/
zb0vleEH5/HjidhnHRX17yMG6q7UN3kuJGQ/UuJywlST8/rORfEPQqiu/9i72xro
ffW3pRXHip/SFBA3b0NqxK1dEkM+QMtpHnZTEr6x34IZ7Vw8LHiwhn45lD1PI2/f
AQAO07efeboCIvHiOaAInnd7aPVRklhLYzmbv1jyWeRy84/kRp7qtFt4ngeKlqqb
uMdKO183Nb06hUeRGErg4x59oJG3dbMFSJAsOD64x644nHOkibAiBiqLtmiCmwOG
VAabg8bL9kKruTfZSqpLAijgWkmAw48uiOUfxqZLH1XEhgCG0scwDJXbbtR2nhm3
m6H5G9SoGpDq/tLhy15Q365RsNi6PvOu7mwJpi9/erplchvpTlx5PM7lDRaTCrLR
mVObc6FjowIDAQABoxswGTAXBgNVHREEEDAOggwqLnBsYW5lLnRlc3QwDQYJKoZI
hvcNAQELBQADggIBAJgcSyxFI9M8Gc3g9Znh5nruMQDUuGmY+vRiRMIjylrTUCp9
hPGIy9jQzuCnqebx8oj8zWwSXCygwwTWvIqLr+aoa4RqpgRtX+WqK15LdtB03B8b
nWt6pNeuNDyGqFEN310aaAslwedAErEDCh7AHbkJNt3pD2RqFTR29bl5ydwcHqjr
OL0RcSz3EQy38YsC68SvPixebgK6AiAyWFeNxq8/JMOCY5y8PSZPeYlkPrYker5g
shd35uHODMCHLs33NQ0Y4iJv8YhswKeZuckepj+eUAoEQME0i3e7bEzPHfsFlY1Z
LZsZShReP2wPyYqRr+YaC/W5xuf9fcp/lqMi9CecP5oBcINsbRY24qhyrXw6c0nH
tcnwWrOr17WLwLlDkUmq5IWTntp26VnVwCT4ZzjfkopAx2xGAxrlVXcWMapqw/C9
fEOT/Y5aahRh2rCAeogntuHcRAul0YEwZPYWILeMZnjnBsjMJoIDUbuMqGQmB51a
QkuFjRCL7JM/0I9aHKnR1/1SSbwEC5Y8VxII40hoT2uiebj8hyzCiTm0S4E4+Ajy
Z/2ZoZqDPshzJF5LlcbMGgA+gT06hHVV8om+mSezgvmk5sr+AsuFhDfZF41ahhHP
BRoaZ4nCROO5Cg0rYGpwy4+AwMy//G7u6lq5rCbvv0nhEWtfSV7GXkinLHzQ
-----END CERTIFICATE-----
52 changes: 52 additions & 0 deletions sample-config/auth/site-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
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
hIsDwbYMspk8BKNPPrIJA3NLI8GcqnU=
-----END PRIVATE KEY-----
3 changes: 3 additions & 0 deletions sample-config/dev-config/drone.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ hosts = ["127.0.0.1"]
[agent]
ip = "127.0.0.1"

[agent.docker]
allow_volume_mounts = true

[proxy]
bind_ip = "127.0.0.1"
http_port = "8080"
Expand Down

0 comments on commit a77959c

Please sign in to comment.