forked from google/omaha-client
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.rs
138 lines (123 loc) · 4.31 KB
/
main.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright 2022 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
use argh::FromArgs;
use mock_omaha_server::{
OmahaServer, OmahaServerBuilder, PrivateKeyAndId, PrivateKeys, ResponseAndMetadata,
};
use std::collections::HashMap;
use std::net::{Ipv6Addr, SocketAddr};
use std::sync::Arc;
#[cfg(feature = "tokio")]
use tokio::sync::Mutex;
#[cfg(fasync)]
use {fuchsia_async as fasync, fuchsia_sync::Mutex};
#[derive(FromArgs)]
/// Arguments for mock-omaha-server.
struct Args {
/// A hashmap from appid to response metadata struct.
/// Example JSON argument (the minimal set of required fields per appid):
/// {
/// "appid_01": {
/// "response": "NoUpdate",
/// "check_assertion": "UpdatesEnabled",
/// "version": "0.1.2.3",
/// "codebase": "fuchsia-pkg://omaha.mock.fuchsia.com/",
/// "package_name": "update?hash=deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
/// },
/// ...
/// }
#[argh(
option,
description = "responses and metadata keyed by appid",
from_str_fn(parse_responses_by_appid),
default = "parse_responses_by_appid(EXAMPLE_RESPONSES_BY_APPID).unwrap()"
)]
responses_by_appid: HashMap<String, ResponseAndMetadata>,
#[argh(
option,
description = "private key ID",
default = "DEFAULT_PRIVATE_KEY_ID.try_into().expect(\"key parse\")"
)]
key_id: u64,
#[argh(
option,
description = "path to private key",
default = "\"mock-omaha-server/src/testing_keys/test_private_key.pem\".to_string()"
)]
key_path: String,
#[argh(option, description = "which port to serve on", default = "0")]
port: u16,
#[argh(
option,
description = "which IP address to listen on. One of '::', '::1', or anything Ipv6Addr::from_str() can interpret.",
default = "Ipv6Addr::UNSPECIFIED"
)]
listen_on: Ipv6Addr,
#[argh(
switch,
description = "if 'true', will only accept requests with CUP enabled."
)]
require_cup: bool,
}
fn parse_responses_by_appid(value: &str) -> Result<HashMap<String, ResponseAndMetadata>, String> {
serde_json::from_str(value).map_err(|e| format!("Parsing failed: {e:?}"))
}
pub const DEFAULT_PRIVATE_KEY_ID: i32 = 42;
const EXAMPLE_RESPONSES_BY_APPID: &str = r#"
{
"appid_01": {
"response": "NoUpdate",
"check_assertion": "UpdatesEnabled",
"version": "14.20230831.4.72",
"codebase": "fuchsia-pkg://omaha.mock.fuchsia.com/",
"package_name": "update?hash=deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
}
}
"#;
#[cfg_attr(fasync, fasync::run(10))]
#[cfg_attr(feature = "tokio", tokio::main)]
async fn main() -> Result<(), anyhow::Error> {
let args: Args = argh::from_env();
let (local_addr, task) = OmahaServer::start(
Arc::new(Mutex::new(
OmahaServerBuilder::default()
.responses_by_appid(args.responses_by_appid)
.private_keys(PrivateKeys {
latest: PrivateKeyAndId {
id: args.key_id,
key: std::fs::read_to_string(&args.key_path)
.unwrap_or_else(|_| {
panic!("read from key_path '{:#?}' failed", args.key_path)
})
.parse()
.expect("failed to parse key"),
},
historical: vec![],
})
.require_cup(args.require_cup)
.build()
.expect("omaha server build"),
)),
Some(SocketAddr::new(args.listen_on.into(), args.port)),
)
.await?;
println!("listening on {}", local_addr);
if let Some(t) = task {
#[cfg(fasync)]
{
t.await;
Ok(())
}
#[cfg(feature = "tokio")]
{
Ok(t.await?)
}
} else {
Ok(())
}
}