Skip to content

Commit 9c9393f

Browse files
committed
add examples
1 parent 451d07d commit 9c9393f

File tree

1 file changed

+68
-15
lines changed

1 file changed

+68
-15
lines changed

decisions/0014-storage-clis-for-blobstore-operations.md

Lines changed: 68 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
## Status
44

5-
🔄 **Under Discussion** This ADR proposes a shared direction for replacing fog-based blobstore implementations. It has not yet been accepted.
5+
🔄 **Under Discussion** - This ADR proposes a shared direction for replacing fog-based blobstore implementations.
66

7-
| Provider | Status | Notes |
8-
|----------|--------------------------|---------------------------------------------------------------------------------------------------------|
9-
| Azure | 🚧 PoC in Progress | [PoC](https://github.com/cloudfoundry/cloud_controller_ng/pull/4397) done with `bosh-azure-storage-cli` |
10-
| AWS | 🧭 Open for Contribution | |
11-
| GCP | 🧭 Open for Contribution | |
12-
| Alicloud | 🧭 Open for Contribution | |
7+
| Provider | Status | Notes |
8+
|--------------|---------------------------|---------------------------------------------------------------------------------------------------------|
9+
| Azure | 🚧 PoC in Progress | [PoC](https://github.com/cloudfoundry/cloud_controller_ng/pull/4397) done with `bosh-azure-storage-cli` |
10+
| AWS | 🧭 Open for Contribution | |
11+
| GCP | 🧭 Open for Contribution | |
12+
| Alibaba Cloud| 🧭 Open for Contribution | |
1313

1414

1515
## Context
@@ -20,21 +20,23 @@ These Ruby gems are largely unmaintained, introducing risks such as:
2020
* Blocking Ruby version upgrades
2121
* Potential for unpatched CVEs
2222

23-
Bosh faces similar issues, as it is also written in Ruby and must interact with blobstores. To address this, BOSH introduced standalone CLI tools (e.g., `bosh-azure-storage-cli`, `bosh-s3cli`) which shell out from Ruby to handle all blobstore operations:
23+
Bosh faces similar issues, as it is also written in Ruby and interacts with blobstores. To address this, Bosh introduced standalone CLI tools which shell out from Ruby to handle all blobstore operations:
2424
- https://github.com/cloudfoundry/bosh-azure-storage-cli
2525
- https://github.com/cloudfoundry/bosh-s3cli
2626
- https://github.com/cloudfoundry/bosh-gcscli
2727
- https://github.com/cloudfoundry/bosh-ali-storage-cli
2828

2929
This approach decouples core logic from Ruby gems and has proven to be robust in production.
3030
These CLIs are implemented in Go and use the respective provider SDKs.
31-
All BOSH storage CLIs currently implement a common interface with the following commands: `put`, `get`, `delete`, `exists`, and `sign`.
31+
All Bosh storage CLIs implement a common interface with the following commands: `put`, `get`, `delete`, `exists`, and `sign`.
3232

3333
A [PoC](https://github.com/cloudfoundry/cloud_controller_ng/pull/4397) has shown that `bosh-azure-storage-cli` can be successfully used in Cloud Controller to push apps.
3434

35+
This ADR does not propose breaking changes to existing Bosh storage CLI commands or their output, but outlines necessary additions to support Cloud Controller use cases. It highlights shared concerns and encourages collaboration between Bosh and Cloud Controller.
36+
3537
## Decision
3638

37-
Cloud Controller will introduce support for CLI-based blobstore clients, starting with Azure.
39+
Cloud Controller will introduce support for CLI based blobstore clients, starting with Azure.
3840
Specifically, we will:
3941
* Add a new blobstore client using `bosh-azure-storage-cli`
4042
* Shell out from Cloud Controller to perform blobstore operations
@@ -47,20 +49,71 @@ The `bosh-azure-storage-cli` needs to be extended with the following commands:
4749
* `properties`
4850
* `ensure-bucket-exists`
4951

50-
Other providers (AWS, GCP, Alibaba) will follow. Each will require equivalent blobstore clients and support for the above commands.
51-
This will eventually allow us to remove all fog-related gems from Cloud Controller.
52+
Other providers (AWS, GCP, Alibaba Cloud) will follow. Each will require equivalent blobstore clients and support for the above commands.
53+
This will eventually allow us to remove all fog related gems from Cloud Controller.
5254

5355
## Consequences
5456

55-
* Enables removing of `fog-azure-rm` and all other fog related gems
57+
* Enables the removal of `fog-azure-rm` and all other fog related gems
5658
* Reduces long-term maintenance burden and potential security issues
5759
* Allows providers to be migrated independently
5860
* Increases initial complexity during migration phase
59-
* With more consumers, interface changes in the BOSH storage CLIs may require more coordination
61+
* With more consumers, interface changes in the Bosh storage CLIs may require more coordination
6062

6163
## Alternatives Considered
6264

63-
* Replace fog with newer Ruby gems → Maintenance risk persists
65+
* Replace fog with newer Ruby gems → Maintenance risk persists and only a short-term solution
6466
* Implement own blobstore client in Ruby → High development and testing effort
6567

6668

69+
## Out Of Scope
70+
71+
* Support for CDNs (currently supported by fog)
72+
* Performance optimizations
73+
74+
## Example Usage of `bosh-azure-storage-cli`
75+
76+
### [Bosh](https://github.com/cloudfoundry/bosh/blob/main/src/bosh-director/lib/bosh/director/blobstore/azurestoragecli_blobstore_client.rb)
77+
```Ruby
78+
def object_exists?(object_id)
79+
begin
80+
out, err, status = Open3.capture3(@azure_storage_cli_path.to_s, '-c', @config_file.to_s, 'exists', object_id.to_s)
81+
return true if status.exitstatus.zero?
82+
return false if status.exitstatus == 3
83+
rescue Exception => e
84+
raise BlobstoreError, e.inspect
85+
end
86+
raise BlobstoreError, "Failed to check existence of az storage account object, code #{status.exitstatus}, output: '#{out}', error: '#{err}'" unless status.success?
87+
end
88+
```
89+
90+
### [Cloud Controller PoC](https://github.com/cloudfoundry/cloud_controller_ng/pull/4397)
91+
```Ruby
92+
def exists?(blobstore_key)
93+
key = partitioned_key(blobstore_key)
94+
logger.info("[azure-blobstore] [exists?] Checking existence for: #{key}")
95+
status = run_cli('exists', key, allow_nonzero: true)
96+
97+
if status.exitstatus == 0
98+
return true
99+
elsif status.exitstatus == 3
100+
return false
101+
end
102+
103+
false
104+
rescue StandardError => e
105+
logger.error("[azure-blobstore] [exists?] azure-storage-cli exists raised error: #{e.message} for #{key}")
106+
false
107+
end
108+
109+
110+
def run_cli(command, *args, allow_nonzero: false)
111+
logger.info("[azure-blobstore] Running azure-storage-cli: #{@cli_path} -c #{@config_file} #{command} #{args.join(' ')}")
112+
_, stderr, status = Open3.capture3(@cli_path, '-c', @config_file, command, *args)
113+
return status if allow_nonzero
114+
115+
raise "azure-storage-cli #{command} failed: #{stderr}" unless status.success?
116+
117+
status
118+
end
119+
```

0 commit comments

Comments
 (0)