1#![allow(clippy::doc_markdown)] use std::fmt::Write;
18use std::process::Command;
19
20use crate::{
21 Application, DORIS_CONTAINER_HOST, DORIS_CONTAINER_QUERY_PORT, HummockInMemoryStrategy,
22 STARROCKS_CONTAINER_HOST, STARROCKS_CONTAINER_QUERY_PORT, ServiceConfig, add_hummock_backend,
23};
24
25pub fn generate_risedev_env(services: &Vec<ServiceConfig>) -> String {
29 let mut env = String::new();
30 for item in services {
31 match item {
32 ServiceConfig::ComputeNode(c) => {
33 {
36 let mut cmd = Command::new("compute-node");
37 if add_hummock_backend(
38 "dummy",
39 c.provide_opendal.as_ref().unwrap(),
40 c.provide_minio.as_ref().unwrap(),
41 c.provide_aws_s3.as_ref().unwrap(),
42 c.provide_moat.as_ref().unwrap(),
43 HummockInMemoryStrategy::Disallowed,
44 &mut cmd,
45 )
46 .is_ok()
47 {
48 writeln!(
49 env,
50 "RW_HUMMOCK_URL=\"{}\"",
51 cmd.get_args().nth(1).unwrap().to_str().unwrap()
52 )
53 .unwrap();
54 }
55 }
56
57 {
59 let meta_node = &c.provide_meta_node.as_ref().unwrap()[0];
60 writeln!(
61 env,
62 "RW_META_ADDR=\"http://{}:{}\"",
63 meta_node.address, meta_node.port
64 )
65 .unwrap();
66 }
67 }
68 ServiceConfig::Frontend(c) => {
69 let listen_address = &c.listen_address;
70 writeln!(
71 env,
72 "RISEDEV_RW_FRONTEND_LISTEN_ADDRESS=\"{listen_address}\"",
73 )
74 .unwrap();
75 let port = &c.port;
76 writeln!(env, "RISEDEV_RW_FRONTEND_PORT=\"{port}\"",).unwrap();
77 }
78 ServiceConfig::Kafka(c) => {
79 let brokers = format!("{}:{}", c.address, c.port);
80 writeln!(env, r#"RISEDEV_KAFKA_BOOTSTRAP_SERVERS="{brokers}""#,).unwrap();
81 writeln!(env, r#"RISEDEV_KAFKA_WITH_OPTIONS_COMMON="connector='kafka',properties.bootstrap.server='{brokers}'""#).unwrap();
82 writeln!(env, r#"RPK_BROKERS="{brokers}""#).unwrap();
83 }
84 ServiceConfig::SchemaRegistry(c) => {
85 let url = format!("http://{}:{}", c.address, c.port);
86 writeln!(env, r#"RISEDEV_SCHEMA_REGISTRY_URL="{url}""#,).unwrap();
87 writeln!(env, r#"RPK_REGISTRY_HOSTS="{url}""#).unwrap();
88 }
89 ServiceConfig::Pulsar(c) => {
90 writeln!(
94 env,
95 r#"PULSAR_BROKER_URL="pulsar://{}:{}""#,
96 c.address, c.broker_port
97 )
98 .unwrap();
99 writeln!(
100 env,
101 r#"PULSAR_HTTP_URL="http://{}:{}""#,
102 c.address, c.http_port
103 )
104 .unwrap();
105 }
106 ServiceConfig::Redis(c) => {
107 let host = &c.address;
108 let port = &c.port;
109 let url = format!("redis://{host}:{port}/");
110 writeln!(env, r#"REDIS_HOST="{host}""#).unwrap();
111 writeln!(env, r#"REDIS_PORT="{port}""#).unwrap();
112 writeln!(env, r#"RISEDEV_REDIS_URL="{url}""#).unwrap();
113 if !c.user_managed {
114 writeln!(env, r#"REDIS_CONTAINER="risedev-{}""#, c.id).unwrap();
115 }
116 writeln!(
117 env,
118 r#"RISEDEV_REDIS_WITH_OPTIONS_COMMON="connector='redis',redis.url='{url}'""#,
119 )
120 .unwrap();
121 }
122 ServiceConfig::ClickHouse(c) => {
123 let host = &c.address;
124 let http_port = &c.http_port;
125 let native_port = &c.native_port;
126 let user = &c.user;
127 let password = &c.password;
128 let database = &c.database;
129 let url = format!("http://{host}:{http_port}");
130 writeln!(env, r#"CLICKHOUSE_HOST="{host}""#).unwrap();
131 writeln!(env, r#"CLICKHOUSE_HTTP_PORT="{http_port}""#).unwrap();
132 writeln!(env, r#"CLICKHOUSE_NATIVE_PORT="{native_port}""#).unwrap();
133 writeln!(env, r#"CLICKHOUSE_USER="{user}""#).unwrap();
134 writeln!(env, r#"CLICKHOUSE_PASSWORD="{password}""#).unwrap();
135 writeln!(env, r#"CLICKHOUSE_DATABASE="{database}""#).unwrap();
136 writeln!(env, r#"RISEDEV_CLICKHOUSE_URL="{url}""#).unwrap();
137 if !c.user_managed {
138 writeln!(env, r#"CLICKHOUSE_CONTAINER="risedev-{}""#, c.id).unwrap();
139 }
140 writeln!(
141 env,
142 r#"RISEDEV_CLICKHOUSE_WITH_OPTIONS_COMMON="connector='clickhouse',clickhouse.url='{url}',clickhouse.user='{user}',clickhouse.password='{password}',clickhouse.database='{database}'""#,
143 )
144 .unwrap();
145 }
146 ServiceConfig::Doris(c) => {
147 let host = &c.address;
148 let http_port = &c.http_port;
149 let query_port = &c.query_port;
150 let user = &c.user;
151 let password = &c.password;
152 let database = &c.database;
153 let admin_user = &c.admin_user;
154 let admin_password = &c.admin_password;
155 let url = format!("http://{host}:{http_port}");
156 writeln!(env, r#"DORIS_HOST="{host}""#).unwrap();
157 writeln!(env, r#"DORIS_HTTP_PORT="{http_port}""#).unwrap();
158 writeln!(env, r#"DORIS_QUERY_PORT="{query_port}""#).unwrap();
159 writeln!(env, r#"DORIS_USER="{user}""#).unwrap();
160 writeln!(env, r#"DORIS_PASSWORD="{password}""#).unwrap();
161 writeln!(env, r#"DORIS_DATABASE="{database}""#).unwrap();
162 writeln!(env, r#"DORIS_ADMIN_USER="{admin_user}""#).unwrap();
163 writeln!(env, r#"DORIS_ADMIN_PASSWORD="{admin_password}""#).unwrap();
164 if !c.user_managed {
165 writeln!(env, r#"DORIS_CONTAINER="risedev-{}""#, c.id).unwrap();
166 writeln!(env, r#"DORIS_CONTAINER_HOST="{DORIS_CONTAINER_HOST}""#).unwrap();
167 writeln!(
168 env,
169 r#"DORIS_CONTAINER_QUERY_PORT="{DORIS_CONTAINER_QUERY_PORT}""#
170 )
171 .unwrap();
172 }
173 writeln!(
174 env,
175 r#"RISEDEV_DORIS_WITH_OPTIONS_COMMON="connector='doris',doris.url='{url}',doris.user='{user}',doris.password='{password}',doris.database='{database}'""#,
176 )
177 .unwrap();
178 }
179 ServiceConfig::Starrocks(c) => {
180 let host = &c.address;
181 let http_port = &c.http_port;
182 let query_port = &c.query_port;
183 let user = &c.user;
184 let password = &c.password;
185 let database = &c.database;
186 let admin_user = &c.admin_user;
187 let admin_password = &c.admin_password;
188 let database_is_disposable = !c.user_managed || c.database_is_disposable;
189
190 writeln!(env, r#"STARROCKS_HOST="{host}""#).unwrap();
191 writeln!(env, r#"STARROCKS_HTTP_PORT="{http_port}""#).unwrap();
192 writeln!(env, r#"STARROCKS_QUERY_PORT="{query_port}""#).unwrap();
193 writeln!(env, r#"STARROCKS_USER="{user}""#).unwrap();
194 writeln!(env, r#"STARROCKS_PASSWORD="{password}""#).unwrap();
195 writeln!(env, r#"STARROCKS_DATABASE="{database}""#).unwrap();
196 writeln!(env, r#"STARROCKS_ADMIN_USER="{admin_user}""#).unwrap();
197 writeln!(env, r#"STARROCKS_ADMIN_PASSWORD="{admin_password}""#).unwrap();
198 writeln!(
199 env,
200 r#"STARROCKS_DATABASE_IS_DISPOSABLE="{database_is_disposable}""#
201 )
202 .unwrap();
203 if !c.user_managed {
204 writeln!(env, r#"STARROCKS_CONTAINER="risedev-{}""#, c.id).unwrap();
205 writeln!(
206 env,
207 r#"STARROCKS_CONTAINER_HOST="{STARROCKS_CONTAINER_HOST}""#
208 )
209 .unwrap();
210 writeln!(
211 env,
212 r#"STARROCKS_CONTAINER_QUERY_PORT="{STARROCKS_CONTAINER_QUERY_PORT}""#
213 )
214 .unwrap();
215 }
216 writeln!(
217 env,
218 r#"RISEDEV_STARROCKS_WITH_OPTIONS_COMMON="connector='starrocks',starrocks.host='{host}',starrocks.mysqlport='{query_port}',starrocks.httpport='{http_port}',starrocks.user='{user}',starrocks.password='{password}',starrocks.database='{database}'""#,
219 )
220 .unwrap();
221 }
222 ServiceConfig::MySql(c) if c.application != Application::Metastore => {
223 let host = &c.address;
224 let port = &c.port;
225 let user = &c.user;
226 let password = &c.password;
227 writeln!(env, r#"MYSQL_HOST="{host}""#,).unwrap();
229 writeln!(env, r#"MYSQL_TCP_PORT="{port}""#,).unwrap();
230 writeln!(env, r#"RISEDEV_MYSQL_USER="{user}""#,).unwrap();
234 writeln!(env, r#"MYSQL_PWD="{password}""#,).unwrap();
235 writeln!(env, r#"RISEDEV_MYSQL_WITH_OPTIONS_COMMON="connector='mysql-cdc',hostname='{host}',port='{port}'""#,).unwrap();
238 }
239 ServiceConfig::Pubsub(c) => {
240 let address = &c.address;
241 let port = &c.port;
242 writeln!(env, r#"PUBSUB_EMULATOR_HOST="{address}:{port}""#,).unwrap();
243 writeln!(env, r#"RISEDEV_PUBSUB_WITH_OPTIONS_COMMON="connector='google_pubsub',pubsub.emulator_host='{address}:{port}'""#,).unwrap();
244 }
245 ServiceConfig::Postgres(c) => {
246 let host = &c.address;
247 let port = &c.port;
248 let user = &c.user;
249 let password = &c.password;
250 let database = &c.database;
251 writeln!(env, r#"PGHOST="{host}""#,).unwrap();
253 writeln!(env, r#"PGPORT="{port}""#,).unwrap();
254 writeln!(env, r#"PGUSER="{user}""#,).unwrap();
255 writeln!(env, r#"PGPASSWORD="{password}""#,).unwrap();
256 writeln!(env, r#"PGDATABASE="{database}""#,).unwrap();
257 writeln!(
258 env,
259 r#"RISEDEV_POSTGRES_WITH_OPTIONS_COMMON="connector='postgres-cdc',hostname='{host}',port='{port}'""#,
260 )
261 .unwrap();
262 }
263 ServiceConfig::Oracle(c) => {
264 let host = &c.address;
265 let port = &c.port;
266 let user = &c.user;
267 let password = &c.password;
268 let database = &c.database;
269 let pdb = &c.pdb;
270 writeln!(env, r#"ORACLE_HOST="{host}""#).unwrap();
271 writeln!(env, r#"ORACLE_PORT="{port}""#).unwrap();
272 writeln!(env, r#"ORACLE_USER="{user}""#).unwrap();
273 writeln!(env, r#"ORACLE_PASSWORD="{password}""#).unwrap();
274 writeln!(env, r#"ORACLE_DATABASE="{database}""#).unwrap();
275 writeln!(env, r#"ORACLE_PDB="{pdb}""#).unwrap();
276 if !c.user_managed {
277 writeln!(env, r#"ORACLE_CONTAINER="risedev-{}""#, c.id).unwrap();
278 }
279 writeln!(
280 env,
281 r#"RISEDEV_ORACLE_WITH_OPTIONS_COMMON="connector='oracle-cdc',hostname='{host}',port='{port}',username='{user}',password='{password}',database.name='{database}',database.pdb.name='{pdb}'""#,
282 )
283 .unwrap();
284 }
285 ServiceConfig::SqlServer(c) => {
286 let host = &c.address;
287 let port = &c.port;
288 let user = &c.user;
289 let password = &c.password;
290 let database = &c.database;
291 writeln!(env, r#"SQLCMDSERVER="{host}""#,).unwrap();
293 writeln!(env, r#"SQLCMDPORT="{port}""#,).unwrap();
294 writeln!(env, r#"SQLCMDUSER="{user}""#,).unwrap();
295 writeln!(env, r#"SQLCMDPASSWORD="{password}""#,).unwrap();
296 writeln!(env, r#"SQLCMDDBNAME="{database}""#,).unwrap();
297 writeln!(
298 env,
299 r#"RISEDEV_SQLSERVER_WITH_OPTIONS_COMMON="connector='sqlserver-cdc',hostname='{host}',port='{port}',username='{user}',password='{password}',database.name='{database}'""#,
300 )
301 .unwrap();
302 }
303 ServiceConfig::MongoDb(c) => {
304 let host = &c.address;
305 let port = &c.port;
306 let url = format!("mongodb://{host}:{port}/?replicaSet=rs0");
307 writeln!(env, r#"MONGODB_HOST="{host}""#).unwrap();
308 writeln!(env, r#"MONGODB_PORT="{port}""#).unwrap();
309 writeln!(env, r#"MONGODB_URL="{url}""#).unwrap();
310 if !c.user_managed {
311 writeln!(env, r#"MONGODB_CONTAINER="risedev-{}""#, c.id).unwrap();
312 }
313 writeln!(
314 env,
315 r#"RISEDEV_MONGODB_WITH_OPTIONS_COMMON="connector='mongodb',mongodb.url='{url}'""#,
316 )
317 .unwrap();
318 }
319 ServiceConfig::ElasticSearch(c) => {
320 let host = &c.address;
321 let port = &c.port;
322 let user = &c.user;
323 let password = &c.password;
324 let url = format!("http://{host}:{port}");
325 writeln!(env, r#"ELASTICSEARCH_HOST="{host}""#).unwrap();
326 writeln!(env, r#"ELASTICSEARCH_PORT="{port}""#).unwrap();
327 writeln!(env, r#"ELASTICSEARCH_USER="{user}""#).unwrap();
328 writeln!(env, r#"ELASTICSEARCH_PASSWORD="{password}""#).unwrap();
329 writeln!(env, r#"RISEDEV_ELASTICSEARCH_URL="{url}""#).unwrap();
330 writeln!(
331 env,
332 r#"RISEDEV_ELASTICSEARCH_WITH_OPTIONS_COMMON="connector='elasticsearch',url='{url}',username='{user}',password='{password}'""#,
333 )
334 .unwrap();
335 writeln!(env, r#"SEARCH_SINK_CONNECTOR="elasticsearch""#).unwrap();
336 writeln!(env, r#"SEARCH_SINK_CONNECTION_TYPE="elasticsearch""#).unwrap();
337 writeln!(env, r#"SEARCH_SINK_URL="{url}""#).unwrap();
338 writeln!(env, r#"SEARCH_SINK_USER="{user}""#).unwrap();
339 writeln!(env, r#"SEARCH_SINK_PASSWORD="{password}""#).unwrap();
340 writeln!(
341 env,
342 r#"SEARCH_SINK_WITH_OPTIONS_COMMON="connector='elasticsearch',url='{url}',username='{user}',password='{password}'""#,
343 )
344 .unwrap();
345 writeln!(
346 env,
347 r#"SEARCH_SINK_ROUTE_WITH_OPTIONS="connector='elasticsearch',connection=es_conn""#,
348 )
349 .unwrap();
350 }
351 ServiceConfig::OpenSearch(c) => {
352 let host = &c.address;
353 let port = &c.port;
354 let user = &c.user;
355 let password = &c.password;
356 let url = format!("http://{host}:{port}");
357 writeln!(env, r#"OPENSEARCH_HOST="{host}""#).unwrap();
358 writeln!(env, r#"OPENSEARCH_PORT="{port}""#).unwrap();
359 writeln!(env, r#"OPENSEARCH_USER="{user}""#).unwrap();
360 writeln!(env, r#"OPENSEARCH_PASSWORD="{password}""#).unwrap();
361 writeln!(env, r#"RISEDEV_OPENSEARCH_URL="{url}""#).unwrap();
362 writeln!(
363 env,
364 r#"RISEDEV_OPENSEARCH_WITH_OPTIONS_COMMON="connector='opensearch',url='{url}',username='{user}',password='{password}'""#,
365 )
366 .unwrap();
367 writeln!(env, r#"SEARCH_SINK_CONNECTOR="opensearch""#).unwrap();
368 writeln!(env, r#"SEARCH_SINK_CONNECTION_TYPE="elasticsearch""#).unwrap();
369 writeln!(env, r#"SEARCH_SINK_URL="{url}""#).unwrap();
370 writeln!(env, r#"SEARCH_SINK_USER="{user}""#).unwrap();
371 writeln!(env, r#"SEARCH_SINK_PASSWORD="{password}""#).unwrap();
372 writeln!(
373 env,
374 r#"SEARCH_SINK_WITH_OPTIONS_COMMON="connector='opensearch',url='{url}',username='{user}',password='{password}'""#,
375 )
376 .unwrap();
377 writeln!(
378 env,
379 r#"SEARCH_SINK_ROUTE_WITH_OPTIONS="connector='opensearch',url='{url}',username='{user}',password='{password}'""#,
380 )
381 .unwrap();
382 }
383 ServiceConfig::Nats(c) => {
384 let server_url = format!("nats://{}:{}", c.address, c.port);
385 writeln!(env, r#"NATS_SERVER_URL="{server_url}""#).unwrap();
386 writeln!(env, r#"RISEDEV_NATS_SERVER_URL="{server_url}""#).unwrap();
387 writeln!(
388 env,
389 r#"RISEDEV_NATS_WITH_OPTIONS_COMMON="connector='nats',server_url='{server_url}'""#,
390 )
391 .unwrap();
392 }
393 ServiceConfig::Mqtt(c) => {
394 let url = format!("tcp://{}:{}", c.address, c.port);
395 writeln!(env, r#"MQTT_URL="{url}""#).unwrap();
396 writeln!(env, r#"RISEDEV_MQTT_URL="{url}""#).unwrap();
397 writeln!(
398 env,
399 r#"RISEDEV_MQTT_WITH_OPTIONS_COMMON="connector='mqtt',url='{url}'""#,
400 )
401 .unwrap();
402 }
403 ServiceConfig::Minio(c) => {
404 let endpoint = format!("http://{}:{}", c.address, c.port);
405 writeln!(env, r#"RISEDEV_MINIO_ENDPOINT="{endpoint}""#).unwrap();
406 writeln!(env, r#"RISEDEV_MINIO_ACCESS_KEY="{0}""#, c.root_user).unwrap();
407 writeln!(env, r#"RISEDEV_MINIO_SECRET_KEY="{0}""#, c.root_password).unwrap();
408
409 writeln!(
410 env,
411 r#"RISEDEV_DELTALAKE_LOCATION="s3a://deltalake/deltalake-test""#
412 )
413 .unwrap();
414 writeln!(env, r#"RISEDEV_DELTALAKE_S3_ENDPOINT="{endpoint}""#).unwrap();
415 writeln!(env, r#"RISEDEV_DELTALAKE_S3_REGION="us-east-1""#).unwrap();
416 writeln!(env, r#"RISEDEV_DELTALAKE_S3_ACCESS_KEY="{0}""#, c.root_user).unwrap();
417 writeln!(
418 env,
419 r#"RISEDEV_DELTALAKE_S3_SECRET_KEY="{0}""#,
420 c.root_password
421 )
422 .unwrap();
423 }
424 ServiceConfig::MetaNode(meta_node_config) => {
425 writeln!(
426 env,
427 r#"RISEDEV_RW_META_DASHBOARD_ADDR="http://{}:{}""#,
428 meta_node_config.address, meta_node_config.dashboard_port
429 )
430 .unwrap();
431 }
432 ServiceConfig::Lakekeeper(c) => {
433 let base_url = format!("http://{}:{}", c.address, c.port);
434 let catalog_url = format!("{}/catalog", base_url);
435 writeln!(env, r#"RISEDEV_LAKEKEEPER_URL="{base_url}""#,).unwrap();
436 writeln!(env, r#"LAKEKEEPER_CATALOG_URL="{catalog_url}""#,).unwrap();
437 writeln!(env, r#"RISEDEV_LAKEKEEPER_WITH_OPTIONS_COMMON="connector='iceberg',catalog.type='rest',catalog.uri='{catalog_url}'""#,).unwrap();
438 }
439 ServiceConfig::Moto(c) => {
440 let endpoint = format!("http://{}:{}", c.address, c.port);
441 let glue_access_key = "my_access_id";
442 let glue_secret_key = "my_secret_key";
443 writeln!(env, r#"RISEDEV_MOTO_ENDPOINT="{endpoint}""#).unwrap();
444 writeln!(env, r#"RISEDEV_GLUE_ENDPOINT="{endpoint}""#).unwrap();
445 writeln!(env, r#"RW_TEST_GLUE_ENDPOINT="{endpoint}""#).unwrap();
446 writeln!(env, r#"RW_TEST_GLUE_ACCESS_KEY="{glue_access_key}""#).unwrap();
447 writeln!(env, r#"RW_TEST_GLUE_SECRET_KEY="{glue_secret_key}""#).unwrap();
448
449 if let Some(minio_configs) = &c.provide_minio
450 && let Some(minio) = minio_configs.first()
451 {
452 let s3_endpoint = format!("http://{}:{}", minio.address, minio.port);
453 let warehouse_path = format!("s3://{}/iceberg", minio.hummock_bucket);
454 writeln!(env, r#"RW_TEST_GLUE_S3_ENDPOINT="{s3_endpoint}""#).unwrap();
455 writeln!(env, r#"RW_TEST_GLUE_S3_ACCESS_KEY="{0}""#, minio.root_user).unwrap();
456 writeln!(
457 env,
458 r#"RW_TEST_GLUE_S3_SECRET_KEY="{0}""#,
459 minio.root_password
460 )
461 .unwrap();
462 writeln!(env, r#"RW_TEST_GLUE_WAREHOUSE_PATH="{warehouse_path}""#).unwrap();
463 writeln!(env, r#"RISEDEV_GLUE_RUST_WITH_OPTIONS_COMMON="connector='iceberg',catalog.type='glue_rust',catalog.uri='{endpoint}',glue.endpoint='{endpoint}',glue.region='us-east-1',glue.access.key='{glue_access_key}',glue.secret.key='{glue_secret_key}',warehouse.path='{warehouse_path}',s3.endpoint='{s3_endpoint}',s3.region='us-east-1',s3.access.key='{0}',s3.secret.key='{1}',s3.path.style.access='true'""#, minio.root_user, minio.root_password).unwrap();
464 writeln!(env, r#"RISEDEV_GLUE_JNI_WITH_OPTIONS_COMMON="connector='iceberg',catalog.type='glue',catalog.uri='{endpoint}',glue.endpoint='{endpoint}',glue.region='us-east-1',glue.access.key='{glue_access_key}',glue.secret.key='{glue_secret_key}',warehouse.path='{warehouse_path}',s3.endpoint='{s3_endpoint}',s3.region='us-east-1',s3.access.key='{0}',s3.secret.key='{1}',s3.path.style.access='true'""#, minio.root_user, minio.root_password).unwrap();
465 }
466 }
467 _ => {}
468 }
469 }
470 env
471}