1
1
import base64
2
- from typing import Any , List
2
+ from typing import Any
3
3
4
4
import requests
5
5
from requests import Response
6
6
7
- from dstack ._internal .core .errors import BackendInvalidCredentialsError
7
+ from dstack ._internal .core .errors import BackendError , BackendInvalidCredentialsError
8
8
9
9
API_URL = "https://api.vultr.com/v2"
10
10
@@ -28,13 +28,7 @@ def get_instance(self, instance_id: str, plan_type: str):
28
28
response = self ._make_request ("GET" , f"/instances/{ instance_id } " )
29
29
return response .json ()["instance" ]
30
30
31
- def launch_instance (
32
- self , region : str , plan : str , label : str , startup_script : str , public_keys : List [str ]
33
- ):
34
- # Fetch or create startup script ID
35
- script_id : str = self .get_startup_script_id (startup_script )
36
- # Fetch or create SSH key IDs
37
- sshkey_ids : List [str ] = self .get_sshkey_id (public_keys )
31
+ def launch_instance (self , region : str , plan : str , label : str , user_data : str ):
38
32
# For Bare-metals
39
33
if "vbm" in plan :
40
34
# "Docker on Ubuntu 22.04" is required for bare-metals.
@@ -43,8 +37,7 @@ def launch_instance(
43
37
"plan" : plan ,
44
38
"label" : label ,
45
39
"image_id" : "docker" ,
46
- "script_id" : script_id ,
47
- "sshkey_id" : sshkey_ids ,
40
+ "user_data" : base64 .b64encode (user_data .encode ()).decode (),
48
41
}
49
42
resp = self ._make_request ("POST" , "/bare-metals" , data )
50
43
return resp .json ()["bare_metal" ]["id" ]
@@ -56,8 +49,7 @@ def launch_instance(
56
49
"plan" : plan ,
57
50
"label" : label ,
58
51
"os_id" : 1743 ,
59
- "script_id" : script_id ,
60
- "sshkey_id" : sshkey_ids ,
52
+ "user_data" : base64 .b64encode (user_data .encode ()).decode (),
61
53
}
62
54
resp = self ._make_request ("POST" , "/instances" , data )
63
55
return resp .json ()["instance" ]["id" ]
@@ -67,64 +59,11 @@ def launch_instance(
67
59
"plan" : plan ,
68
60
"label" : label ,
69
61
"image_id" : "docker" ,
70
- "script_id" : script_id ,
71
- "sshkey_id" : sshkey_ids ,
62
+ "user_data" : base64 .b64encode (user_data .encode ()).decode (),
72
63
}
73
64
resp = self ._make_request ("POST" , "/instances" , data )
74
65
return resp .json ()["instance" ]["id" ]
75
66
76
- def get_startup_script_id (self , startup_script : str ) -> str :
77
- script_name = "dstack-shim-script"
78
- encoded_script = base64 .b64encode (startup_script .encode ()).decode ()
79
-
80
- # Get the list of startup scripts
81
- response = self ._make_request ("GET" , "/startup-scripts" )
82
- scripts = response .json ()["startup_scripts" ]
83
-
84
- # Find the script by name
85
- existing_script = next ((s for s in scripts if s ["name" ] == script_name ), None )
86
-
87
- if existing_script :
88
- # Update the existing script
89
- startup_id = existing_script ["id" ]
90
- update_payload = {
91
- "name" : script_name ,
92
- "script" : encoded_script ,
93
- }
94
- self ._make_request ("PATCH" , f"/startup-scripts/{ startup_id } " , update_payload )
95
- else :
96
- # Create a new script
97
- create_payload = {
98
- "name" : script_name ,
99
- "type" : "boot" ,
100
- "script" : encoded_script ,
101
- }
102
- create_response = self ._make_request ("POST" , "/startup-scripts" , create_payload )
103
- startup_id = create_response .json ()["startup_script" ]["id" ]
104
-
105
- return startup_id
106
-
107
- def get_sshkey_id (self , ssh_ids : List [str ]) -> List [str ]:
108
- # Fetch existing SSH keys
109
- response = self ._make_request ("GET" , "/ssh-keys" )
110
- ssh_keys = response .json ()["ssh_keys" ]
111
-
112
- ssh_key_ids = []
113
- existing_keys = {key ["ssh_key" ]: key ["id" ] for key in ssh_keys }
114
-
115
- for ssh_key in ssh_ids :
116
- if ssh_key in existing_keys :
117
- # SSH key already exists, add its id to the list
118
- ssh_key_ids .append (existing_keys [ssh_key ])
119
- else :
120
- # Create new SSH key
121
- create_payload = {"name" : "dstack-ssh-key" , "ssh_key" : ssh_key }
122
- create_response = self ._make_request ("POST" , "/ssh-keys" , create_payload )
123
- new_ssh_key_id = create_response .json ()["ssh_key" ]["id" ]
124
- ssh_key_ids .append (new_ssh_key_id )
125
-
126
- return ssh_key_ids
127
-
128
67
def terminate_instance (self , instance_id : str , plan_type : str ):
129
68
if plan_type == "bare-metal" :
130
69
# Terminate bare-metal instance
@@ -151,4 +90,10 @@ def _make_request(self, method: str, path: str, data: Any = None) -> Response:
151
90
requests .codes .unauthorized ,
152
91
):
153
92
raise BackendInvalidCredentialsError (e .response .text )
93
+ if e .response is not None and e .response .status_code in (
94
+ requests .codes .bad_request ,
95
+ requests .codes .internal_server_error ,
96
+ requests .codes .not_found ,
97
+ ):
98
+ raise BackendError (e .response .text )
154
99
raise
0 commit comments