Skip to content

Commit c4991c4

Browse files
committed
add create prototype
Signed-off-by: vsoch <[email protected]>
1 parent 05ab562 commit c4991c4

File tree

9 files changed

+354
-185
lines changed

9 files changed

+354
-185
lines changed

README.md

+4-184
Original file line numberDiff line numberDiff line change
@@ -3,183 +3,9 @@
33
![img/compspec.png](img/compspec.png)
44

55
This is a prototype compatibility checking tool. Right now our aim is to use in the context of
6-
[these build matrices](https://github.com/rse-ops/lammps-matrix) for LAMMPS and these prototype [specifications](https://github.com/supercontainers/compspec) that are based off of [Proposal C](https://github.com/opencontainers/wg-image-compatibility/pull/8) of the Compatibility Working Group. This is experimental because all of that is subject (and likely) to change.
7-
8-
## Design
9-
10-
The design is based on the prototype from that pull request, shown below.
11-
12-
![img/proposal-c-plugin-design.png](img/proposal-c-plugin-design.png)
13-
14-
Specifically, I'll try to do simple interfaces (in [plugins](plugins)) to:
15-
16-
- **Extract** Scan a system to collect compatibility metadata / attributes for a named set of extractions
17-
- this maybe isn't great practice, but if I build the containers I trust them
18-
- I can also do something simple like run this tool in a pod-> container small cluster
19-
- load in an artifact spec (json) from a URL
20-
- compare with a request for a specific system (with any level of detail desired)
21-
- "basic" might just be providing the architecture
22-
- "descriptive" might include other variables
23-
24-
The extraction step is also important, but likely this would happen at build time (maybe by another tool).
25-
For now (since this is a prototype) I'm going to just manually do it.
26-
27-
## Usage
28-
29-
### Build
30-
31-
Build the `compspec` binary with:
32-
33-
```bash
34-
make
35-
```
36-
37-
This generates the `bin/compspec` that you can use:
38-
39-
```bash
40-
./bin/compspec
41-
```
42-
```console
43-
┏┏┓┏┳┓┏┓┏┏┓┏┓┏
44-
┗┗┛┛┗┗┣┛┛┣┛┗ ┗
45-
┛ ┛
46-
47-
[sub]Command required
48-
usage: compspec <Command> [-h|--help] [-n|--name "<value>" [-n|--name "<value>"
49-
...]]
50-
51-
Compatibility checking for container images
52-
53-
Commands:
54-
55-
version See the version of compspec
56-
extract Run one or more extractors
57-
58-
Arguments:
59-
60-
-h --help Print help information
61-
-n --name One or more specific extractor plugin names
62-
```
63-
64-
65-
### Version
66-
67-
```bash
68-
$ ./bin/compspec version
69-
```
70-
```console
71-
⭐️ compspec version 0.1.0-draft
72-
```
73-
74-
I know, the star should not be there. Fight me.
75-
76-
### List
77-
78-
The list command lists each extractor, and sections available for it.
79-
80-
```bash
81-
$ ./bin/compspec list
82-
```
83-
```console
84-
Compatibility Plugins
85-
TYPE NAME SECTION
86-
extrator kernel boot
87-
extrator kernel config
88-
extrator kernel modules
89-
extrator system cpu
90-
extrator system processor
91-
extrator system os
92-
extrator library mpi
93-
TOTAL 7
94-
```
95-
96-
Note that we will eventually add a description column - it's not really warranted yet!
97-
98-
### Extract
99-
100-
If you want to extract metadata to your local machine, you can use extract! Either just run all extractors and dump to the terminal:
101-
102-
```bash
103-
# Not recommend, it's a lot!
104-
./bin/compspec extract
105-
```
106-
107-
Or target a specific one:
108-
109-
```bash
110-
./bin/compspec extract --name kernel
111-
```
112-
113-
Better, save to json file:
114-
115-
```bash
116-
./bin/compspec extract --name kernel -o test-kernel.json
117-
```
118-
119-
This has a better structure for inspecting easily (only the top of the file is shown):
120-
121-
<details>
122-
123-
<summary>Kernel JSON output</summary>
124-
125-
```json
126-
{
127-
"extractors": {
128-
"kernel": {
129-
"sections": {
130-
"boot": {
131-
"BOOT_IMAGE": "/boot/vmlinuz-6.1.0-1028-oem",
132-
"quiet": "",
133-
"ro": "",
134-
"root": "UUID",
135-
"splash": "",
136-
"vt.handoff": "7"
137-
},
138-
"config": {
139-
"CONFIG_104_QUAD_8": "m",
140-
"CONFIG_60XX_WDT": "m",
141-
"CONFIG_64BIT": "y",
142-
"CONFIG_6LOWPAN": "m"
143-
}
144-
}
145-
}
146-
}
147-
}
148-
```
149-
150-
</details>
151-
152-
An extractor is made up of sections, and you can ask for parsing just a specific one.
153-
154-
```bash
155-
./bin/compspec extract --name kernel[config]
156-
```
157-
```console
158-
⭐️ Running extract...
159-
--Result for kernel
160-
-- Section boot
161-
root: UUID
162-
ro:
163-
quiet:
164-
splash:
165-
vt.handoff: 7
166-
BOOT_IMAGE: /boot/vmlinuz-6.1.0-1028-oem
167-
Extraction has run!
168-
```
169-
170-
To ask for more than one, it's a comma separated list.
171-
172-
```bash
173-
./bin/compspec extract --name kernel[config,boot]
174-
```
175-
176-
The ordering of your list is honored.
177-
178-
## Developer
179-
180-
Note that there is a [developer environment](.devcontainer) that provides a consistent version of Go, etc.
181-
However, it won't work with all extractors. Note that for any command that uses a plugin (e.g., `extract` and `check`)
6+
[these build matrices](https://github.com/rse-ops/lammps-matrix) for LAMMPS and these prototype [specifications](https://github.com/supercontainers/compspec) that are based off of [Proposal C](https://github.com/opencontainers/wg-image-compatibility/pull/8) of the Compatibility Working Group. This is experimental because all of that is subject (and likely) to change. This project is under development, and you can see our [docs](docs) for early documentation.
1827

8+
- ⭐️ [Documentation](docs) ⭐️
1839

18410
### Limitations
18511

@@ -188,6 +14,8 @@ However, it won't work with all extractors. Note that for any command that uses
18814

18915
## TODO
19016

17+
- metadata namespace and exposure: someone writing a spec to create an artifact needs to know the extract namespace (and what is available) for the mapping.
18+
- tests: matrix that has several different flavors of builds, generating compspec json output to validate generation and correctness
19119
- likely we want a common configuration file to take an extraction -> check recipe
19220
- need to develop check plugin family
19321
- todo thinking around manifest.yaml that has listing of images / artifacts
@@ -197,16 +25,8 @@ However, it won't work with all extractors. Note that for any command that uses
19725
A `*` indicates required for the work / prototype I want to do
19826

19927
- power usage data [valorium](https://ipo.llnl.gov/sites/default/files/2023-08/Final_variorum-rnd-100-award.pdf)
200-
- * architecture [archspec](https://github.com/archspec)
201-
- * MPI existence / variants
202-
- * operating system stuff
20328
- ... please add more!
20429

205-
206-
## Thanks and Previous Art
207-
208-
- I learned about kernel parsing from [mfranczy/compat](https://github.com/mfranczy/compat)
209-
21030
## License
21131

21232
This repository contains code derived from [sysinfo](https://github.com/zcalusic/sysinfo/tree/30169cfb37112a562cbf9133494a323764ad852c)

cmd/compspec/compspec.go

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/akamensky/argparse"
99
"github.com/supercontainers/compspec-go/cmd/compspec/extract"
10+
"github.com/supercontainers/compspec-go/cmd/compspec/create"
1011
"github.com/supercontainers/compspec-go/cmd/compspec/list"
1112
"github.com/supercontainers/compspec-go/pkg/types"
1213
)
@@ -30,12 +31,14 @@ func main() {
3031
versionCmd := parser.NewCommand("version", "See the version of compspec")
3132
extractCmd := parser.NewCommand("extract", "Run one or more extractors")
3233
listCmd := parser.NewCommand("list", "List plugins and known sections")
34+
createCmd := parser.NewCommand("create", "Create a compatibility artifact for the current host according to a definition")
3335

3436
// Shared arguments (likely this will break into check and extract, shared for now)
3537
pluginNames := parser.StringList("n", "name", &argparse.Options{Help: "One or more specific plugins to target names"})
3638

3739
// Extract arguments
3840
filename := extractCmd.String("o", "out", &argparse.Options{Help: "Save extraction to json file"})
41+
specname := createCmd.String("i", "in", &argparse.Options{Help: "Input yaml that contains spec for creation"})
3942

4043
// Now parse the arguments
4144
err := parser.Parse(os.Args)
@@ -50,6 +53,8 @@ func main() {
5053
if err != nil {
5154
log.Fatalf("Issue with extraction: %s", err)
5255
}
56+
} else if createCmd.Happened() {
57+
create.Run(*specname)
5358
} else if listCmd.Happened() {
5459
list.Run(*pluginNames)
5560
} else if versionCmd.Happened() {

cmd/compspec/create/create.go

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package create
2+
3+
// Run will create a compatibility artifact based on a request in YAML
4+
func Run(specname string) error {
5+
return nil
6+
}

cmd/compspec/list/list.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
p "github.com/supercontainers/compspec-go/plugins"
55
)
66

7-
// Run will run an extraction of host metadata
7+
// Run will list the extractor names and sections known
88
func Run(pluginNames []string) error {
99
// parse [section,...,section] into named plugins and sections
1010
// return plugins

docs/README.md

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Compspec Go
2+
3+
This is early documentation that will be converted eventually to something prettier. Read more about:
4+
5+
- [Design](design.md)
6+
- [Usage](usage.md)
7+
8+
9+
## Thanks and Previous Art
10+
11+
- I learned about kernel parsing from [mfranczy/compat](https://github.com/mfranczy/compat)
12+

docs/design.md

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Design
2+
3+
The compatibility tool is responsible for extracting information about a system, and comparing the host metadata to a contender container image to determine if it is compatible. This is a two step process that includes:
4+
5+
1. Extracting metadata about the container image at build time
6+
2. Extracting metadata about the host at image selection time, and comparing against a set of contender container images to select the best one.
7+
8+
## Definitions
9+
10+
### Extractor
11+
12+
An **extractor** is a core plugin that knows how to retrieve metadata about a host. An extractor is ususally going to be run for two cases:
13+
14+
1. During CI to extract (and save) metadata about a particular build to put in a compatibility artifact.
15+
2. During image selection to extract information about the host to compare to.
16+
17+
Examples extractors could be "library" or "system."
18+
19+
### Section
20+
21+
A **section** is a group of metadata within an extractor. For example, within "library" a section is for "mpi." This allows a user to specify running the `--name library[mpi]` extractor to ask for the mpi section of the library family. Another example is under kernel.
22+
The user might want to ask for more than one group to be extracted and might ask for `--name kernel[boot,config]`. Section basically provides more granularity to an extractor namespace. For the above two examples, the metadata generated would be organized like:
23+
24+
```
25+
library
26+
mpi.<attribute>
27+
kernel
28+
config.<attribute>
29+
boot.<attribute>
30+
```
31+
32+
For the above, right now I am implementing extractors generally, or "wild-westy" in the sense that the namespace is oriented toward the extractor name and sections it owns (e.g., no community namespaces like archspec, spack, opencontainers, etc). This is subject to change depending on the design the working group decides on.
33+
34+
### Creator
35+
36+
A creator is a plugin that is responsible for creating an artifact that includes some extracted metadata. The creator is agnostic to what it it being asked to generate in the sense that it just needs a mapping. The mapping will be from the extractor namespace to the compatibility artifact namespace. For our first prototype, this just means asking for particular extractor attributes to map to a set of annotations that we want to dump into json. To start there should only be one creator plugin needed, however if there are different structures of artifacts needed, I could imagine more. An example creation specification for a prototype experiment where we care about architecture, MPI, and GPU is provided in [examples](examples).
37+
38+
## Overview
39+
40+
The design is based on the prototype from that pull request, shown below.
41+
42+
![img/proposal-c-plugin-design.png](img/proposal-c-plugin-design.png)
43+
44+
Specifically, I'll try to do simple interfaces (in [plugins](plugins)) to:
45+
46+
- **Extract** Scan a system to collect compatibility metadata / attributes for a named set of extractions
47+
- this maybe isn't great practice, but if I build the containers I trust them
48+
- I can also do something simple like run this tool in a pod-> container small cluster
49+
- load in an artifact spec (json) from a URL
50+
- compare with a request for a specific system (with any level of detail desired)
51+
- "basic" might just be providing the architecture
52+
- "descriptive" might include other variables
53+
54+
The extraction step is also important, but likely this would happen at build time (maybe by another tool).
55+
For now (since this is a prototype) I'm going to just manually do it.

0 commit comments

Comments
 (0)