risedev/
risedev_env.rs

1// Copyright 2025 RisingWave Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#![allow(clippy::doc_markdown)] // RiseDev
16
17use std::fmt::Write;
18use std::process::Command;
19
20use crate::{Application, HummockInMemoryStrategy, ServiceConfig, add_hummock_backend};
21
22/// Generate environment variables (put in file `.risingwave/config/risedev-env`)
23/// from the given service configurations to be used by future
24/// RiseDev commands, like `risedev ctl` or `risedev psql` ().
25pub fn generate_risedev_env(services: &Vec<ServiceConfig>) -> String {
26    let mut env = String::new();
27    for item in services {
28        match item {
29            ServiceConfig::ComputeNode(c) => {
30                // RW_HUMMOCK_URL
31                // If the cluster is launched without a shared storage, we will skip this.
32                {
33                    let mut cmd = Command::new("compute-node");
34                    if add_hummock_backend(
35                        "dummy",
36                        c.provide_opendal.as_ref().unwrap(),
37                        c.provide_minio.as_ref().unwrap(),
38                        c.provide_aws_s3.as_ref().unwrap(),
39                        HummockInMemoryStrategy::Disallowed,
40                        &mut cmd,
41                    )
42                    .is_ok()
43                    {
44                        writeln!(
45                            env,
46                            "RW_HUMMOCK_URL=\"{}\"",
47                            cmd.get_args().nth(1).unwrap().to_str().unwrap()
48                        )
49                        .unwrap();
50                    }
51                }
52
53                // RW_META_ADDR
54                {
55                    let meta_node = &c.provide_meta_node.as_ref().unwrap()[0];
56                    writeln!(
57                        env,
58                        "RW_META_ADDR=\"http://{}:{}\"",
59                        meta_node.address, meta_node.port
60                    )
61                    .unwrap();
62                }
63            }
64            ServiceConfig::Frontend(c) => {
65                let listen_address = &c.listen_address;
66                writeln!(
67                    env,
68                    "RISEDEV_RW_FRONTEND_LISTEN_ADDRESS=\"{listen_address}\"",
69                )
70                .unwrap();
71                let port = &c.port;
72                writeln!(env, "RISEDEV_RW_FRONTEND_PORT=\"{port}\"",).unwrap();
73            }
74            ServiceConfig::Kafka(c) => {
75                let brokers = format!("{}:{}", c.address, c.port);
76                writeln!(env, r#"RISEDEV_KAFKA_BOOTSTRAP_SERVERS="{brokers}""#,).unwrap();
77                writeln!(env, r#"RISEDEV_KAFKA_WITH_OPTIONS_COMMON="connector='kafka',properties.bootstrap.server='{brokers}'""#).unwrap();
78                writeln!(env, r#"RPK_BROKERS="{brokers}""#).unwrap();
79            }
80            ServiceConfig::SchemaRegistry(c) => {
81                let url = format!("http://{}:{}", c.address, c.port);
82                writeln!(env, r#"RISEDEV_SCHEMA_REGISTRY_URL="{url}""#,).unwrap();
83                writeln!(env, r#"RPK_REGISTRY_HOSTS="{url}""#).unwrap();
84            }
85            ServiceConfig::Pulsar(c) => {
86                // These 2 names are NOT defined by Pulsar, but by us.
87                // The `pulsar-admin` CLI uses a `PULSAR_CLIENT_CONF` file with `brokerServiceUrl` and `webServiceUrl`
88                // It may be used by our upcoming `PulsarCat` #21401
89                writeln!(
90                    env,
91                    r#"PULSAR_BROKER_URL="pulsar://{}:{}""#,
92                    c.address, c.broker_port
93                )
94                .unwrap();
95                writeln!(
96                    env,
97                    r#"PULSAR_HTTP_URL="http://{}:{}""#,
98                    c.address, c.http_port
99                )
100                .unwrap();
101            }
102            ServiceConfig::MySql(c) if c.application != Application::Metastore => {
103                let host = &c.address;
104                let port = &c.port;
105                let user = &c.user;
106                let password = &c.password;
107                // These envs are used by `mysql` cli.
108                writeln!(env, r#"MYSQL_HOST="{host}""#,).unwrap();
109                writeln!(env, r#"MYSQL_TCP_PORT="{port}""#,).unwrap();
110                // Note: There's no env var for the username read by `mysql` cli. Here we set
111                // `RISEDEV_MYSQL_USER`, which will be read by `e2e_test/commands/mysql` when
112                // running `risedev slt`, as a wrapper of `mysql` cli.
113                writeln!(env, r#"RISEDEV_MYSQL_USER="{user}""#,).unwrap();
114                writeln!(env, r#"MYSQL_PWD="{password}""#,).unwrap();
115                // Note: user and password are not included in the common WITH options.
116                // It's expected to create another dedicated user for the source.
117                writeln!(env, r#"RISEDEV_MYSQL_WITH_OPTIONS_COMMON="connector='mysql-cdc',hostname='{host}',port='{port}'""#,).unwrap();
118            }
119            ServiceConfig::Pubsub(c) => {
120                let address = &c.address;
121                let port = &c.port;
122                writeln!(env, r#"PUBSUB_EMULATOR_HOST="{address}:{port}""#,).unwrap();
123                writeln!(env, r#"RISEDEV_PUBSUB_WITH_OPTIONS_COMMON="connector='google_pubsub',pubsub.emulator_host='{address}:{port}'""#,).unwrap();
124            }
125            ServiceConfig::Postgres(c) => {
126                let host = &c.address;
127                let port = &c.port;
128                let user = &c.user;
129                let password = &c.password;
130                let database = &c.database;
131                // These envs are used by `postgres` cli.
132                writeln!(env, r#"PGHOST="{host}""#,).unwrap();
133                writeln!(env, r#"PGPORT="{port}""#,).unwrap();
134                writeln!(env, r#"PGUSER="{user}""#,).unwrap();
135                writeln!(env, r#"PGPASSWORD="{password}""#,).unwrap();
136                writeln!(env, r#"PGDATABASE="{database}""#,).unwrap();
137                writeln!(
138                    env,
139                    r#"RISEDEV_POSTGRES_WITH_OPTIONS_COMMON="connector='postgres-cdc',hostname='{host}',port='{port}'""#,
140                )
141                .unwrap();
142            }
143            ServiceConfig::SqlServer(c) => {
144                let host = &c.address;
145                let port = &c.port;
146                let user = &c.user;
147                let password = &c.password;
148                let database = &c.database;
149                // These envs are used by `sqlcmd`.
150                writeln!(env, r#"SQLCMDSERVER="{host}""#,).unwrap();
151                writeln!(env, r#"SQLCMDPORT="{port}""#,).unwrap();
152                writeln!(env, r#"SQLCMDUSER="{user}""#,).unwrap();
153                writeln!(env, r#"SQLCMDPASSWORD="{password}""#,).unwrap();
154                writeln!(env, r#"SQLCMDDBNAME="{database}""#,).unwrap();
155                writeln!(
156                    env,
157                    r#"RISEDEV_SQLSERVER_WITH_OPTIONS_COMMON="connector='sqlserver-cdc',hostname='{host}',port='{port}',username='{user}',password='{password}',database.name='{database}'""#,
158                )
159                .unwrap();
160            }
161            ServiceConfig::MetaNode(meta_node_config) => {
162                writeln!(
163                    env,
164                    r#"RISEDEV_RW_META_DASHBOARD_ADDR="http://{}:{}""#,
165                    meta_node_config.address, meta_node_config.dashboard_port
166                )
167                .unwrap();
168            }
169            _ => {}
170        }
171    }
172    env
173}