diff --git a/api/cmd/portainer/main.go b/api/cmd/portainer/main.go index 6ae3368d6..91bfce5f3 100644 --- a/api/cmd/portainer/main.go +++ b/api/cmd/portainer/main.go @@ -76,7 +76,7 @@ func initDataStore(dataStorePath string, fileService portainer.FileService) port } func initComposeStackManager(assetsPath string, dataStorePath string, reverseTunnelService portainer.ReverseTunnelService, proxyManager *proxy.Manager) portainer.ComposeStackManager { - composeWrapper := exec.NewComposeWrapper(assetsPath, proxyManager) + composeWrapper := exec.NewComposeWrapper(assetsPath, dataStorePath, proxyManager) if composeWrapper != nil { return composeWrapper } diff --git a/api/exec/compose_wrapper.go b/api/exec/compose_wrapper.go index 918411685..87aef1724 100644 --- a/api/exec/compose_wrapper.go +++ b/api/exec/compose_wrapper.go @@ -16,17 +16,19 @@ import ( // ComposeWrapper is a wrapper for docker-compose binary type ComposeWrapper struct { binaryPath string + dataPath string proxyManager *proxy.Manager } // NewComposeWrapper returns a docker-compose wrapper if corresponding binary present, otherwise nil -func NewComposeWrapper(binaryPath string, proxyManager *proxy.Manager) *ComposeWrapper { +func NewComposeWrapper(binaryPath, dataPath string, proxyManager *proxy.Manager) *ComposeWrapper { if !IsBinaryPresent(programPath(binaryPath, "docker-compose")) { return nil } return &ComposeWrapper{ binaryPath: binaryPath, + dataPath: dataPath, proxyManager: proxyManager, } } @@ -84,6 +86,8 @@ func (w *ComposeWrapper) command(command []string, stack *portainer.Stack, endpo var stderr bytes.Buffer cmd := exec.Command(program, args...) + cmd.Env = os.Environ() + cmd.Env = append(cmd.Env, fmt.Sprintf("DOCKER_CONFIG=%s", w.dataPath)) cmd.Stderr = &stderr out, err := cmd.Output() diff --git a/api/exec/compose_wrapper_integration_test.go b/api/exec/compose_wrapper_integration_test.go index 766622614..42c4af1c1 100644 --- a/api/exec/compose_wrapper_integration_test.go +++ b/api/exec/compose_wrapper_integration_test.go @@ -42,7 +42,7 @@ func Test_UpAndDown(t *testing.T) { stack, endpoint := setup(t) - w := NewComposeWrapper("", nil) + w := NewComposeWrapper("", "", nil) err := w.Up(stack, endpoint) if err != nil { diff --git a/api/http/proxy/factory/azure/containergroup.go b/api/http/proxy/factory/azure/containergroup.go index c3383035c..242968de5 100644 --- a/api/http/proxy/factory/azure/containergroup.go +++ b/api/http/proxy/factory/azure/containergroup.go @@ -23,6 +23,36 @@ func (transport *Transport) proxyContainerGroupRequest(request *http.Request) (* } func (transport *Transport) proxyContainerGroupPutRequest(request *http.Request) (*http.Response, error) { + //add a lock before processing existense check + transport.mutex.Lock() + defer transport.mutex.Unlock() + + //generate a temp http GET request based on the current PUT request + validationRequest := &http.Request{ + Method: http.MethodGet, + URL: request.URL, + Header: http.Header{ + "Authorization": []string{request.Header.Get("Authorization")}, + }, + } + + //fire the request to Azure API to validate if there is an existing container instance with the same name + //positive - reject the request + //negative - continue the process + validationResponse, err := http.DefaultTransport.RoundTrip(validationRequest) + if err != nil { + return validationResponse, err + } + + if validationResponse.StatusCode >= 200 && validationResponse.StatusCode < 300 { + resp := &http.Response{} + errObj := map[string]string{ + "message": "A container instance with the same name already exists inside the selected resource group", + } + err = responseutils.RewriteResponse(resp, errObj, http.StatusConflict) + return resp, err + } + response, err := http.DefaultTransport.RoundTrip(request) if err != nil { return response, err diff --git a/api/portainer.go b/api/portainer.go index f134eb26a..282a8b5f4 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -336,7 +336,7 @@ type ( // Whether non-administrator should be able to use container capabilities AllowContainerCapabilitiesForRegularUsers bool `json:"allowContainerCapabilitiesForRegularUsers" example:"true"` // Whether non-administrator should be able to use sysctl settings - AllowSysctlSettingForRegularUsers bool `json:"AllowSysctlSettingForRegularUsers" example:"true"` + AllowSysctlSettingForRegularUsers bool `json:"allowSysctlSettingForRegularUsers" example:"true"` // Whether host management features are enabled EnableHostManagementFeatures bool `json:"enableHostManagementFeatures" example:"true"` } diff --git a/app/docker/components/imageRegistry/por-image-registry.html b/app/docker/components/imageRegistry/por-image-registry.html index 77ca79c82..97b5c07e4 100644 --- a/app/docker/components/imageRegistry/por-image-registry.html +++ b/app/docker/components/imageRegistry/por-image-registry.html @@ -1,6 +1,6 @@ -