Get a BackupContainerFileSystem based on a container URL string TODO: refactor to not duplicate IBackupContainer::openContainer. It's the exact same code but returning a different template type because you can't cast between them
| 1492 | // TODO: refactor to not duplicate IBackupContainer::openContainer. It's the exact same |
| 1493 | // code but returning a different template type because you can't cast between them |
| 1494 | Reference<BackupContainerFileSystem> BackupContainerFileSystem::openContainerFS( |
| 1495 | const std::string& url, |
| 1496 | const Optional<std::string>& proxy, |
| 1497 | const Optional<std::string>& encryptionKeyFileName) { |
| 1498 | static std::map<std::string, Reference<BackupContainerFileSystem>> m_cache; |
| 1499 | |
| 1500 | Reference<BackupContainerFileSystem>& r = m_cache[url]; |
| 1501 | if (r) |
| 1502 | return r; |
| 1503 | |
| 1504 | try { |
| 1505 | StringRef u(url); |
| 1506 | if (u.startsWith("file://"_sr)) { |
| 1507 | r = makeReference<BackupContainerLocalDirectory>(url, encryptionKeyFileName); |
| 1508 | } else if (u.startsWith("blobstore://"_sr)) { |
| 1509 | std::string resource; |
| 1510 | |
| 1511 | // The URL parameters contain blobstore endpoint tunables as well as possible backup-specific options. |
| 1512 | S3BlobStoreEndpoint::ParametersT backupParams; |
| 1513 | Reference<S3BlobStoreEndpoint> bstore = |
| 1514 | S3BlobStoreEndpoint::fromString(url, proxy, &resource, &lastOpenError, &backupParams); |
| 1515 | |
| 1516 | if (resource.empty()) |
| 1517 | throw backup_invalid_url(); |
| 1518 | for (auto c : resource) |
| 1519 | if (!isalnum(c) && c != '_' && c != '-' && c != '.' && c != '/') |
| 1520 | throw backup_invalid_url(); |
| 1521 | r = makeReference<BackupContainerS3BlobStore>(bstore, resource, backupParams, encryptionKeyFileName); |
| 1522 | } |
| 1523 | #ifdef BUILD_AZURE_BACKUP |
| 1524 | else if (u.startsWith("azure://"_sr)) { |
| 1525 | u.eat("azure://"_sr); |
| 1526 | auto address = u.eat("/"_sr); |
| 1527 | if (address.endsWith(std::string(azure::storage_lite::constants::default_endpoint_suffix))) { |
| 1528 | CODE_PROBE(true, "Azure backup url with standard azure storage account endpoint"); |
| 1529 | // <account>.<service>.core.windows.net/<resource_path> |
| 1530 | auto endPoint = address.toString(); |
| 1531 | auto accountName = address.eat("."_sr).toString(); |
| 1532 | auto containerName = u.eat("/"_sr).toString(); |
| 1533 | r = makeReference<BackupContainerAzureBlobStore>( |
| 1534 | endPoint, accountName, containerName, encryptionKeyFileName); |
| 1535 | } else { |
| 1536 | // resolve the network address if necessary |
| 1537 | std::string endpoint(address.toString()); |
| 1538 | Optional<NetworkAddress> parsedAddress = NetworkAddress::parseOptional(endpoint); |
| 1539 | if (!parsedAddress.present()) { |
| 1540 | try { |
| 1541 | auto hostname = Hostname::parse(endpoint); |
| 1542 | auto resolvedAddress = hostname.resolveBlocking(); |
| 1543 | if (resolvedAddress.present()) { |
| 1544 | CODE_PROBE(true, "Azure backup url with hostname in the endpoint"); |
| 1545 | parsedAddress = resolvedAddress.get(); |
| 1546 | } |
| 1547 | } catch (Error& e) { |
| 1548 | TraceEvent(SevError, "InvalidAzureBackupUrl").error(e).detail("Endpoint", endpoint); |
| 1549 | throw backup_invalid_url(); |
| 1550 | } |
| 1551 | } |
nothing calls this directly
no test coverage detected