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
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ require (
github.com/tcnksm/go-input v0.0.0-20180404061846-548a7d7a8ee8
github.com/withfig/autocomplete-tools/integrations/cobra v0.0.0-20220721102007-67b2515c5ea4
github.com/xanzy/go-gitlab v0.55.1
go.uber.org/multierr v1.6.0
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
gopkg.in/gookit/color.v1 v1.1.6
Expand Down Expand Up @@ -185,6 +186,7 @@ require (
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
go.uber.org/atomic v1.7.0 // indirect
golang.org/x/exp v0.0.0-20210901193431-a062eea981d2 // indirect
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1345,11 +1345,13 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.8.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
Expand Down
90 changes: 26 additions & 64 deletions internal/pkg/plugin/gitlabcedocker/create.go
Original file line number Diff line number Diff line change
@@ -1,83 +1,45 @@
package gitlabcedocker

import (
"fmt"
"strconv"
"strings"

"github.com/mitchellh/mapstructure"

"github.com/devstream-io/devstream/pkg/util/docker"
"github.com/devstream-io/devstream/internal/pkg/plugininstaller"
dockerInstaller "github.com/devstream-io/devstream/internal/pkg/plugininstaller/docker"
"github.com/devstream-io/devstream/pkg/util/log"
)

func Create(options map[string]interface{}) (map[string]interface{}, error) {
var opts Options
if err := mapstructure.Decode(options, &opts); err != nil {
// 1. create config and pre-handle operations
opts, err := preHandleOptions(options)
if err != nil {
return nil, err
}

defaults(&opts)
gitlabURL = opts.getGitLabURL()

if errs := validate(&opts); len(errs) != 0 {
for _, e := range errs {
log.Errorf("Options error: %s.", e)
}
return nil, fmt.Errorf("opts are illegal")
// 2. config install operations
runner := &plugininstaller.Runner{
PreExecuteOperations: []plugininstaller.MutableOperation{
dockerInstaller.Validate,
},
ExecuteOperations: []plugininstaller.BaseOperation{
dockerInstaller.InstallOrUpdate,
showGitLabURL,
},
TerminateOperations: []plugininstaller.BaseOperation{
dockerInstaller.HandleRunFailure,
},
GetStatusOperation: dockerInstaller.GetStaticStateFromOptions,
}

op := GetDockerOperator(opts)

// 1. try to pull the image
// always pull the image because docker will check the image existence
if err := op.ImagePull(getImageNameWithTag(opts)); err != nil {
// 3. execute installer get status and error
rawOptions, err := buildDockerOptions(opts).Encode()
if err != nil {
return nil, err
}

// 2. try to run the container
log.Info("Running container as the name <gitlab>")
if err := op.ContainerRun(buildDockerRunOptions(opts), dockerRunShmSizeParam); err != nil {
return nil, fmt.Errorf("failed to run container: %v", err)
}

// 3. check if the container is started successfully
if ok := op.ContainerIfRunning(gitlabContainerName); !ok {
return nil, fmt.Errorf("failed to run container")
}

// 4. check if the volume is created successfully
mounts, err := op.ContainerListMounts(gitlabContainerName)
status, err := runner.Execute(rawOptions)
if err != nil {
return nil, fmt.Errorf("failed to get container mounts: %v", err)
}
volumes := mounts.ExtractSources()
if docker.IfVolumesDiffer(volumes, getVolumesDirFromOptions(opts)) {
return nil, fmt.Errorf("failed to create volumes")
}

// 5. show the access url
showGitLabURL(opts)

resource := gitlabResource{
ContainerRunning: true,
Volumes: volumes,
Hostname: opts.Hostname,
SSHPort: strconv.Itoa(int(opts.SSHPort)),
HTTPPort: strconv.Itoa(int(opts.HTTPPort)),
HTTPSPort: strconv.Itoa(int(opts.HTTPSPort)),
}

return resource.toMap(), nil
}

func showGitLabURL(opts Options) {
accessUrl := opts.Hostname
if opts.HTTPPort != 80 {
accessUrl += ":" + strconv.Itoa(int(opts.HTTPPort))
}
if !strings.HasPrefix(accessUrl, "http") {
accessUrl = "http://" + accessUrl
return nil, err
}
log.Debugf("Return map: %v", status)

log.Infof("GitLab access URL: %s", accessUrl)
return status, nil
}
106 changes: 20 additions & 86 deletions internal/pkg/plugin/gitlabcedocker/delete.go
Original file line number Diff line number Diff line change
@@ -1,102 +1,36 @@
package gitlabcedocker

import (
"fmt"
"os"

"github.com/mitchellh/mapstructure"

"github.com/devstream-io/devstream/pkg/util/log"
"github.com/devstream-io/devstream/internal/pkg/plugininstaller"
dockerInstaller "github.com/devstream-io/devstream/internal/pkg/plugininstaller/docker"
)

func Delete(options map[string]interface{}) (bool, error) {
var opts Options
if err := mapstructure.Decode(options, &opts); err != nil {
// 1. create config and pre-handle operations
opts, err := preHandleOptions(options)
if err != nil {
return false, err
}

defaults(&opts)

if errs := validate(&opts); len(errs) != 0 {
for _, e := range errs {
log.Errorf("Options error: %s.", e)
}
return false, fmt.Errorf("opts are illegal")
// 2. config delete operations
runner := &plugininstaller.Runner{
PreExecuteOperations: []plugininstaller.MutableOperation{
dockerInstaller.Validate,
},
ExecuteOperations: []plugininstaller.BaseOperation{
dockerInstaller.Delete,
},
}

op := GetDockerOperator(opts)

// 1. stop the container if it is running
if ok := op.ContainerIfRunning(gitlabContainerName); ok {
if err := op.ContainerStop(gitlabContainerName); err != nil {
log.Errorf("Failed to stop container: %v", err)
}
}

// 2. remove the container if it exists
if ok := op.ContainerIfExist(gitlabContainerName); ok {
if err := op.ContainerRemove(gitlabContainerName); err != nil {
log.Errorf("failed to remove container %v: %v", gitlabContainerName, err)
}
}

// 3. remove the image if it exists
if ok := op.ImageIfExist(getImageNameWithTag(opts)); ok {
if err := op.ImageRemove(getImageNameWithTag(opts)); err != nil {
log.Errorf("failed to remove image %v: %v", getImageNameWithTag(opts), err)
}
}

// 4. remove the volume if it exists
volumesDirFromOptions := getVolumesDirFromOptions(opts)
if opts.RmDataAfterDelete {
for _, volume := range volumesDirFromOptions {
if err := os.RemoveAll(volume); err != nil {
log.Errorf("failed to remove data %v: %v", volume, err)
}
}
}

var errs []error

// 1. check if the container is stopped and deleted
if ok := op.ContainerIfRunning(gitlabContainerName); ok {
errs = append(errs, fmt.Errorf("failed to delete/stop container %s", gitlabContainerName))
}
if ok := op.ContainerIfExist(gitlabContainerName); ok {
errs = append(errs, fmt.Errorf("failed to delete container %s", gitlabContainerName))
}

// 2. check if the image is removed
if ok := op.ImageIfExist(getImageNameWithTag(opts)); ok {
errs = append(errs, fmt.Errorf("failed to delete image %s", getImageNameWithTag(opts)))
}

// 3. check if the data volume is removed
if opts.RmDataAfterDelete {
errs = append(errs, RemoveDirs(volumesDirFromOptions)...)
// 3. delete and get status
rawOptions, err := buildDockerOptions(opts).Encode()
if err != nil {
return false, err
}

// splice the errors
if len(errs) != 0 {
errsString := ""
for _, e := range errs {
errsString += e.Error() + "; "
}
return false, fmt.Errorf(errsString)
_, err = runner.Execute(rawOptions)
if err != nil {
return false, err
}

return true, nil
}

// RemoveDirs removes the all the directories in the given list recursively
func RemoveDirs(dirs []string) []error {
var errs []error
for _, dir := range dirs {
if err := os.RemoveAll(dir); err != nil {
errs = append(errs, err)
}
}

return errs
}
71 changes: 0 additions & 71 deletions internal/pkg/plugin/gitlabcedocker/delete_test.go

This file was deleted.

43 changes: 10 additions & 33 deletions internal/pkg/plugin/gitlabcedocker/gitlabcedocker.go
Original file line number Diff line number Diff line change
@@ -1,51 +1,28 @@
package gitlabcedocker

import (
"strings"
"fmt"

"github.com/devstream-io/devstream/pkg/util/docker"
"github.com/devstream-io/devstream/pkg/util/docker/dockersh"
"github.com/devstream-io/devstream/internal/pkg/plugininstaller"
"github.com/devstream-io/devstream/pkg/util/log"
)

const (
gitlabImageName = "gitlab/gitlab-ce"
defaultImageTag = "rc"
gitlabContainerName = "gitlab"
tcp = "tcp"
dockerRunShmSizeParam = "--shm-size 256m"
)

func getImageNameWithTag(opt Options) string {
return gitlabImageName + ":" + opt.ImageTag
}

func defaults(opts *Options) {
if opts.ImageTag == "" {
opts.ImageTag = defaultImageTag
}
}
// gitlabURL is the access URL of GitLab.
var gitlabURL string

func GetDockerOperator(_ Options) docker.Operator {
// just return a ShellOperator for now
return &dockersh.ShellOperator{}
func (opts *Options) getGitLabURL() string {
return fmt.Sprintf("http://%s:%d", opts.Hostname, opts.HTTPPort)
}

type gitlabResource struct {
ContainerRunning bool
Volumes []string
Hostname string
SSHPort string
HTTPPort string
HTTPSPort string
}
func showGitLabURL(options plugininstaller.RawOptions) error {
log.Infof("GitLab access URL: %s", gitlabURL)

func (res *gitlabResource) toMap() map[string]interface{} {
return map[string]interface{}{
"containerRunning": res.ContainerRunning,
"volumes": strings.Join(res.Volumes, ","),
"hostname": res.Hostname,
"SSHPort": res.SSHPort,
"HTTPPort": res.HTTPPort,
"HTTPSPort": res.HTTPSPort,
}
return nil
}
Loading