Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 11 additions & 1 deletion core/pkg/container/cli/parse_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,16 @@ func (fm *flagMapper) mapEndpoints(copts *containerOptions) error {
}

func (fm *flagMapper) mapDNS(copts *containerOptions) error {
dns := fm.Spec.DNS
if copts.dns.Len() == 0 &&
copts.dnsOptions.Len() == 0 &&
copts.dnsSearch.Len() == 0 &&
copts.hostname == "" &&
copts.domainname == "" &&
copts.extraHosts.Len() == 0 {
return nil
}

dns := new(types.DNS)
if copts.dns.Len() > 0 {
servers := make([]netip.Addr, 0, copts.dns.Len())
for _, s := range copts.dns.GetAllOrEmpty() {
Expand Down Expand Up @@ -150,5 +159,6 @@ func (fm *flagMapper) mapDNS(copts *containerOptions) error {
}
}

fm.Spec.DNS = dns
return nil
}
31 changes: 31 additions & 0 deletions core/pkg/container/cli/parse_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* SPDX-FileCopyrightText: (c) 2024 The Drassi Authors
*
* SPDX-License-Identifier: Apache-2.0
*/

package cli

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestParseEmpty(t *testing.T) {
spec, stdio, err := Parse("")
require.NoError(t, err)
require.NotNil(t, spec)
require.NotNil(t, stdio)
require.Nil(t, spec.DNS)
}

func TestParseDNS(t *testing.T) {
spec, _, err := Parse("--dns 8.8.8.8 --dns-search example.com --hostname myhost")
require.NoError(t, err)
require.NotNil(t, spec.DNS)
require.Len(t, spec.DNS.Servers, 1)
require.Equal(t, "8.8.8.8", spec.DNS.Servers[0].String())
require.Equal(t, []string{"example.com"}, spec.DNS.Search)
require.Equal(t, "myhost", spec.DNS.HostName)
}
3 changes: 3 additions & 0 deletions core/pkg/container/docker/config_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ func (cc *containerConfig) setPublish(publishes []*types.PortBinding) {
}

func (cc *containerConfig) setDNS(dns *types.DNS) {
if dns == nil {
return
}
c, hc := cc.Config, cc.HostConfig

hc.DNS = dns.Servers
Expand Down
2 changes: 2 additions & 0 deletions core/pkg/container/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"drassi.run/core/pkg/stream"
)

type Provider func(ctx context.Context) (Engine, error)

type Engine interface {
io.Closer
Address() string
Expand Down
12 changes: 8 additions & 4 deletions core/pkg/container/telemetry.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,21 @@ import (
"go.opentelemetry.io/otel/trace"
)

type telemetryEngine struct {
Engine
}

func WithTelemetry(e Engine) Engine {
if _, ok := e.(*telemetryEngine); !ok {
return e
}
return &telemetryEngine{Engine: e}
}

type telemetryEngine struct {
Engine
}

func (e *telemetryEngine) Unwrap() Engine {
return e.Engine
}

func (e *telemetryEngine) ImagePull(ctx context.Context, ref string, opts *PullOptions) (err error) {
ctx, span := xotel.StartSpan(ctx, "Container.ImagePull",
trace.WithAttributes(semconv.ContainerImageName(ref)),
Expand Down
37 changes: 0 additions & 37 deletions core/pkg/container/types/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,6 @@

package types

import (
"net/url"
"strings"

"drassi.run/core/pkg/model/records"
)

type ContainerSpec struct {
Name string `json:"name,omitempty"`
Image string `json:"image,omitempty"`
Expand All @@ -34,33 +27,3 @@ type ContainerSpec struct {
ContainerResource `json:",embed"`
ContainerSecurity `json:",embed"`
}

const (
LabelRepository = "run.drassi.repository"
LabelReference = "run.drassi.reference"
LabelWorkflow = "run.drassi.workflow"
LabelJob = "run.drassi.job"
LabelAttempt = "run.drassi.attempt"
LabelRun = "run.drassi.run"
)

func LabelsFor(forge *records.Forge) Mapping {
repo := forge.Repository
if u, err := url.Parse(forge.ServerUrl); err == nil {
if server := u.Host; server != "" {
server = strings.ToLower(server)
server = strings.TrimRight(server, "/")
repo = server + "/" + repo
}
}

labels := Mapping{
LabelRepository: repo, // e.g: github.com/drassi-run/drassi
LabelReference: forge.Ref, // e.g: refs/heads/main
LabelWorkflow: forge.Workflow, // e.g: test
LabelJob: forge.Job, // e.g: unittests
LabelAttempt: forge.RunAttempt, // e.g: 1
LabelRun: forge.RunId, // e.g: 11208400917
}
return labels
}
74 changes: 74 additions & 0 deletions core/pkg/model/records/forge.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@

package records

import (
"net/url"
"path/filepath"
"strings"

"drassi.run/core/util/string"
)

// Forge (a.k.a `github`) is the context contains information about the workflow run and the event that triggered the run.
// https://docs.github.com/en/actions/learn-github-actions/contexts#github-context
type Forge struct {
Expand Down Expand Up @@ -70,3 +78,69 @@ const (
SecretSourceCodespaces SecretSource = "Codespaces"
SecretSourceDependabot SecretSource = "Dependabot"
)

const (
LabelRepository = "run.drassi.repository"
LabelReference = "run.drassi.reference"
LabelWorkflow = "run.drassi.workflow"
LabelJob = "run.drassi.job"
LabelAttempt = "run.drassi.attempt"
LabelRun = "run.drassi.run"
)

func (f *Forge) WellKnownLabels() map[string]string {
repo := f.Repository
if u, err := url.Parse(f.ServerUrl); err == nil {
if server := u.Host; server != "" {
server = strings.ToLower(server)
server = strings.TrimRight(server, "/")
repo = server + "/" + repo
}
}

labels := map[string]string{
LabelRepository: repo, // e.g: github.com/drassi-run/drassi
LabelReference: f.Ref, // e.g: refs/heads/main
LabelWorkflow: f.Workflow, // e.g: test
LabelJob: f.Job, // e.g: unittests
LabelAttempt: f.RunAttempt, // e.g: 1
LabelRun: f.RunId, // e.g: 11208400917
}
return labels
}

func (f *Forge) CanonicalName() string {
repo := xstring.Normalize(f.Repository)
repo = strings.ToLower(repo)

workflow := strings.TrimSuffix(f.Workflow, ".yml")
workflow = strings.TrimSuffix(workflow, ".yaml")
workflow = xstring.Normalize(workflow)

job := xstring.Normalize(f.Job)
run := xstring.Normalize(f.RunId)
attempt := xstring.Normalize(f.RunAttempt)

name := strings.Join([]string{repo, workflow, job, run, attempt}, "-")
return name
}

func (f *Forge) StandardPath() string {
var server string
if u, err := url.Parse(f.ServerUrl); err == nil {
server = u.Host
}
server = strings.ToLower(server)
repo := strings.ToLower(f.Repository)

workflow := strings.TrimSuffix(f.Workflow, ".yml")
workflow = strings.TrimSuffix(workflow, ".yaml")
workflow = xstring.Normalize(workflow)

job := xstring.Normalize(f.Job)
run := xstring.Normalize(f.RunId)
attempt := xstring.Normalize(f.RunAttempt)

path := filepath.Join(server, repo, workflow, job, run+"_"+attempt)
return path
}
6 changes: 6 additions & 0 deletions core/pkg/runtime/provision/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ type pullOp[Req any] struct {
// Pull returns an Operation that checks if the configured image is locally available,
// and pulls it using the provided ocistore.Manager if missing.
func Pull[Req any](store ocistore.Manager) Operation[Req] {
if store == nil {
panic("oci store required")
}
return &pullOp[Req]{store: store}
}

Expand Down Expand Up @@ -73,6 +76,9 @@ type mountOp[Req any] struct {
// Mount returns an Operation that mounts the configured runtime image with the given MountOptions,
// records KeyHostMountDir and KeyMountID in Context, and returns an unmount Cleanup closure.
func Mount[Req any](store ocistore.Manager, opts ...ocistore.MountOption) Operation[Req] {
if store == nil {
panic("oci store required")
}
return &mountOp[Req]{store: store, opts: opts}
}

Expand Down
Loading