Skip to content

Commit

Permalink
feat: add more docker-compose support
Browse files Browse the repository at this point in the history
Signed-off-by: Vasek - Tom C <[email protected]>
  • Loading branch information
TomChv committed Jan 29, 2025
1 parent 037e88a commit 445f8c1
Show file tree
Hide file tree
Showing 17 changed files with 436 additions and 143 deletions.
53 changes: 51 additions & 2 deletions docker_sdk/src/codebase/codebase.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import (
"context"
"fmt"
"os"
"path/filepath"

"dagger.io/dockersdk/codebase/dockercompose"
"dagger.io/dockersdk/codebase/dockerfile"
"dagger.io/dockersdk/codebase/finder"
)

const CodebasePath = "/app"
Expand All @@ -23,12 +25,14 @@ func New(ctx context.Context) (*Codebase, error) {
return nil, fmt.Errorf("failed to read source directory: %w", err)
}

dockerfile, dockerfileExists, err := getDockerfile(CodebasePath, dir)
finder := finder.New(CodebasePath, dir)

dockerfile, dockerfileExists, err := getDockerfile(finder)
if err != nil {
return nil, fmt.Errorf("failed to get Dockerfile: %w", err)
}

dockercompose, composeExistsExists, err := getDockerCompose(ctx, CodebasePath, dir)
dockercompose, composeExistsExists, err := getDockerCompose(ctx, finder)
if err != nil {
return nil, fmt.Errorf("failed to get docker-compose file: %w", err)
}
Expand All @@ -43,4 +47,49 @@ func New(ctx context.Context) (*Codebase, error) {
dockerfile: dockerfile,
dockercompose: dockercompose,
}, nil
}

func getDockerfile(finder *finder.Finder) (*dockerfile.Dockerfile, bool, error) {
patterns := []string{"Dockerfile", "*.Dockerfile"}

dockerfilePath, exist := finder.FindFileFromPattern(patterns)
if !exist {
return nil, false, nil
}

file, err := os.Open(dockerfilePath)
if err != nil {
return nil, true, fmt.Errorf("failed to open Dockerfile: %w", err)
}
defer file.Close()

filename := filepath.Base(dockerfilePath)
dockerfile, err := dockerfile.NewDockerfile(filename, file)
if err != nil {
return nil, true, fmt.Errorf("failed to parse Dockerfile: %w", err)
}

return dockerfile, true, nil
}

func getDockerCompose(ctx context.Context, finder *finder.Finder) (*dockercompose.DockerCompose, bool, error) {
patterns := []string{"docker-compose.yml", "docker-compose.yaml", "compose.yaml", "compose.yml"}

dockerComposePath, exist := finder.FindFileFromPattern(patterns)
if !exist {
return nil, false, nil
}

filename := filepath.Base(dockerComposePath)
fileContent, err := os.ReadFile(dockerComposePath)
if err != nil {
return nil, true, fmt.Errorf("failed to get %s content: %w", filename, err)
}

compose, err := dockercompose.NewDockerCompose(ctx, filename, fileContent, finder)
if err != nil {
return nil, true, fmt.Errorf("failed to parse docker-compose.yml: %w", err)
}

return compose, true, nil
}
8 changes: 6 additions & 2 deletions docker_sdk/src/codebase/dockercompose/docker_compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@ import (
"context"
"fmt"

"dagger.io/dockersdk/codebase/finder"
"github.com/compose-spec/compose-go/loader"
"github.com/compose-spec/compose-go/types"
)

type DockerCompose struct {
filename string
project *types.Project

finder *finder.Finder
}

func NewDockerCompose(ctx context.Context, filename string, content []byte) (*DockerCompose, error) {
func NewDockerCompose(ctx context.Context, filename string, content []byte, finder *finder.Finder) (*DockerCompose, error) {
project, err := loader.LoadWithContext(ctx, types.ConfigDetails{
ConfigFiles: []types.ConfigFile{
{
Expand All @@ -33,14 +36,15 @@ func NewDockerCompose(ctx context.Context, filename string, content []byte) (*Do
return &DockerCompose{
filename: filename,
project: project,
finder: finder,
}, nil
}

func (d *DockerCompose) Services() []*Service {
services := make([]*Service, len(d.project.Services))

for i, service := range d.project.Services {
services[i] = NewService(&service)
services[i] = NewService(d, &service, d.finder)
}

return services
Expand Down
88 changes: 80 additions & 8 deletions docker_sdk/src/codebase/dockercompose/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"fmt"
"strconv"

"dagger.io/dockersdk/codebase/finder"
"dagger.io/dockersdk/utils"
"github.com/compose-spec/compose-go/types"
)

Expand All @@ -12,7 +14,7 @@ type SourceImage struct {
}

type SourceDockerfile struct {
Context string
Context string
Dockerfile string
BuildArgs map[string]*string
Target *string
Expand All @@ -35,19 +37,33 @@ type Source struct {
}

type Service struct {
s *types.ServiceConfig
sourceCompose *DockerCompose
s *types.ServiceConfig
finder *finder.Finder

exposedPorts []int
}

func NewService(service *types.ServiceConfig) *Service {
func NewService(sourceCompose *DockerCompose, service *types.ServiceConfig, finder *finder.Finder) *Service {
return &Service{
sourceCompose: sourceCompose,
s: service,
finder: finder,
}
}

func (s *Service) Name() string {
return s.s.Name
}

func (s *Service) ContainerName() string {
if s.s.ContainerName != "" {
return s.s.ContainerName
}

return s.s.Name
}

func (s *Service) Source() *Source {
if s.s.Image != "" {
return &Source{
Expand Down Expand Up @@ -116,9 +132,22 @@ func (s *Service) Ports() []int {
ports = append(ports, published)
}

for _, port := range s.exposedPorts {
ports = append(ports, port)
}

// Clean duplicates
ports = utils.RemoveListDuplicates(ports)

return ports
}

func (s *Service) WithExposedPort(port int) *Service {
s.exposedPorts = append(s.exposedPorts, port)

return s
}

func (s *Service) Environment() (env map[string]*string, secrets []string) {
env = map[string]*string{}

Expand Down Expand Up @@ -153,19 +182,62 @@ func (s *Service) Volumes() ([]*Volume, []*Cache) {
case "volume":
caches = append(caches, &Cache{name: v.Source, path: v.Target})
case "bind":
volumes = append(volumes, &Volume{origin: trimHostPath(v.Source), target: v.Target})
source := trimHostPath(v.Source)
isDir, err := s.finder.IsPathDirectory(source)

// If we can't get the volumes, we'll convert it to cache
if err != nil {
caches = append(caches, &Cache{name: source, path: v.Target})

continue
}

volumes = append(volumes, &Volume{origin: source, target: v.Target, isDir: isDir})
}
}

return volumes, caches
}

func (s *Service) DependsOn() []string{
dependentServices := []string{}
func (s *Service) DependsOn() []string {
dependentServices := map[string]bool{}

for key := range s.s.DependsOn {
dependentServices = append(dependentServices, key)
dependentServices[key] = true

service, err := s.sourceCompose.GetService(key)
if err != nil {
fmt.Printf("failed to get service %s: %s\n", key, err.Error())

continue
}

serviceDeps := service.DependsOn()
for _, dep := range serviceDeps {
dependentServices[dep] = true
}
}

var dependentServicesList []string
for service := range dependentServices {
dependentServicesList = append(dependentServicesList, service)
}

return dependentServicesList
}

func (s *Service) Entrypoint() ([]string, bool) {
if s.s.Entrypoint != nil {
return s.s.Entrypoint, true
}

return nil, false
}

func (s *Service) Command() ([]string, bool) {
if s.s.Command != nil {
return s.s.Command, true
}

return dependentServices
return nil, false
}
5 changes: 5 additions & 0 deletions docker_sdk/src/codebase/dockercompose/volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import "path"
type Volume struct {
origin string
target string
isDir bool
}

func (v *Volume) Name() string {
Expand All @@ -17,4 +18,8 @@ func (v *Volume) Origin() string {

func (v *Volume) Target() string {
return v.target
}

func (v *Volume) IsDir() bool {
return v.isDir
}
62 changes: 0 additions & 62 deletions docker_sdk/src/codebase/finder.go

This file was deleted.

Loading

0 comments on commit 445f8c1

Please sign in to comment.