|
29 | 29 | except ImportError: |
30 | 30 | CRYPTO_AVAILABLE = False |
31 | 31 |
|
32 | | -# Default whitelist file location |
| 32 | +# Default config file locations |
| 33 | +DEFAULT_CONFIG_PATH = os.path.expanduser("~/.dstack-vmm/config.json") |
33 | 34 | DEFAULT_KMS_WHITELIST_PATH = os.path.expanduser( |
34 | 35 | "~/.dstack-vmm/kms-whitelist.json") |
35 | 36 |
|
36 | 37 |
|
| 38 | +def load_config() -> Dict[str, Any]: |
| 39 | + """ |
| 40 | + Load configuration from the default config file. |
| 41 | +
|
| 42 | + Returns: |
| 43 | + Dictionary with configuration values (url, auth_user, auth_password) |
| 44 | + """ |
| 45 | + if not os.path.exists(DEFAULT_CONFIG_PATH): |
| 46 | + return {} |
| 47 | + |
| 48 | + try: |
| 49 | + with open(DEFAULT_CONFIG_PATH, 'r') as f: |
| 50 | + return json.load(f) |
| 51 | + except (json.JSONDecodeError, FileNotFoundError): |
| 52 | + return {} |
| 53 | + |
| 54 | + |
37 | 55 | def encrypt_env(envs, hex_public_key: str) -> str: |
38 | 56 | """ |
39 | 57 | Encrypts environment variables using a one-time X25519 key exchange and AES-GCM. |
@@ -1174,19 +1192,31 @@ def save_whitelist(whitelist: List[str]) -> None: |
1174 | 1192 | def main(): |
1175 | 1193 | parser = argparse.ArgumentParser(description='dstack-vmm CLI - Manage VMs') |
1176 | 1194 |
|
1177 | | - # Get default URL from environment variable or use localhost |
1178 | | - default_url = os.environ.get('DSTACK_VMM_URL', 'http://localhost:8080') |
| 1195 | + # Load config file defaults |
| 1196 | + config = load_config() |
| 1197 | + |
| 1198 | + # Priority: command line > environment variable > config file > default |
| 1199 | + default_url = os.environ.get( |
| 1200 | + 'DSTACK_VMM_URL', |
| 1201 | + config.get('url', 'http://localhost:8080')) |
| 1202 | + default_auth_user = os.environ.get( |
| 1203 | + 'DSTACK_VMM_AUTH_USER', |
| 1204 | + config.get('auth_user')) |
| 1205 | + default_auth_password = os.environ.get( |
| 1206 | + 'DSTACK_VMM_AUTH_PASSWORD', |
| 1207 | + config.get('auth_password')) |
1179 | 1208 |
|
1180 | 1209 | parser.add_argument( |
1181 | | - '--url', default=default_url, help='dstack-vmm API URL (can also be set via DSTACK_VMM_URL env var)') |
| 1210 | + '--url', default=default_url, |
| 1211 | + help='dstack-vmm API URL (can also be set via DSTACK_VMM_URL env var or config file)') |
1182 | 1212 |
|
1183 | 1213 | # Basic authentication arguments |
1184 | 1214 | parser.add_argument( |
1185 | | - '--auth-user', default=os.environ.get('DSTACK_VMM_AUTH_USER'), |
1186 | | - help='Basic auth username (can also be set via DSTACK_VMM_AUTH_USER env var)') |
| 1215 | + '--auth-user', default=default_auth_user, |
| 1216 | + help='Basic auth username (can also be set via DSTACK_VMM_AUTH_USER env var or config file)') |
1187 | 1217 | parser.add_argument( |
1188 | | - '--auth-password', default=os.environ.get('DSTACK_VMM_AUTH_PASSWORD'), |
1189 | | - help='Basic auth password (can also be set via DSTACK_VMM_AUTH_PASSWORD env var)') |
| 1218 | + '--auth-password', default=default_auth_password, |
| 1219 | + help='Basic auth password (can also be set via DSTACK_VMM_AUTH_PASSWORD env var or config file)') |
1190 | 1220 |
|
1191 | 1221 | subparsers = parser.add_subparsers(dest='command', help='Commands') |
1192 | 1222 |
|
|
0 commit comments