summaryrefslogtreecommitdiff
path: root/vendor/github.com/opencontainers/runtime-tools/specerror
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@gmail.com>2017-11-01 11:24:59 -0400
committerMatthew Heon <matthew.heon@gmail.com>2017-11-01 11:24:59 -0400
commita031b83a09a8628435317a03f199cdc18b78262f (patch)
treebc017a96769ce6de33745b8b0b1304ccf38e9df0 /vendor/github.com/opencontainers/runtime-tools/specerror
parent2b74391cd5281f6fdf391ff8ad50fd1490f6bf89 (diff)
downloadpodman-a031b83a09a8628435317a03f199cdc18b78262f.tar.gz
podman-a031b83a09a8628435317a03f199cdc18b78262f.tar.bz2
podman-a031b83a09a8628435317a03f199cdc18b78262f.zip
Initial checkin from CRI-O repo
Signed-off-by: Matthew Heon <matthew.heon@gmail.com>
Diffstat (limited to 'vendor/github.com/opencontainers/runtime-tools/specerror')
-rw-r--r--vendor/github.com/opencontainers/runtime-tools/specerror/error.go170
1 files changed, 170 insertions, 0 deletions
diff --git a/vendor/github.com/opencontainers/runtime-tools/specerror/error.go b/vendor/github.com/opencontainers/runtime-tools/specerror/error.go
new file mode 100644
index 000000000..c75bb6b14
--- /dev/null
+++ b/vendor/github.com/opencontainers/runtime-tools/specerror/error.go
@@ -0,0 +1,170 @@
+// Package specerror implements runtime-spec-specific tooling for
+// tracking RFC 2119 violations.
+package specerror
+
+import (
+ "fmt"
+
+ "github.com/hashicorp/go-multierror"
+ rfc2119 "github.com/opencontainers/runtime-tools/error"
+)
+
+const referenceTemplate = "https://github.com/opencontainers/runtime-spec/blob/v%s/%s"
+
+// Code represents the spec violation, enumerating both
+// configuration violations and runtime violations.
+type Code int
+
+const (
+ // NonError represents that an input is not an error
+ NonError Code = iota
+ // NonRFCError represents that an error is not a rfc2119 error
+ NonRFCError
+
+ // ConfigFileExistence represents the error code of 'config.json' existence test
+ ConfigFileExistence
+ // ArtifactsInSingleDir represents the error code of artifacts place test
+ ArtifactsInSingleDir
+
+ // SpecVersion represents the error code of specfication version test
+ SpecVersion
+
+ // RootOnNonHyperV represents the error code of root setting test on non hyper-v containers
+ RootOnNonHyperV
+ // RootOnHyperV represents the error code of root setting test on hyper-v containers
+ RootOnHyperV
+ // PathFormatOnWindows represents the error code of the path format test on Window
+ PathFormatOnWindows
+ // PathName represents the error code of the path name test
+ PathName
+ // PathExistence represents the error code of the path existence test
+ PathExistence
+ // ReadonlyFilesystem represents the error code of readonly test
+ ReadonlyFilesystem
+ // ReadonlyOnWindows represents the error code of readonly setting test on Windows
+ ReadonlyOnWindows
+
+ // DefaultFilesystems represents the error code of default filesystems test
+ DefaultFilesystems
+
+ // CreateWithID represents the error code of 'create' lifecyle test with 'id' provided
+ CreateWithID
+ // CreateWithUniqueID represents the error code of 'create' lifecyle test with unique 'id' provided
+ CreateWithUniqueID
+ // CreateNewContainer represents the error code 'create' lifecyle test that creates new container
+ CreateNewContainer
+)
+
+type errorTemplate struct {
+ Level rfc2119.Level
+ Reference func(version string) (reference string, err error)
+}
+
+// Error represents a runtime-spec violation.
+type Error struct {
+ // Err holds the RFC 2119 violation.
+ Err rfc2119.Error
+
+ // Code is a matchable holds a Code
+ Code Code
+}
+
+var (
+ containerFormatRef = func(version string) (reference string, err error) {
+ return fmt.Sprintf(referenceTemplate, version, "bundle.md#container-format"), nil
+ }
+ specVersionRef = func(version string) (reference string, err error) {
+ return fmt.Sprintf(referenceTemplate, version, "config.md#specification-version"), nil
+ }
+ rootRef = func(version string) (reference string, err error) {
+ return fmt.Sprintf(referenceTemplate, version, "config.md#root"), nil
+ }
+ defaultFSRef = func(version string) (reference string, err error) {
+ return fmt.Sprintf(referenceTemplate, version, "config-linux.md#default-filesystems"), nil
+ }
+ runtimeCreateRef = func(version string) (reference string, err error) {
+ return fmt.Sprintf(referenceTemplate, version, "runtime.md#create"), nil
+ }
+)
+
+var ociErrors = map[Code]errorTemplate{
+ // Bundle.md
+ // Container Format
+ ConfigFileExistence: {Level: rfc2119.Must, Reference: containerFormatRef},
+ ArtifactsInSingleDir: {Level: rfc2119.Must, Reference: containerFormatRef},
+
+ // Config.md
+ // Specification Version
+ SpecVersion: {Level: rfc2119.Must, Reference: specVersionRef},
+ // Root
+ RootOnNonHyperV: {Level: rfc2119.Required, Reference: rootRef},
+ RootOnHyperV: {Level: rfc2119.Must, Reference: rootRef},
+ // TODO: add tests for 'PathFormatOnWindows'
+ PathFormatOnWindows: {Level: rfc2119.Must, Reference: rootRef},
+ PathName: {Level: rfc2119.Should, Reference: rootRef},
+ PathExistence: {Level: rfc2119.Must, Reference: rootRef},
+ ReadonlyFilesystem: {Level: rfc2119.Must, Reference: rootRef},
+ ReadonlyOnWindows: {Level: rfc2119.Must, Reference: rootRef},
+
+ // Config-Linux.md
+ // Default Filesystems
+ DefaultFilesystems: {Level: rfc2119.Should, Reference: defaultFSRef},
+
+ // Runtime.md
+ // Create
+ CreateWithID: {Level: rfc2119.Must, Reference: runtimeCreateRef},
+ CreateWithUniqueID: {Level: rfc2119.Must, Reference: runtimeCreateRef},
+ CreateNewContainer: {Level: rfc2119.Must, Reference: runtimeCreateRef},
+}
+
+// Error returns the error message with specification reference.
+func (err *Error) Error() string {
+ return err.Err.Error()
+}
+
+// NewError creates an Error referencing a spec violation. The error
+// can be cast to an *Error for extracting structured information
+// about the level of the violation and a reference to the violated
+// spec condition.
+//
+// A version string (for the version of the spec that was violated)
+// must be set to get a working URL.
+func NewError(code Code, err error, version string) error {
+ template := ociErrors[code]
+ reference, err2 := template.Reference(version)
+ if err2 != nil {
+ return err2
+ }
+ return &Error{
+ Err: rfc2119.Error{
+ Level: template.Level,
+ Reference: reference,
+ Err: err,
+ },
+ Code: code,
+ }
+}
+
+// FindError finds an error from a source error (multiple error) and
+// returns the error code if found.
+// If the source error is nil or empty, return NonError.
+// If the source error is not a multiple error, return NonRFCError.
+func FindError(err error, code Code) Code {
+ if err == nil {
+ return NonError
+ }
+
+ if merr, ok := err.(*multierror.Error); ok {
+ if merr.ErrorOrNil() == nil {
+ return NonError
+ }
+ for _, e := range merr.Errors {
+ if rfcErr, ok := e.(*Error); ok {
+ if rfcErr.Code == code {
+ return code
+ }
+ }
+ }
+ }
+ return NonRFCError
+}