Esempio n. 1
0
// mainList - is a handler for mc ls command
func mainList(ctx *cli.Context) {
	// Additional command speific theme customization.
	console.SetColor("File", color.New(color.FgWhite))
	console.SetColor("Dir", color.New(color.FgCyan, color.Bold))
	console.SetColor("Size", color.New(color.FgYellow))
	console.SetColor("Time", color.New(color.FgGreen))

	// Set global flags from context.
	setGlobalsFromContext(ctx)

	// check 'ls' cli arguments.
	checkListSyntax(ctx)

	// Set command flags from context.
	isRecursive := ctx.Bool("recursive")
	isIncomplete := ctx.Bool("incomplete")

	args := ctx.Args()
	// mimic operating system tool behavior.
	if !ctx.Args().Present() {
		args = []string{"."}
	}

	for _, targetURL := range args {
		var clnt client.Client
		clnt, err := newClient(targetURL)
		fatalIf(err.Trace(targetURL), "Unable to initialize target ‘"+targetURL+"’.")

		err = doList(clnt, isRecursive, isIncomplete)
		if err != nil {
			errorIf(err.Trace(clnt.GetURL().String()), "Unable to list target ‘"+clnt.GetURL().String()+"’.")
			continue
		}
	}
}
Esempio n. 2
0
// Validate command line arguments.
func checkRmSyntax(ctx *cli.Context) {
	args := ctx.Args()

	ishelp := ctx.GlobalBool("help")
	isForce := ctx.Bool("force")

	if !args.Present() || ishelp {
		exitCode := 1
		cli.ShowCommandHelpAndExit(ctx, "rm", exitCode)
	}

	URLs, err := args2URLs(args)
	fatalIf(err.Trace(ctx.Args()...), "Unable to parse arguments.")

	// If input validation fails then provide context sensitive help without displaying generic help message.
	// The context sensitive help is shown per argument instead of all arguments to keep the help display
	// as well as the code simple. Also most of the times there will be just one arg
	for _, url := range URLs {
		u := client.NewURL(url)
		if strings.HasSuffix(url, string(u.Separator)) {
			fatalIf(errDummy().Trace(),
				"‘"+url+"’ is a folder. To remove this folder recursively, please try ‘"+url+"...’ as argument.")
		}
		if isURLRecursive(url) && !isForce {
			fatalIf(errDummy().Trace(),
				"Recursive removal requires --force option. Please review carefully before performing this operation.")
		}
	}
}
Esempio n. 3
0
// mainList - is a handler for mc ls command
func mainList(ctx *cli.Context) {
	// Additional command speific theme customization.
	console.SetColor("File", color.New(color.FgWhite))
	console.SetColor("Dir", color.New(color.FgCyan, color.Bold))
	console.SetColor("Size", color.New(color.FgYellow))
	console.SetColor("Time", color.New(color.FgGreen))

	// check 'ls' cli arguments
	checkListSyntax(ctx)

	args := ctx.Args()
	isIncomplete := ctx.Bool("incomplete")

	// mimic operating system tool behavior
	if globalMimicFlag && !ctx.Args().Present() {
		args = []string{"."}
	}

	targetURLs, err := args2URLs(args.Head())
	fatalIf(err.Trace(args...), "One or more unknown URL types passed.")
	for _, targetURL := range targetURLs {
		// if recursive strip off the "..."
		var clnt client.Client
		clnt, err = url2Client(stripRecursiveURL(targetURL))
		fatalIf(err.Trace(targetURL), "Unable to initialize target ‘"+targetURL+"’.")

		err = doList(clnt, isURLRecursive(targetURL), isIncomplete)
		fatalIf(err.Trace(clnt.GetURL().String()), "Unable to list target ‘"+clnt.GetURL().String()+"’.")
	}
}
Esempio n. 4
0
// Main entry point for mirror command.
func mainMirror(ctx *cli.Context) {
	// Set global flags from context.
	setGlobalsFromContext(ctx)

	// check 'mirror' cli arguments.
	checkMirrorSyntax(ctx)

	// Additional command speific theme customization.
	console.SetColor("Mirror", color.New(color.FgGreen, color.Bold))

	var e error
	session := newSessionV6()
	session.Header.CommandType = "mirror"
	session.Header.RootPath, e = os.Getwd()
	if e != nil {
		session.Delete()
		fatalIf(probe.NewError(e), "Unable to get current working folder.")
	}

	// Set command flags from context.
	isForce := ctx.Bool("force")
	session.Header.CommandBoolFlags["force"] = isForce

	// extract URLs.
	session.Header.CommandArgs = ctx.Args()
	doMirrorSession(session)
	session.Delete()
}
Esempio n. 5
0
// checkListSyntax - validate all the passed arguments
func checkListSyntax(ctx *cli.Context) {
	args := ctx.Args()
	if !ctx.Args().Present() {
		args = []string{"."}
	}
	for _, arg := range args {
		if strings.TrimSpace(arg) == "" {
			fatalIf(errInvalidArgument().Trace(args...), "Unable to validate empty argument.")
		}
	}
	// extract URLs.
	URLs := ctx.Args()
	isIncomplete := ctx.Bool("incomplete")

	for _, url := range URLs {
		_, _, err := url2Stat(url)
		if err != nil && !isURLPrefixExists(url, isIncomplete) {
			// Bucket name empty is a valid error for 'ls myminio',
			// treat it as such.
			if _, ok := err.ToGoError().(BucketNameEmpty); ok {
				continue
			}
			fatalIf(err.Trace(url), "Unable to stat ‘"+url+"’.")
		}
	}
}
Esempio n. 6
0
// main for share download.
func mainShareDownload(ctx *cli.Context) error {
	// Set global flags from context.
	setGlobalsFromContext(ctx)

	// check input arguments.
	checkShareDownloadSyntax(ctx)

	// Initialize share config folder.
	initShareConfig()

	// Additional command speific theme customization.
	shareSetColor()

	// Set command flags from context.
	isRecursive := ctx.Bool("recursive")
	expiry := shareDefaultExpiry
	if ctx.String("expire") != "" {
		var e error
		expiry, e = time.ParseDuration(ctx.String("expire"))
		fatalIf(probe.NewError(e), "Unable to parse expire=‘"+ctx.String("expire")+"’.")
	}

	for _, targetURL := range ctx.Args() {
		err := doShareDownloadURL(targetURL, isRecursive, expiry)
		if err != nil {
			switch err.ToGoError().(type) {
			case APINotImplemented:
				fatalIf(err.Trace(), "Unable to share a non S3 url ‘"+targetURL+"’.")
			default:
				fatalIf(err.Trace(targetURL), "Unable to share target ‘"+targetURL+"’.")
			}
		}
	}
	return nil
}
Esempio n. 7
0
// main for share upload command.
func mainShareUpload(ctx *cli.Context) {
	// Set global flags from context.
	setGlobalsFromContext(ctx)

	// check input arguments.
	checkShareUploadSyntax(ctx)

	// Initialize share config folder.
	initShareConfig()

	// Additional command speific theme customization.
	shareSetColor()

	// Set command flags from context.
	isRecursive := ctx.Bool("recursive")
	expireArg := ctx.String("expire")
	expiry := shareDefaultExpiry
	contentType := ctx.String("content-type")
	if expireArg != "" {
		var e error
		expiry, e = time.ParseDuration(expireArg)
		fatalIf(probe.NewError(e), "Unable to parse expire=‘"+expireArg+"’.")
	}

	for _, targetURL := range ctx.Args() {
		err := doShareUploadURL(targetURL, isRecursive, expiry, contentType)
		fatalIf(err.Trace(targetURL), "Unable to generate curl command for upload ‘"+targetURL+"’.")
	}
}
Esempio n. 8
0
func mainMirror(ctx *cli.Context) {
	checkMirrorSyntax(ctx)

	// Additional command speific theme customization.
	console.SetColor("Mirror", color.New(color.FgGreen, color.Bold))

	var e error
	session := newSessionV3()
	session.Header.CommandType = "mirror"
	session.Header.RootPath, e = os.Getwd()
	if e != nil {
		session.Delete()
		fatalIf(probe.NewError(e), "Unable to get current working folder.")
	}

	// If force flag is set save it with in session
	session.Header.CommandBoolFlag.Key = "force"
	session.Header.CommandBoolFlag.Value = ctx.Bool("force")

	// extract URLs.
	var err *probe.Error
	session.Header.CommandArgs, err = args2URLs(ctx.Args())
	if err != nil {
		session.Delete()
		fatalIf(err.Trace(ctx.Args()...), fmt.Sprintf("One or more unknown argument types found in ‘%s’.", ctx.Args()))
	}

	doMirrorSession(session)
	session.Delete()
}
Esempio n. 9
0
// mainCopy is the entry point for cp command.
func mainCopy(ctx *cli.Context) {
	// Set global flags from context.
	setGlobalsFromContext(ctx)

	// check 'copy' cli arguments.
	checkCopySyntax(ctx)

	// Additional command speific theme customization.
	console.SetColor("Copy", color.New(color.FgGreen, color.Bold))

	session := newSessionV6()
	session.Header.CommandType = "cp"
	session.Header.CommandBoolFlags["recursive"] = ctx.Bool("recursive")

	var e error
	if session.Header.RootPath, e = os.Getwd(); e != nil {
		session.Delete()
		fatalIf(probe.NewError(e), "Unable to get current working folder.")
	}

	// extract URLs.
	session.Header.CommandArgs = ctx.Args()
	doCopySession(session)
	session.Delete()
}
Esempio n. 10
0
// main entry point for update command.
func mainUpdate(ctx *cli.Context) {
	// Check for update.
	if ctx.Bool("experimental") {
		getReleaseUpdate(minioUpdateExperimentalURL)
	} else {
		getReleaseUpdate(minioUpdateStableURL)
	}
}
Esempio n. 11
0
// checkEventsRemoveSyntax - validate all the passed arguments
func checkEventsRemoveSyntax(ctx *cli.Context) {
	if len(ctx.Args()) == 0 || len(ctx.Args()) > 2 {
		cli.ShowCommandHelpAndExit(ctx, "remove", 1) // last argument is exit code
	}
	if len(ctx.Args()) == 1 && !ctx.Bool("force") {
		fatalIf(probe.NewError(errors.New("")), "--force flag needs to be passed to remove all bucket notifications")
	}
}
Esempio n. 12
0
func checkCopySyntax(ctx *cli.Context) {
	if len(ctx.Args()) < 2 {
		cli.ShowCommandHelpAndExit(ctx, "cp", 1) // last argument is exit code.
	}

	// extract URLs.
	URLs := ctx.Args()
	if len(URLs) < 2 {
		fatalIf(errDummy().Trace(ctx.Args()...), fmt.Sprintf("Unable to parse source and target arguments."))
	}

	srcURLs := URLs[:len(URLs)-1]
	tgtURL := URLs[len(URLs)-1]
	isRecursive := ctx.Bool("recursive")

	/****** Generic Invalid Rules *******/
	// Verify if source(s) exists.
	for _, srcURL := range srcURLs {
		_, _, err := url2Stat(srcURL)
		if err != nil {
			fatalIf(err.Trace(srcURL), fmt.Sprintf("Unable to stat '%s'.", srcURL))
		}
	}

	// Check if bucket name is passed for URL type arguments.
	url := newClientURL(tgtURL)
	if url.Host != "" {
		// This check is for type URL.
		if !isURLVirtualHostStyle(url.Host) {
			if url.Path == string(url.Separator) {
				fatalIf(errInvalidArgument().Trace(), fmt.Sprintf("Target ‘%s’ does not contain bucket name.", tgtURL))
			}
		}
	}

	// Guess CopyURLsType based on source and target URLs.
	copyURLsType, err := guessCopyURLType(srcURLs, tgtURL, isRecursive)
	if err != nil {
		fatalIf(errInvalidArgument().Trace(), "Unable to guess the type of copy operation.")
	}
	switch copyURLsType {
	case copyURLsTypeA: // File -> File.
		checkCopySyntaxTypeA(srcURLs, tgtURL)
	case copyURLsTypeB: // File -> Folder.
		checkCopySyntaxTypeB(srcURLs, tgtURL)
	case copyURLsTypeC: // Folder... -> Folder.
		checkCopySyntaxTypeC(srcURLs, tgtURL, isRecursive)
	case copyURLsTypeD: // File1...FileN -> Folder.
		checkCopySyntaxTypeD(srcURLs, tgtURL)
	default:
		fatalIf(errInvalidArgument().Trace(), "Unable to guess the type of copy operation.")
	}
}
Esempio n. 13
0
// mainList - is a handler for mc ls command
func mainList(ctx *cli.Context) error {
	// Additional command specific theme customization.
	console.SetColor("File", color.New(color.Bold))
	console.SetColor("Dir", color.New(color.FgCyan, color.Bold))
	console.SetColor("Size", color.New(color.FgYellow))
	console.SetColor("Time", color.New(color.FgGreen))

	// Set global flags from context.
	setGlobalsFromContext(ctx)

	// check 'ls' cli arguments.
	checkListSyntax(ctx)

	// Set command flags from context.
	isRecursive := ctx.Bool("recursive")
	isIncomplete := ctx.Bool("incomplete")

	args := ctx.Args()
	// mimic operating system tool behavior.
	if !ctx.Args().Present() {
		args = []string{"."}
	}

	var cErr error
	for _, targetURL := range args {
		var clnt Client
		clnt, err := newClient(targetURL)
		fatalIf(err.Trace(targetURL), "Unable to initialize target ‘"+targetURL+"’.")

		var st *clientContent
		if st, err = clnt.Stat(isIncomplete); err != nil {
			switch err.ToGoError().(type) {
			case BucketNameEmpty:
			// For aliases like ``mc ls s3`` it's acceptable to receive BucketNameEmpty error.
			// Nothing to do.
			default:
				fatalIf(err.Trace(targetURL), "Unable to initialize target ‘"+targetURL+"’.")
			}
		} else if st.Type.IsDir() {
			if !strings.HasSuffix(targetURL, string(clnt.GetURL().Separator)) {
				targetURL = targetURL + string(clnt.GetURL().Separator)
			}
			clnt, err = newClient(targetURL)
			fatalIf(err.Trace(targetURL), "Unable to initialize target ‘"+targetURL+"’.")
		}
		if e := doList(clnt, isRecursive, isIncomplete); e != nil {
			cErr = e
		}
	}
	return cErr
}
Esempio n. 14
0
// main entry point for update command.
func mainUpdate(ctx *cli.Context) {
	// Set global flags from context.
	setGlobalsFromContext(ctx)

	// Additional command speific theme customization.
	console.SetColor("Update", color.New(color.FgGreen, color.Bold))

	// Check for update.
	if ctx.Bool("experimental") {
		getReleaseUpdate(mcUpdateExperimentalURL)
	} else {
		getReleaseUpdate(mcUpdateStableURL)
	}
}
Esempio n. 15
0
// Parse command arguments and set global variables accordingly
func setGlobalsFromContext(c *cli.Context) {
	// Set config dir
	switch {
	case c.IsSet("config-dir"):
		globalConfigDir = c.String("config-dir")
	case c.GlobalIsSet("config-dir"):
		globalConfigDir = c.GlobalString("config-dir")
	}
	if globalConfigDir == "" {
		console.Fatalf("Unable to get config file. Config directory is empty.")
	}
	// Set global quiet flag.
	globalQuiet = c.Bool("quiet") || c.GlobalBool("quiet")
}
Esempio n. 16
0
// main for rm command.
func mainRm(ctx *cli.Context) {
	// Set global flags from context.
	setGlobalsFromContext(ctx)

	// check 'rm' cli arguments.
	checkRmSyntax(ctx)

	// rm specific flags.
	isForce := ctx.Bool("force")
	isIncomplete := ctx.Bool("incomplete")
	isRecursive := ctx.Bool("recursive")
	isFake := ctx.Bool("fake")

	// Set color.
	console.SetColor("Remove", color.New(color.FgGreen, color.Bold))

	// Support multiple targets.
	for _, url := range ctx.Args() {
		targetAlias, targetURL, _ := mustExpandAlias(url)
		if isRecursive && isForce {
			rmAll(targetAlias, targetURL, isRecursive, isIncomplete, isFake)
		} else {
			if err := rm(targetAlias, targetURL, isIncomplete, isFake); err != nil {
				errorIf(err.Trace(url), "Unable to remove ‘"+url+"’.")
				continue
			}
			printMsg(rmMessage{Status: "success", URL: url})
		}
	}
}
Esempio n. 17
0
// Set global states. NOTE: It is deliberately kept monolithic to ensure we dont miss out any flags.
func setGlobalsFromContext(ctx *cli.Context) {
	quiet := ctx.Bool("quiet") || ctx.GlobalBool("quiet")
	debug := ctx.Bool("debug") || ctx.GlobalBool("debug")
	json := ctx.Bool("json") || ctx.GlobalBool("json")
	noColor := ctx.Bool("no-color") || ctx.GlobalBool("no-color")
	insecure := ctx.Bool("insecure") || ctx.GlobalBool("insecure")
	setGlobals(quiet, debug, json, noColor, insecure)
}
Esempio n. 18
0
// main for rm command.
func mainRm(ctx *cli.Context) {
	checkRmSyntax(ctx)

	// rm specific flags.
	isForce := ctx.Bool("force")
	isIncomplete := ctx.Bool("incomplete")

	// Set color.
	console.SetColor("Remove", color.New(color.FgGreen, color.Bold))

	// Parse args.
	URLs, err := args2URLs(ctx.Args())
	fatalIf(err.Trace(ctx.Args()...), "Unable to parse arguments.")

	// Support multiple targets.
	for _, url := range URLs {
		if isURLRecursive(url) && isForce {
			url := stripRecursiveURL(url)
			removeTopFolder := false

			// find if the URL is dir or not.
			_, content, err := url2Stat(url)
			fatalIf(err.Trace(url), "Unable to stat ‘"+url+"’.")

			if content.Type.IsDir() {
				/* Determine whether to remove the top folder or only its
				contents. If the URL does not end with a separator, then
				include the top folder as well, otherwise not. */
				u := client.NewURL(url)
				if !strings.HasSuffix(url, string(u.Separator)) {
					// Add separator at the end to remove all its contents.
					url = url + string(u.Separator)
					// Remember to remove the top most folder.
					removeTopFolder = true
				}
			}
			// Remove contents of this folder.
			rmAll(url, isIncomplete)
			if removeTopFolder {
				// Remove top folder as well.
				rm(url, isIncomplete)
			}

		} else {
			rm(url, isIncomplete)
		}
	}
}
Esempio n. 19
0
// checkMirrorSyntax(URLs []string)
func checkMirrorSyntax(ctx *cli.Context) {
	if len(ctx.Args()) != 2 {
		cli.ShowCommandHelpAndExit(ctx, "mirror", 1) // last argument is exit code.
	}

	// extract URLs.
	URLs := ctx.Args()
	srcURL := URLs[0]
	tgtURL := URLs[1]

	/****** Generic rules *******/
	if !ctx.Bool("watch") {
		_, srcContent, err := url2Stat(srcURL)
		// incomplete uploads are not necessary for copy operation, no need to verify for them.
		isIncomplete := false
		if err != nil && !isURLPrefixExists(srcURL, isIncomplete) {
			errorIf(err.Trace(srcURL), "Unable to stat source ‘"+srcURL+"’.")
		}

		if err == nil && !srcContent.Type.IsDir() {
			fatalIf(errInvalidArgument().Trace(srcContent.URL.String(), srcContent.Type.String()), fmt.Sprintf("Source ‘%s’ is not a folder. Only folders are supported by mirror command.", srcURL))
		}
	}

	if len(tgtURL) == 0 && tgtURL == "" {
		fatalIf(errInvalidArgument().Trace(), "Invalid target arguments to mirror command.")
	}

	url := newClientURL(tgtURL)
	if url.Host != "" {
		if !isURLVirtualHostStyle(url.Host) {
			if url.Path == string(url.Separator) {
				fatalIf(errInvalidArgument().Trace(tgtURL),
					fmt.Sprintf("Target ‘%s’ does not contain bucket name.", tgtURL))
			}
		}
	}
	_, _, err := url2Stat(tgtURL)
	// we die on any error other than PathNotFound - destination directory need not exist.
	switch err.ToGoError().(type) {
	case PathNotFound:
	case ObjectMissing:
	default:
		fatalIf(err.Trace(tgtURL), fmt.Sprintf("Unable to stat target ‘%s’.", tgtURL))
	}
}
Esempio n. 20
0
// main entry point for update command.
func mainUpdate(ctx *cli.Context) {
	// Error out if 'update' command is issued for development based builds.
	if Version == "DEVELOPMENT.GOGET" {
		fatalIf(errors.New(""), "Update mechanism is not supported for ‘go get’ based binary builds. Please download official releases from https://minio.io/#minio")
	}

	// Check for update.
	var updateMsg updateMessage
	var errMsg string
	var err error
	if ctx.Bool("experimental") {
		updateMsg, errMsg, err = getReleaseUpdate(minioUpdateExperimentalURL)
	} else {
		updateMsg, errMsg, err = getReleaseUpdate(minioUpdateStableURL)
	}
	fatalIf(err, errMsg)
	console.Println(updateMsg)
}
Esempio n. 21
0
// main entry point for update command.
func mainUpdate(ctx *cli.Context) error {
	// Set global flags from context.
	setGlobalsFromContext(ctx)

	// Additional command speific theme customization.
	console.SetColor("Update", color.New(color.FgGreen, color.Bold))

	var updateMsg updateMessage
	var errMsg string
	var err *probe.Error
	// Check for update.
	if ctx.Bool("experimental") {
		updateMsg, errMsg, err = getReleaseUpdate(mcUpdateExperimentalURL)
	} else {
		updateMsg, errMsg, err = getReleaseUpdate(mcUpdateStableURL)
	}
	fatalIf(err, errMsg)
	printMsg(updateMsg)
	return nil
}
Esempio n. 22
0
// "minio control shutdown" entry point.
func shutdownControl(c *cli.Context) {
	if len(c.Args()) != 1 {
		cli.ShowCommandHelpAndExit(c, "shutdown", 1)
	}

	parsedURL, err := url.Parse(c.Args()[0])
	fatalIf(err, "Unable to parse URL.")

	authCfg := &authConfig{
		accessKey:   serverConfig.GetCredential().AccessKeyID,
		secretKey:   serverConfig.GetCredential().SecretAccessKey,
		address:     parsedURL.Host,
		path:        path.Join(reservedBucket, controlPath),
		loginMethod: "Controller.LoginHandler",
	}
	client := newAuthClient(authCfg)

	args := &ShutdownArgs{Restart: c.Bool("restart")}
	err = client.Call("Controller.ShutdownHandler", args, &GenericReply{})
	errorIf(err, "Shutting down Minio server at %s failed.", parsedURL.Host)
}
Esempio n. 23
0
// checkListSyntax - validate all the passed arguments
func checkListSyntax(ctx *cli.Context) {
	args := ctx.Args()
	if !ctx.Args().Present() {
		args = []string{"."}
	}
	for _, arg := range args {
		if strings.TrimSpace(arg) == "" {
			fatalIf(errInvalidArgument().Trace(args...), "Unable to validate empty argument.")
		}
	}
	// extract URLs.
	URLs := ctx.Args()
	isIncomplete := ctx.Bool("incomplete")

	for _, url := range URLs {
		_, _, err := url2Stat(url)
		if err != nil && !isURLPrefixExists(url, isIncomplete) {
			fatalIf(err.Trace(url), "Unable to stat ‘"+url+"’.")
		}
	}
}
Esempio n. 24
0
// checkShareUploadSyntax - validate command-line args.
func checkShareUploadSyntax(ctx *cli.Context) {
	args := ctx.Args()
	if !args.Present() {
		cli.ShowCommandHelpAndExit(ctx, "upload", 1) // last argument is exit code.
	}

	// Set command flags from context.
	isRecursive := ctx.Bool("recursive")
	expireArg := ctx.String("expire")

	// Parse expiry.
	expiry := shareDefaultExpiry
	if expireArg != "" {
		var e error
		expiry, e = time.ParseDuration(expireArg)
		fatalIf(probe.NewError(e), "Unable to parse expire=‘"+expireArg+"’.")
	}

	// Validate expiry.
	if expiry.Seconds() < 1 {
		fatalIf(errDummy().Trace(expiry.String()),
			"Expiry cannot be lesser than 1 second.")
	}
	if expiry.Seconds() > 604800 {
		fatalIf(errDummy().Trace(expiry.String()),
			"Expiry cannot be larger than 7 days.")
	}

	for _, targetURL := range ctx.Args() {
		url := client.NewURL(targetURL)
		if strings.HasSuffix(targetURL, string(url.Separator)) && !isRecursive {
			fatalIf(errInvalidArgument().Trace(targetURL),
				"Use --recursive option to generate curl command for prefixes.")
		}
	}
}
Esempio n. 25
0
// main for rm command.
func mainRm(ctx *cli.Context) error {
	// Set global flags from context.
	setGlobalsFromContext(ctx)

	// check 'rm' cli arguments.
	checkRmSyntax(ctx)

	// rm specific flags.
	isIncomplete := ctx.Bool("incomplete")
	isRecursive := ctx.Bool("recursive")
	isFake := ctx.Bool("fake")
	isStdin := ctx.Bool("stdin")
	older := ctx.Int("older-than")

	// Set color.
	console.SetColor("Remove", color.New(color.FgGreen, color.Bold))

	// Support multiple targets.
	for _, url := range ctx.Args() {
		if isRecursive {
			return removeRecursive(url, isIncomplete, isFake, older)
		} // else {
		return removeSingle(url, isIncomplete, isFake, older)
	}

	if !isStdin {
		return nil
	}

	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		url := scanner.Text()
		if isRecursive {
			return removeRecursive(url, isIncomplete, isFake, older)
		} // else {
		return removeSingle(url, isIncomplete, isFake, older)
	}
	return nil
}
Esempio n. 26
0
// Main entry point for mirror command.
func mainMirror(ctx *cli.Context) error {
	// Set global flags from context.
	setGlobalsFromContext(ctx)

	// check 'mirror' cli arguments.
	checkMirrorSyntax(ctx)

	// Additional command speific theme customization.
	console.SetColor("Mirror", color.New(color.FgGreen, color.Bold))

	session := newSessionV8()
	session.Header.CommandType = "mirror"

	if v, err := os.Getwd(); err == nil {
		session.Header.RootPath = v
	} else {
		session.Delete()
		fatalIf(probe.NewError(err), "Unable to get current working folder.")
	}

	// Set command flags from context.
	session.Header.CommandBoolFlags["force"] = ctx.Bool("force")
	session.Header.CommandBoolFlags["fake"] = ctx.Bool("fake")
	session.Header.CommandBoolFlags["watch"] = ctx.Bool("watch")
	session.Header.CommandBoolFlags["remove"] = ctx.Bool("remove")

	// extract URLs.
	session.Header.CommandArgs = ctx.Args()

	ms := newMirrorSession(session)

	// Mirroring.
	ms.mirror()

	// delete will be run when terminating normally,
	ms.Delete()

	return nil
}
Esempio n. 27
0
// Validate command line arguments.
func checkRmSyntax(ctx *cli.Context) {
	// Set command flags from context.
	isForce := ctx.Bool("force")
	isRecursive := ctx.Bool("recursive")
	isStdin := ctx.Bool("stdin")

	if !ctx.Args().Present() && !isStdin {
		exitCode := 1
		cli.ShowCommandHelpAndExit(ctx, "rm", exitCode)
	}

	// For all recursive operations make sure to check for 'force' flag.
	if (isRecursive || isStdin) && !isForce {
		fatalIf(errDummy().Trace(),
			"Removal requires --force option. This operational is *IRREVERSIBLE*. Please review carefully before performing this *DANGEROUS* operation.")
	}
}
Esempio n. 28
0
// Validate command line arguments.
func checkRmSyntax(ctx *cli.Context) {
	// Set command flags from context.
	isForce := ctx.Bool("force")
	isRecursive := ctx.Bool("recursive")
	isIncomplete := ctx.Bool("incomplete")

	if !ctx.Args().Present() {
		exitCode := 1
		cli.ShowCommandHelpAndExit(ctx, "rm", exitCode)
	}

	if !isRecursive && !isIncomplete {
		for _, url := range ctx.Args() {
			if _, _, err := url2Stat(url); err != nil {
				fatalIf(err.Trace(url), "Unable to stat.")
			}
		}
	}

	if isRecursive && !isForce {
		fatalIf(errDummy().Trace(),
			"Recursive removal requires --force option. Please review carefully before performing this *DANGEROUS* operation.")
	}
}
Esempio n. 29
0
func mainWatch(ctx *cli.Context) error {
	console.SetColor("Time", color.New(color.FgGreen))
	console.SetColor("Size", color.New(color.FgYellow))
	console.SetColor("EventType", color.New(color.FgCyan, color.Bold))
	console.SetColor("ObjectName", color.New(color.Bold))

	setGlobalsFromContext(ctx)
	checkWatchSyntax(ctx)

	args := ctx.Args()
	path := args[0]

	prefix := ctx.String("prefix")
	suffix := ctx.String("suffix")
	events := strings.Split(ctx.String("events"), ",")
	recursive := ctx.Bool("recursive")

	s3Client, pErr := newClient(path)
	if pErr != nil {
		fatalIf(pErr.Trace(), "Cannot parse the provided url.")
	}

	params := watchParams{
		recursive: recursive,
		accountID: fmt.Sprintf("%d", time.Now().Unix()),
		events:    events,
		prefix:    prefix,
		suffix:    suffix,
	}

	// Start watching on events
	wo, err := s3Client.Watch(params)
	fatalIf(err, "Cannot watch on the specified bucket.")

	trapCh := signalTrap(os.Interrupt, syscall.SIGTERM)

	// Initialize.. waitgroup to track the go-routine.
	wg := sync.WaitGroup{}

	// Increment wait group to wait subsequent routine.
	wg.Add(1)

	// Start routine to watching on events.
	go func() {
		defer wg.Done()

		// Wait for all events.
		for {
			select {
			case <-trapCh:
				// Signal received we are done.
				close(wo.done)
				return
			case event, ok := <-wo.Events():
				if !ok {
					return
				}
				msg := watchMessage{Event: event}
				printMsg(msg)
			case err, ok := <-wo.Errors():
				if !ok {
					return
				}
				errorIf(err, "Cannot watch on events.")
				return
			}
		}
	}()

	// Wait on the routine to be finished or exit.
	wg.Wait()

	return nil
}