Skip to content

Commit bf49d4c

Browse files
Add bind_address config field (mozilla#2307)
* Add bind_address Use public_addr as default * Add documentation, tests for bind_address * Use correct port for tests * Link Distributed.md to DistributedConfiguration.md * Fold DistributedConfiguration.md into Distributed.md
1 parent c0a0b6e commit bf49d4c

File tree

5 files changed

+226
-11
lines changed

5 files changed

+226
-11
lines changed

docs/Distributed.md

+143
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,149 @@ the heartbeat. If a client does not have the appropriate certificate for communi
285285
securely with a server (after receiving a job allocation from the scheduler), the
286286
certificate will be requested from the scheduler.
287287

288+
## Configuration
289+
290+
Use the `--config` argument to pass the path to its configuration file to `sccache-dist`.
291+
292+
293+
### scheduler.toml
294+
295+
```toml
296+
# The socket address the scheduler will listen on. It's strongly recommended
297+
# to listen on localhost and put a HTTPS server in front of it.
298+
public_addr = "127.0.0.1:10600"
299+
300+
[client_auth]
301+
type = "token"
302+
token = "my client token"
303+
304+
[server_auth]
305+
type = "jwt_hs256"
306+
secret_key = "my secret key"
307+
```
308+
309+
310+
#### [client_auth]
311+
312+
The `[client_auth]` section can be one of (sorted by authentication method):
313+
```toml
314+
# OAuth2
315+
[client_auth]
316+
type = "mozilla"
317+
318+
client_auth = { type = "proxy_token", url = "...", cache_secs = 60 }
319+
320+
# JWT
321+
[client_auth]
322+
type = "jwt_validate"
323+
audience = "audience"
324+
issuer = "issuer"
325+
jwks_url = "..."
326+
327+
# Token
328+
[client_auth]
329+
type = "token"
330+
token = "preshared token"
331+
332+
# None
333+
[client_auth]
334+
type = "DANGEROUSLY_INSECURE"
335+
```
336+
337+
338+
#### [server_auth]
339+
340+
The `[server_auth]` section can be can be one of:
341+
```toml
342+
[server_auth]
343+
type = "jwt_hs256"
344+
secret_key = "my secret key"
345+
346+
[server_auth]
347+
type = "token"
348+
token = "preshared token"
349+
350+
[server_auth]
351+
type = "DANGEROUSLY_INSECURE"
352+
```
353+
354+
### server.toml
355+
356+
357+
```toml
358+
# This is where client toolchains will be stored.
359+
cache_dir = "/tmp/toolchains"
360+
# The maximum size of the toolchain cache, in bytes.
361+
# If unspecified the default is 10GB.
362+
#toolchain_cache_size = 10737418240
363+
# A public IP address and port that clients will use to connect to this builder.
364+
public_addr = "192.168.1.1:10501"
365+
# The socket address the builder will listen on. Falls back to public_addr.
366+
#bind_address = "0.0.0.0:10501"
367+
# The URL used to connect to the scheduler (should use https, given an ideal
368+
# setup of a HTTPS server in front of the scheduler)
369+
scheduler_url = "https://192.168.1.1"
370+
371+
[builder]
372+
type = "overlay"
373+
# The directory under which a sandboxed filesystem will be created for builds.
374+
build_dir = "/tmp/build"
375+
# The path to the bubblewrap version 0.3.0+ `bwrap` binary.
376+
bwrap_path = "/usr/bin/bwrap"
377+
378+
[scheduler_auth]
379+
type = "jwt_token"
380+
# This will be generated by the `generate-jwt-hs256-server-token` command or
381+
# provided by an administrator of the sccache cluster.
382+
token = "my server's token"
383+
```
384+
385+
386+
#### [builder]
387+
388+
The `[builder]` section can be can be one of:
389+
```toml
390+
[builder]
391+
type = "docker"
392+
393+
[builder]
394+
type = "overlay"
395+
# The directory under which a sandboxed filesystem will be created for builds.
396+
build_dir = "/tmp/build"
397+
# The path to the bubblewrap version 0.3.0+ `bwrap` binary.
398+
bwrap_path = "/usr/bin/bwrap"
399+
400+
[builder]
401+
type = "pot"
402+
# Pot filesystem root
403+
#pot_fs_root = "/opt/pot"
404+
# Reference pot cloned when creating containers
405+
#clone_from = "sccache-template"
406+
# Command to invoke when calling pot
407+
#pot_cmd = "pot"
408+
# Arguments passed to `pot clone` command
409+
#pot_clone_args = ["-i", "lo0|127.0.0.2"]
410+
411+
```
412+
413+
414+
#### [scheduler_auth]
415+
416+
The `[scheduler_auth]` section can be can be one of:
417+
```toml
418+
[scheduler_auth]
419+
type = "jwt_token"
420+
token = "my server's token"
421+
422+
[scheduler_auth]
423+
type = "token"
424+
token = "preshared token"
425+
426+
[scheduler_auth]
427+
type = "DANGEROUSLY_INSECURE"
428+
```
429+
430+
288431
# Building the Distributed Server Binaries
289432

290433
Until these binaries [are included in releases](https://github.com/mozilla/sccache/issues/393) I've put together a Docker container that can be used to easily build a release binary:

src/bin/sccache-dist/main.rs

+2
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ fn run(command: Command) -> Result<i32> {
225225
builder,
226226
cache_dir,
227227
public_addr,
228+
bind_address,
228229
scheduler_url,
229230
scheduler_auth,
230231
toolchain_cache_size,
@@ -289,6 +290,7 @@ fn run(command: Command) -> Result<i32> {
289290
.context("Failed to create sccache server instance")?;
290291
let http_server = dist::http::Server::new(
291292
public_addr,
293+
bind_address,
292294
scheduler_url.to_url(),
293295
scheduler_auth,
294296
server,

src/config.rs

+66-3
Original file line numberDiff line numberDiff line change
@@ -1165,7 +1165,7 @@ pub mod server {
11651165
.collect()
11661166
}
11671167

1168-
#[derive(Debug, Serialize, Deserialize)]
1168+
#[derive(Debug, Serialize, Deserialize, PartialEq)]
11691169
#[serde(tag = "type")]
11701170
#[serde(deny_unknown_fields)]
11711171
pub enum BuilderType {
@@ -1189,7 +1189,7 @@ pub mod server {
11891189
},
11901190
}
11911191

1192-
#[derive(Debug, Serialize, Deserialize)]
1192+
#[derive(Debug, Serialize, Deserialize, PartialEq)]
11931193
#[serde(tag = "type")]
11941194
#[serde(deny_unknown_fields)]
11951195
pub enum SchedulerAuth {
@@ -1201,12 +1201,13 @@ pub mod server {
12011201
Token { token: String },
12021202
}
12031203

1204-
#[derive(Debug, Serialize, Deserialize)]
1204+
#[derive(Debug, Serialize, Deserialize, PartialEq)]
12051205
#[serde(deny_unknown_fields)]
12061206
pub struct Config {
12071207
pub builder: BuilderType,
12081208
pub cache_dir: PathBuf,
12091209
pub public_addr: SocketAddr,
1210+
pub bind_address: Option<SocketAddr>,
12101211
pub scheduler_url: HTTPUrl,
12111212
pub scheduler_auth: SchedulerAuth,
12121213
#[serde(default = "default_toolchain_cache_size")]
@@ -1594,3 +1595,65 @@ no_credentials = true
15941595
}
15951596
)
15961597
}
1598+
1599+
#[test]
1600+
#[cfg(feature = "dist-server")]
1601+
fn server_toml_parse() {
1602+
use server::BuilderType;
1603+
use server::SchedulerAuth;
1604+
const CONFIG_STR: &str = r#"
1605+
# This is where client toolchains will be stored.
1606+
cache_dir = "/tmp/toolchains"
1607+
# The maximum size of the toolchain cache, in bytes.
1608+
# If unspecified the default is 10GB.
1609+
toolchain_cache_size = 10737418240
1610+
# A public IP address and port that clients will use to connect to this builder.
1611+
public_addr = "192.168.1.1:10501"
1612+
# The socket address the builder will listen on.
1613+
bind_address = "0.0.0.0:10501"
1614+
# The URL used to connect to the scheduler (should use https, given an ideal
1615+
# setup of a HTTPS server in front of the scheduler)
1616+
scheduler_url = "https://192.168.1.1"
1617+
1618+
[builder]
1619+
type = "overlay"
1620+
# The directory under which a sandboxed filesystem will be created for builds.
1621+
build_dir = "/tmp/build"
1622+
# The path to the bubblewrap version 0.3.0+ `bwrap` binary.
1623+
bwrap_path = "/usr/bin/bwrap"
1624+
1625+
[scheduler_auth]
1626+
type = "jwt_token"
1627+
# This will be generated by the `generate-jwt-hs256-server-token` command or
1628+
# provided by an administrator of the sccache cluster.
1629+
token = "my server's token"
1630+
"#;
1631+
1632+
let server_config: server::Config = toml::from_str(CONFIG_STR).expect("Is valid toml.");
1633+
assert_eq!(
1634+
server_config,
1635+
server::Config {
1636+
builder: BuilderType::Overlay {
1637+
build_dir: PathBuf::from("/tmp/build"),
1638+
bwrap_path: PathBuf::from("/usr/bin/bwrap"),
1639+
},
1640+
cache_dir: PathBuf::from("/tmp/toolchains"),
1641+
public_addr: "192.168.1.1:10501"
1642+
.parse()
1643+
.expect("Public address must be valid socket address"),
1644+
bind_address: Some(
1645+
"0.0.0.0:10501"
1646+
.parse()
1647+
.expect("Bind address must be valid socket address")
1648+
),
1649+
1650+
scheduler_url: parse_http_url("https://192.168.1.1")
1651+
.map(|url| { HTTPUrl::from_url(url) })
1652+
.expect("Scheduler url must be valid url str"),
1653+
scheduler_auth: SchedulerAuth::JwtToken {
1654+
token: "my server's token".to_owned()
1655+
},
1656+
toolchain_cache_size: 10737418240,
1657+
}
1658+
)
1659+
}

src/dist/http.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ mod server {
870870
}
871871

872872
pub struct Server<S> {
873-
public_addr: SocketAddr,
873+
bind_address: SocketAddr,
874874
scheduler_url: reqwest::Url,
875875
scheduler_auth: String,
876876
// HTTPS pieces all the builders will use for connection encryption
@@ -887,6 +887,7 @@ mod server {
887887
impl<S: dist::ServerIncoming + 'static> Server<S> {
888888
pub fn new(
889889
public_addr: SocketAddr,
890+
bind_address: Option<SocketAddr>,
890891
scheduler_url: reqwest::Url,
891892
scheduler_auth: String,
892893
handler: S,
@@ -899,7 +900,7 @@ mod server {
899900
let server_nonce = ServerNonce::new();
900901

901902
Ok(Self {
902-
public_addr,
903+
bind_address: bind_address.unwrap_or(public_addr),
903904
scheduler_url,
904905
scheduler_auth,
905906
cert_digest,
@@ -913,7 +914,7 @@ mod server {
913914

914915
pub fn start(self) -> Result<Infallible> {
915916
let Self {
916-
public_addr,
917+
bind_address,
917918
scheduler_url,
918919
scheduler_auth,
919920
cert_digest,
@@ -963,10 +964,10 @@ mod server {
963964
}
964965
});
965966

966-
info!("Server listening for clients on {}", public_addr);
967+
info!("Server listening for clients on {}", bind_address);
967968
let request_count = atomic::AtomicUsize::new(0);
968969

969-
let server = rouille::Server::new_ssl(public_addr, move |request| {
970+
let server = rouille::Server::new_ssl(bind_address, move |request| {
970971
let req_id = request_count.fetch_add(1, atomic::Ordering::SeqCst);
971972
trace!("Req {} ({}): {:?}", req_id, request.remote_addr(), request);
972973
let response = (|| router!(request,

tests/harness/mod.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ fn sccache_server_cfg(
195195
},
196196
cache_dir: Path::new(CONFIGS_CONTAINER_PATH).join(relpath),
197197
public_addr: SocketAddr::new(server_ip, SERVER_PORT),
198+
bind_address: Some(SocketAddr::from(([0, 0, 0, 0], SERVER_PORT))),
198199
scheduler_url,
199200
scheduler_auth: sccache::config::server::SchedulerAuth::Token {
200201
token: DIST_SERVER_TOKEN.to_owned(),
@@ -409,9 +410,14 @@ impl DistSystem {
409410
listener.local_addr().unwrap()
410411
};
411412
let token = create_server_token(ServerId::new(server_addr), DIST_SERVER_TOKEN);
412-
let server =
413-
dist::http::Server::new(server_addr, self.scheduler_url().to_url(), token, handler)
414-
.unwrap();
413+
let server = dist::http::Server::new(
414+
server_addr,
415+
Some(SocketAddr::from(([0, 0, 0, 0], server_addr.port()))),
416+
self.scheduler_url().to_url(),
417+
token,
418+
handler,
419+
)
420+
.unwrap();
415421
let pid = match unsafe { nix::unistd::fork() }.unwrap() {
416422
ForkResult::Parent { child } => {
417423
self.server_pids.push(child);

0 commit comments

Comments
 (0)