Compare commits
9 Commits
develop
...
release/2.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
535215833d | ||
|
|
c4a1243af9 | ||
|
|
305d0d2da0 | ||
|
|
e4605d990d | ||
|
|
768697157c | ||
|
|
d3086da139 | ||
|
|
95894e8047 | ||
|
|
81de55fedd | ||
|
|
84827b8782 |
@@ -74,7 +74,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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
@@ -79,6 +81,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()
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1125,7 +1125,7 @@ type (
|
||||
|
||||
const (
|
||||
// APIVersion is the version number of the Portainer API
|
||||
APIVersion = "2.0.1"
|
||||
APIVersion = "2.1.1"
|
||||
// DBVersion is the version number of the Portainer database
|
||||
DBVersion = 25
|
||||
// ComposeSyntaxMaxVersion is a maximum supported version of the docker compose syntax
|
||||
|
||||
@@ -1,10 +1,32 @@
|
||||
import _ from 'lodash-es';
|
||||
import { KubernetesConfigMap } from 'Kubernetes/models/config-map/models';
|
||||
import { KubernetesConfigMap, KubernetesPortainerAccessConfigMap } from 'Kubernetes/models/config-map/models';
|
||||
import { KubernetesConfigMapCreatePayload, KubernetesConfigMapUpdatePayload } from 'Kubernetes/models/config-map/payloads';
|
||||
import { KubernetesPortainerConfigurationOwnerLabel } from 'Kubernetes/models/configuration/models';
|
||||
import { KubernetesConfigurationFormValuesEntry } from 'Kubernetes/models/configuration/formvalues';
|
||||
|
||||
class KubernetesConfigMapConverter {
|
||||
static apiToPortainerAccessConfigMap(data) {
|
||||
const res = new KubernetesPortainerAccessConfigMap();
|
||||
res.Id = data.metadata.uid;
|
||||
res.Data = data.data;
|
||||
return res;
|
||||
}
|
||||
|
||||
static createAccessPayload(data) {
|
||||
const res = new KubernetesConfigMapCreatePayload();
|
||||
_.unset(res, 'binaryData');
|
||||
res.metadata.name = data.Name;
|
||||
res.metadata.namespace = data.Namespace;
|
||||
res.data = data.Data;
|
||||
return res;
|
||||
}
|
||||
|
||||
static updateAccessPayload(data) {
|
||||
const res = KubernetesConfigMapConverter.createAccessPayload(data);
|
||||
res.metadata.uid = data.Id;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* API ConfigMap to front ConfigMap
|
||||
*/
|
||||
|
||||
@@ -52,6 +52,8 @@ class KubernetesConfigurationHelper {
|
||||
}
|
||||
|
||||
static parseData(formValues) {
|
||||
if (!formValues.Data.length) return '';
|
||||
|
||||
const data = _.reduce(
|
||||
formValues.Data,
|
||||
(acc, entry) => {
|
||||
|
||||
@@ -2,6 +2,15 @@ export const KubernetesPortainerConfigMapNamespace = 'portainer';
|
||||
export const KubernetesPortainerConfigMapConfigName = 'portainer-config';
|
||||
export const KubernetesPortainerConfigMapAccessKey = 'NamespaceAccessPolicies';
|
||||
|
||||
export function KubernetesPortainerAccessConfigMap() {
|
||||
return {
|
||||
Id: 0,
|
||||
Name: KubernetesPortainerConfigMapConfigName,
|
||||
Namespace: KubernetesPortainerConfigMapNamespace,
|
||||
Data: {},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* ConfigMap Model
|
||||
*/
|
||||
|
||||
@@ -3,6 +3,7 @@ import _ from 'lodash-es';
|
||||
import PortainerError from 'Portainer/error';
|
||||
import KubernetesConfigMapConverter from 'Kubernetes/converters/configMap';
|
||||
import { KubernetesCommonParams } from 'Kubernetes/models/common/params';
|
||||
import { KubernetesPortainerAccessConfigMap } from 'Kubernetes/models/config-map/models';
|
||||
|
||||
class KubernetesConfigMapService {
|
||||
/* @ngInject */
|
||||
@@ -17,6 +18,54 @@ class KubernetesConfigMapService {
|
||||
this.deleteAsync = this.deleteAsync.bind(this);
|
||||
}
|
||||
|
||||
getAccess(namespace, name) {
|
||||
return this.$async(async () => {
|
||||
try {
|
||||
const params = new KubernetesCommonParams();
|
||||
params.id = name;
|
||||
const raw = await this.KubernetesConfigMaps(namespace).get(params).$promise;
|
||||
return KubernetesConfigMapConverter.apiToPortainerAccessConfigMap(raw);
|
||||
} catch (err) {
|
||||
if (err.status === 404) {
|
||||
return new KubernetesPortainerAccessConfigMap();
|
||||
}
|
||||
throw new PortainerError('Unable to retrieve Portainer accesses', err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
createAccess(config) {
|
||||
return this.$async(async () => {
|
||||
try {
|
||||
const payload = KubernetesConfigMapConverter.createAccessPayload(config);
|
||||
const params = {};
|
||||
const namespace = payload.metadata.namespace;
|
||||
const data = await this.KubernetesConfigMaps(namespace).create(params, payload).$promise;
|
||||
return KubernetesConfigMapConverter.apiToPortainerAccessConfigMap(data);
|
||||
} catch (err) {
|
||||
throw new PortainerError('Unable to create Portainer accesses', err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateAccess(config) {
|
||||
return this.$async(async () => {
|
||||
try {
|
||||
if (!config.Id) {
|
||||
return await this.createAccess(config);
|
||||
}
|
||||
const payload = KubernetesConfigMapConverter.updateAccessPayload(config);
|
||||
const params = new KubernetesCommonParams();
|
||||
params.id = payload.metadata.name;
|
||||
const namespace = payload.metadata.namespace;
|
||||
const data = await this.KubernetesConfigMaps(namespace).update(params, payload).$promise;
|
||||
return KubernetesConfigMapConverter.apiToPortainerAccessConfigMap(data);
|
||||
} catch (err) {
|
||||
throw new PortainerError('Unable to update Portainer accesses', err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* GET
|
||||
*/
|
||||
@@ -29,12 +78,12 @@ class KubernetesConfigMapService {
|
||||
this.KubernetesConfigMaps(namespace).getYaml(params).$promise,
|
||||
]);
|
||||
|
||||
if (_.get(rawPromise, 'reason.status') == 404 && _.get(yamlPromise, 'reason.status') == 404) {
|
||||
if (_.get(rawPromise, 'reason.status') === 404 && _.get(yamlPromise, 'reason.status') === 404) {
|
||||
return KubernetesConfigMapConverter.defaultConfigMap(namespace, name);
|
||||
}
|
||||
|
||||
// Saving binary data to 'data' field in configMap Object is not allowed by kubernetes and getYaml() may get
|
||||
// an error. We should keep binary data to 'binaryData' field instead of 'data'. Before that, we
|
||||
// Saving binary data to 'data' field in configMap Object is not allowed by kubernetes and getYaml() may get
|
||||
// an error. We should keep binary data to 'binaryData' field instead of 'data'. Before that, we
|
||||
// use response from get() and ignore 500 error as a workaround.
|
||||
if (rawPromise.value) {
|
||||
return KubernetesConfigMapConverter.apiToConfigMap(rawPromise.value, yamlPromise.value);
|
||||
|
||||
@@ -1299,7 +1299,7 @@
|
||||
ng-min="1"
|
||||
ng-max="65535"
|
||||
ng-required="!publishedPort.NeedsDeletion"
|
||||
ng-change="ctrl.onChangePortMappingLoadBalancerPort()"
|
||||
ng-change="ctrl.onChangePortMappingLoadBalancer()"
|
||||
ng-disabled="ctrl.disableLoadBalancerEdit() || ctrl.isEditAndNotNewPublishedPort($index)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -409,13 +409,14 @@ class KubernetesCreateApplicationController {
|
||||
}
|
||||
|
||||
onChangePortProtocol(index) {
|
||||
this.onChangePortMappingContainerPort();
|
||||
if (this.formValues.PublishingType === KubernetesApplicationPublishingTypes.LOAD_BALANCER) {
|
||||
const newPorts = _.filter(this.formValues.PublishedPorts, { IsNew: true });
|
||||
_.forEach(newPorts, (port) => {
|
||||
port.Protocol = index ? this.formValues.PublishedPorts[index].Protocol : newPorts[0].Protocol;
|
||||
});
|
||||
this.onChangePortMappingLoadBalancer();
|
||||
}
|
||||
this.onChangePortMappingContainerPort();
|
||||
}
|
||||
/* #endregion */
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ class KubernetesResourcePoolAccessController {
|
||||
let [endpoint, pool, configMap] = await Promise.all([
|
||||
this.EndpointService.endpoint(this.endpointId),
|
||||
this.KubernetesResourcePoolService.get(name),
|
||||
this.KubernetesConfigMapService.get(KubernetesPortainerConfigMapNamespace, KubernetesPortainerConfigMapConfigName),
|
||||
this.KubernetesConfigMapService.getAccess(KubernetesPortainerConfigMapNamespace, KubernetesPortainerConfigMapConfigName),
|
||||
]);
|
||||
const group = await this.GroupService.group(endpoint.GroupId);
|
||||
const roles = [];
|
||||
@@ -96,7 +96,7 @@ class KubernetesResourcePoolAccessController {
|
||||
this.state.actionInProgress = true;
|
||||
const newAccesses = _.concat(this.authorizedUsersAndTeams, this.formValues.multiselectOutput);
|
||||
const accessConfigMap = KubernetesConfigMapHelper.modifiyNamespaceAccesses(angular.copy(this.accessConfigMap), this.pool.Namespace.Name, newAccesses);
|
||||
await this.KubernetesConfigMapService.update(accessConfigMap);
|
||||
await this.KubernetesConfigMapService.updateAccess(accessConfigMap);
|
||||
this.Notifications.success('Access successfully created');
|
||||
this.$state.reload();
|
||||
} catch (err) {
|
||||
@@ -116,7 +116,7 @@ class KubernetesResourcePoolAccessController {
|
||||
this.state.actionInProgress = true;
|
||||
const newAccesses = _.without(this.authorizedUsersAndTeams, ...selectedItems);
|
||||
const accessConfigMap = KubernetesConfigMapHelper.modifiyNamespaceAccesses(angular.copy(this.accessConfigMap), this.pool.Namespace.Name, newAccesses);
|
||||
await this.KubernetesConfigMapService.update(accessConfigMap);
|
||||
await this.KubernetesConfigMapService.updateAccess(accessConfigMap);
|
||||
this.Notifications.success('Access successfully removed');
|
||||
this.$state.reload();
|
||||
} catch (err) {
|
||||
|
||||
@@ -167,7 +167,6 @@ angular
|
||||
|
||||
async function initView() {
|
||||
var endpointMode = $scope.applicationState.endpoint.mode;
|
||||
const endpointId = +$state.params.endpointId;
|
||||
$scope.state.StackType = 2;
|
||||
if (endpointMode.provider === 'DOCKER_SWARM_MODE' && endpointMode.role === 'MANAGER') {
|
||||
$scope.state.StackType = 1;
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
param (
|
||||
[string]$platform,
|
||||
[string]$arch
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop";
|
||||
|
||||
$binary = "portainer.exe"
|
||||
$go_path = "$($(Get-ITEM -Path env:AGENT_TEMPDIRECTORY).Value)\go"
|
||||
|
||||
Set-Item env:GOPATH "$go_path"
|
||||
|
||||
New-Item -Name dist -Path "." -ItemType Directory -Force | Out-Null
|
||||
New-Item -Name portainer -Path "$go_path\src\github.com\portainer" -ItemType Directory -Force | Out-Null
|
||||
|
||||
Copy-Item -Path "api" -Destination "$go_path\src\github.com\portainer\portainer\api" -Recurse -Force
|
||||
|
||||
Set-Location -Path "api\cmd\portainer"
|
||||
|
||||
go get -t -d -v ./...
|
||||
## go build -v
|
||||
& cmd /c 'go build -v 2>&1'
|
||||
|
||||
Copy-Item -Path "portainer.exe" -Destination "$($env:BUILD_SOURCESDIRECTORY)\dist\portainer.exe" -Force
|
||||
@@ -1,3 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
PLATFORM=$1
|
||||
ARCH=$2
|
||||
|
||||
export GOPATH="/tmp/go"
|
||||
|
||||
binary="portainer"
|
||||
@@ -10,6 +15,10 @@ cp -R api ${GOPATH}/src/github.com/portainer/portainer/api
|
||||
cd 'api/cmd/portainer'
|
||||
|
||||
go get -t -d -v ./...
|
||||
GOOS=$1 GOARCH=$2 CGO_ENABLED=0 go build -a --installsuffix cgo --ldflags '-s'
|
||||
GOOS=${PLATFORM} GOARCH=${ARCH} CGO_ENABLED=0 go build -a --installsuffix cgo --ldflags '-s'
|
||||
|
||||
mv "$BUILD_SOURCESDIRECTORY/api/cmd/portainer/$binary" "$BUILD_SOURCESDIRECTORY/dist/portainer"
|
||||
if [ "${PLATFORM}" == 'windows' ]; then
|
||||
mv "$BUILD_SOURCESDIRECTORY/api/cmd/portainer/${binary}.exe" "$BUILD_SOURCESDIRECTORY/dist/portainer.exe"
|
||||
else
|
||||
mv "$BUILD_SOURCESDIRECTORY/api/cmd/portainer/$binary" "$BUILD_SOURCESDIRECTORY/dist/portainer"
|
||||
fi
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
param (
|
||||
[string]$docker_version
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop";
|
||||
$ProgressPreference = "SilentlyContinue";
|
||||
|
||||
New-Item -Path "docker-binary" -ItemType Directory | Out-Null
|
||||
|
||||
$download_folder = "docker-binary"
|
||||
|
||||
Invoke-WebRequest -O "$($download_folder)/docker-binaries.zip" "https://dockermsft.azureedge.net/dockercontainer/docker-$($docker_version).zip"
|
||||
Expand-Archive -Path "$($download_folder)/docker-binaries.zip" -DestinationPath "$($download_folder)"
|
||||
Move-Item -Path "$($download_folder)/docker/docker.exe" -Destination "dist"
|
||||
Move-Item -Path "$($download_folder)/docker/*.dll" -Destination "dist"
|
||||
@@ -10,9 +10,10 @@ rm -rf "${DOWNLOAD_FOLDER}"
|
||||
mkdir -pv "${DOWNLOAD_FOLDER}"
|
||||
|
||||
if [ "${PLATFORM}" == 'win' ]; then
|
||||
wget -O "${DOWNLOAD_FOLDER}/docker-binaries.zip" "https://download.docker.com/${PLATFORM}/static/stable/${ARCH}/docker-${DOCKER_VERSION}.zip"
|
||||
wget -O "${DOWNLOAD_FOLDER}/docker-binaries.zip" "https://dockermsft.azureedge.net/dockercontainer/docker-${DOCKER_VERSION}.zip"
|
||||
unzip "${DOWNLOAD_FOLDER}/docker-binaries.zip" -d "${DOWNLOAD_FOLDER}"
|
||||
mv "${DOWNLOAD_FOLDER}/docker/docker.exe" dist/
|
||||
mv ${DOWNLOAD_FOLDER}/docker/*.dll dist/
|
||||
else
|
||||
wget -O "${DOWNLOAD_FOLDER}/docker-binaries.tgz" "https://download.docker.com/${PLATFORM}/static/stable/${ARCH}/docker-${DOCKER_VERSION}.tgz"
|
||||
tar -xf "${DOWNLOAD_FOLDER}/docker-binaries.tgz" -C "${DOWNLOAD_FOLDER}"
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
param (
|
||||
[string]$docker_compose_version
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop";
|
||||
$ProgressPreference = "SilentlyContinue";
|
||||
|
||||
Invoke-WebRequest -O "dist/docker-compose.exe" "https://github.com/docker/compose/releases/download/$($docker_compose_version)/docker-compose-Windows-x86_64.exe"
|
||||
@@ -10,6 +10,9 @@ if [ "${PLATFORM}" == 'linux' ] && [ "${ARCH}" == 'amd64' ]; then
|
||||
elif [ "${PLATFORM}" == 'mac' ]; then
|
||||
wget -O "dist/docker-compose" "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-Darwin-x86_64"
|
||||
chmod +x "dist/docker-compose"
|
||||
elif [ "${PLATFORM}" == 'win' ]; then
|
||||
wget -O "dist/docker-compose.exe" "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-Windows-x86_64.exe"
|
||||
chmod +x "dist/docker-compose.exe"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
param (
|
||||
[string]$kompose_version
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop";
|
||||
$ProgressPreference = "SilentlyContinue";
|
||||
|
||||
Invoke-WebRequest -O "dist/kompose.exe" "https://github.com/kubernetes/kompose/releases/download/$($kompose_version)/kompose-windows-amd64.exe"
|
||||
@@ -4,7 +4,12 @@ PLATFORM=$1
|
||||
ARCH=$2
|
||||
KOMPOSE_VERSION=$3
|
||||
|
||||
wget -O "dist/kompose" "https://github.com/kubernetes/kompose/releases/download/${KOMPOSE_VERSION}/kompose-${PLATFORM}-${ARCH}"
|
||||
chmod +x "dist/kompose"
|
||||
if [ "${PLATFORM}" == 'linux' ]; then
|
||||
wget -O "dist/kompose" "https://github.com/kubernetes/kompose/releases/download/${KOMPOSE_VERSION}/kompose-${PLATFORM}-${ARCH}"
|
||||
chmod +x "dist/kompose"
|
||||
elif [ "${PLATFORM}" == 'windows' ]; then
|
||||
wget -O "dist/kompose.exe" "https://github.com/kubernetes/kompose/releases/download/${KOMPOSE_VERSION}/kompose-windows-amd64.exe"
|
||||
chmod +x "dist/kompose.exe"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
param (
|
||||
[string]$kubectl_version
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop";
|
||||
$ProgressPreference = "SilentlyContinue";
|
||||
|
||||
Invoke-WebRequest -O "dist/kubectl.exe" "https://storage.googleapis.com/kubernetes-release/release/$($kubectl_version)/bin/windows/amd64/kubectl.exe"
|
||||
@@ -4,7 +4,12 @@ PLATFORM=$1
|
||||
ARCH=$2
|
||||
KUBECTL_VERSION=$3
|
||||
|
||||
wget -O "dist/kubectl" "https://storage.googleapis.com/kubernetes-release/release/${KUBECTL_VERSION}/bin/${PLATFORM}/${ARCH}/kubectl"
|
||||
chmod +x "dist/kubectl"
|
||||
if [ "${PLATFORM}" == 'linux' ]; then
|
||||
wget -O "dist/kubectl" "https://storage.googleapis.com/kubernetes-release/release/${KUBECTL_VERSION}/bin/${PLATFORM}/${ARCH}/kubectl"
|
||||
chmod +x "dist/kubectl"
|
||||
elif [ "${PLATFORM}" == 'windows' ]; then
|
||||
wget -O "dist/kubectl.exe" "https://storage.googleapis.com/kubernetes-release/release/${KUBECTL_VERSION}/bin/windows/amd64/kubectl.exe"
|
||||
chmod +x "dist/kubectl.exe"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
24
build/windows/Dockerfile
Normal file
24
build/windows/Dockerfile
Normal file
@@ -0,0 +1,24 @@
|
||||
ARG OSVERSION
|
||||
FROM --platform=linux/amd64 gcr.io/k8s-staging-e2e-test-images/windows-servercore-cache:1.0-linux-amd64-${OSVERSION} as core
|
||||
FROM --platform=linux/amd64 alpine:3.13.0 as downloader
|
||||
ENV GIT_VERSION 2.30.0
|
||||
ENV GIT_PATCH_VERSION 2
|
||||
|
||||
RUN mkdir mingit/ \
|
||||
&& wget https://github.com/git-for-windows/git/releases/download/v$GIT_VERSION.windows.$GIT_PATCH_VERSION/MinGit-$GIT_VERSION.$GIT_PATCH_VERSION-busybox-64-bit.zip \
|
||||
&& unzip MinGit-$GIT_VERSION.$GIT_PATCH_VERSION-busybox-64-bit.zip -d mingit/
|
||||
|
||||
FROM mcr.microsoft.com/windows/nanoserver:${OSVERSION}
|
||||
ENV PATH "C:\mingit\cmd;C:\Windows\system32;C:\Windows;"
|
||||
|
||||
COPY --from=downloader /mingit mingit/
|
||||
COPY --from=core /Windows/System32/netapi32.dll /Windows/System32/netapi32.dll
|
||||
|
||||
USER ContainerAdministrator
|
||||
|
||||
COPY dist /
|
||||
|
||||
EXPOSE 9000
|
||||
EXPOSE 8000
|
||||
|
||||
ENTRYPOINT ["/portainer.exe"]
|
||||
@@ -1,27 +0,0 @@
|
||||
FROM mcr.microsoft.com/windows/servercore:ltsc2019 as core
|
||||
|
||||
ENV GIT_VERSION 2.30.0
|
||||
ENV GIT_PATCH_VERSION 2
|
||||
|
||||
RUN powershell -Command $ErrorActionPreference = 'Stop' ; \
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; \
|
||||
Invoke-WebRequest $('https://github.com/git-for-windows/git/releases/download/v{0}.windows.{1}/MinGit-{0}.{1}-busybox-64-bit.zip' -f $env:GIT_VERSION, $env:GIT_PATCH_VERSION) -OutFile 'mingit.zip' -UseBasicParsing ; \
|
||||
Expand-Archive mingit.zip -DestinationPath c:\mingit
|
||||
|
||||
FROM mcr.microsoft.com/windows/nanoserver:1809-amd64
|
||||
|
||||
USER ContainerAdministrator
|
||||
|
||||
COPY --from=core /windows/system32/netapi32.dll /windows/system32/netapi32.dll
|
||||
COPY --from=core /mingit /mingit
|
||||
|
||||
COPY dist /
|
||||
|
||||
RUN setx /M path "C:\mingit\cmd;%path%"
|
||||
|
||||
WORKDIR /
|
||||
|
||||
EXPOSE 9000
|
||||
EXPOSE 8000
|
||||
|
||||
ENTRYPOINT ["/portainer.exe"]
|
||||
103
gruntfile.js
103
gruntfile.js
@@ -165,11 +165,7 @@ function shell_build_binary(p, a) {
|
||||
}
|
||||
|
||||
function shell_build_binary_azuredevops(p, a) {
|
||||
if (p === 'linux') {
|
||||
return 'build/build_binary_azuredevops.sh ' + p + ' ' + a + ';';
|
||||
} else {
|
||||
return 'powershell -Command ".\\build\\build_binary_azuredevops.ps1 -platform ' + p + ' -arch ' + a + '"';
|
||||
}
|
||||
return 'build/build_binary_azuredevops.sh ' + p + ' ' + a + ';';
|
||||
}
|
||||
|
||||
function shell_run_container() {
|
||||
@@ -195,83 +191,52 @@ function shell_download_docker_binary(p, a) {
|
||||
var ip = ps[p] === undefined ? p : ps[p];
|
||||
var ia = as[a] === undefined ? a : as[a];
|
||||
var binaryVersion = p === 'windows' ? '<%= binaries.dockerWindowsVersion %>' : '<%= binaries.dockerLinuxVersion %>';
|
||||
|
||||
if (p === 'linux' || p === 'mac') {
|
||||
return ['if [ -f dist/docker ]; then', 'echo "docker binary exists";', 'else', 'build/download_docker_binary.sh ' + ip + ' ' + ia + ' ' + binaryVersion + ';', 'fi'].join(' ');
|
||||
} else {
|
||||
return [
|
||||
'powershell -Command "& {if (Test-Path -Path "dist/docker.exe") {',
|
||||
'Write-Host "Skipping download, Docker binary exists"',
|
||||
'return',
|
||||
'} else {',
|
||||
'& ".\\build\\download_docker_binary.ps1" -docker_version ' + binaryVersion + '',
|
||||
'}}"',
|
||||
].join(' ');
|
||||
}
|
||||
|
||||
return [
|
||||
'if [ -f dist/docker ] || [ -f dist/docker.exe ]; then',
|
||||
'echo "docker binary exists";',
|
||||
'else',
|
||||
'build/download_docker_binary.sh ' + ip + ' ' + ia + ' ' + binaryVersion + ';',
|
||||
'fi',
|
||||
].join(' ');
|
||||
}
|
||||
|
||||
function shell_download_docker_compose_binary(p, a) {
|
||||
console.log('request docker compose for ' + p + ':' + a);
|
||||
var ps = { windows: 'win', darwin: 'mac' };
|
||||
var as = { arm: 'armhf', arm64: 'aarch64' };
|
||||
var ip = ps[p] || p;
|
||||
var ia = as[a] || a;
|
||||
console.log('download docker compose for ' + ip + ':' + ia);
|
||||
var linuxBinaryVersion = '<%= binaries.dockerLinuxComposeVersion %>';
|
||||
var windowsBinaryVersion = '<%= binaries.dockerWindowsComposeVersion %>';
|
||||
console.log('download docker compose versions; Linux: ' + linuxBinaryVersion + ' Windows: ' + windowsBinaryVersion);
|
||||
|
||||
if (ip === 'linux' || ip === 'mac') {
|
||||
return [
|
||||
'if [ -f dist/docker-compose ]; then',
|
||||
'echo "Docker Compose binary exists";',
|
||||
'else',
|
||||
'build/download_docker_compose_binary.sh ' + ip + ' ' + ia + ' ' + linuxBinaryVersion + ';',
|
||||
'fi',
|
||||
].join(' ');
|
||||
} else if (ip === 'win') {
|
||||
return [
|
||||
'powershell -Command "& {if (Test-Path -Path "dist/docker-compose.exe") {',
|
||||
'Write-Host "Skipping download, Docker Compose binary exists"',
|
||||
'return',
|
||||
'} else {',
|
||||
'& ".\\build\\download_docker_compose_binary.ps1" -docker_compose_version ' + windowsBinaryVersion + '',
|
||||
'}}"',
|
||||
].join(' ');
|
||||
}
|
||||
console.log('docker compose is downloaded');
|
||||
var binaryVersion = p === 'windows' ? '<%= binaries.dockerWindowsComposeVersion %>' : '<%= binaries.dockerLinuxComposeVersion %>';
|
||||
|
||||
return [
|
||||
'if [ -f dist/docker-compose ] || [ -f dist/docker-compose.exe ]; then',
|
||||
'echo "Docker Compose binary exists";',
|
||||
'else',
|
||||
'build/download_docker_compose_binary.sh ' + ip + ' ' + ia + ' ' + binaryVersion + ';',
|
||||
'fi',
|
||||
].join(' ');
|
||||
}
|
||||
|
||||
function shell_download_kompose_binary(p, a) {
|
||||
var binaryVersion = '<%= binaries.komposeVersion %>';
|
||||
|
||||
if (p === 'linux' || p === 'darwin') {
|
||||
return ['if [ -f dist/kompose ]; then', 'echo "kompose binary exists";', 'else', 'build/download_kompose_binary.sh ' + p + ' ' + a + ' ' + binaryVersion + ';', 'fi'].join(' ');
|
||||
} else {
|
||||
return [
|
||||
'powershell -Command "& {if (Test-Path -Path "dist/kompose.exe") {',
|
||||
'Write-Host "Skipping download, Kompose binary exists"',
|
||||
'return',
|
||||
'} else {',
|
||||
'& ".\\build\\download_kompose_binary.ps1" -kompose_version ' + binaryVersion + '',
|
||||
'}}"',
|
||||
].join(' ');
|
||||
}
|
||||
|
||||
return [
|
||||
'if [ -f dist/kompose ] || [ -f dist/kompose.exe ]; then',
|
||||
'echo "kompose binary exists";',
|
||||
'else',
|
||||
'build/download_kompose_binary.sh ' + p + ' ' + a + ' ' + binaryVersion + ';',
|
||||
'fi',
|
||||
].join(' ');
|
||||
}
|
||||
|
||||
function shell_download_kubectl_binary(p, a) {
|
||||
var binaryVersion = '<%= binaries.kubectlVersion %>';
|
||||
|
||||
if (p === 'linux' || p === 'darwin') {
|
||||
return ['if [ -f dist/kubectl ]; then', 'echo "kubectl binary exists";', 'else', 'build/download_kubectl_binary.sh ' + p + ' ' + a + ' ' + binaryVersion + ';', 'fi'].join(' ');
|
||||
} else {
|
||||
return [
|
||||
'powershell -Command "& {if (Test-Path -Path "dist/kubectl.exe") {',
|
||||
'Write-Host "Skipping download, Kubectl binary exists"',
|
||||
'return',
|
||||
'} else {',
|
||||
'& ".\\build\\download_kubectl_binary.ps1" -kubectl_version ' + binaryVersion + '',
|
||||
'}}"',
|
||||
].join(' ');
|
||||
}
|
||||
|
||||
return [
|
||||
'if [ -f dist/kubectl ] || [ -f dist/kubectl.exe ]; then',
|
||||
'echo "kubectl binary exists";',
|
||||
'else',
|
||||
'build/download_kubectl_binary.sh ' + p + ' ' + a + ' ' + binaryVersion + ';',
|
||||
'fi',
|
||||
].join(' ');
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"author": "Portainer.io",
|
||||
"name": "portainer",
|
||||
"homepage": "http://portainer.io",
|
||||
"version": "2.0.0",
|
||||
"version": "2.1.1",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:portainer/portainer.git"
|
||||
@@ -77,10 +77,8 @@
|
||||
"chart.js": "~2.6.0",
|
||||
"codemirror": "~5.30.0",
|
||||
"fast-json-patch": "^3.0.0-1",
|
||||
"file-system": "^2.2.2",
|
||||
"filesize": "~3.3.0",
|
||||
"filesize-parser": "^1.5.0",
|
||||
"fs": "^0.0.1-security",
|
||||
"jquery": "^3.5.1",
|
||||
"js-base64": "^3.6.0",
|
||||
"js-yaml": "^3.14.0",
|
||||
|
||||
26
yarn.lock
26
yarn.lock
@@ -1352,7 +1352,6 @@ angular-moment-picker@^0.10.2:
|
||||
dependencies:
|
||||
angular-mocks "1.6.1"
|
||||
angular-sanitize "1.6.1"
|
||||
lodash-es "^4.17.15"
|
||||
|
||||
angular-resource@1.8.0:
|
||||
version "1.8.0"
|
||||
@@ -4577,13 +4576,6 @@ file-loader@^1.1.11:
|
||||
loader-utils "^1.0.2"
|
||||
schema-utils "^0.4.5"
|
||||
|
||||
file-match@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/file-match/-/file-match-1.0.2.tgz#c9cad265d2c8adf3a81475b0df475859069faef7"
|
||||
integrity sha1-ycrSZdLIrfOoFHWw30dYWQafrvc=
|
||||
dependencies:
|
||||
utils-extend "^1.0.6"
|
||||
|
||||
file-saver@^1.3.3:
|
||||
version "1.3.8"
|
||||
resolved "https://registry.yarnpkg.com/file-saver/-/file-saver-1.3.8.tgz#e68a30c7cb044e2fb362b428469feb291c2e09d8"
|
||||
@@ -4594,14 +4586,6 @@ file-sync-cmp@^0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz#a5e7a8ffbfa493b43b923bbd4ca89a53b63b612b"
|
||||
integrity sha1-peeo/7+kk7Q7kju9TKiaU7Y7YSs=
|
||||
|
||||
file-system@^2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/file-system/-/file-system-2.2.2.tgz#7d65833e3a2347dcd956a813c677153ed3edd987"
|
||||
integrity sha1-fWWDPjojR9zZVqgTxncVPtPt2Yc=
|
||||
dependencies:
|
||||
file-match "^1.0.1"
|
||||
utils-extend "^1.0.4"
|
||||
|
||||
file-type@5.2.0, file-type@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6"
|
||||
@@ -4920,11 +4904,6 @@ fs.realpath@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||
|
||||
fs@^0.0.1-security:
|
||||
version "0.0.1-security"
|
||||
resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.1-security.tgz#8a7bd37186b6dddf3813f23858b57ecaaf5e41d4"
|
||||
integrity sha1-invTcYa23d84E/I4WLV+yq9eQdQ=
|
||||
|
||||
fsevents@^1.2.7:
|
||||
version "1.2.13"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38"
|
||||
@@ -11021,11 +11000,6 @@ utila@^0.4.0, utila@~0.4:
|
||||
resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c"
|
||||
integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=
|
||||
|
||||
utils-extend@^1.0.4, utils-extend@^1.0.6:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/utils-extend/-/utils-extend-1.0.8.tgz#ccfd7b64540f8e90ee21eec57769d0651cab8a5f"
|
||||
integrity sha1-zP17ZFQPjpDuIe7Fd2nQZRyril8=
|
||||
|
||||
utils-merge@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
|
||||
|
||||
Reference in New Issue
Block a user