package deployer import ( "encoding/base64" "encoding/json" "fmt" "sync" "github.com/google/uuid" "github.com/moby/moby/api/types/registry" "github.com/moby/moby/client" ) type DockerDeployer struct { client *client.Client deployJobs map[string]*DeployJob deployJobsMutex sync.RWMutex containerCreateMutex sync.Mutex instancerDomain string registryURL string registryUsername string registryPassword string proxyContainerName string imagePrefix string } type DeployJob struct { DeployChan chan DeployStatus deployKey string challenge string team string } func New(registryURL, registryUsername, registryPassword, instancerDomain, imagePrefix, proxyContainerName string) (DockerDeployer, error) { c, err := client.New(client.FromEnv) if err != nil { return DockerDeployer{}, fmt.Errorf("docker client error: %w", err) } return DockerDeployer{ client: c, deployJobs: make(map[string]*DeployJob), registryURL: registryURL, registryUsername: registryUsername, registryPassword: registryPassword, instancerDomain: instancerDomain, imagePrefix: imagePrefix, proxyContainerName: proxyContainerName, }, nil } func (d *DockerDeployer) GetJob(deployKey string) *DeployJob { d.deployJobsMutex.RLock() defer d.deployJobsMutex.RUnlock() return d.deployJobs[deployKey] } func (d *DockerDeployer) registryLogin() string { options := registry.AuthConfig{ ServerAddress: d.registryURL, Username: d.registryUsername, Password: d.registryPassword, } encodedJSON, err := json.Marshal(options) if err != nil { panic(err) } return base64.StdEncoding.EncodeToString(encodedJSON) } func (d *DockerDeployer) createDeployJob(challenge, team string) (string, *DeployJob) { d.deployJobsMutex.Lock() defer d.deployJobsMutex.Unlock() deploymentKey := uuid.New().String() deploymentChan := make(chan DeployStatus) job := &DeployJob{ DeployChan: deploymentChan, deployKey: deploymentKey, challenge: challenge, team: team, } d.deployJobs[deploymentKey] = job return deploymentKey, job } func (d *DockerDeployer) writeDeployChannel(deploymentKey string, status DeployStatus) { d.deployJobsMutex.RLock() defer d.deployJobsMutex.RUnlock() job := d.deployJobs[deploymentKey] if job == nil || job.DeployChan == nil { return } job.DeployChan <- status if status.Status == statusSuccess || status.Status == statusError { job.DeployChan <- DeployStatus{Status: "done", Message: "done"} close(job.DeployChan) //TODO cleanup } }