diff --git a/docs.kosli.com/content/faq/_index.md b/docs.kosli.com/content/faq/_index.md index 06934641f..3cdfe912c 100644 --- a/docs.kosli.com/content/faq/_index.md +++ b/docs.kosli.com/content/faq/_index.md @@ -242,3 +242,17 @@ kosli attest generic Dockerfile true ... ``` The parser then sees `Dockerfile` and `true` as the two arguments to `kosli attest generic`. + +## Path/Image name is a single whitespace character! + +In order to calculate the fingerprint for an artifact, Kosli requires the path to the relevant file or directory, or the relevant image name. The command typically takes the form: +``` +kosli attest generic [IMAGE-NAME | FILE-PATH | DIR-PATH] [flags] +``` + +When using multi-line commands in the shell or a script, if the image name or path has not been provided as above and whitespace has unintentionally been added after the line-continuation backslash on one of the lines, this whitespace character is interpreted as the name or path. + +If you're using multi-line commands and receive an error message similar to this, check your command for extraneous whitespace: +``` +Error: failed to calculate artifact fingerprint: stat : no such file or directory. The directory path is ' '. +``` \ No newline at end of file diff --git a/internal/digest/digest.go b/internal/digest/digest.go index 984f9a504..a2c262b3c 100644 --- a/internal/digest/digest.go +++ b/internal/digest/digest.go @@ -35,6 +35,9 @@ func DirSha256(dirPath string, excludePaths []string, logger *logger.Logger) (st logger.Debug("calculating fingerprint for path [%s] -- excluding paths: %s", dirPath, excludePaths) info, err := os.Stat(dirPath) if err != nil { + if dirPath == " " { + return "", fmt.Errorf("%s. The directory path is '%s'. https://docs.kosli.com/faq/#pathimage-name-is-a-single-whitespace-character", err, dirPath) + } return "", err } if !info.IsDir() { @@ -83,6 +86,9 @@ func OciSha256(artifactName string, registryUsername string, registryPassword st // Parse image reference ref, err := docker.ParseReference(imageName) if err != nil { + if artifactName == " " { + return "", fmt.Errorf("%w. The artifact name is '%s'. https://docs.kosli.com/faq/#pathimage-name-is-a-single-whitespace-character", err, artifactName) + } return "", fmt.Errorf("failed to parse image reference for %s: %w", imageName, err) } @@ -171,6 +177,9 @@ func FileSha256(filepath string) (string, error) { hasher := sha256.New() f, err := os.Open(filepath) if err != nil { + if filepath == " " { + return "", fmt.Errorf("%s. The filename is '%s'. https://docs.kosli.com/faq/#pathimage-name-is-a-single-whitespace-character", err, filepath) + } return "", err } defer f.Close() @@ -191,6 +200,9 @@ func DockerImageSha256(imageID string) (string, error) { } imageInspect, err := cli.ImageInspect(context.Background(), imageID) if err != nil { + if imageID == " " { + return "", fmt.Errorf("%s. The image ID is '%s'. https://docs.kosli.com/faq/#pathimage-name-is-a-single-whitespace-character", err, imageID) + } return "", err } repoDigests := imageInspect.RepoDigests