Skip to content

Commit b446e38

Browse files
committed
add specerror framework; complete rfc errors of bundle.md and config.md
Signed-off-by: Liang Chenye <[email protected]>
1 parent f3c1c70 commit b446e38

File tree

9 files changed

+294
-99
lines changed

9 files changed

+294
-99
lines changed

cmd/runtimetest/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ func validateRootFS(spec *rspec.Spec) error {
328328
if spec.Root.Readonly {
329329
err := testWriteAccess("/")
330330
if err == nil {
331-
return specerror.NewError(specerror.ReadonlyFilesystem, fmt.Errorf("rootfs must be readonly"), rspec.Version)
331+
return specerror.NewError(specerror.RootReadonlyImplement, fmt.Errorf("rootfs must be readonly"), rspec.Version)
332332
}
333333
}
334334

specerror/bundle.go

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package specerror
2+
3+
import (
4+
"fmt"
5+
6+
rfc2119 "github.com/opencontainers/runtime-tools/error"
7+
)
8+
9+
// define error codes
10+
const (
11+
// ConfigInRootBundleDir represents "This REQUIRED file MUST reside in the root of the bundle directory"
12+
ConfigInRootBundleDir = "This REQUIRED file MUST reside in the root of the bundle directory."
13+
// ConfigConstName represents "This REQUIRED file MUST be named `config.json`."
14+
ConfigConstName = "This REQUIRED file MUST be named `config.json`."
15+
// ArtifactsInSingleDir represents "When supplied, while these artifacts MUST all be present in a single directory on the local filesystem, that directory itself is not part of the bundle."
16+
ArtifactsInSingleDir = "When supplied, while these artifacts MUST all be present in a single directory on the local filesystem, that directory itself is not part of the bundle."
17+
)
18+
19+
var (
20+
containerFormatRef = func(version string) (reference string, err error) {
21+
return fmt.Sprintf(referenceTemplate, version, "bundle.md#container-format"), nil
22+
}
23+
)
24+
25+
func init() {
26+
register(ConfigInRootBundleDir, rfc2119.Must, containerFormatRef)
27+
register(ConfigConstName, rfc2119.Must, containerFormatRef)
28+
register(ArtifactsInSingleDir, rfc2119.Must, containerFormatRef)
29+
}

specerror/config-linux.go

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package specerror
2+
3+
import (
4+
"fmt"
5+
6+
rfc2119 "github.com/opencontainers/runtime-tools/error"
7+
)
8+
9+
// define error codes
10+
const (
11+
// DefaultFilesystems represents "The following filesystems SHOULD be made available in each container's filesystem:"
12+
DefaultFilesystems = "The following filesystems SHOULD be made available in each container's filesystem:"
13+
)
14+
15+
var (
16+
defaultFilesystemsRef = func(version string) (reference string, err error) {
17+
return fmt.Sprintf(referenceTemplate, version, "config-linux.md#default-filesystems"), nil
18+
}
19+
)
20+
21+
func init() {
22+
register(DefaultFilesystems, rfc2119.Should, defaultFilesystemsRef)
23+
}

specerror/config.go

+185
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
package specerror
2+
3+
import (
4+
"fmt"
5+
6+
rfc2119 "github.com/opencontainers/runtime-tools/error"
7+
)
8+
9+
// define error codes
10+
const (
11+
// SpecVersionInSemVer represents "**`ociVersion`** (string, Required) MUST be in [SemVer v2.0.0][semver-v2.0.0] format and specifies the version of the Open Container Initiative Runtime Specification with which the bundle complies."
12+
SpecVersionInSemVer = "**`ociVersion`** (string, Required) MUST be in [SemVer v2.0.0][semver-v2.0.0] format and specifies the version of the Open Container Initiative Runtime Specification with which the bundle complies."
13+
// RootOnWindowsRequired represents "On Windows, for Windows Server Containers, this field is REQUIRED."
14+
RootOnWindowsRequired = "On Windows, for Windows Server Containers, this field is REQUIRED."
15+
// RootOnHyperVNotSet represents "For [Hyper-V Containers](config-windows.md#hyperv), this field MUST NOT be set."
16+
RootOnHyperVNotSet = "For [Hyper-V Containers](config-windows.md#hyperv), this field MUST NOT be set."
17+
// RootOnNonHyperVRequired represents "On all other platforms, this field is REQUIRED."
18+
RootOnNonHyperVRequired = "On all other platforms, this field is REQUIRED."
19+
// RootPathOnWindowsGUID represents "On Windows, `path` MUST be a [volume GUID path][naming-a-volume]."
20+
RootPathOnWindowsGUID = "On Windows, `path` MUST be a [volume GUID path][naming-a-volume]."
21+
// RootPathOnPosixConvention represents "The value SHOULD be the conventional `rootfs`."
22+
RootPathOnPosixConvention = "The value SHOULD be the conventional `rootfs`."
23+
// RootPathExist represents "A directory MUST exist at the path declared by the field."
24+
RootPathExist = "A directory MUST exist at the path declared by the field."
25+
// RootReadonlyImplement represents "**`readonly`** (bool, OPTIONAL) If true then the root filesystem MUST be read-only inside the container, defaults to false."
26+
RootReadonlyImplement = "**`readonly`** (bool, OPTIONAL) If true then the root filesystem MUST be read-only inside the container, defaults to false."
27+
// RootReadonlyOnWindowsFalse represents "* On Windows, this field MUST be omitted or false."
28+
RootReadonlyOnWindowsFalse = "On Windows, this field MUST be omitted or false."
29+
// MountsInOrder represents "The runtime MUST mount entries in the listed order."
30+
MountsInOrder = "The runtime MUST mount entries in the listed order."
31+
// MountsDestAbs represents "Destination of mount point: path inside container. This value MUST be an absolute path."
32+
MountsDestAbs = "Destination of mount point: path inside container. This value MUST be an absolute path."
33+
// MountsDestOnWindowsNotNested represents "Windows: one mount destination MUST NOT be nested within another mount (e.g., c:\\foo and c:\\foo\\bar)."
34+
MountsDestOnWindowsNotNested = "Windows: one mount destination MUST NOT be nested within another mount (e.g., c:\\foo and c:\\foo\\bar)."
35+
// MountsOptionsOnWindowsROSupport represents "Windows: runtimes MUST support `ro`, mounting the filesystem read-only when `ro` is given."
36+
MountsOptionsOnWindowsROSupport = "Windows: runtimes MUST support `ro`, mounting the filesystem read-only when `ro` is given."
37+
// ProcRequiredAtStart represents "This property is REQUIRED when [`start`](runtime.md#start) is called."
38+
ProcRequiredAtStart = "This property is REQUIRED when [`start`](runtime.md#start) is called."
39+
// ProcessConsoleSizeIgnore represents "Runtimes MUST ignore `consoleSize` if `terminal` is `false` or unset."
40+
ProcessConsoleSizeIgnore = "Runtimes MUST ignore `consoleSize` if `terminal` is `false` or unset."
41+
// ProcCwdAbs represents "** cwd ** (string, REQUIRED) is the working directory that will be set for the executable. This value MUST be an absolute path."
42+
ProcCwdAbs = "** cwd ** (string, REQUIRED) is the working directory that will be set for the executable. This value MUST be an absolute path."
43+
// ProcArgsOneEntryRequired represents "This specification extends the IEEE standard in that at least one entry is REQUIRED, and that entry is used with the same semantics as `execvp`'s *file*."
44+
ProcArgsOneEntryRequired = "This specification extends the IEEE standard in that at least one entry is REQUIRED, and that entry is used with the same semantics as `execvp`'s *file*."
45+
// PosixProcRlimitsTypeGeneError represents "The runtime MUST [generate an error](runtime.md#errors) for any values which cannot be mapped to a relevant kernel interface."
46+
PosixProcRlimitsTypeGeneError = "The runtime MUST [generate an error](runtime.md#errors) for any values which cannot be mapped to a relevant kernel interface."
47+
// PosixProcRlimitsTypeGet represents "For each entry in `rlimits`, a [`getrlimit(3)`][getrlimit.3] on `type` MUST succeed."
48+
PosixProcRlimitsTypeGet = "For each entry in `rlimits`, a [`getrlimit(3)`][getrlimit.3] on `type` MUST succeed."
49+
// PosixProcRlimitsSoftMatchCur represents "`rlim.rlim_cur` MUST match the configured value."
50+
PosixProcRlimitsSoftMatchCur = "`rlim.rlim_cur` MUST match the configured value."
51+
// PosixProcRlimitsHardMatchMax represents "`rlim.rlim_max` MUST match the configured value."
52+
PosixProcRlimitsHardMatchMax = "`rlim.rlim_max` MUST match the configured value."
53+
// PosixProcRlimitsErrorOnDup represents "If `rlimits` contains duplicated entries with same `type`, the runtime MUST [generate an error](runtime.md#errors)."
54+
PosixProcRlimitsErrorOnDup = "If `rlimits` contains duplicated entries with same `type`, the runtime MUST [generate an error](runtime.md#errors)."
55+
// LinuxProcCapError represents "Any value which cannot be mapped to a relevant kernel interface MUST cause an error."
56+
LinuxProcCapError = "Any value which cannot be mapped to a relevant kernel interface MUST cause an error."
57+
// LinuxProcOomScoreAdjSet represents "If `oomScoreAdj` is set, the runtime MUST set `oom_score_adj` to the given value."
58+
LinuxProcOomScoreAdjSet = "If `oomScoreAdj` is set, the runtime MUST set `oom_score_adj` to the given value."
59+
// LinuxProcOomScoreAdjNotSet represents "If `oomScoreAdj` is not set, the runtime MUST NOT change the value of `oom_score_adj`."
60+
LinuxProcOomScoreAdjNotSet = "If `oomScoreAdj` is not set, the runtime MUST NOT change the value of `oom_score_adj`."
61+
// PlatformSpecConfOnWindowsSet represents "This MUST be set if the target platform of this spec is `windows`."
62+
PlatformSpecConfOnWindowsSet = "This MUST be set if the target platform of this spec is `windows`."
63+
// PosixHooksPathAbs represents "This specification extends the IEEE standard in that **`path`** MUST be absolute."
64+
PosixHooksPathAbs = "This specification extends the IEEE standard in that **`path`** MUST be absolute."
65+
// PosixHooksTimeoutPositive represents "If set, `timeout` MUST be greater than zero."
66+
PosixHooksTimeoutPositive = "If set, `timeout` MUST be greater than zero."
67+
// PosixHooksCalledInOrder represents "Hooks MUST be called in the listed order."
68+
PosixHooksCalledInOrder = "Hooks MUST be called in the listed order."
69+
// PosixHooksStateToStdin represents "The [state](runtime.md#state) of the container MUST be passed to hooks over stdin so that they may do work appropriate to the current state of the container."
70+
PosixHooksStateToStdin = "The [state](runtime.md#state) of the container MUST be passed to hooks over stdin so that they may do work appropriate to the current state of the container."
71+
// PrestartTiming represents "The pre-start hooks MUST be called after the [`start`](runtime.md#start) operation is called but [before the user-specified program command is executed](runtime.md#lifecycle)."
72+
PrestartTiming = "The pre-start hooks MUST be called after the [`start`](runtime.md#start) operation is called but [before the user-specified program command is executed](runtime.md#lifecycle)."
73+
// PoststartTiming represents "The post-start hooks MUST be called [after the user-specified process is executed](runtime.md#lifecycle) but before the [`start`](runtime.md#start) operation returns."
74+
PoststartTiming = "The post-start hooks MUST be called [after the user-specified process is executed](runtime.md#lifecycle) but before the [`start`](runtime.md#start) operation returns."
75+
// PoststopTiming represents "The post-stop hooks MUST be called [after the container is deleted](runtime.md#lifecycle) but before the [`delete`](runtime.md#delete) operation returns."
76+
PoststopTiming = "The post-stop hooks MUST be called [after the container is deleted](runtime.md#lifecycle) but before the [`delete`](runtime.md#delete) operation returns."
77+
// AnnotationsKeyValueMap represents "Annotations MUST be a key-value map."
78+
AnnotationsKeyValueMap = "Annotations MUST be a key-value map."
79+
// AnnotationsKeyString represents "Keys MUST be strings."
80+
AnnotationsKeyString = "Keys MUST be strings."
81+
// AnnotationsKeyRequired represents "Keys MUST NOT be an empty string."
82+
AnnotationsKeyRequired = "Keys MUST NOT be an empty string."
83+
// AnnotationsKeyReversedDomain represents "Keys SHOULD be named using a reverse domain notation - e.g. `com.example.myKey`."
84+
AnnotationsKeyReversedDomain = "Keys SHOULD be named using a reverse domain notation - e.g. `com.example.myKey`."
85+
// AnnotationsKeyReservedNS represents "Keys using the `org.opencontainers` namespace are reserved and MUST NOT be used by subsequent specifications."
86+
AnnotationsKeyReservedNS = "Keys using the `org.opencontainers` namespace are reserved and MUST NOT be used by subsequent specifications."
87+
// AnnotationsKeyIgnoreUnknown represents "Implementations that are reading/processing this configuration file MUST NOT generate an error if they encounter an unknown annotation key."
88+
AnnotationsKeyIgnoreUnknown = "Implementations that are reading/processing this configuration file MUST NOT generate an error if they encounter an unknown annotation key."
89+
// AnnotationsValueString represents "Values MUST be strings."
90+
AnnotationsValueString = "Values MUST be strings."
91+
// ExtensibilityIgnoreUnknownProp represents "Runtimes that are reading or processing this configuration file MUST NOT generate an error if they encounter an unknown property."
92+
ExtensibilityIgnoreUnknownProp = "Runtimes that are reading or processing this configuration file MUST NOT generate an error if they encounter an unknown property.\nInstead they MUST ignore unknown properties."
93+
// ValidValues represents "Runtimes that are reading or processing this configuration file MUST generate an error when invalid or unsupported values are encountered."
94+
ValidValues = "Runtimes that are reading or processing this configuration file MUST generate an error when invalid or unsupported values are encountered."
95+
)
96+
97+
var (
98+
specificationVersionRef = func(version string) (reference string, err error) {
99+
return fmt.Sprintf(referenceTemplate, version, "config.md#specification-version"), nil
100+
}
101+
rootRef = func(version string) (reference string, err error) {
102+
return fmt.Sprintf(referenceTemplate, version, "config.md#root"), nil
103+
}
104+
mountsRef = func(version string) (reference string, err error) {
105+
return fmt.Sprintf(referenceTemplate, version, "config.md#mounts"), nil
106+
}
107+
processRef = func(version string) (reference string, err error) {
108+
return fmt.Sprintf(referenceTemplate, version, "config.md#process"), nil
109+
}
110+
posixProcessRef = func(version string) (reference string, err error) {
111+
return fmt.Sprintf(referenceTemplate, version, "config.md#posix-process"), nil
112+
}
113+
linuxProcessRef = func(version string) (reference string, err error) {
114+
return fmt.Sprintf(referenceTemplate, version, "config.md#linux-process"), nil
115+
}
116+
platformSpecificConfigurationRef = func(version string) (reference string, err error) {
117+
return fmt.Sprintf(referenceTemplate, version, "config.md#platform-specific-configuration"), nil
118+
}
119+
posixPlatformHooksRef = func(version string) (reference string, err error) {
120+
return fmt.Sprintf(referenceTemplate, version, "config.md#posix-platform-hooks"), nil
121+
}
122+
prestartRef = func(version string) (reference string, err error) {
123+
return fmt.Sprintf(referenceTemplate, version, "config.md#prestart"), nil
124+
}
125+
poststartRef = func(version string) (reference string, err error) {
126+
return fmt.Sprintf(referenceTemplate, version, "config.md#poststart"), nil
127+
}
128+
poststopRef = func(version string) (reference string, err error) {
129+
return fmt.Sprintf(referenceTemplate, version, "config.md#poststop"), nil
130+
}
131+
annotationsRef = func(version string) (reference string, err error) {
132+
return fmt.Sprintf(referenceTemplate, version, "config.md#annotations"), nil
133+
}
134+
extensibilityRef = func(version string) (reference string, err error) {
135+
return fmt.Sprintf(referenceTemplate, version, "config.md#extensibility"), nil
136+
}
137+
validValuesRef = func(version string) (reference string, err error) {
138+
return fmt.Sprintf(referenceTemplate, version, "config.md#valid-values"), nil
139+
}
140+
)
141+
142+
func init() {
143+
register(SpecVersionInSemVer, rfc2119.Must, specificationVersionRef)
144+
register(RootOnWindowsRequired, rfc2119.Required, rootRef)
145+
register(RootOnHyperVNotSet, rfc2119.Must, rootRef)
146+
register(RootOnNonHyperVRequired, rfc2119.Required, rootRef)
147+
register(RootPathOnWindowsGUID, rfc2119.Must, rootRef)
148+
register(RootPathOnPosixConvention, rfc2119.Should, rootRef)
149+
register(RootPathExist, rfc2119.Must, rootRef)
150+
register(RootReadonlyImplement, rfc2119.Must, rootRef)
151+
register(RootReadonlyOnWindowsFalse, rfc2119.Must, rootRef)
152+
register(MountsInOrder, rfc2119.Must, mountsRef)
153+
register(MountsDestAbs, rfc2119.Must, mountsRef)
154+
register(MountsDestOnWindowsNotNested, rfc2119.Must, mountsRef)
155+
register(MountsOptionsOnWindowsROSupport, rfc2119.Must, mountsRef)
156+
register(ProcRequiredAtStart, rfc2119.Required, processRef)
157+
register(ProcessConsoleSizeIgnore, rfc2119.Must, processRef)
158+
register(ProcCwdAbs, rfc2119.Must, processRef)
159+
register(ProcArgsOneEntryRequired, rfc2119.Required, processRef)
160+
register(PosixProcRlimitsTypeGeneError, rfc2119.Must, posixProcessRef)
161+
register(PosixProcRlimitsTypeGet, rfc2119.Must, posixProcessRef)
162+
register(PosixProcRlimitsSoftMatchCur, rfc2119.Must, posixProcessRef)
163+
register(PosixProcRlimitsHardMatchMax, rfc2119.Must, posixProcessRef)
164+
register(PosixProcRlimitsErrorOnDup, rfc2119.Must, posixProcessRef)
165+
register(LinuxProcCapError, rfc2119.Must, linuxProcessRef)
166+
register(LinuxProcOomScoreAdjSet, rfc2119.Must, linuxProcessRef)
167+
register(LinuxProcOomScoreAdjNotSet, rfc2119.Must, linuxProcessRef)
168+
register(PlatformSpecConfOnWindowsSet, rfc2119.Must, platformSpecificConfigurationRef)
169+
register(PosixHooksPathAbs, rfc2119.Must, posixPlatformHooksRef)
170+
register(PosixHooksTimeoutPositive, rfc2119.Must, posixPlatformHooksRef)
171+
register(PosixHooksCalledInOrder, rfc2119.Must, posixPlatformHooksRef)
172+
register(PosixHooksStateToStdin, rfc2119.Must, posixPlatformHooksRef)
173+
register(PrestartTiming, rfc2119.Must, prestartRef)
174+
register(PoststartTiming, rfc2119.Must, poststartRef)
175+
register(PoststopTiming, rfc2119.Must, poststopRef)
176+
register(AnnotationsKeyValueMap, rfc2119.Must, annotationsRef)
177+
register(AnnotationsKeyString, rfc2119.Must, annotationsRef)
178+
register(AnnotationsKeyRequired, rfc2119.Must, annotationsRef)
179+
register(AnnotationsKeyReversedDomain, rfc2119.Should, annotationsRef)
180+
register(AnnotationsKeyReservedNS, rfc2119.Must, annotationsRef)
181+
register(AnnotationsKeyIgnoreUnknown, rfc2119.Must, annotationsRef)
182+
register(AnnotationsValueString, rfc2119.Must, annotationsRef)
183+
register(ExtensibilityIgnoreUnknownProp, rfc2119.Must, extensibilityRef)
184+
register(ValidValues, rfc2119.Must, validValuesRef)
185+
}

0 commit comments

Comments
 (0)