-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
176 lines (161 loc) · 4.14 KB
/
main.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// A Dagger module meant to provide some use in working with Distrobox
// primarily for bootstrapping container images
//
// https://github.com/89luca89/distrobox
package main
import (
"context"
"dagger/distrobox/internal/dagger"
"fmt"
"path"
"regexp"
)
var distrobox = "distrobox"
type Distrobox struct{}
// ContainerWithDistroboxCloned returns a Container with the Distrobox
// project cloned inside
func (d *Distrobox) ContainerWithDistroboxCloned(
// container to use to clone the distrobox project
// note: `git` is expected to be the entrypoint!
// +optional
// +default="cgr.dev/chainguard/git:latest"
from string,
// desired path inside the container to clone the distrobox project
// +optional
path *string,
) *dagger.Container {
if path == nil {
path = &distrobox
}
return dag.
Container().
From(from).
WithExec([]string{
"git",
"clone",
"https://github.com/89luca89/distrobox.git",
"--single-branch", *path,
})
}
// ContainerWithFileFromUrl will exec curl to grab url content and place it at
// the given (or default) path
func (d *Distrobox) ContainerWithFileFromUrl(
// container to use to execute curl
// note: `curl` is expected to be the entrypoint!
// +optional
// +default="cgr.dev/chainguard/curl:latest"
from string,
// url to grab the content from
url string,
// path to place the file at
// +optional
// +default="/tmp"
destination string,
// name the file should be saved as
// +optional
// +default=""
name string,
) *dagger.Container {
if name == "" {
name = path.Base(destination)
}
filePath := fmt.Sprintf("%s/%s", destination, name)
return dag.
Container().
From(from).
WithExec([]string{
"curl", "-fsSL", "-o", filePath, url,
})
}
// ContainerWithHostExec will grab the appropriate version of the host-spawn
// binary from GitHub releases as it associates with the downloaded distrobox
// release
func (d *Distrobox) HostSpawnFile(
ctx context.Context,
// container to use to execute curl to retrieve the host-spawn binary
// note: `curl` is expected to be the entrypoint!
// +optional
// +default="cgr.dev/chainguard/curl:latest"
from string,
// cpu architecture
// +optional
// +default="x86_64"
arch string,
) (*dagger.File, error) {
hostSpawnVersion, err := d.FindStringSubmatchInFile(
ctx, d.HostExecFile(
"cgr.dev/chainguard/git:latest", // HostExecFile uses git (not curl)
&distrobox,
), `host_spawn_version="(.*?)"`,
)
if err != nil {
return nil, err
}
url := fmt.Sprintf(
"https://github.com/1player/host-spawn/releases/download/%s/host-spawn-%s",
hostSpawnVersion,
arch,
)
return d.
ContainerWithFileFromUrl(
from, url, "/tmp", "host-spawn",
).
File("/tmp/host-spawn"), nil
}
// HostExecFile returns the distrobox-host-exec File
func (d *Distrobox) HostExecFile(
// container to use to clone the distrobox project
// note: `git` is expected to be the entrypoint!
// +optional
// +default="cgr.dev/chainguard/git:latest"
from string,
// desired path inside the container to clone the distrobox project
// +optional
path *string,
) *dagger.File {
if path == nil {
path = &distrobox
}
return d.
ContainerWithDistroboxCloned(from, path).
File(
fmt.Sprintf("%s/distrobox-host-exec", *path),
)
}
// FindStringSubmatchInFile returns the string matchings the given regex pattern
// in the provided File
func (d *Distrobox) FindStringSubmatchInFile(
ctx context.Context,
// file to match string in
file *dagger.File,
// regex to match against
regex string,
) (string, error) {
fileContents, err := file.Contents(ctx)
if err != nil {
return "", err
}
version, err := d.regexFindStringSubmatch(
fileContents,
regex,
)
if err != nil {
return version, fmt.Errorf("unable to match '%s' in file", regex)
}
return version, nil
}
// regexFindStringSubmatch returns the string matched to the given regex
func (d *Distrobox) regexFindStringSubmatch(
// text to match regex against
text string,
// regex to match against
regex string,
) (string, error) {
match := regexp.
MustCompile(regex).
FindStringSubmatch(text)
if match == nil {
return "", fmt.Errorf("no value found for regex: %s", regex)
}
return match[1], nil
}