diff --git a/lang/inputs/inputs.go b/lang/inputs/inputs.go index c50580578f..034c815b88 100644 --- a/lang/inputs/inputs.go +++ b/lang/inputs/inputs.go @@ -27,9 +27,12 @@ import ( "fmt" "io/ioutil" "os" + "path" "path/filepath" "strings" + "github.com/pkg/errors" + "github.com/purpleidea/mgmt/engine" "github.com/purpleidea/mgmt/gapi" "github.com/purpleidea/mgmt/lang/interfaces" @@ -205,6 +208,7 @@ func inputMetadata(s string, fs engine.Fs) (*ParsedInput, error) { // real files/ directory if metadata.Files != "" { // TODO: nil pointer instead? filesDir := basePath + metadata.Files + // TODO: handle files that throw stat(2) errors if _, err := fs.Stat(filesDir); err == nil { files = append(files, filesDir) } @@ -274,25 +278,31 @@ func inputMcl(s string, fs engine.Fs) (*ParsedInput, error) { // inputDirectory checks if we're given the path to a directory. func inputDirectory(s string, fs engine.Fs) (*ParsedInput, error) { - if !strings.HasSuffix(s, "/") { - return nil, nil // not us, but no error - } - var err error - if s, err = absify(s); err != nil { // s is now absolute - return nil, err - } // does dir exist? fi, err := fs.Stat(s) if err != nil { - return nil, errwrap.Wrapf(err, "dir: `%s` does not exist", s) + if errors.Is(err, os.ErrNotExist) { + return nil, nil // not us, but no error + } + + return nil, errwrap.Wrapf(err, "could not stat dir `%s`", s) } if !fi.IsDir() { return nil, errwrap.Wrapf(err, "dir: `%s` is not a dir", s) } + if s, err = absify(s); err != nil { // s is now absolute + return nil, err + } + // try looking for a metadata file in the root - md := s + interfaces.MetadataFilename // absolute file - if _, err := fs.Stat(md); err == nil { + md := path.Join(s, interfaces.MetadataFilename) // absolute file + _, err = fs.Stat(md) + // only return errors if they're not ENOENT, e.g. EPERM, EACCES + // ignore ENOENT errors and assume that the file is deliberately absent + if err != nil && !errors.Is(err, os.ErrNotExist) { + return nil, err + } else if err == nil { if x, err := inputMetadata(md, fs); err != nil { // recurse return nil, err } else if x != nil { @@ -301,8 +311,12 @@ func inputDirectory(s string, fs engine.Fs) (*ParsedInput, error) { } // try looking for a main.mcl file in the root - mf := s + interfaces.MainFilename // absolute file - if _, err := fs.Stat(mf); err == nil { + mf := path.Join(s, interfaces.MainFilename) // absolute file + _, err = fs.Stat(md) + // same error handling as above. ignore ENOENT and handle all others + if err != nil && !errors.Is(err, os.ErrNotExist) { + return nil, err + } else if err == nil { if x, err := inputMcl(mf, fs); err != nil { // recurse return nil, err } else if x != nil {