From da4e54c3db9018aa958b794657d49eb9bbcccddc Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 7 Jun 2016 20:30:09 +0200 Subject: [PATCH 1/4] Change stdin handling to be only used if needed or if user asks for it License: MIT Signed-off-by: Jakub Sztandera --- commands/cli/parse.go | 59 ++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 34 deletions(-) diff --git a/commands/cli/parse.go b/commands/cli/parse.go index 680fa466e87..471886c6cea 100644 --- a/commands/cli/parse.go +++ b/commands/cli/parse.go @@ -244,15 +244,6 @@ func parseArgs(inputs []string, stdin *os.File, argDefs []cmds.Argument, recursi stdin = nil } - // check if stdin is coming from terminal or is being piped in - if stdin != nil { - if term, err := isTerminal(stdin); err != nil { - return nil, nil, err - } else if term { - stdin = nil // set to nil so we ignore it - } - } - // count required argument definitions numRequired := 0 for _, argDef := range argDefs { @@ -293,9 +284,18 @@ func parseArgs(inputs []string, stdin *os.File, argDefs []cmds.Argument, recursi numRequired-- } + fillingVariadic := argDefIndex+1 > len(argDefs) + var err error if argDef.Type == cmds.ArgString { - if stdin == nil { + if len(inputs) > 0 { + // If argument is "-" use stdin + if inputs[0] == "-" && argDef.SupportsStdin { + stringArgs, stdin, err = appendStdinAsString(stringArgs, stdin) + if err != nil { + return nil, nil, err + } + } // add string values stringArgs, inputs = appendString(stringArgs, inputs) } else if !argDef.SupportsStdin { @@ -307,35 +307,39 @@ func parseArgs(inputs []string, stdin *os.File, argDefs []cmds.Argument, recursi stringArgs, inputs = appendString(stringArgs, inputs) } else { - if len(inputs) > 0 { - // don't use stdin if we have inputs - stdin = nil - } else { + if stdin != nil && argDef.Required && !fillingVariadic { // if we have a stdin, read it in and use the data as a string value stringArgs, stdin, err = appendStdinAsString(stringArgs, stdin) if err != nil { return nil, nil, err } + } else { + break } } } else if argDef.Type == cmds.ArgFile { - if stdin == nil || !argDef.SupportsStdin { + if len(inputs) > 0 { // treat stringArg values as file paths fpath := inputs[0] inputs = inputs[1:] - file, err := appendFile(fpath, argDef, recursive, hidden) + var file files.File + var err error + if fpath == "-" { + file = files.NewReaderFile("", "", stdin, nil) + } else { + file, err = appendFile(fpath, argDef, recursive, hidden) + } if err != nil { return nil, nil, err } fileArgs[fpath] = file } else { - if len(inputs) > 0 { - // don't use stdin if we have inputs - stdin = nil - } else { - // if we have a stdin, create a file from it + if stdin != nil && argDef.SupportsStdin && + argDef.Required && !fillingVariadic { fileArgs[""] = files.NewReaderFile("", "", stdin, nil) + } else { + break } } } @@ -431,16 +435,3 @@ func appendFile(fpath string, argDef *cmds.Argument, recursive, hidden bool) (fi return files.NewSerialFile(path.Base(fpath), fpath, hidden, stat) } - -// isTerminal returns true if stdin is a Stdin pipe (e.g. `cat file | ipfs`), -// and false otherwise (e.g. nothing is being piped in, so stdin is -// coming from the terminal) -func isTerminal(stdin *os.File) (bool, error) { - stat, err := stdin.Stat() - if err != nil { - return false, err - } - - // if stdin is a CharDevice, return true - return ((stat.Mode() & os.ModeCharDevice) != 0), nil -} From 4190076c6673fdd8d186c5fcfa2420ae7686ae6d Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 8 Jun 2016 12:22:32 +0200 Subject: [PATCH 2/4] Add the time-out script License: MIT Signed-off-by: Jakub Sztandera --- test/bin/.gitignore | 1 + test/bin/time-out | 91 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100755 test/bin/time-out diff --git a/test/bin/.gitignore b/test/bin/.gitignore index c032badeef4..8eec62514ef 100644 --- a/test/bin/.gitignore +++ b/test/bin/.gitignore @@ -8,3 +8,4 @@ !checkflags !continueyn !verify-go-fmt.sh +!time-out diff --git a/test/bin/time-out b/test/bin/time-out new file mode 100755 index 00000000000..5c19d2ec9fb --- /dev/null +++ b/test/bin/time-out @@ -0,0 +1,91 @@ +#!/bin/bash +# +# The Bash shell script executes a command with a time-out. +# Upon time-out expiration SIGTERM (15) is sent to the process. If the signal +# is blocked, then the subsequent SIGKILL (9) terminates it. +# +# Based on the Bash documentation example. + +# Hello Chet, +# please find attached a "little easier" :-) to comprehend +# time-out example. If you find it suitable, feel free to include +# anywhere: the very same logic as in the original examples/scripts, a +# little more transparent implementation to my taste. +# +# Dmitry V Golovashkin + +scriptName="${0##*/}" + +declare -i DEFAULT_TIMEOUT=9 +declare -i DEFAULT_INTERVAL=1 +declare -i DEFAULT_DELAY=1 + +# Timeout. +declare -i timeout=DEFAULT_TIMEOUT +# Interval between checks if the process is still alive. +declare -i interval=DEFAULT_INTERVAL +# Delay between posting the SIGTERM signal and destroying the process by SIGKILL. +declare -i delay=DEFAULT_DELAY + +function printUsage() { + cat < 0)); do + sleep $interval + kill -0 $$ || exit 0 + ((t -= interval)) + done + + # Be nice, post SIGTERM first. + # The 'exit 0' below will be executed if any preceeding command fails. + kill -s SIGTERM $$ && kill -0 $$ || exit 0 + sleep $delay + kill -s SIGKILL $$ +) 2> /dev/null & + +exec "$@" From 6822c0c6703407ec11a42a9d24449eb173de0283 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 7 Jun 2016 20:54:21 +0200 Subject: [PATCH 3/4] Revert "Revert "Implements repository initialization with default config"" This reverts commit 77ef3913d9f5682c5a0dedbba5488e794e9da1b5. License: MIT Signed-off-by: Jakub Sztandera --- cmd/ipfs/init.go | 37 +++++++++++++++---- test/sharness/t0022-init-default.sh | 55 +++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 7 deletions(-) create mode 100755 test/sharness/t0022-init-default.sh diff --git a/cmd/ipfs/init.go b/cmd/ipfs/init.go index 2492268a730..86c84d005eb 100644 --- a/cmd/ipfs/init.go +++ b/cmd/ipfs/init.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "errors" "fmt" "io" @@ -33,7 +34,9 @@ environment variable: export IPFS_PATH=/path/to/ipfsrepo `, }, - + Arguments: []cmds.Argument{ + cmds.FileArg("default-config", false, false, "Initialize with the given configuration.").EnableStdin(), + }, Options: []cmds.Option{ cmds.IntOption("bits", "b", "Number of bits to use in the generated RSA private key.").Default(nBitsForKeypairDefault), cmds.BoolOption("empty-repo", "e", "Don't add and pin help files to the local storage.").Default(false), @@ -76,7 +79,24 @@ environment variable: return } - if err := doInit(os.Stdout, req.InvocContext().ConfigRoot, empty, nBitsForKeypair); err != nil { + var conf *config.Config + + f := req.Files() + if f != nil { + confFile, err := f.NextFile() + if err != nil { + res.SetError(err, cmds.ErrNormal) + return + } + + conf = &config.Config{} + if err := json.NewDecoder(confFile).Decode(conf); err != nil { + res.SetError(err, cmds.ErrNormal) + return + } + } + + if err := doInit(os.Stdout, req.InvocContext().ConfigRoot, empty, nBitsForKeypair, conf); err != nil { res.SetError(err, cmds.ErrNormal) return } @@ -88,10 +108,10 @@ Reinitializing would overwrite your keys. `) func initWithDefaults(out io.Writer, repoRoot string) error { - return doInit(out, repoRoot, false, nBitsForKeypairDefault) + return doInit(out, repoRoot, false, nBitsForKeypairDefault, nil) } -func doInit(out io.Writer, repoRoot string, empty bool, nBitsForKeypair int) error { +func doInit(out io.Writer, repoRoot string, empty bool, nBitsForKeypair int, conf *config.Config) error { if _, err := fmt.Fprintf(out, "initializing ipfs node at %s\n", repoRoot); err != nil { return err } @@ -104,9 +124,12 @@ func doInit(out io.Writer, repoRoot string, empty bool, nBitsForKeypair int) err return errRepoExists } - conf, err := config.Init(out, nBitsForKeypair) - if err != nil { - return err + if conf == nil { + var err error + conf, err = config.Init(out, nBitsForKeypair) + if err != nil { + return err + } } if err := fsrepo.Init(repoRoot, conf); err != nil { diff --git a/test/sharness/t0022-init-default.sh b/test/sharness/t0022-init-default.sh new file mode 100755 index 00000000000..8adb7fa7f0a --- /dev/null +++ b/test/sharness/t0022-init-default.sh @@ -0,0 +1,55 @@ +#!/bin/sh +# +# Copyright (c) 2014 Christian Couder +# MIT Licensed; see the LICENSE file in this repository. +# + +test_description="Test init command with default config" + +. lib/test-lib.sh + +cfg_key="Addresses.API" +cfg_val="/ip4/0.0.0.0/tcp/5001" + +# test that init succeeds +test_expect_success "ipfs init succeeds" ' + export IPFS_PATH="$(pwd)/.ipfs" && + echo "IPFS_PATH: \"$IPFS_PATH\"" && + BITS="2048" && + ipfs init --bits="$BITS" >actual_init || + test_fsh cat actual_init +' + +test_expect_success ".ipfs/config has been created" ' + test -f "$IPFS_PATH"/config || + test_fsh ls -al .ipfs +' + +test_expect_success "ipfs config succeeds" ' + ipfs config $cfg_flags "$cfg_key" "$cfg_val" +' + +test_expect_success "ipfs read config succeeds" ' + IPFS_DEFAULT_CONFIG=$(cat "$IPFS_PATH"/config) +' + +test_expect_success "clean up ipfs dir" ' + rm -rf "$IPFS_PATH" +' + +test_expect_success "ipfs init default config succeeds" ' + echo $IPFS_DEFAULT_CONFIG | ipfs init - >actual_init || + test_fsh cat actual_init +' + +test_expect_success "ipfs config output looks good" ' + echo "$cfg_val" >expected && + ipfs config "$cfg_key" >actual && + test_cmp expected actual +' + +test_launch_ipfs_daemon + +test_kill_ipfs_daemon + +test_done From 628e458e7db54ab63d6226c9012f2f69f99d10ff Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Tue, 7 Jun 2016 23:15:07 +0200 Subject: [PATCH 4/4] Add regression sharness test for ipfs init This tests expects ipfs init with no arguments to work even with occuipied stdin. License: MIT Signed-off-by: Jakub Sztandera --- test/bin/time-out | 8 -------- test/sharness/t0500-issues-and-regressions-offline.sh | 6 ++++++ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/test/bin/time-out b/test/bin/time-out index 5c19d2ec9fb..47d863bd0f5 100755 --- a/test/bin/time-out +++ b/test/bin/time-out @@ -6,14 +6,6 @@ # # Based on the Bash documentation example. -# Hello Chet, -# please find attached a "little easier" :-) to comprehend -# time-out example. If you find it suitable, feel free to include -# anywhere: the very same logic as in the original examples/scripts, a -# little more transparent implementation to my taste. -# -# Dmitry V Golovashkin - scriptName="${0##*/}" declare -i DEFAULT_TIMEOUT=9 diff --git a/test/sharness/t0500-issues-and-regressions-offline.sh b/test/sharness/t0500-issues-and-regressions-offline.sh index 866edba0c01..5e755065532 100755 --- a/test/sharness/t0500-issues-and-regressions-offline.sh +++ b/test/sharness/t0500-issues-and-regressions-offline.sh @@ -8,4 +8,10 @@ test_init_ipfs # Tests go here +test_expect_success "ipfs init with occupied input works - #2748" ' + export IPFS_PATH="ipfs_path" + echo "" | time-out ipfs init && + rm -rf ipfs_path +' + test_done