mirror of
https://github.com/minio/mc.git
synced 2025-11-13 12:22:45 +03:00
131 lines
4.1 KiB
Go
131 lines
4.1 KiB
Go
/*
|
|
* Minio Client (C) 2015 Minio, Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package main
|
|
|
|
import (
|
|
"io"
|
|
"os"
|
|
|
|
"github.com/cheggaaa/pb"
|
|
"github.com/minio-io/minio/pkg/iodine"
|
|
)
|
|
|
|
/// mc cp - related internal functions
|
|
|
|
// doCopy
|
|
func doCopy(methods clientMethods, reader io.ReadCloser, md5hex string, length int64, targetURL string, targetConfig *hostConfig) error {
|
|
writeCloser, err := methods.getTargetWriter(targetURL, targetConfig, md5hex, length)
|
|
if err != nil {
|
|
return iodine.New(err, nil)
|
|
}
|
|
var writers []io.Writer
|
|
writers = append(writers, writeCloser)
|
|
// set up progress bar
|
|
var bar *pb.ProgressBar
|
|
if !globalQuietFlag {
|
|
bar = startBar(length)
|
|
bar.Start()
|
|
writers = append(writers, bar)
|
|
}
|
|
// write progress bar
|
|
multiWriter := io.MultiWriter(writers...)
|
|
// copy data to writers
|
|
_, copyErr := io.CopyN(multiWriter, reader, length)
|
|
// close to see the error, verify it later
|
|
err = writeCloser.Close()
|
|
if copyErr != nil {
|
|
return iodine.New(copyErr, nil)
|
|
}
|
|
if err != nil {
|
|
return iodine.New(err, nil)
|
|
}
|
|
if !globalQuietFlag {
|
|
bar.Finish()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// doCopySingleSource
|
|
func doCopySingleSource(methods clientMethods, sourceURL, targetURL string, sourceConfig, targetConfig *hostConfig) error {
|
|
reader, length, md5hex, err := methods.getSourceReader(sourceURL, sourceConfig)
|
|
if err != nil {
|
|
return iodine.New(err, nil)
|
|
}
|
|
// check if its a folder, construct the new TargetURL, if not fallback
|
|
newTargetURL, err := getNewTargetURL(targetURL, sourceURL)
|
|
switch iodine.ToError(err).(type) {
|
|
case errIsNotFolder:
|
|
return doCopy(methods, reader, md5hex, length, targetURL, targetConfig)
|
|
case errIsNotBucket:
|
|
return doCopy(methods, reader, md5hex, length, targetURL, targetConfig)
|
|
case nil:
|
|
return doCopy(methods, reader, md5hex, length, newTargetURL, targetConfig)
|
|
default:
|
|
return iodine.New(err, nil)
|
|
}
|
|
}
|
|
|
|
// doCopySingleSourceRecursive
|
|
func doCopySingleSourceRecursive(methods clientMethods, sourceURL, targetURL string, sourceConfig, targetConfig *hostConfig) error {
|
|
sourceClnt, err := methods.getNewClient(sourceURL, sourceConfig, globalDebugFlag)
|
|
if err != nil {
|
|
return iodine.New(err, nil)
|
|
}
|
|
for contentCh := range sourceClnt.ListRecursive() {
|
|
if contentCh.Err != nil {
|
|
continue
|
|
}
|
|
newSourceURL, newTargetURL := getNewURLRecursive(sourceURL, targetURL, contentCh.Content.Name)
|
|
if err := doCopySingleSource(methods, newSourceURL, newTargetURL, sourceConfig, targetConfig); err != nil {
|
|
// verify for directory related errors, if "open" failed on directories ignore those errors
|
|
switch e := iodine.ToError(err).(type) {
|
|
case *os.PathError:
|
|
switch true {
|
|
// even with in PathError specific error related to directory reads is ignored
|
|
// do not ignore any other errors, since they might be valid problems on the filesystem
|
|
case e.Op == "read" && e.Err.Error() == "is a directory":
|
|
continue
|
|
default:
|
|
return iodine.New(err, nil)
|
|
}
|
|
default:
|
|
return iodine.New(err, nil)
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// doCopyMultipleSources -
|
|
func doCopyMultipleSources(methods clientMethods, sourceURLConfigMap map[string]*hostConfig, targetURL string, targetConfig *hostConfig) error {
|
|
sourceURLReaderMap, err := getSourceReaders(methods, sourceURLConfigMap)
|
|
if err != nil {
|
|
return iodine.New(err, nil)
|
|
}
|
|
for sourceURL, sourceReader := range sourceURLReaderMap {
|
|
newTargetURL, err := getNewTargetURL(targetURL, sourceURL)
|
|
if err != nil {
|
|
return iodine.New(err, nil)
|
|
}
|
|
err = doCopy(methods, sourceReader.reader, sourceReader.md5hex, sourceReader.length, newTargetURL, targetConfig)
|
|
if err != nil {
|
|
return iodine.New(err, map[string]string{"Source": sourceURL})
|
|
}
|
|
}
|
|
return nil
|
|
}
|