github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/pkg/platform/runtime/executors/execmeta/execmeta.go (about) 1 // Package execmeta models the executor meta data that is communicated from the 2 // state tool to executors via file. The meta file is stored alongside the 3 // executors and should be named "meta.as". It should be applied to the file 4 // file system when the runtime is manifested on disk. 5 // 6 // IMPORTANT: This package should have minimal dependencies as it will be 7 // imported by cmd/state-exec. The resulting compiled executable must remain as 8 // small as possible. 9 package execmeta 10 11 import ( 12 "bytes" 13 "encoding/json" 14 "fmt" 15 "io" 16 "os" 17 "path/filepath" 18 "strings" 19 ) 20 21 type Target struct { 22 CommitUUID string 23 Namespace string 24 Dir string 25 Headless bool 26 } 27 28 const ( 29 MetaFileName = "meta.as" 30 metaFileDetectionToken = `"SockPath":` 31 ) 32 33 type ExecMeta struct { 34 SockPath string 35 Env []string 36 Bins map[string]string // map[alias]dest 37 CommitUUID string 38 Namespace string 39 Headless bool 40 } 41 42 func New(sockPath string, env []string, t Target, bins map[string]string) *ExecMeta { 43 return &ExecMeta{ 44 SockPath: sockPath, 45 Env: env, 46 Bins: bins, 47 CommitUUID: t.CommitUUID, 48 Namespace: t.Namespace, 49 Headless: t.Headless, 50 } 51 } 52 53 func NewFromReader(r io.Reader) (*ExecMeta, error) { 54 m := ExecMeta{} 55 if err := json.NewDecoder(r).Decode(&m); err != nil { 56 return nil, err 57 } 58 59 return &m, nil 60 } 61 62 // NewFromFile is a convenience func, not intended to be tested. 63 func NewFromFile(path string) (*ExecMeta, error) { 64 data, err := readFile(path) 65 if err != nil { 66 return nil, err 67 } 68 buf := bytes.NewBuffer(data) 69 return NewFromReader(buf) 70 } 71 72 func (m *ExecMeta) Encode(w io.Writer) error { 73 return json.NewEncoder(w).Encode(m) 74 } 75 76 // WriteToDisk is a convenience func, not intended to be unit tested. 77 func (m *ExecMeta) WriteToDisk(dir string) error { 78 path := filepath.Join(dir, MetaFileName) 79 buf := &bytes.Buffer{} 80 if err := m.Encode(buf); err != nil { 81 return err 82 } 83 if err := writeFile(path, buf.Bytes()); err != nil { 84 return err 85 } 86 return nil 87 } 88 89 func IsMetaFile(fileContents []byte) bool { 90 return strings.Contains(string(fileContents), metaFileDetectionToken) 91 } 92 93 func readFile(filePath string) ([]byte, error) { 94 b, err := os.ReadFile(filePath) 95 if err != nil { 96 return nil, fmt.Errorf("os.ReadFile %s failed: %w", filePath, err) 97 } 98 return b, nil 99 } 100 101 func writeFile(filePath string, data []byte) error { 102 f, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) 103 if err != nil { 104 return fmt.Errorf("os.OpenFile %s failed: %w", filePath, err) 105 } 106 defer f.Close() 107 108 _, err = f.Write(data) 109 if err != nil { 110 return fmt.Errorf("file.Write %s failed: %w", filePath, err) 111 } 112 return nil 113 }