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

mendersoftware / mender-server / 1622978334

13 Jan 2025 03:51PM UTC coverage: 72.802% (-3.8%) from 76.608%
1622978334

Pull #300

gitlab-ci

alfrunes
fix: Deployment device count should not exceed max devices

Added a condition to skip deployments when the device count reaches max
devices.

Changelog: Title
Ticket: MEN-7847
Signed-off-by: Alf-Rune Siqveland <alf.rune@northern.tech>
Pull Request #300: fix: Deployment device count should not exceed max devices

4251 of 6164 branches covered (68.96%)

Branch coverage included in aggregate %.

0 of 18 new or added lines in 1 file covered. (0.0%)

2544 existing lines in 83 files now uncovered.

42741 of 58384 relevant lines covered (73.21%)

21.49 hits per line

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

64.11
/backend/services/inventory/main.go
1
// Copyright 2023 Northern.tech AS
2
//
3
//        Licensed under the Apache License, Version 2.0 (the "License");
4
//        you may not use this file except in compliance with the License.
5
//        You may obtain a copy of the License at
6
//
7
//            http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//        Unless required by applicable law or agreed to in writing, software
10
//        distributed under the License is distributed on an "AS IS" BASIS,
11
//        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//        See the License for the specific language governing permissions and
13
//        limitations under the License.
14
package main
15

16
import (
17
        "context"
18
        "encoding/json"
19
        "fmt"
20
        "os"
21
        "strings"
22

23
        "github.com/urfave/cli"
24

25
        "github.com/mendersoftware/mender-server/pkg/log"
26
        "github.com/mendersoftware/mender-server/pkg/version"
27

28
        "github.com/mendersoftware/mender-server/services/inventory/config"
29
        "github.com/mendersoftware/mender-server/services/inventory/store/mongo"
30
)
31

32
var appVersion = version.Get()
33

34
func main() {
1✔
35
        doMain(os.Args)
1✔
36
}
1✔
37

38
const maintenanceDescription = `Run migrations in maintenance mode.
39
   WARNING: All external endpoints modifying state in the database must be
40
            temporarily disabled while maintenance is in progress:
41
       - PUT    /api/management/v1/inventory/devices/{id}/group
42
       - DELETE /api/management/v1/inventory/devices/{id}
43
       - DELETE /api/management/v1/inventory/devices/{id}/group/{name}
44
       - PATCH  /api/devices/v1/inventory/devices/attributes`
45

46
func doMain(args []string) {
1✔
47
        var configPath string
1✔
48
        var debug bool
1✔
49

1✔
50
        app := cli.NewApp()
1✔
51
        app.Usage = "Device Authentication Service"
1✔
52

1✔
53
        app.Flags = []cli.Flag{
1✔
54
                cli.StringFlag{
1✔
55
                        Name: "config",
1✔
56
                        Usage: "Configuration `FILE`." +
1✔
57
                                " Supports JSON, TOML, YAML and HCL formatted configs.",
1✔
58
                        Destination: &configPath,
1✔
59
                },
1✔
60
                cli.BoolFlag{
1✔
61
                        Name:  "dev",
1✔
62
                        Usage: "Use development setup",
1✔
63
                },
1✔
64
                cli.BoolFlag{
1✔
65
                        Name:        "debug",
1✔
66
                        Usage:       "Enable debug logging",
1✔
67
                        Destination: &debug,
1✔
68
                },
1✔
69
        }
1✔
70

1✔
71
        app.Commands = []cli.Command{
1✔
72
                {
1✔
73
                        Name:  "server",
1✔
74
                        Usage: "Run the service as a server",
1✔
75
                        Flags: []cli.Flag{
1✔
76
                                cli.BoolFlag{
1✔
77
                                        Name:  "automigrate",
1✔
78
                                        Usage: "Run database migrations before starting.",
1✔
79
                                },
1✔
80
                        },
1✔
81

1✔
82
                        Action: cmdServer,
1✔
83
                },
1✔
84
                {
1✔
85
                        Name:  "migrate",
1✔
86
                        Usage: "Run migrations",
1✔
87
                        Flags: []cli.Flag{
1✔
88
                                cli.StringFlag{
1✔
89
                                        Name:  "tenant",
1✔
90
                                        Usage: "Takes ID of specific tenant to migrate.",
1✔
91
                                },
1✔
92
                        },
1✔
93

1✔
94
                        Action: cmdMigrate,
1✔
95
                },
1✔
96
                {
1✔
97
                        Name:        "maintenance",
1✔
98
                        Description: maintenanceDescription,
1✔
99
                        Flags: []cli.Flag{
1✔
100
                                cli.StringSliceFlag{
1✔
101
                                        Name: "tenant, t",
1✔
102
                                        Usage: "Takes ID of specific " +
1✔
103
                                                "tenant(s) to migrate. " +
1✔
104
                                                "Flag can be provided " +
1✔
105
                                                "multiple times.",
1✔
106
                                },
1✔
107
                                cli.StringFlag{
1✔
108
                                        Name:  "version",
1✔
109
                                        Usage: "Target version to migrate",
1✔
110
                                        Value: mongo.DbVersion,
1✔
111
                                },
1✔
112
                        },
1✔
113

1✔
114
                        Action: cmdMaintenence,
1✔
115
                },
1✔
116
                {
1✔
117
                        Name:  "version",
1✔
118
                        Usage: "Show version information",
1✔
119
                        Flags: []cli.Flag{
1✔
120
                                cli.StringFlag{
1✔
121
                                        Name:  "output",
1✔
122
                                        Usage: "Output format <json|text>",
1✔
123
                                        Value: "text",
1✔
124
                                },
1✔
125
                        },
1✔
126
                        Action: func(args *cli.Context) error {
1✔
127
                                switch strings.ToLower(args.String("output")) {
×
128
                                case "text":
×
129
                                        fmt.Print(appVersion)
×
130
                                case "json":
×
131
                                        _ = json.NewEncoder(os.Stdout).Encode(appVersion)
×
132
                                default:
×
133
                                        return fmt.Errorf("Unknown output format %q", args.String("output"))
×
134
                                }
135
                                return nil
×
136
                        },
137
                },
138
        }
139

140
        app.Version = appVersion.Version
1✔
141
        app.Action = cmdServer
1✔
142
        app.Before = func(args *cli.Context) error {
2✔
143
                log.Setup(debug)
1✔
144

1✔
145
                err := config.FromConfigFile(configPath, configDefaults)
1✔
146
                if err != nil {
1✔
147
                        return cli.NewExitError(
×
148
                                fmt.Sprintf("error loading configuration: %s", err),
×
149
                                1)
×
150
                }
×
151

152
                // Enable setting conig values by environment variables
153
                config.Config.SetEnvPrefix("INVENTORY")
1✔
154
                config.Config.AutomaticEnv()
1✔
155

1✔
156
                return nil
1✔
157
        }
158

159
        _ = app.Run(args)
1✔
160
}
161

162
func makeDataStoreConfig() mongo.DataStoreMongoConfig {
1✔
163
        return mongo.DataStoreMongoConfig{
1✔
164
                ConnectionString: config.Config.GetString(SettingDb),
1✔
165

1✔
166
                SSL:           config.Config.GetBool(SettingDbSSL),
1✔
167
                SSLSkipVerify: config.Config.GetBool(SettingDbSSLSkipVerify),
1✔
168

1✔
169
                Username: config.Config.GetString(SettingDbUsername),
1✔
170
                Password: config.Config.GetString(SettingDbPassword),
1✔
171
        }
1✔
172

1✔
173
}
1✔
174

UNCOV
175
func cmdServer(args *cli.Context) error {
×
UNCOV
176
        l := log.New(log.Ctx{})
×
UNCOV
177

×
UNCOV
178
        db, err := mongo.NewDataStoreMongo(makeDataStoreConfig())
×
UNCOV
179
        if err != nil {
×
180
                return cli.NewExitError(
×
181
                        fmt.Sprintf("failed to connect to db: %v", err),
×
182
                        3)
×
183
        }
×
184

UNCOV
185
        if args.Bool("automigrate") {
×
UNCOV
186
                db = db.WithAutomigrate()
×
UNCOV
187
        }
×
188

UNCOV
189
        ctx := context.Background()
×
UNCOV
190
        err = db.Migrate(ctx, mongo.DbVersion)
×
UNCOV
191
        if err != nil {
×
192
                return cli.NewExitError(
×
193
                        fmt.Sprintf("failed to run migrations: %v", err),
×
194
                        3)
×
195
        }
×
196

UNCOV
197
        l.Print("Inventory Service starting up")
×
UNCOV
198

×
UNCOV
199
        err = RunServer(config.Config)
×
UNCOV
200
        if err != nil {
×
201
                return cli.NewExitError(err.Error(), 4)
×
202
        }
×
203

UNCOV
204
        return nil
×
205
}
206

207
func cmdMigrate(args *cli.Context) error {
1✔
208
        tenantId := args.String("tenant")
1✔
209

1✔
210
        l := log.New(log.Ctx{})
1✔
211

1✔
212
        l.Print("Inventory Service starting up")
1✔
213

1✔
214
        if tenantId != "" {
2✔
215
                l.Printf("migrating tenant %v", tenantId)
1✔
216
        } else {
2✔
217
                l.Printf("migrating all the tenants")
1✔
218
        }
1✔
219

220
        db, err := mongo.NewDataStoreMongo(makeDataStoreConfig())
1✔
221

1✔
222
        if err != nil {
1✔
223
                return cli.NewExitError(
×
224
                        fmt.Sprintf("failed to connect to db: %v", err),
×
225
                        3)
×
226
        }
×
227

228
        // we want to apply migrations
229
        db = db.WithAutomigrate()
1✔
230

1✔
231
        ctx := context.Background()
1✔
232

1✔
233
        if tenantId != "" {
2✔
234
                err = db.MigrateTenant(ctx, mongo.DbVersion, tenantId)
1✔
235
        } else {
2✔
236
                err = db.Migrate(ctx, mongo.DbVersion)
1✔
237
        }
1✔
238
        if err != nil {
1✔
239
                return cli.NewExitError(
×
240
                        fmt.Sprintf("failed to run migrations: %v", err),
×
241
                        3)
×
242
        }
×
243

244
        return nil
1✔
245
}
246

247
func cmdMaintenence(args *cli.Context) error {
×
248
        tenantIDs := args.StringSlice("tenant")
×
249
        version := args.String("version")
×
250

×
251
        l := log.New(log.Ctx{})
×
252

×
253
        if len(tenantIDs) > 0 {
×
254
                l.Infof("performing maintenence for tenants: %v", tenantIDs)
×
255
        } else {
×
256
                l.Info("performing maintenance for all the tenants")
×
257
        }
×
258
        db, err := mongo.NewDataStoreMongo(makeDataStoreConfig())
×
259

×
260
        if err != nil {
×
261
                return cli.NewExitError(
×
262
                        fmt.Sprintf("failed to connect to db: %v", err),
×
263
                        3)
×
264
        }
×
265

266
        // we want to apply migrations
267
        db = db.WithAutomigrate()
×
268

×
269
        ctx := context.Background()
×
270

×
271
        err = db.Maintenance(ctx, version, tenantIDs...)
×
272
        if err != nil {
×
273
                return cli.NewExitError(
×
274
                        fmt.Sprintf("failed to run migrations: %v", err),
×
275
                        3)
×
276
        }
×
277

278
        return nil
×
279
}
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

© 2025 Coveralls, Inc