Skip to content

Commit cc18333

Browse files
authored
Merge pull request #9 from supercontainers/update-new-graph-specs
update create command for new spec
2 parents 37443a9 + 08b92ba commit cc18333

File tree

6 files changed

+90
-87
lines changed

6 files changed

+90
-87
lines changed

cmd/compspec/create/create.go

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ func Run(specname string, fields []string, saveto string) error {
5252

5353
// The compspec returned is the populated Compatibility request!
5454
compspec, err := PopulateExtractors(&result, request)
55+
if err != nil {
56+
return err
57+
}
58+
5559
output, err := compspec.ToJson()
5660
if err != nil {
5761
return err
@@ -71,43 +75,58 @@ func Run(specname string, fields []string, saveto string) error {
7175
// After this we can save the populated thing into an artifact (json DUMP)
7276
func PopulateExtractors(result *p.Result, request *types.CompatibilityRequest) (*types.CompatibilityRequest, error) {
7377

78+
// Every metadata attribute must be known under a schema
79+
schemas := request.Metadata.Schemas
80+
if len(schemas) == 0 {
81+
return nil, fmt.Errorf("the request must have one or more schemas")
82+
}
7483
for i, compat := range request.Compatibilities {
75-
for key, extractorKey := range compat.Annotations {
84+
85+
// The compatibility section name is a schema, and must be defined
86+
url, ok := schemas[compat.Name]
87+
if !ok {
88+
return nil, fmt.Errorf("%s is missing a schema", compat.Name)
89+
}
90+
if url == "" {
91+
return nil, fmt.Errorf("%s has an empty schema", compat.Name)
92+
}
93+
94+
for key, extractorKey := range compat.Attributes {
7695

7796
// Get the extractor, section, and subfield from the extractor lookup key
7897
f, err := p.ParseField(extractorKey)
7998
if err != nil {
8099
fmt.Printf("warning: cannot parse %s: %s, setting to empty\n", key, extractorKey)
81-
compat.Annotations[key] = ""
100+
compat.Attributes[key] = ""
82101
continue
83102
}
84103

85104
// If we get here, we can parse it and look it up in our result metadata
86105
extractor, ok := result.Results[f.Extractor]
87106
if !ok {
88107
fmt.Printf("warning: extractor %s is unknown, setting to empty\n", f.Extractor)
89-
compat.Annotations[key] = ""
108+
compat.Attributes[key] = ""
90109
continue
91110
}
92111

93112
// Now get the section
94113
section, ok := extractor.Sections[f.Section]
95114
if !ok {
96115
fmt.Printf("warning: section %s.%s is unknown, setting to empty\n", f.Extractor, f.Section)
97-
compat.Annotations[key] = ""
116+
compat.Attributes[key] = ""
98117
continue
99118
}
100119

101120
// Now get the value!
102121
value, ok := section[f.Field]
103122
if !ok {
104123
fmt.Printf("warning: field %s.%s.%s is unknown, setting to empty\n", f.Extractor, f.Section, f.Field)
105-
compat.Annotations[key] = ""
124+
compat.Attributes[key] = ""
106125
continue
107126
}
108127

109128
// If we get here - we found it! Hooray!
110-
compat.Annotations[key] = value
129+
compat.Attributes[key] = value
111130
}
112131

113132
// Update the compatibiity

docs/usage.md

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -91,31 +91,32 @@ The idea here is that you can add custom metadata fields during your build, whic
9191
"kind": "CompatibilitySpec",
9292
"metadata": {
9393
"name": "lammps-prototype",
94-
"jsonSchema": "https://raw.githubusercontent.com/supercontainers/compspec/main/supercontainers/compspec.json"
94+
"schemas": {
95+
"archspec.io": "https://raw.githubusercontent.com/supercontainers/compspec/main/archspec/compspec.json",
96+
"org.supercontainers": "https://raw.githubusercontent.com/supercontainers/compspec/main/supercontainers/compspec.json"
97+
}
9598
},
9699
"compatibilities": [
97100
{
98-
"name": "org.supercontainers.mpi",
101+
"name": "org.supercontainers",
99102
"version": "0.0.0",
100-
"annotations": {
101-
"implementation": "mpich",
102-
"version": "4.1.1"
103+
"attributes": {
104+
"hardware.gpu.available": "yes",
105+
"mpi.implementation": "mpich",
106+
"mpi.version": "4.1.1",
107+
"os.name": "Ubuntu 22.04.3 LTS",
108+
"os.release": "22.04.3",
109+
"os.vendor": "ubuntu",
110+
"os.version": "22.04"
103111
}
104112
},
105113
{
106-
"name": "org.supercontainers.hardware.gpu",
114+
"name": "archspec.io",
107115
"version": "0.0.0",
108-
"annotations": {
109-
"available": "yes"
110-
}
111-
},
112-
{
113-
"name": "io.archspec.cpu",
114-
"version": "0.0.0",
115-
"annotations": {
116-
"model": "13th Gen Intel(R) Core(TM) i5-1335U",
117-
"target": "amd64",
118-
"vendor": "GenuineIntel"
116+
"attributes": {
117+
"cpu.model": "13th Gen Intel(R) Core(TM) i5-1335U",
118+
"cpu.target": "amd64",
119+
"cpu.vendor": "GenuineIntel"
119120
}
120121
}
121122
]
@@ -136,7 +137,7 @@ For now we will manually remember the pairing, at least until the compatibility
136137

137138
Check is the command you would use to check a potential host against one or more existing artifacts.
138139
For a small experiment of using create against a set of containers and then testing how to do a check, we are going to place content
139-
in [examples/check-lammps](examples/check-lammps). As an example, we might use the manifest in that directory to run a check.
140+
in [examples/check-lammps](examples/check-lammps). Note that we generated the actual compatibility spec and pushed with oras before running the example here! Following that, we might use the manifest in that directory to run a check.
140141
Note that since most use cases aren't checking the images in the manifest list against the host running the command, we instead
141142
provide the parameters about the expected runtime host to them.
142143

examples/check-lammps/generate-artifact.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ wget --quiet https://github.com/supercontainers/compspec-go/releases/download/1-
99
chmod +x compspec
1010

1111
# Download the spec for our compatibility artifact
12-
wget --quiet https://gist.githubusercontent.com/vsoch/fcd0f7d633860674cb085a8540ce4bb2/raw/880f3764b9394ccaa21fd768b235c7a89609aa65/lammps-experiment.yaml
12+
wget --quiet https://gist.githubusercontent.com/vsoch/fcd0f7d633860674cb085a8540ce4bb2/raw/4f8e730f1d74c070e63de79bf8b6f86a528ef1c9/lammps-experiment.yaml
1313

1414
# Generate!
1515
./compspec create --in ./lammps-experiment.yaml -a custom.gpu.available=$hasGpu -o ${path}

examples/generated-compatibility-spec.json

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,32 @@
33
"kind": "CompatibilitySpec",
44
"metadata": {
55
"name": "lammps-prototype",
6-
"jsonSchema": "https://raw.githubusercontent.com/supercontainers/compspec/main/supercontainers/compspec.json"
6+
"schemas": {
7+
"archspec.io": "https://raw.githubusercontent.com/supercontainers/compspec/main/archspec/compspec.json",
8+
"org.supercontainers": "https://raw.githubusercontent.com/supercontainers/compspec/main/supercontainers/compspec.json"
9+
}
710
},
811
"compatibilities": [
912
{
10-
"name": "org.supercontainers.mpi",
11-
"version": "0.0.0",
12-
"annotations": {
13-
"implementation": "mpich",
14-
"version": "4.1.1"
15-
}
16-
},
17-
{
18-
"name": "org.supercontainers.os",
19-
"version": "0.0.0",
20-
"annotations": {
21-
"name": "Ubuntu 22.04.3 LTS",
22-
"release": "22.04.3",
23-
"vendor": "ubuntu",
24-
"version": "22.04"
25-
}
26-
},
27-
{
28-
"name": "org.supercontainers.hardware.gpu",
13+
"name": "org.supercontainers",
2914
"version": "0.0.0",
30-
"annotations": {
31-
"available": "yes"
15+
"attributes": {
16+
"hardware.gpu.available": "yes",
17+
"mpi.implementation": "mpich",
18+
"mpi.version": "4.1.1",
19+
"os.name": "Ubuntu 22.04.3 LTS",
20+
"os.release": "22.04.3",
21+
"os.vendor": "ubuntu",
22+
"os.version": "22.04"
3223
}
3324
},
3425
{
35-
"name": "io.archspec.cpu",
26+
"name": "archspec.io",
3627
"version": "0.0.0",
37-
"annotations": {
38-
"model": "13th Gen Intel(R) Core(TM) i5-1335U",
39-
"target": "amd64",
40-
"vendor": "GenuineIntel"
28+
"attributes": {
29+
"cpu.model": "13th Gen Intel(R) Core(TM) i5-1335U",
30+
"cpu.target": "amd64",
31+
"cpu.vendor": "GenuineIntel"
4132
}
4233
}
4334
]

examples/lammps-experiment.yaml

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,38 +7,30 @@ kind: CompatibilitySpec
77
metadata:
88
name: lammps-prototype
99

10-
# "Validate the final compatibility spec against this schema'
11-
jsonSchema: https://raw.githubusercontent.com/supercontainers/compspec/main/supercontainers/compspec.json
10+
# "Validate the namespaced attributes with these schemas"
11+
schemas:
12+
org.supercontainers: https://raw.githubusercontent.com/supercontainers/compspec/main/supercontainers/compspec.json
13+
archspec.io: https://raw.githubusercontent.com/supercontainers/compspec/main/archspec/compspec.json
1214

1315
# These are not values, but mappings, from an extractor into the compspec we want
1416
compatibilities:
15-
- name: "org.supercontainers.mpi"
17+
- name: "org.supercontainers"
1618
version: "0.0.0"
17-
annotations:
18-
implementation: library.mpi.variant
19-
version: library.mpi.version
20-
21-
- name: "org.supercontainers.os"
22-
version: "0.0.0"
23-
annotations:
24-
name: system.os.name
25-
release: system.os.release
26-
vendor: system.os.vendor
27-
version: system.os.version
28-
29-
# This is an example of a custom metadata attribute provided by the user (commandline)
30-
# It can override an actual attribute, or just be random / new, -o custom.gpu.available=yes
31-
- name: "org.supercontainers.hardware.gpu"
32-
version: "0.0.0"
33-
annotations:
34-
available: custom.gpu.available
19+
attributes:
20+
mpi.implementation: library.mpi.variant
21+
mpi.version: library.mpi.version
22+
os.name: system.os.name
23+
os.release: system.os.release
24+
os.vendor: system.os.vendor
25+
os.version: system.os.version
26+
hardware.gpu.available: custom.gpu.available
3527

3628
# Note that for now we are using the processor in index 0 to represent all
3729
# I'm not sure about cases where this set isn't homogeneous!
3830
# Since target is part of the container build, we will provide it
39-
- name: "io.archspec.cpu"
31+
- name: "archspec.io"
4032
version: "0.0.0"
41-
annotations:
42-
model: system.processor.0.model
43-
target: system.arch.name
44-
vendor: system.processor.0.vendor
33+
attributes:
34+
cpu.model: system.processor.0.model
35+
cpu.target: system.arch.name
36+
cpu.vendor: system.processor.0.vendor

pkg/types/types.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ type CompatibilitySpec struct {
1010
Compatibilities map[string]CompatibilitySpec `json:"compatibilities"`
1111
}
1212
type CompatibiitySpec struct {
13-
Version string `json:"version"`
14-
Annotations Annotations `json:"annotations"`
13+
Version string `json:"version"`
14+
Attributes Attributes `json:"attributes"`
1515
}
1616

17-
type Annotations map[string]string
17+
type Attributes map[string]string
1818

1919
// A compatibility request is a mapping between a user preferences (some request to create a
2020
// compatibility artifact) to a set of metadata attributes known by extractors.
@@ -27,16 +27,16 @@ type CompatibilityRequest struct {
2727
Compatibilities []CompatibilityMapping `json:"compatibilities,omitempty"`
2828
}
2929
type Metadata struct {
30-
Name string `json:"name,omitempty"`
31-
JSONSchema string `json:"jsonSchema,omitempty"`
30+
Name string `json:"name,omitempty"`
31+
Schemas map[string]string `json:"schemas,omitempty"`
3232
}
3333

3434
// A compatibility mapping has one or more annotations that convert
3535
// between extractor and compspec.json (the JsonSchema provided above)
3636
type CompatibilityMapping struct {
37-
Name string `json:"name,omitempty"`
38-
Version string `json:"version,omitempty"`
39-
Annotations map[string]string `json:"annotations,omitempty"`
37+
Name string `json:"name,omitempty"`
38+
Version string `json:"version,omitempty"`
39+
Attributes map[string]string `json:"attributes,omitempty"`
4040
}
4141

4242
// ToJson dumps our request to json for the artifact
@@ -53,7 +53,7 @@ func (r *CompatibilityRequest) GetExtractors() []string {
5353

5454
set := map[string]bool{}
5555
for _, compat := range r.Compatibilities {
56-
for _, request := range compat.Annotations {
56+
for _, request := range compat.Attributes {
5757

5858
// The extractor name is the first field
5959
parts := strings.Split(request, ".")

0 commit comments

Comments
 (0)