@@ -3,108 +3,50 @@ package validate
33import (
44 "errors"
55 "fmt"
6- "strings"
76
8- rspec "github.com/opencontainers/runtime-spec/specs-go "
7+ rfc2119 "github.com/opencontainers/runtime-tools/error "
98)
109
11- // ComplianceLevel represents the OCI compliance levels
12- type ComplianceLevel int
10+ const referenceTemplate = "https://github.com/opencontainers/runtime-spec/blob/v%s/%s"
1311
14- const (
15- // MAY-level
16-
17- // ComplianceMay represents 'MAY' in RFC2119
18- ComplianceMay ComplianceLevel = iota
19- // ComplianceOptional represents 'OPTIONAL' in RFC2119
20- ComplianceOptional
21-
22- // SHOULD-level
23-
24- // ComplianceShould represents 'SHOULD' in RFC2119
25- ComplianceShould
26- // ComplianceShouldNot represents 'SHOULD NOT' in RFC2119
27- ComplianceShouldNot
28- // ComplianceRecommended represents 'RECOMMENDED' in RFC2119
29- ComplianceRecommended
30- // ComplianceNotRecommended represents 'NOT RECOMMENDED' in RFC2119
31- ComplianceNotRecommended
32-
33- // MUST-level
34-
35- // ComplianceMust represents 'MUST' in RFC2119
36- ComplianceMust
37- // ComplianceMustNot represents 'MUST NOT' in RFC2119
38- ComplianceMustNot
39- // ComplianceShall represents 'SHALL' in RFC2119
40- ComplianceShall
41- // ComplianceShallNot represents 'SHALL NOT' in RFC2119
42- ComplianceShallNot
43- // ComplianceRequired represents 'REQUIRED' in RFC2119
44- ComplianceRequired
45- )
46-
47- // ErrorCode represents the compliance content
12+ // ErrorCode represents the compliance content.
4813type ErrorCode int
4914
5015const (
51- // DefaultFilesystems represents the error code of default filesystems test
16+ // DefaultFilesystems represents the error code of default filesystems test.
5217 DefaultFilesystems ErrorCode = iota
5318)
5419
55- // Error represents an error with compliance level and OCI reference
56- type Error struct {
57- Level ComplianceLevel
58- Reference string
59- Err error
20+ type errorTemplate struct {
21+ Level rfc2119.Level
22+ Reference func (version string ) (reference string , err error )
6023}
6124
62- const referencePrefix = "https://github.com/opencontainers/runtime-spec/blob"
63-
64- var ociErrors = map [ErrorCode ]Error {
65- DefaultFilesystems : Error {Level : ComplianceShould , Reference : "config-linux.md#default-filesystems" },
25+ var ociErrors = map [ErrorCode ]errorTemplate {
26+ DefaultFilesystems : errorTemplate {
27+ Level : rfc2119 .Should ,
28+ Reference : func (version string ) (reference string , err error ) {
29+ return fmt .Sprintf (referenceTemplate , version , "config-linux.md#default-filesystems" ), nil
30+ },
31+ },
6632}
6733
68- // ParseLevel takes a string level and returns the OCI compliance level constant
69- func ParseLevel (level string ) (ComplianceLevel , error ) {
70- switch strings .ToUpper (level ) {
71- case "MAY" :
72- fallthrough
73- case "OPTIONAL" :
74- return ComplianceMay , nil
75- case "SHOULD" :
76- fallthrough
77- case "SHOULDNOT" :
78- fallthrough
79- case "RECOMMENDED" :
80- fallthrough
81- case "NOTRECOMMENDED" :
82- return ComplianceShould , nil
83- case "MUST" :
84- fallthrough
85- case "MUSTNOT" :
86- fallthrough
87- case "SHALL" :
88- fallthrough
89- case "SHALLNOT" :
90- fallthrough
91- case "REQUIRED" :
92- return ComplianceMust , nil
34+ // NewError creates an Error referencing a spec violation. The error
35+ // can be cast to a *runtime-tools.error.Error for extracting
36+ // structured information about the level of the violation and a
37+ // reference to the violated spec condition.
38+ //
39+ // A version string (for the version of the spec that was violated)
40+ // must be set to get a working URL.
41+ func NewError (code ErrorCode , msg string , version string ) (err error ) {
42+ template := ociErrors [code ]
43+ reference , err := template .Reference (version )
44+ if err != nil {
45+ return err
46+ }
47+ return & rfc2119.Error {
48+ Level : template .Level ,
49+ Reference : reference ,
50+ Err : errors .New (msg ),
9351 }
94-
95- var l ComplianceLevel
96- return l , fmt .Errorf ("%q is not a valid compliance level" , level )
97- }
98-
99- // NewError creates an Error by ErrorCode and message
100- func NewError (code ErrorCode , msg string ) error {
101- err := ociErrors [code ]
102- err .Err = errors .New (msg )
103-
104- return & err
105- }
106-
107- // Error returns the error message with OCI reference
108- func (oci * Error ) Error () string {
109- return fmt .Sprintf ("%s\n Refer to: %s/v%s/%s" , oci .Err .Error (), referencePrefix , rspec .Version , oci .Reference )
11052}
0 commit comments