Skip to content

Commit f1a1ee3

Browse files
authored
10.0.4 release (Azure#111)
* fixed the relative path of the file at the destination in case of upload with list-of-file flag * sync counters added * added question to ask user permission before for sync upload / download * added the force flag * changed progress reporting for sync * changes for sync command * fixed the smoke test for sync changes * sync redesign changes * changes in sync upload algorithm * Adding a missing comma (Azure#103) * Adding note about the blob data contributor role (Azure#101) * sync algorithm changes * changes in sync upload * sync download changes * fixed the error message * Added script to generate packages * changed the cca.setScanningComplete place in upload / download case * fixed the smoke tests for latest sync changes * fixed uploading empty vhd; delete performance-test-script-win.py * symlink support added for sync / copy command #TestNotCompleted * symlink support changes for sync / copy command * added the http error codes in the JobPartPlanTransfer; changed the Json output format (no new line after each field) * added blob type flag; localToPageBlob processor * added append blob; fixed the smoke tests * fixed the page blob smoke test * fixed the remove op smoke tests * added throughput in resume command * Changes for handling bad / expired sas * fixed the CR comments for list-of-files flag * Added env command + allow user to change log location (Azure#106) * Update script to generate latest_version.txt * Added env command and allow user to change log location * CR Comments addressed for CR Changes * sync redesign changes * changes in sync upload algorithm * sync algorithm changes * changes in sync upload * sync download changes * fixed the error message * changed the cca.setScanningComplete place in upload / download case * fixed the smoke tests for latest sync changes * fixed uploading empty vhd; delete performance-test-script-win.py * symlink support added for sync / copy command #TestNotCompleted * symlink support changes for sync / copy command * added the http error codes in the JobPartPlanTransfer; changed the Json output format (no new line after each field) * added blob type flag; localToPageBlob processor * added append blob; fixed the smoke tests * fixed the page blob smoke test * fixed the remove op smoke tests * added throughput in resume command * Changes for handling bad / expired sas * fixed the CR comments for list-of-files flag * CR Comments addressed for CR Changes * Improved content type detection (Azure#109) * Release 10.0.4
1 parent cc824d9 commit f1a1ee3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+2079
-1496
lines changed

.gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# ignore DS_STORE on Mac OS
22
*.DS_Store
33

4+
# ignore built packages
5+
dist/
6+
47
#CI
58
azure-storage-azcopy_*_amd64
69
test-validator
@@ -328,3 +331,7 @@ venv*
328331

329332
#json create files
330333
*.json
334+
335+
# go files
336+
*.mod
337+
*.sum

Gopkg.lock

+5-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Gopkg.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
version = "0.1.7"
44

55
[[constraint]]
6-
branch = "master"
6+
version = "0.3.0"
77
name = "github.com/Azure/azure-storage-blob-go"
88

99
[[constraint]]

README.md

+9
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,15 @@ You can resume a failed/cancelled job using its identifier along with the SAS to
188188

189189
Raise an issue on this repository for any feedback or issue encountered.
190190

191+
### FAQ
192+
193+
- What is the difference between `sync` and `copy`?
194+
- The `copy` command is a simple transferring operation, it scans the source and attempts to transfer every single file/blob. The supported source/destination pairs are listed in the help message of the tool. On the other hand, `sync` makes sure that whatever is present in the source will be replicated to the destination, and also whatever is not at the source will be deleted from the destination. If your goal is to simply move some files, then `copy` is definitely the right command, since it offers much better performance.
195+
- For `sync`, last modified times are used to determine whether to transfer the same file present at both the source and the destination.
196+
- If the use case is to incrementally transfer data, then `sync` is the better choice, since only the modified/missing files are transferred.
197+
- Will `copy` overwrite my files?
198+
- By default, AzCopy will overwrite the files at the destination if they already exist. To avoid this behavior, please use the flag `--overwrite`.
199+
191200
## Contributing
192201

193202
This project welcomes contributions and suggestions. Most contributions require you to agree to a

build_executables.sh

-10
This file was deleted.

cmd/copy.go

+44-16
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,13 @@ import (
3232
"strings"
3333
"time"
3434

35+
"io/ioutil"
36+
3537
"github.com/Azure/azure-storage-azcopy/common"
3638
"github.com/Azure/azure-storage-azcopy/ste"
37-
"github.com/Azure/azure-storage-blob-go/2018-03-28/azblob"
39+
"github.com/Azure/azure-storage-blob-go/azblob"
3840
"github.com/Azure/azure-storage-file-go/2017-07-29/azfile"
3941
"github.com/spf13/cobra"
40-
"io/ioutil"
4142
)
4243

4344
// upload related
@@ -83,13 +84,15 @@ type rawCopyCmdArgs struct {
8384
contentEncoding string
8485
noGuessMimeType bool
8586
preserveLastModifiedTime bool
86-
blockBlobTier string
87-
pageBlobTier string
88-
background bool
89-
output string
90-
acl string
91-
logVerbosity string
92-
cancelFromStdin bool
87+
// defines the type of the blob at the destination in case of upload / account to account copy
88+
blobType string
89+
blockBlobTier string
90+
pageBlobTier string
91+
background bool
92+
output string
93+
acl string
94+
logVerbosity string
95+
cancelFromStdin bool
9396
// list of blobTypes to exclude while enumerating the transfer
9497
excludeBlobType string
9598
}
@@ -114,6 +117,19 @@ func (raw rawCopyCmdArgs) cook() (cookedCopyCmdArgs, error) {
114117
cooked.forceWrite = raw.forceWrite
115118
cooked.blockSize = raw.blockSize
116119

120+
// parse the given blob type.
121+
err = cooked.blobType.Parse(raw.blobType)
122+
if err != nil {
123+
return cooked, err
124+
}
125+
126+
// If the given blobType is AppendBlob, block-size should not be greater than
127+
// 4MB.
128+
if cooked.blobType == common.EBlobType.AppendBlob() &&
129+
raw.blockSize > common.MaxAppendBlobBlockSize {
130+
return cooked, fmt.Errorf("block size cannot be greater than 4MB for AppendBlob blob type")
131+
}
132+
117133
err = cooked.blockBlobTier.Parse(raw.blockBlobTier)
118134
if err != nil {
119135
return cooked, err
@@ -127,7 +143,7 @@ func (raw rawCopyCmdArgs) cook() (cookedCopyCmdArgs, error) {
127143
return cooked, err
128144
}
129145
// User can provide either listOfFilesToCopy or include since listOFFiles mentions
130-
// file names to include explicitly and include file may mention at pattern.
146+
// file names to include explicitly and include file may mention the pattern.
131147
// This could conflict enumerating the files to queue up for transfer.
132148
if len(raw.listOfFilesToCopy) > 0 && len(raw.include) > 0 {
133149
return cooked, fmt.Errorf("user provided argument with both listOfFilesToCopy and include flag. Only one should be provided")
@@ -139,12 +155,11 @@ func (raw rawCopyCmdArgs) cook() (cookedCopyCmdArgs, error) {
139155
// can be supplied with the argument, but Storage Explorer folks requirements was not to impose
140156
// any limit on the number of files that can be copied.
141157
if len(raw.listOfFilesToCopy) > 0 {
142-
//files := strings.Split(raw.listOfFilesToCopy, ";")
143158
jsonFile, err := os.Open(raw.listOfFilesToCopy)
144159
if err != nil {
145160
return cooked, fmt.Errorf("cannot open %s file passed with the list-of-file flag", raw.listOfFilesToCopy)
146161
}
147-
// read our opened xmlFile as a byte array.
162+
// read opened json file as a byte array.
148163
jsonBytes, err := ioutil.ReadAll(jsonFile)
149164
if err != nil {
150165
return cooked, fmt.Errorf("error %s read %s file passed with the list-of-file flag", err.Error(), raw.listOfFilesToCopy)
@@ -314,6 +329,7 @@ type cookedCopyCmdArgs struct {
314329
blockSize uint32
315330
// list of blobTypes to exclude while enumerating the transfer
316331
excludeBlobType []azblob.BlobType
332+
blobType common.BlobType
317333
blockBlobTier common.BlockBlobTier
318334
pageBlobTier common.PageBlobTier
319335
metadata string
@@ -485,6 +501,7 @@ func (cca *cookedCopyCmdArgs) processCopyJobPartOrders() (err error) {
485501
Exclude: cca.exclude,
486502
ExcludeBlobType: cca.excludeBlobType,
487503
BlobAttributes: common.BlobTransferAttributes{
504+
BlobType: cca.blobType,
488505
BlockSizeInBytes: cca.blockSize,
489506
ContentType: cca.contentType,
490507
ContentEncoding: cca.contentEncoding,
@@ -595,7 +612,7 @@ func (cca *cookedCopyCmdArgs) processCopyJobPartOrders() (err error) {
595612
// path differently, replace the path separator with the
596613
// the linux path separator '/'
597614
if os.PathSeparator == '\\' {
598-
cca.source = strings.Replace(cca.source, common.OS_PATH_SEPARATOR, "/", -1)
615+
cca.source = strings.Replace(cca.source, common.OS_PATH_SEPARATOR, common.AZCOPY_PATH_SEPARATOR_STRING, -1)
599616
}
600617
}
601618

@@ -683,7 +700,7 @@ func (cca *cookedCopyCmdArgs) processCopyJobPartOrders() (err error) {
683700
func (cca *cookedCopyCmdArgs) waitUntilJobCompletion(blocking bool) {
684701
// print initial message to indicate that the job is starting
685702
glcm.Info("\nJob " + cca.jobID.String() + " has started\n")
686-
glcm.Info(fmt.Sprintf("%s.log file created in %s", cca.jobID, azcopyAppPathFolder))
703+
glcm.Info(fmt.Sprintf("Log file is located at: %s/%s.log", azcopyLogPathFolder, cca.jobID))
687704

688705
// initialize the times necessary to track progress
689706
cca.jobStartTime = time.Now()
@@ -790,7 +807,7 @@ func (cca *cookedCopyCmdArgs) ReportProgressOrExit(lcm common.LifecycleMgr) {
790807
summary.TotalTransfers,
791808
scanningString))
792809
} else {
793-
glcm.Progress(fmt.Sprintf("%v Done, %v Failed, %v Pending, %v Skipped %v Total %s, 2-sec Throughput (Mb/s): %v",
810+
glcm.Progress(fmt.Sprintf("%v Done, %v Failed, %v Pending, %v Skipped, %v Total %s, 2-sec Throughput (Mb/s): %v",
794811
summary.TransfersCompleted,
795812
summary.TransfersFailed,
796813
summary.TotalTransfers-(summary.TransfersCompleted+summary.TransfersFailed+summary.TransfersSkipped),
@@ -829,6 +846,16 @@ Copies source data to a destination location. The supported pairs are:
829846
- Azure Block Blob (SAS or public) <-> Azure Block Blob (SAS or OAuth authentication)
830847
831848
Please refer to the examples for more information.
849+
850+
Advanced:
851+
Please note that AzCopy automatically detects the Content-Type of files when uploading from local disk, based on file extension or file content(if no extension).
852+
853+
The built-in lookup table is small but on unix it is augmented by the local system's mime.types file(s) if available under one or more of these names:
854+
- /etc/mime.types
855+
- /etc/apache2/mime.types
856+
- /etc/apache/mime.types
857+
858+
On Windows, MIME types are extracted from the registry. This feature can be turned off with the help of a flag. Please refer to the flag section.
832859
`,
833860
Example: `Upload a single file with SAS:
834861
- azcopy cp "/path/to/file.txt" "https://[account].blob.core.windows.net/[container]/[path/to/blob]?[SAS]"
@@ -938,12 +965,13 @@ Copy an entire account with SAS:
938965
cpCmd.PersistentFlags().StringVar(&raw.output, "output", "text", "format of the command's output, the choices include: text, json.")
939966
cpCmd.PersistentFlags().StringVar(&raw.logVerbosity, "log-level", "INFO", "define the log verbosity for the log file, available levels: DEBUG, INFO, WARNING, ERROR, PANIC, and FATAL.")
940967
cpCmd.PersistentFlags().Uint32Var(&raw.blockSize, "block-size", 0, "use this block(chunk) size when uploading/downloading to/from Azure Storage.")
968+
cpCmd.PersistentFlags().StringVar(&raw.blobType, "blobType", "None", "defines the type of blob at the destination. This is used in case of upload / account to account copy")
941969
cpCmd.PersistentFlags().StringVar(&raw.blockBlobTier, "block-blob-tier", "None", "upload block blob to Azure Storage using this blob tier.")
942970
cpCmd.PersistentFlags().StringVar(&raw.pageBlobTier, "page-blob-tier", "None", "upload page blob to Azure Storage using this blob tier.")
943971
cpCmd.PersistentFlags().StringVar(&raw.metadata, "metadata", "", "upload to Azure Storage with these key-value pairs as metadata.")
944972
cpCmd.PersistentFlags().StringVar(&raw.contentType, "content-type", "", "specifies content type of the file. Implies no-guess-mime-type.")
945973
cpCmd.PersistentFlags().StringVar(&raw.contentEncoding, "content-encoding", "", "upload to Azure Storage using this content encoding.")
946-
cpCmd.PersistentFlags().BoolVar(&raw.noGuessMimeType, "no-guess-mime-type", false, "this sets the content-type based on the extension of the file.")
974+
cpCmd.PersistentFlags().BoolVar(&raw.noGuessMimeType, "no-guess-mime-type", false, "prevents AzCopy from detecting the content-type based on the extension/content of the file.")
947975
cpCmd.PersistentFlags().BoolVar(&raw.preserveLastModifiedTime, "preserve-last-modified-time", false, "only available when destination is file system.")
948976
cpCmd.PersistentFlags().BoolVar(&raw.cancelFromStdin, "cancel-from-stdin", false, "true if user wants to cancel the process by passing 'cancel' "+
949977
"to the standard input. This is mostly used when the application is spawned by another process.")

cmd/copyBlobToNEnumerator.go

+2-9
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@ package cmd
22

33
import (
44
"context"
5-
"encoding/base64"
65
"errors"
76
"fmt"
87
"net/url"
98
"strings"
109

1110
"github.com/Azure/azure-storage-azcopy/common"
12-
"github.com/Azure/azure-storage-blob-go/2018-03-28/azblob"
11+
"github.com/Azure/azure-storage-blob-go/azblob"
1312
)
1413

1514
// copyBlobToNEnumerator enumerates blob source, and submit request for copy blob to N,
@@ -225,12 +224,6 @@ func (e *copyBlobToNEnumerator) addBlobToNTransfer(srcURL, destURL url.URL, prop
225224
common.URLExtension{URL: srcURL}.RedactSigQueryParamForLogging()))
226225
}
227226

228-
// work around an existing client bug, the contentMD5 returned from list is base64 encoded bytes, and should be base64 decoded bytes.
229-
md5DecodedBytes, err := base64.StdEncoding.DecodeString(string(properties.ContentMD5))
230-
if err != nil {
231-
return err
232-
}
233-
234227
return e.addTransfer(common.CopyTransfer{
235228
Source: gCopyUtil.stripSASFromBlobUrl(srcURL).String(),
236229
Destination: gCopyUtil.stripSASFromBlobUrl(destURL).String(),
@@ -241,7 +234,7 @@ func (e *copyBlobToNEnumerator) addBlobToNTransfer(srcURL, destURL url.URL, prop
241234
ContentDisposition: *properties.ContentDisposition,
242235
ContentLanguage: *properties.ContentLanguage,
243236
CacheControl: *properties.CacheControl,
244-
ContentMD5: md5DecodedBytes,
237+
ContentMD5: properties.ContentMD5,
245238
Metadata: common.FromAzBlobMetadataToCommonMetadata(metadata),
246239
BlobType: properties.BlobType},
247240
//BlobTier: string(properties.AccessTier)}, // TODO: blob tier setting correctly

cmd/copyDownloadBlobEnumerator.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010

1111
"github.com/Azure/azure-storage-azcopy/common"
1212
"github.com/Azure/azure-storage-azcopy/ste"
13-
"github.com/Azure/azure-storage-blob-go/2018-03-28/azblob"
13+
"github.com/Azure/azure-storage-blob-go/azblob"
1414
)
1515

1616
type copyDownloadBlobEnumerator common.CopyJobPartOrderRequest
@@ -139,8 +139,6 @@ func (e *copyDownloadBlobEnumerator) enumerate(cca *cookedCopyCmdArgs) error {
139139
if util.doesBlobRepresentAFolder(blobProperties.NewMetadata()) {
140140
continue
141141
}
142-
//blobRelativePath := util.getRelativePath(parentSourcePath, blobPath)
143-
//blobRelativePath := util.getRelativePath(parentSourcePath, blobPath)
144142
blobRelativePath := strings.Replace(blobPath, parentSourcePath, "", 1)
145143
if len(blobRelativePath) > 0 && blobRelativePath[0] == common.AZCOPY_PATH_SEPARATOR_CHAR {
146144
blobRelativePath = blobRelativePath[1:]

cmd/copyEnumeratorHelper.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
"time"
99

1010
"github.com/Azure/azure-storage-azcopy/common"
11-
"github.com/Azure/azure-storage-blob-go/2018-03-28/azblob"
11+
"github.com/Azure/azure-storage-blob-go/azblob"
1212
"github.com/Azure/azure-storage-file-go/2017-07-29/azfile"
1313
)
1414

cmd/copyS2SEnumerator.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99

1010
"github.com/Azure/azure-pipeline-go/pipeline"
1111
"github.com/Azure/azure-storage-azcopy/common"
12-
"github.com/Azure/azure-storage-blob-go/2018-03-28/azblob"
12+
"github.com/Azure/azure-storage-blob-go/azblob"
1313
)
1414

1515
// copyS2SEnumerator is the base of other service to service copy enumerators,

0 commit comments

Comments
 (0)