-
Notifications
You must be signed in to change notification settings - Fork 11
/
bundle_utils.go
142 lines (118 loc) · 4.32 KB
/
bundle_utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package embedshim
import (
"encoding/binary"
"encoding/json"
"fmt"
"os"
"path/filepath"
pkgbundle "github.com/fuweid/embedshim/pkg/bundle"
"github.com/fuweid/embedshim/pkg/runcext"
"github.com/containerd/containerd/runtime"
"github.com/containerd/containerd/runtime/v2/runc/options"
"github.com/gogo/protobuf/types"
)
var (
// bundleFileKeyTraceEventID is the filename about bpf trace event ID,
// which is used to receive the init's exit event from bpf MAP.
bundleFileKeyTraceEventID = "trace_event_id.binary"
// bundleFileKeyOCISpec is the filename about OCI spec which used by
// runC-like command.
bundleFileKeyOCISpec = "config.json"
// bundleFileKeyOptions is the filename about runtime or task options
// which used to get options, like runc-like command name.
bundleFileKeyOptions = "options.pb"
// bundleFileKeyStio is the filename about init's stdio settings which
// used to determine how to reload the init task.
//
// NOTE: For the init task running with stdin or terminal, the plugin
// might kill-9 init when recover.
bundleFileKeyStio = "stdio.json"
// bundleInitPidFile name of the file that contains the init pid
bundleInitPidFile = "init.pid"
)
func newInitPidFile(bundle *pkgbundle.Bundle) *runcext.PidFile {
return runcext.NewPidFile(filepath.Join(bundle.Path, bundleInitPidFile))
}
func readInitTraceEventID(b *pkgbundle.Bundle) (uint64, error) {
pathname := filepath.Join(b.Path, bundleFileKeyTraceEventID)
value, err := os.ReadFile(pathname)
if err != nil {
return 0, fmt.Errorf("failed to read %v: %w", pathname, err)
}
return binary.LittleEndian.Uint64(value), nil
}
// withBundleApplyInitTraceEventID applies the bpf eventID with little-endian
// binary into bundle.
func withBundleApplyInitTraceEventID(eventID uint64) pkgbundle.ApplyOpts {
return func(b *pkgbundle.Bundle) error {
var value [8]byte
binary.LittleEndian.PutUint64(value[:], eventID)
pathname := filepath.Join(b.Path, bundleFileKeyTraceEventID)
if err := os.WriteFile(pathname, value[:], 0666); err != nil {
return fmt.Errorf("failed to store in %v: %w", pathname, err)
}
return nil
}
}
// withBundleApplyInitOCISpec applies the init OCI spec into bundle.
func withBundleApplyInitOCISpec(spec *types.Any) pkgbundle.ApplyOpts {
return func(b *pkgbundle.Bundle) error {
pathname := filepath.Join(b.Path, bundleFileKeyOCISpec)
if err := os.WriteFile(pathname, spec.Value, 0666); err != nil {
return fmt.Errorf("failed to store in %v: %w", pathname, err)
}
return nil
}
}
func readInitOptions(b *pkgbundle.Bundle) (*options.Options, error) {
pathname := filepath.Join(b.Path, bundleFileKeyOptions)
value, err := os.ReadFile(pathname)
if err != nil {
return nil, fmt.Errorf("failed to read %v: %w", pathname, err)
}
opt := &options.Options{}
if err = opt.Unmarshal(value); err != nil {
return nil, fmt.Errorf("failed to unmarshal pb into options: %w", err)
}
return opt, nil
}
// withBundleApplyInitOptions applies the init's options into bundle.
func withBundleApplyInitOptions(opt *options.Options) pkgbundle.ApplyOpts {
return func(b *pkgbundle.Bundle) error {
value, err := opt.Marshal()
if err != nil {
return fmt.Errorf("failed to marshal %+v into pb: %w", opt, err)
}
pathname := filepath.Join(b.Path, bundleFileKeyOptions)
if err := os.WriteFile(pathname, value, 0666); err != nil {
return fmt.Errorf("failed to store in %v: %w", pathname, err)
}
return nil
}
}
func readInitStdio(b *pkgbundle.Bundle) (runtime.IO, error) {
stdio := runtime.IO{}
pathname := filepath.Join(b.Path, bundleFileKeyStio)
value, err := os.ReadFile(pathname)
if err != nil {
return stdio, fmt.Errorf("failed to read %v: %w", pathname, err)
}
if err := json.Unmarshal(value, &stdio); err != nil {
return stdio, fmt.Errorf("failed to unmarshal json into stdio: %w", err)
}
return stdio, nil
}
// withBundleApplyInitStdio applies the init's stdio settings into bundle.
func withBundleApplyInitStdio(stdio runtime.IO) pkgbundle.ApplyOpts {
return func(b *pkgbundle.Bundle) error {
value, err := json.Marshal(stdio)
if err != nil {
return fmt.Errorf("failed to marshal %+v into json: %w", stdio, err)
}
pathname := filepath.Join(b.Path, bundleFileKeyStio)
if err := os.WriteFile(pathname, value, 0666); err != nil {
return fmt.Errorf("failed to store in %v: %w", pathname, err)
}
return nil
}
}