• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vinyl-linux / vin / 4255415897

pending completion
4255415897

push

github

GitHub
Merge pull request #47 from vinyl-linux/installation_regressions

9 of 9 new or added lines in 2 files covered. (100.0%)

1024 of 1159 relevant lines covered (88.35%)

15.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.42
/server.go
1
package main
2

3
import (
4
        "context"
5
        "fmt"
6
        "path/filepath"
7
        "strings"
8
        "sync"
9
        "time"
10

11
        "github.com/hashicorp/go-version"
12
        "github.com/vinyl-linux/vin/server"
13
        "google.golang.org/grpc/codes"
14
        "google.golang.org/grpc/status"
15
        "google.golang.org/protobuf/types/known/emptypb"
16
)
17

18
const (
19
        DefaultProfile = "default"
20
)
21

22
var (
23
        errEmptyPackage = status.Error(codes.InvalidArgument, "package must not be empty")
24
)
25

26
type Server struct {
27
        server.UnimplementedVinServer
28

29
        sdb StateDB
30
        mdb ManifestDB
31

32
        operationLock *sync.Mutex
33
}
34

35
func NewServer(m ManifestDB, sdb StateDB) (s Server, err error) {
4✔
36
        return Server{
4✔
37
                UnimplementedVinServer: server.UnimplementedVinServer{},
4✔
38
                sdb:                    sdb,
4✔
39
                mdb:                    m,
4✔
40
                operationLock:          &sync.Mutex{},
4✔
41
        }, nil
4✔
42
}
4✔
43

44
func (s *Server) getOpsLock(oc chan string) {
13✔
45
        done := make(chan bool, 0)
13✔
46
        go func() {
26✔
47
                c := time.Tick(time.Second)
13✔
48

13✔
49
                for {
26✔
50
                        select {
13✔
51
                        case <-done:
13✔
52
                                return
13✔
53
                        case <-c:
×
54
                                oc <- "waiting for lock"
×
55
                        }
56
                }
57
        }()
58

59
        s.operationLock.Lock()
13✔
60
        done <- true
13✔
61
}
62

63
func (s Server) Install(is *server.InstallSpec, vs server.Vin_InstallServer) (err error) {
15✔
64
        var (
15✔
65
                pkg string
15✔
66
                ver version.Constraints
15✔
67
        )
15✔
68

15✔
69
        switch len(is.Pkg) {
15✔
70
        case 0:
1✔
71
                return errEmptyPackage
1✔
72

73
        case 1:
12✔
74
                pkg = is.Pkg[0]
12✔
75
                if pkg == "" {
13✔
76
                        return errEmptyPackage
1✔
77
                }
1✔
78

79
                if is.Version != "" {
18✔
80
                        ver, err = version.NewConstraint(is.Version)
7✔
81
                        if err != nil {
8✔
82
                                return
1✔
83
                        }
1✔
84
                }
85

86
        default:
2✔
87
                err = s.createMetaPackage(is.Pkg)
2✔
88
                if err != nil {
3✔
89
                        return err
1✔
90
                }
1✔
91

92
                pkg = MetaManifestName
1✔
93
                ver = latest
1✔
94

1✔
95
                defer s.mdb.deleteManifest(pkg)
1✔
96
        }
97

98
        output := NewOutputter(vs)
11✔
99
        output.Prefix = "setup"
11✔
100

11✔
101
        defer close(output.C)
11✔
102
        go output.Dispatch()
11✔
103

11✔
104
        output.C <- fmt.Sprintf("installing %s", pkg)
11✔
105

11✔
106
        s.getOpsLock(output.C)
11✔
107
        defer s.operationLock.Unlock()
11✔
108

11✔
109
        g := NewGraph(&s.mdb, &s.sdb, output.C)
11✔
110
        tasks, err := g.Solve(DefaultProfile, pkg, ver)
11✔
111
        if err != nil {
13✔
112
                return
2✔
113
        }
2✔
114

115
        output.C <- installingLine(tasks)
9✔
116

9✔
117
        var (
9✔
118
                cmd string
9✔
119
        )
9✔
120

9✔
121
        // Write world db to disk on return
9✔
122
        defer s.sdb.Write()
9✔
123

9✔
124
        // Store finaliser commands
9✔
125
        finalisers := make([]*Manifest, 0)
9✔
126

9✔
127
        // for each pkg
9✔
128
        for _, task := range tasks {
20✔
129
                output.Prefix = task.ID
11✔
130

11✔
131
                if s.sdb.IsInstalled(task.ID) && !is.Force {
11✔
132
                        output.C <- fmt.Sprintf("%s is already installed, skipping", task.ID)
×
133

×
134
                        continue
×
135
                }
136

137
                if task.Meta {
14✔
138
                        output.C <- fmt.Sprintf("%s is a meta-package, skipping", task.ID)
3✔
139

3✔
140
                        continue
3✔
141
                }
142

143
                err = task.Prepare(output.C)
8✔
144
                if err != nil {
10✔
145
                        return
2✔
146
                }
2✔
147

148
                err = task.Commands.Patch(task.Commands.absoluteWorkingDir, output.C)
6✔
149
                if err != nil {
6✔
150
                        return
×
151
                }
×
152

153
                for _, raw := range task.Commands.Slice() {
20✔
154
                        cmd, err = task.Commands.installationValues.Expand(raw)
14✔
155
                        if err != nil {
15✔
156
                                return
1✔
157
                        }
1✔
158

159
                        err = execute(task.Commands.absoluteWorkingDir, cmd, task.Commands.Skipenv, output.C)
13✔
160
                        if err != nil {
14✔
161
                                return
1✔
162
                        }
1✔
163
                }
164

165
                if task.ServiceDir != "" {
5✔
166
                        output.C <- "installing service directory"
1✔
167
                        err = installServiceDir(filepath.Join(task.ManifestDir, task.ServiceDir))
1✔
168
                        if err != nil {
1✔
169
                                return
×
170
                        }
×
171
                }
172

173
                if task.Commands.Finaliser != "" {
5✔
174
                        finalisers = append(finalisers, task)
1✔
175
                }
1✔
176

177
                s.sdb.AddInstalled(task.ID, time.Now())
4✔
178
        }
179

180
        for _, task := range finalisers {
6✔
181
                var cmd string
1✔
182
                cmd, err = task.Commands.installationValues.Expand(task.Commands.Finaliser)
1✔
183
                if err != nil {
1✔
184
                        return
×
185
                }
×
186

187
                err = execute(task.Commands.absoluteWorkingDir, cmd, task.Commands.Skipenv, output.C)
1✔
188
                if err != nil {
1✔
189
                        return
×
190
                }
×
191
        }
192

193
        if pkg != MetaManifestName {
9✔
194
                s.sdb.AddWorld(pkg, is.Version)
4✔
195
        }
4✔
196

197
        return
5✔
198
}
199

200
func (s Server) Reload(_ *emptypb.Empty, vs server.Vin_ReloadServer) (err error) {
2✔
201
        output := NewOutputter(vs)
2✔
202
        output.Prefix = "reload"
2✔
203

2✔
204
        defer close(output.C)
2✔
205
        go output.Dispatch()
2✔
206

2✔
207
        output.C <- "reloading config"
2✔
208

2✔
209
        s.getOpsLock(output.C)
2✔
210
        defer s.operationLock.Unlock()
2✔
211

2✔
212
        // reload mdb
2✔
213
        s.mdb.Reload()
2✔
214

2✔
215
        output.C <- "reloaded"
2✔
216

2✔
217
        return
2✔
218
}
2✔
219

220
func (s Server) Version(ctx context.Context, _ *emptypb.Empty) (v *server.VersionMessage, err error) {
1✔
221
        return &server.VersionMessage{
1✔
222
                Ref:       ref,
1✔
223
                BuildUser: buildUser,
1✔
224
                BuiltOn:   builtOn,
1✔
225
        }, nil
1✔
226
}
1✔
227

228
func (s Server) createMetaPackage(packages []string) (err error) {
2✔
229
        var pm *Manifest
2✔
230

2✔
231
        // create a new 'meta package'
2✔
232
        deps := make([]Dep, len(packages))
2✔
233
        for i, p := range packages {
5✔
234
                if p == "" {
4✔
235
                        return errEmptyPackage
1✔
236
                }
1✔
237

238
                pm, err = s.mdb.Latest(p, latest)
2✔
239
                if err != nil {
2✔
240
                        return
×
241
                }
×
242

243
                deps[i] = [2]string{pm.Provides, pm.Version.String()}
2✔
244
        }
245

246
        metaManifest := &Manifest{
1✔
247
                Provides: MetaManifestName,
1✔
248
                Version:  new(version.Version),
1✔
249
                Meta:     true,
1✔
250
                Profiles: map[string]Profile{
1✔
251
                        "default": Profile{
1✔
252
                                Deps: deps,
1✔
253
                        },
1✔
254
                },
1✔
255
        }
1✔
256

1✔
257
        metaManifest.ID = metaManifest.String()
1✔
258

1✔
259
        // add metaManifest to database
1✔
260
        tx := s.mdb.db.Txn(true)
1✔
261
        defer tx.Commit()
1✔
262

1✔
263
        return s.mdb.addManifest(tx, metaManifest)
1✔
264
}
265

266
func installingLine(tasks []*Manifest) string {
9✔
267
        sb := strings.Builder{}
9✔
268

9✔
269
        sb.WriteString("installing dependencies:")
9✔
270
        for _, t := range tasks {
20✔
271
                sb.WriteString("\n")
11✔
272
                sb.WriteString("\t")
11✔
273
                sb.WriteString(t.ID)
11✔
274
        }
11✔
275

276
        return sb.String()
9✔
277
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc