Skip to content

Commit fdf87ad

Browse files
committed
bug fix, does not re-create nested directory structure
1 parent 7d80718 commit fdf87ad

3 files changed

Lines changed: 76 additions & 4 deletions

File tree

internal/files/files.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ func downloadAndProcessURL(ctx *log.Context, url, downloadDir string, fileName s
6969

7070
//If there was an error downloading using SAS URI or SAS was not provided, download using managedIdentity or publicly.
7171
if scriptSASDownloadErr != nil || scriptSAS == "" {
72+
ctx.Log("info",fmt.Sprintf("Downloading script using SAS token failed: %v. Attempting download using managed identity or public access.", scriptSASDownloadErr))
7273
downloaders, getDownloadersError := getDownloaders(url, sourceManagedIdentity, download.ProdMsiDownloader{})
7374
if getDownloadersError == nil {
7475
const mode = 0500 // we assume users download scripts to execute

pkg/download/blob.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,16 @@ func GetSASBlob(blobURI, blobSas, targetDir string) (string, error) {
9696
// Extract container name from Path of the url https://<hostName>/<Path> For ex. Path = "containerName/dir1/dir2/file.sh"
9797
trimmedPath := strings.Trim(blobParsedurl.Path, "/")
9898
splitStrings := strings.Split(trimmedPath, "/")
99-
containerName := splitStrings[0]
99+
//containerName := splitStrings[0]
100100

101101
// Extract the blob path after container name
102-
fileName, blobPathError := getBlobPathAfterContainerName(blobURI, containerName)
103-
if fileName == "" || blobPathError != nil {
104-
return "", errors.Wrapf(blobPathError, "Failed to extract blob path name from URL: %q", loggableBlobUri)
102+
// fileName, blobPathError := getBlobPathAfterContainerName(blobURI, containerName)
103+
// if fileName == "" || blobPathError != nil {
104+
// return "", errors.Wrapf(blobPathError, "Failed to extract blob path name from URL: %q", loggableBlobUri)
105+
// }
106+
fileName := splitStrings[len(splitStrings)-1]
107+
if fileName == "" {
108+
return "", errors.Errorf("cannot extract file name from URL: %q", loggableBlobUri)
105109
}
106110

107111
// Create the local file

pkg/download/blob_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,73 @@ func Test_blobDownload_actualBlob(t *testing.T) {
200200
require.EqualValues(t, chunk, b, "retrieved body is different body=%d chunk=%d", len(b), len(chunk))
201201
}
202202

203+
func Test_GetSASBlob_nestedDirectories_actualBlob(t *testing.T) {
204+
acct := os.Getenv("AZURE_STORAGE_ACCOUNT")
205+
key := os.Getenv("AZURE_STORAGE_ACCESS_KEY")
206+
if acct == "" || key == "" {
207+
t.Skipf("Skipping: AZURE_STORAGE_ACCOUNT or AZURE_STORAGE_ACCESS_KEY not specified to run this test")
208+
}
209+
base := storage.DefaultBaseURL
210+
211+
// Create a blob in a nested directory structure
212+
client, err := storage.NewClient(acct, key, base, storage.DefaultAPIVersion, true)
213+
require.Nil(t, err)
214+
blobStorageClient := client.GetBlobService()
215+
216+
var (
217+
content = []byte("test script content\n")
218+
name = "dir1/dir2/script.sh" // nested path
219+
container = fmt.Sprintf("run-command-test-%d", rand.New(rand.NewSource(time.Now().UnixNano())).Int63())
220+
)
221+
222+
containerReference := blobStorageClient.GetContainerReference(container)
223+
_, err = containerReference.DeleteIfExists(nil)
224+
require.Nil(t, err)
225+
_, err = containerReference.CreateIfNotExists(&storage.CreateContainerOptions{Access: storage.ContainerAccessTypePrivate})
226+
require.Nil(t, err)
227+
defer containerReference.Delete(nil)
228+
229+
blobReference := containerReference.GetBlobReference(name)
230+
require.Nil(t, blobReference.PutAppendBlob(nil))
231+
require.Nil(t, blobReference.AppendBlock(content, nil))
232+
233+
// Generate SAS URL for the blob
234+
d := NewBlobDownload(acct, key, blobutil.AzureBlobRef{
235+
Container: container,
236+
Blob: name,
237+
StorageBase: base,
238+
})
239+
v, ok := d.(blobDownload)
240+
require.True(t, ok)
241+
sasURL, err := v.getURL()
242+
require.Nil(t, err)
243+
244+
// Parse the SAS URL to separate URI from SAS token
245+
blobURI := fmt.Sprintf("https://%s.blob.%s/%s/%s", acct, base, container, name)
246+
sasToken := sasURL[len(blobURI):] // Everything after the base URI is the SAS token
247+
248+
// Download the blob using GetSASBlob
249+
tmpDir, err := ioutil.TempDir("", "nested-test-")
250+
require.Nil(t, err)
251+
defer os.RemoveAll(tmpDir)
252+
253+
scriptFilePath, err := GetSASBlob(blobURI, sasToken, tmpDir)
254+
require.Nil(t, err)
255+
256+
// Verify that the file was downloaded with correct content
257+
result, err := ioutil.ReadFile(scriptFilePath)
258+
require.Nil(t, err)
259+
require.EqualValues(t, content, result, "downloaded content should match")
260+
261+
// Verify that the file was created
262+
require.Contains(t, scriptFilePath, tmpDir, "file path should be in temp directory")
263+
264+
// Verify the file exists and is not a directory
265+
fileInfo, err := os.Stat(scriptFilePath)
266+
require.Nil(t, err)
267+
require.False(t, fileInfo.IsDir(), "should be a file, not a directory")
268+
}
269+
203270
func Test_blobAppend_actualBlob(t *testing.T) {
204271
// Before running the test locally prepare storage account and set the following env variables:
205272
// export AZURE_STORAGE_BLOB="https://atanas.blob.core.windows.net/con1/output5.txt"

0 commit comments

Comments
 (0)