This repository has no description
1package microvm
2
3import (
4 "crypto/sha256"
5 "database/sql"
6 "encoding/hex"
7 "encoding/json"
8 "errors"
9 "fmt"
10 "time"
11
12 "tangled.org/core/spindle/db"
13)
14
15// v2 keys are scoped by repo did in v1 keys were global
16const nixosToplevelCacheSchemaVersion = 2
17
18type nixosToplevelCacheRecord struct {
19 ConfigKey string `json:"config_key"`
20 Toplevel string `json:"toplevel"`
21 UpdatedAt time.Time `json:"updated_at"`
22}
23
24type nixosToplevelCacheStore struct {
25 db *db.DB
26}
27
28func newNixOSToplevelCacheStore(d *db.DB) nixosToplevelCacheStore {
29 return nixosToplevelCacheStore{db: d}
30}
31
32func (s nixosToplevelCacheStore) Lookup(configKey string) (nixosToplevelCacheRecord, bool, error) {
33 if s.db == nil {
34 return nixosToplevelCacheRecord{}, false, nil
35 }
36 r, err := s.db.GetNixOSToplevelCacheRecord(configKey)
37 if err != nil {
38 if errors.Is(err, sql.ErrNoRows) {
39 return nixosToplevelCacheRecord{}, false, nil
40 }
41 return nixosToplevelCacheRecord{}, false, err
42 }
43 return nixosToplevelCacheRecord{
44 ConfigKey: r.ConfigKey,
45 Toplevel: r.Toplevel,
46 UpdatedAt: r.UpdatedAt,
47 }, true, nil
48}
49
50func (s nixosToplevelCacheStore) Commit(configKey, toplevel string) error {
51 if configKey == "" {
52 return fmt.Errorf("config key is empty")
53 }
54 if toplevel == "" {
55 return fmt.Errorf("config toplevel is empty")
56 }
57 if s.db == nil {
58 return nil
59 }
60 return s.db.SaveNixOSToplevelCacheRecord(configKey, toplevel)
61}
62
63func BaseConfigHash(imageSpec ImageSpec) (string, error) {
64 if imageSpec.BaseConfigHash == "" {
65 return "", fmt.Errorf("microvm image spec missing baseConfigHash")
66 }
67 return imageSpec.BaseConfigHash, nil
68}
69
70func userConfigHash(cfg manifestConfig) string {
71 data, _ := json.Marshal(cfg)
72 sum := sha256.Sum256(data)
73 return hex.EncodeToString(sum[:])
74}
75
76func buildConfigKey(imageSpec ImageSpec, cfg manifestConfig, repoDid string) (string, error) {
77 baseHash, err := BaseConfigHash(imageSpec)
78 if err != nil {
79 return "", err
80 }
81 payload := struct {
82 Schema int `json:"schema"`
83 BaseConfig string `json:"base_config"`
84 UserConfig string `json:"user_config"`
85 RepoDid string `json:"repo_did"`
86 }{
87 Schema: nixosToplevelCacheSchemaVersion,
88 BaseConfig: baseHash,
89 UserConfig: userConfigHash(cfg),
90 RepoDid: repoDid,
91 }
92 data, _ := json.Marshal(payload)
93 sum := sha256.Sum256(data)
94 return hex.EncodeToString(sum[:]), nil
95}
96
97func BuildConfigKey(imageSpec ImageSpec, userConfigJSON string, repoDid string) (string, error) {
98 var cfg manifestConfig
99 if err := json.Unmarshal([]byte(userConfigJSON), &cfg); err != nil {
100 return "", err
101 }
102 return buildConfigKey(imageSpec, cfg, repoDid)
103}