|
1 | 1 | from typing import Optional, Union |
| 2 | +from pathlib import Path |
2 | 3 |
|
3 | 4 | from upcloud_api.api import API |
4 | 5 | from upcloud_api.storage import Storage |
5 | 6 | from upcloud_api.storage_import import StorageImport |
6 | | -from upcloud_api.utils import get_raw_data_from_file |
7 | 7 |
|
8 | 8 |
|
9 | 9 | class StorageManager: |
@@ -41,10 +41,10 @@ def get_storage(self, storage: str) -> Storage: |
41 | 41 |
|
42 | 42 | def create_storage( |
43 | 43 | self, |
| 44 | + zone: str, |
44 | 45 | size: int = 10, |
45 | 46 | tier: str = 'maxiops', |
46 | 47 | title: str = 'Storage disk', |
47 | | - zone: str = 'fi-hel1', |
48 | 48 | backup_rule: Optional[dict] = None, |
49 | 49 | ) -> Storage: |
50 | 50 | """ |
@@ -184,33 +184,37 @@ def create_storage_import( |
184 | 184 | Creates an import task to import data into an existing storage. |
185 | 185 | Source types: http_import or direct_upload. |
186 | 186 | """ |
| 187 | + if source not in ["http_import", "direct_upload"]: |
| 188 | + raise Exception("invalid storage import source: %s", source) |
| 189 | + |
187 | 190 | url = f'/storage/{storage}/import' |
188 | 191 | body = {'storage_import': {'source': source}} |
189 | 192 | if source_location: |
190 | 193 | body['storage_import']['source_location'] = source_location |
191 | 194 | res = self.api.post_request(url, body) |
192 | 195 | return StorageImport(**res['storage_import']) |
193 | 196 |
|
194 | | - def upload_file_for_storage_import(self, storage_import, file): |
| 197 | + def upload_file_for_storage_import(self, storage_import: StorageImport, file: Path, timeout: int = 600): |
195 | 198 | """ |
196 | 199 | Uploads a file directly to UpCloud's uploader session. |
197 | 200 | """ |
198 | | - # TODO: this should not buffer the entire `file` into memory |
199 | | - |
200 | | - # This is importing and using `requests` directly since there doesn't |
201 | | - # seem to be a point in adding a `.api.raw_request()` call to the `API` class. |
202 | | - # That could be changed. |
203 | 201 |
|
204 | 202 | import requests |
205 | 203 |
|
206 | | - resp = requests.put( |
207 | | - url=storage_import.direct_upload_url, |
208 | | - data=get_raw_data_from_file(file), |
209 | | - headers={'Content-type': 'application/octet-stream'}, |
210 | | - timeout=600, |
211 | | - ) |
212 | | - resp.raise_for_status() |
213 | | - return resp.json() |
| 204 | + # This is importing and using `requests` directly since there doesn't |
| 205 | + # seem to be a point in adding a `.api.raw_request()` call to the `API` class. |
| 206 | + # That could be changed if there starts to be more of these cases. |
| 207 | + |
| 208 | + with open(file, 'rb') as f: |
| 209 | + resp = requests.put( |
| 210 | + url=storage_import.direct_upload_url, |
| 211 | + data=f, |
| 212 | + headers={'Content-type': 'application/octet-stream'}, |
| 213 | + timeout=timeout, |
| 214 | + ) |
| 215 | + |
| 216 | + resp.raise_for_status() |
| 217 | + return resp.json() |
214 | 218 |
|
215 | 219 | def get_storage_import_details(self, storage: str) -> StorageImport: |
216 | 220 | """ |
|
0 commit comments