Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Azure Blob Storage implementation #2223

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/actions/setup-localstack/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,19 @@ runs:
env:
AWS_ACCESS_KEY_ID: fake
AWS_SECRET_ACCESS_KEY: fake

- shell: bash
run: |
docker run -d -p 10000:10000 -p 10001:10001 -p 10002:10002 --name azurite \
-v /tmp/data:/data \
-e "AZURITE_ACCOUNTS=zot-storage-test:YXp1cml0ZQo=" \
mcr.microsoft.com/azure-storage/azurite:3.31.0 azurite-blob --blobHost 0.0.0.0


- shell: bash
run: |
sleep 10
az storage container create --name zot-storage
env:
# https://github.com/Azure/Azurite/blob/main/README.md#usage-with-azure-storage-sdks-or-tools
AZURE_STORAGE_CONNECTION_STRING: DefaultEndpointsProtocol=http;AccountName=zot-storage-test;AccountKey=YXp1cml0ZQo=;BlobEndpoint=http://127.0.0.1:10000/zot-storage-test;
4 changes: 4 additions & 0 deletions .github/actions/teardown-localstack/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ runs:
- shell: bash
if: always()
run: localstack stop

- shell: bash
if: always()
run: docker rm -f azurite
107 changes: 99 additions & 8 deletions .github/workflows/gc-stress-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ jobs:
run: |
python3 - <<'EOF'
from minio import Minio

try:
minio = Minio(
'localhost:9000',
Expand All @@ -119,7 +119,7 @@ jobs:
)
except Exception as ex:
raise

minio.make_bucket('zot-storage')
print(f'{minio.list_buckets()}')
EOF
Expand All @@ -132,9 +132,9 @@ jobs:
./bin/zot-linux-amd64 serve test/gc-stress/config-gc-referrers-bench-s3-minio.json &
sleep 10
bin/zb-linux-amd64 -c 10 -n 100 -o ci-cd http://localhost:8080

killall -r zot-*

# clean zot storage
sudo rm -rf /tmp/zot
env:
Expand Down Expand Up @@ -184,7 +184,7 @@ jobs:
run: |
python3 - <<'EOF'
from minio import Minio

try:
minio = Minio(
'localhost:9000',
Expand All @@ -194,7 +194,7 @@ jobs:
)
except Exception as ex:
raise

minio.make_bucket('zot-storage')
print(f'{minio.list_buckets()}')
EOF
Expand All @@ -207,9 +207,9 @@ jobs:
./bin/zot-linux-amd64 serve test/gc-stress/config-gc-bench-s3-minio.json &
sleep 10
bin/zb-linux-amd64 -c 10 -n 100 -o ci-cd http://localhost:8080

killall -r zot-*

# clean zot storage
sudo rm -rf /tmp/zot
env:
Expand All @@ -223,3 +223,94 @@ jobs:
cat /tmp/gc-bench-s3.log
exit 1
- uses: ./.github/actions/teardown-localstack
gc-referrers-stress-azure-blob:
name: GC(with referrers) on azure-blob(azurite) with short interval
runs-on: ubuntu-latest-8-cores
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
cache: false
go-version: 1.22.x
- name: Setup azurite service
run: |
docker run -d -p 10000:10000 -p 10001:10001 -p 10002:10002 --name azurite \
-v /tmp/data:/data \
-e "AZURITE_ACCOUNTS=zot-storage-test:YXp1cml0ZQo=" \
mcr.microsoft.com/azure-storage/azurite:3.31.0 azurite-blob --blobHost 0.0.0.0

- name: Wait for azurite to come up
run: |
sleep 10
az storage container create --name zot-storage-test
env:
# https://github.com/Azure/Azurite/blob/main/README.md#usage-with-azure-storage-sdks-or-tools
AZURE_STORAGE_CONNECTION_STRING: DefaultEndpointsProtocol=http;AccountName=zot-storage-test;AccountKey=YXp1cml0ZQo=;BlobEndpoint=http://localhost:10000/zot-storage-test;

- name: Run zb
id: bench
run: |
make binary
make bench
./bin/zot-linux-amd64 serve test/gc-stress/config-gc-referrers-bench-azure-blob-azurite.json &
sleep 10
bin/zb-linux-amd64 -c 10 -n 100 -o ci-cd http://localhost:8080

killall -r zot-*

# clean zot storage
sudo rm -rf /tmp/zot
env:
AWS_ACCESS_KEY_ID: fake
AWS_SECRET_ACCESS_KEY: fake
continue-on-error: true

- name: Check on failures
if: steps.bench.outcome != 'success'
run: |
cat /tmp/gc-referrers-bench-azure-blob.log
exit 1
gc-stress-azure-blob:
name: GC(without referrers) on azure-blob(azurite) with short interval
runs-on: ubuntu-latest-8-cores
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
cache: false
go-version: 1.22.x
- name: Setup azurite service
run: |
docker run -d -p 10000:10000 -p 10001:10001 -p 10002:10002 --name azurite \
-v /tmp/data:/data \
-e "AZURITE_ACCOUNTS=zot-storage-test:YXp1cml0ZQo=" \
mcr.microsoft.com/azure-storage/azurite:3.31.0 azurite-blob --blobHost 0.0.0.0

- name: Wait for azurite to come up
run: |
sleep 10
az storage container create --name zot-storage-test
env:
# https://github.com/Azure/Azurite/blob/main/README.md#usage-with-azure-storage-sdks-or-tools
AZURE_STORAGE_CONNECTION_STRING: DefaultEndpointsProtocol=http;AccountName=zot-storage-test;AccountKey=YXp1cml0ZQo=;BlobEndpoint=http://127.0.0.1:10000/zot-storage-test;

- name: Run zb
id: bench
run: |
make binary
make bench
./bin/zot-linux-amd64 serve test/gc-stress/config-gc-referrers-bench-azure-blob-azurite.json &
sleep 10
bin/zb-linux-amd64 -c 10 -n 100 -o ci-cd http://localhost:8080

killall -r zot-*

# clean zot storage
sudo rm -rf /tmp/zot
continue-on-error: true

- name: Check on failures
if: steps.bench.outcome != 'success'
run: |
cat /tmp/gc-bench-azure-blob.log
exit 1
2 changes: 2 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ jobs:
env:
S3MOCK_ENDPOINT: localhost:4566
DYNAMODBMOCK_ENDPOINT: http://localhost:4566
AZURE_BLOB_MOCK_ENDPOINT: http://localhost:10000/
AWS_ACCESS_KEY_ID: fake
AWS_SECRET_ACCESS_KEY: fake
- name: upload coverage
Expand Down Expand Up @@ -83,6 +84,7 @@ jobs:
env:
S3MOCK_ENDPOINT: localhost:4566
DYNAMODBMOCK_ENDPOINT: http://localhost:4566
AZURE_BLOB_MOCK_ENDPOINT: http://localhost:10000/
AWS_ACCESS_KEY_ID: fake
AWS_SECRET_ACCESS_KEY: fake
- name: upload coverage
Expand Down
64 changes: 64 additions & 0 deletions examples/config-azure.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"distSpecVersion": "1.1.0",
"storage": {
"rootDirectory": "/tmp/zot",
"dedupe": false,
"remoteCache": false,
"storageDriver": {
"name": "azure",
"rootdirectory": "/zot",
"container": "zot-storage",
"accountname": "zot-storage",
"accountkey": "azurite",
"serviceurl": "http://localhost:10000"
},
"subPaths": {
"/a": {
"rootDirectory": "/tmp/zot1",
"dedupe": false,
"remoteCache": false,
"storageDriver": {
"name": "azure",
"rootdirectory": "/zot-a",
"container": "zot-storage",
"accountname": "zot-storage",
"accountkey": "azurite",
"serviceurl": "http://localhost:10000"
}
},
"/b": {
"rootDirectory": "/tmp/zot2",
"dedupe": false,
"remoteCache": false,
"storageDriver": {
"name": "azure",
"rootdirectory": "/zot-b",
"container": "zot-storage",
"accountname": "zot-storage",
"accountkey": "azurite",
"serviceurl": "http://localhost:10000"
}
},
"/c": {
"rootDirectory": "/tmp/zot3",
"dedupe": false,
"remoteCache": false,
"storageDriver": {
"name": "azure",
"rootdirectory": "/zot-c",
"container": "zot-storage",
"accountname": "zot-storage",
"accountkey": "azurite",
"serviceurl": "http://localhost:10000"
}
}
}
},
"http": {
"address": "127.0.0.1",
"port": "8080"
},
"log": {
"level": "debug"
}
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.13.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.4.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.29 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,14 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.6.0 h1:PiSrjRPpkQNjrM8H0WwKMnZUdu1RGMtd/LdGKUrOo+c=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.6.0/go.mod h1:oDrbWx4ewMylP7xHivfgixbfGBT6APAwsSoHRKotnIc=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.1.0 h1:DRiANoJTiW6obBQe3SqZizkuV1PEgfiiGivmVocDy64=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.1.0/go.mod h1:qLIye2hwb/ZouqhpSD9Zn3SJipvpEnz1Ywl3VUk9Y0s=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 h1:D3occbWoio4EBLkbkevetNMAVX197GkzbUMtqjGWn80=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0/go.mod h1:bTSOgj05NGRuHHhQwAdPnYr9TOdNmKlZTgGLL6nyAdI=
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.4.0 h1:Be6KInmFEKV81c0pOAEbRYehLMwmmGI1exuFj248AMk=
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.4.0/go.mod h1:WCPBHsOXfBVnivScjs2ypRfimjEW0qPVLGgJkZlrIOA=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
Expand Down
3 changes: 3 additions & 0 deletions pkg/cli/server/extensions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func TestVerifyExtensionsConfig(t *testing.T) {
"rootdirectory":"/zot",
"region":"us-east-2",
"bucket":"zot-storage",
"forcepathstyle":true,
"secure":true,
"skipverify":false
}
Expand Down Expand Up @@ -79,6 +80,7 @@ func TestVerifyExtensionsConfig(t *testing.T) {
"rootdirectory":"/zot-a",
"region":"us-east-2",
"bucket":"zot-storage",
"forcepathstyle":true,
"secure":true,
"skipverify":false
}
Expand Down Expand Up @@ -1897,6 +1899,7 @@ func TestSyncWithRemoteStorageConfig(t *testing.T) {
"rootdirectory":"/zot-a",
"region":"us-east-2",
"bucket":"zot-storage",
"forcepathstyle":true,
"secure":true,
"skipverify":true
}
Expand Down
13 changes: 9 additions & 4 deletions pkg/cli/server/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,10 @@ func validateConfiguration(config *config.Config, log zlog.Logger) error {
}

if len(config.Storage.StorageDriver) != 0 {
// enforce s3 driver in case of using storage driver
if config.Storage.StorageDriver["name"] != storageConstants.S3StorageDriverName {
switch config.Storage.StorageDriver["name"] {
case storageConstants.S3StorageDriverName:
case storageConstants.AzureBlobStorageDriverName:
default:
log.Error().Err(zerr.ErrBadConfig).Interface("cacheDriver", config.Storage.StorageDriver["name"]).
Msg("unsupported storage driver")

Expand All @@ -425,14 +427,17 @@ func validateConfiguration(config *config.Config, log zlog.Logger) error {

for route, storageConfig := range subPaths {
if len(storageConfig.StorageDriver) != 0 {
if storageConfig.StorageDriver["name"] != storageConstants.S3StorageDriverName {
switch storageConfig.StorageDriver["name"] {
case storageConstants.S3StorageDriverName:
case storageConstants.AzureBlobStorageDriverName:
default:
log.Error().Err(zerr.ErrBadConfig).Str("subpath", route).Interface("storageDriver",
storageConfig.StorageDriver["name"]).Msg("unsupported storage driver")

return zerr.ErrBadConfig
}

// enforce tmpDir in case sync + s3
// enforce tmpDir in case sync + blob storage
if config.Extensions != nil && config.Extensions.Sync != nil && config.Extensions.Sync.DownloadDir == "" {
log.Error().Err(zerr.ErrBadConfig).
Msg("using both sync and remote storage features needs config.Extensions.Sync.DownloadDir to be specified")
Expand Down
7 changes: 7 additions & 0 deletions pkg/cli/server/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ storage:
"rootdirectory":"/zot",
"region":"us-east-2",
"bucket":"zot-storage",
"forcepathstyle":true,
"secure":true,
"skipverify":false
}
Expand Down Expand Up @@ -235,6 +236,7 @@ storage:
"rootdirectory":"/zot-a",
"region":"us-east-2",
"bucket":"zot-storage",
"forcepathstyle":true,
"secure":true,
"skipverify":false
}
Expand Down Expand Up @@ -278,6 +280,7 @@ storage:
"rootdirectory":"/zot",
"region":"us-east-2",
"bucket":"zot-storage",
"forcepathstyle":true,
"secure":true,
"skipverify":false
}
Expand Down Expand Up @@ -347,6 +350,7 @@ storage:
"rootdirectory":"/zot",
"region":"us-east-2",
"bucket":"zot-storage",
"forcepathstyle":true,
"secure":true,
"skipverify":false
}
Expand Down Expand Up @@ -387,6 +391,7 @@ storage:
"rootdirectory":"/zot",
"region":"us-east-2",
"bucket":"zot-storage",
"forcepathstyle":true,
"secure":true,
"skipverify":false
}
Expand Down Expand Up @@ -427,6 +432,7 @@ storage:
"rootdirectory":"/zot",
"region":"us-east-2",
"bucket":"zot-storage",
"forcepathstyle":true,
"secure":true,
"skipverify":false
}
Expand Down Expand Up @@ -508,6 +514,7 @@ storage:
"rootdirectory":"/zot",
"region":"us-east-2",
"bucket":"zot-storage",
"forcepathstyle":true,
"secure":true,
"skipverify":false
}
Expand Down
Loading
Loading