Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
a2d671c
build: bump from golang:1.25.6-alpine to golang:1.25.7-alpine (#798)
madhavilosetty-intel Feb 11, 2026
ab98937
build(deps): bump github.com/device-management-toolkit/go-wsman-messa…
dependabot[bot] Feb 11, 2026
21b2184
build(deps): bump modernc.org/sqlite from 1.44.3 to 1.45.0 (#787)
dependabot[bot] Feb 11, 2026
0c2ba3f
build(docs): failing to generate api spec should not be fatal (#800)
rsdmike Feb 11, 2026
e32651a
feat(power): add EnforceSecureBoot error message for CCM mode (#779)
madhavilosetty-intel Feb 11, 2026
fa74ec1
fix: handle encryption and decryption errors instead of silently igno…
DevipriyaS17 Feb 16, 2026
d2ef635
docs: add security guidelines (#808)
graikhel-intel Feb 18, 2026
f6559ab
feat: add KVM performance timing metrics and monitoring (#761)
nmgaston Feb 18, 2026
e6cdaa1
fix: prevent segfault in CIRA cleanup and EOF errors in hardware coll…
amarnath-ac Feb 20, 2026
55b99fa
build(deps): bump modernc.org/sqlite from 1.45.0 to 1.46.1 (#809)
dependabot[bot] Feb 20, 2026
e14916d
build(deps): bump github.com/zsais/go-gin-prometheus from 1.0.2 to 1.…
dependabot[bot] Feb 23, 2026
9f48eb3
fix: Update the validator criteria to allow wifi config is empty when…
choonkeat1986 Feb 23, 2026
026453f
build(docker): ensure user is non-root
rsdmike Feb 11, 2026
9f475a1
refactor: use one logger throughout application
rsdmike Feb 11, 2026
f2971d5
fix: suppress browser launch in noui builds (#812)
nmgaston Feb 25, 2026
049374b
fix: ensure auth failure returns without next() call (#803)
rsdmike Feb 25, 2026
cc8b501
ci: fix release build introduced in #812
rsdmike Feb 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,9 @@ jobs:
with:
go-version: ${{ matrix.go-version }}
- name: build go
run: go build ./cmd/app/main.go
run: go build ./cmd/app
- name: build noui (headless)
run: CGO_ENABLED=0 go build -tags=noui -o console-headless ./cmd/app/main.go
run: CGO_ENABLED=0 go build -tags=noui -o console-headless ./cmd/app
- name: Install Test Converter and run tests
run: |
export GOPATH="$HOME/go/"
Expand Down
18 changes: 9 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,28 +103,28 @@ jobs:
# Cross-compile all platform binaries from a single runner using CGO_ENABLED=0
# Static Go binaries are cross-platform compatible, so we can build all targets from Linux
- name: Build Linux x64
run: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-s -w -X 'github.com/device-management-toolkit/console/internal/app.Version=${{ needs.prepare.outputs.version }}'" -trimpath -o dist/linux/console_linux_x64 ./cmd/app/main.go
run: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-s -w -X 'github.com/device-management-toolkit/console/internal/app.Version=${{ needs.prepare.outputs.version }}'" -trimpath -o dist/linux/console_linux_x64 ./cmd/app

- name: Build Linux x64 headless
run: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -tags=noui -ldflags "-s -w -X 'github.com/device-management-toolkit/console/internal/app.Version=${{ needs.prepare.outputs.version }}'" -trimpath -o dist/linux/console_linux_x64_headless ./cmd/app/main.go
run: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -tags=noui -ldflags "-s -w -X 'github.com/device-management-toolkit/console/internal/app.Version=${{ needs.prepare.outputs.version }}'" -trimpath -o dist/linux/console_linux_x64_headless ./cmd/app

- name: Build Linux arm64
run: CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags "-s -w -X 'github.com/device-management-toolkit/console/internal/app.Version=${{ needs.prepare.outputs.version }}'" -trimpath -o dist/linux/console_linux_arm64 ./cmd/app/main.go
run: CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags "-s -w -X 'github.com/device-management-toolkit/console/internal/app.Version=${{ needs.prepare.outputs.version }}'" -trimpath -o dist/linux/console_linux_arm64 ./cmd/app

- name: Build Linux arm64 headless
run: CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -tags=noui -ldflags "-s -w -X 'github.com/device-management-toolkit/console/internal/app.Version=${{ needs.prepare.outputs.version }}'" -trimpath -o dist/linux/console_linux_arm64_headless ./cmd/app/main.go
run: CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -tags=noui -ldflags "-s -w -X 'github.com/device-management-toolkit/console/internal/app.Version=${{ needs.prepare.outputs.version }}'" -trimpath -o dist/linux/console_linux_arm64_headless ./cmd/app

- name: Build Windows x64
run: CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags "-s -w -X 'github.com/device-management-toolkit/console/internal/app.Version=${{ needs.prepare.outputs.version }}'" -trimpath -o dist/windows/console_windows_x64.exe ./cmd/app/main.go
run: CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags "-s -w -X 'github.com/device-management-toolkit/console/internal/app.Version=${{ needs.prepare.outputs.version }}'" -trimpath -o dist/windows/console_windows_x64.exe ./cmd/app

- name: Build Windows x64 headless
run: CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -tags=noui -ldflags "-s -w -X 'github.com/device-management-toolkit/console/internal/app.Version=${{ needs.prepare.outputs.version }}'" -trimpath -o dist/windows/console_windows_x64_headless.exe ./cmd/app/main.go
run: CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -tags=noui -ldflags "-s -w -X 'github.com/device-management-toolkit/console/internal/app.Version=${{ needs.prepare.outputs.version }}'" -trimpath -o dist/windows/console_windows_x64_headless.exe ./cmd/app

- name: Build macOS arm64
run: CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -ldflags "-s -w -X 'github.com/device-management-toolkit/console/internal/app.Version=${{ needs.prepare.outputs.version }}'" -trimpath -o dist/darwin/console_mac_arm64 ./cmd/app/main.go
run: CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -ldflags "-s -w -X 'github.com/device-management-toolkit/console/internal/app.Version=${{ needs.prepare.outputs.version }}'" -trimpath -o dist/darwin/console_mac_arm64 ./cmd/app

- name: Build macOS arm64 headless
run: CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -tags=noui -ldflags "-s -w -X 'github.com/device-management-toolkit/console/internal/app.Version=${{ needs.prepare.outputs.version }}'" -trimpath -o dist/darwin/console_mac_arm64_headless ./cmd/app/main.go
run: CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -tags=noui -ldflags "-s -w -X 'github.com/device-management-toolkit/console/internal/app.Version=${{ needs.prepare.outputs.version }}'" -trimpath -o dist/darwin/console_mac_arm64_headless ./cmd/app

# Cache all build artifacts in a single step
- uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
Expand Down Expand Up @@ -246,7 +246,7 @@ jobs:
- name: Generate OpenAPI specification
if: steps.semantic-release.outputs.new_release_published == 'true' && steps.check-openapi-changes.outputs.changed == 'true'
run: |
GIN_MODE=debug go run ./cmd/app/main.go
GIN_MODE=debug go run ./cmd/app

- name: Verify OpenAPI spec was generated
run: |
Expand Down
12 changes: 7 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
ARG BUILD_TAGS=""

# Step 1: Modules caching
FROM golang:1.25.6-alpine@sha256:98e6cffc31ccc44c7c15d83df1d69891efee8115a5bb7ede2bf30a38af3e3c92 AS modules
FROM golang:1.25.7-alpine@sha256:f6751d823c26342f9506c03797d2527668d095b0a15f1862cddb4d927a7a4ced AS modules
COPY go.mod go.sum /modules/
WORKDIR /modules
RUN apk add --no-cache git
RUN go mod download

# Step 2: Builder
FROM golang:1.25.6-alpine@sha256:98e6cffc31ccc44c7c15d83df1d69891efee8115a5bb7ede2bf30a38af3e3c92 AS builder
FROM golang:1.25.7-alpine@sha256:f6751d823c26342f9506c03797d2527668d095b0a15f1862cddb4d927a7a4ced AS builder
# Build tags control dependencies:
# - Default (no tags): Full build with UI
# - noui: Excludes web UI assets
Expand All @@ -37,10 +37,12 @@ RUN mkdir -p /.config/device-management-toolkit
# Step 3: Final - Use scratch for all builds (all are fully static with pure Go)
FROM scratch
ENV TMPDIR=/tmp
COPY --from=builder /app/tmp /tmp
COPY --from=builder /app/config /config
ENV XDG_CONFIG_HOME=/.config
COPY --chown=65534:65534 --from=builder /app/tmp /tmp
COPY --chown=65534:65534 --from=builder /app/config /config
COPY --from=builder /app/internal/app/migrations /migrations
COPY --from=builder /bin/app /app
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /.config/device-management-toolkit /.config/device-management-toolkit
COPY --chown=65534:65534 --from=builder /.config/device-management-toolkit /.config/device-management-toolkit
USER 65534:65534
CMD ["/app"]
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Security Policy
Intel is committed to rapidly addressing security vulnerabilities affecting our customers and providing clear guidance on the solution, impact, severity and mitigation.

## Reporting a Vulnerability

Please report any security vulnerabilities in this project utilizing the Github's guidelines [here](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability).
Please report any security vulnerabilities in this project utilizing the guidelines [here](https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html).
57 changes: 57 additions & 0 deletions cmd/app/browser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//go:build !noui

package main

import (
"context"
"os/exec"
"runtime"

"github.com/device-management-toolkit/console/config"
)

func launchBrowser(cfg *config.Config) {
scheme := "http"
if cfg.TLS.Enabled {
scheme = "https"
}

if err := openBrowser(scheme+"://localhost:"+cfg.Port, runtime.GOOS); err != nil {
panic(err)
}
}

// CommandExecutor is an interface to allow for mocking exec.Command in tests.
type CommandExecutor interface {
Execute(name string, arg ...string) error
}

// RealCommandExecutor is a real implementation of CommandExecutor.
type RealCommandExecutor struct{}

func (e *RealCommandExecutor) Execute(name string, arg ...string) error {
return exec.CommandContext(context.Background(), name, arg...).Start()
}

// Global command executor, can be replaced in tests.
var cmdExecutor CommandExecutor = &RealCommandExecutor{}

func openBrowser(url, currentOS string) error {
var cmd string

var args []string

switch currentOS {
case "darwin":
cmd = "open"
args = []string{url}
case "windows":
cmd = "cmd"
args = []string{"/c", "start", url}
default:
cmd = "xdg-open"
args = []string{url}
}

return cmdExecutor.Execute(cmd, args...)
}
8 changes: 8 additions & 0 deletions cmd/app/browser_noui.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//go:build noui

package main

import "github.com/device-management-toolkit/console/config"

// launchBrowser is a no-op in noui builds; there is no UI to open.
func launchBrowser(_ *config.Config) {}
53 changes: 53 additions & 0 deletions cmd/app/browser_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//go:build !noui

package main

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)

type MockCommandExecutor struct {
mock.Mock
}

func (m *MockCommandExecutor) Execute(name string, arg ...string) error {
args := m.Called(name, arg)

return args.Error(0)
}

func TestOpenBrowserWindows(t *testing.T) { //nolint:paralleltest // cannot have simultaneous tests modifying executor.
mockCmdExecutor := new(MockCommandExecutor)
cmdExecutor = mockCmdExecutor

mockCmdExecutor.On("Execute", "cmd", []string{"/c", "start", "http://localhost:8080"}).Return(nil)

err := openBrowser("http://localhost:8080", "windows")
assert.NoError(t, err)
mockCmdExecutor.AssertExpectations(t)
}

func TestOpenBrowserDarwin(t *testing.T) { //nolint:paralleltest // cannot have simultaneous tests modifying executor.
mockCmdExecutor := new(MockCommandExecutor)
cmdExecutor = mockCmdExecutor

mockCmdExecutor.On("Execute", "open", []string{"http://localhost:8080"}).Return(nil)

err := openBrowser("http://localhost:8080", "darwin")
assert.NoError(t, err)
mockCmdExecutor.AssertExpectations(t)
}

func TestOpenBrowserLinux(t *testing.T) { //nolint:paralleltest // cannot have simultaneous tests modifying executor.
mockCmdExecutor := new(MockCommandExecutor)
cmdExecutor = mockCmdExecutor

mockCmdExecutor.On("Execute", "xdg-open", []string{"http://localhost:8080"}).Return(nil)

err := openBrowser("http://localhost:8080", "ubuntu")
assert.NoError(t, err)
mockCmdExecutor.AssertExpectations(t)
}
80 changes: 17 additions & 63 deletions cmd/app/main.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package main

import (
"context"
"errors"
"fmt"
"log"
"os"
"os/exec"
"runtime"

"github.com/device-management-toolkit/go-wsman-messages/v2/pkg/security"

Expand All @@ -30,7 +27,9 @@ var (
var (
initializeConfigFunc = config.NewConfig
initializeAppFunc = app.Init
runAppFunc = app.Run
runAppFunc = func(cfg *config.Config, log logger.Interface) {
app.Run(cfg, log)
}
// NewGeneratorFunc allows tests to inject a fake OpenAPI generator.
NewGeneratorFunc = func(u usecase.Usecases, l logger.Interface) interface {
GenerateSpec() ([]byte, error)
Expand Down Expand Up @@ -63,9 +62,11 @@ func main() {
log.Fatalf("CIRA certificate setup error: %s", err)
}

l := logger.New(cfg.Level)

handleEncryptionKey(cfg)
handleDebugMode(cfg)
runAppFunc(cfg)
handleDebugMode(cfg, l)
runAppFunc(cfg, l)
}

func setupCIRACertificates(cfg *config.Config, secretsClient security.Storager) error {
Expand All @@ -86,29 +87,15 @@ func setupCIRACertificates(cfg *config.Config, secretsClient security.Storager)
return nil
}

func handleDebugMode(cfg *config.Config) {
func handleDebugMode(cfg *config.Config, l logger.Interface) {
if os.Getenv("GIN_MODE") != "debug" {
go launchBrowser(cfg)
} else {
if err := handleOpenAPIGeneration(); err != nil {
log.Fatalf("Failed to generate OpenAPI spec: %s", err)
}
}
}

func launchBrowser(cfg *config.Config) {
scheme := "http"
if cfg.TLS.Enabled {
scheme = "https"
}

if err := openBrowser(scheme+"://localhost:"+cfg.Port, runtime.GOOS); err != nil {
panic(err)
handleOpenAPIGeneration(l)
}
}

func handleOpenAPIGeneration() error {
l := logger.New("info")
func handleOpenAPIGeneration(l logger.Interface) {
usecases := usecase.Usecases{}

// Create OpenAPI generator
Expand All @@ -117,17 +104,19 @@ func handleOpenAPIGeneration() error {
// Generate specification
spec, err := generator.GenerateSpec()
if err != nil {
return err
l.Warn("Failed to generate OpenAPI spec: %s", err)

return
}

// Save to file
if err := generator.SaveSpec(spec, "doc/openapi.json"); err != nil {
return err
}
l.Warn("Failed to save OpenAPI spec: %s", err)

log.Println("OpenAPI specification generated at doc/openapi.json")
return
}

return nil
l.Info("OpenAPI specification generated at doc/openapi.json")
}

func handleSecretsConfig(cfg *config.Config) (security.Storager, error) {
Expand Down Expand Up @@ -299,38 +288,3 @@ func handleKeyNotFound(toolkitCrypto security.Crypto, _, _ security.Storager) st

return toolkitCrypto.GenerateKey()
}

// CommandExecutor is an interface to allow for mocking exec.Command in tests.
type CommandExecutor interface {
Execute(name string, arg ...string) error
}

// RealCommandExecutor is a real implementation of CommandExecutor.
type RealCommandExecutor struct{}

func (e *RealCommandExecutor) Execute(name string, arg ...string) error {
return exec.CommandContext(context.Background(), name, arg...).Start()
}

// Global command executor, can be replaced in tests.
var cmdExecutor CommandExecutor = &RealCommandExecutor{}

func openBrowser(url, currentOS string) error {
var cmd string

var args []string

switch currentOS {
case "darwin":
cmd = "open"
args = []string{url}
case "windows":
cmd = "cmd"
args = []string{"/c", "start", url}
default:
cmd = "xdg-open"
args = []string{url}
}

return cmdExecutor.Execute(cmd, args...)
}
Loading
Loading