Compare commits
8 Commits
Author | SHA1 | Date |
---|---|---|
|
6554cfcf08 | |
|
402cb9cd90 | |
|
2aa692dc2f | |
|
ca0a71ff52 | |
|
744430356d | |
|
6094e966ac | |
|
3e66fa1ad8 | |
|
7baf47d70e |
|
@ -16,7 +16,7 @@ env:
|
|||
jobs:
|
||||
|
||||
golangci-lint:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
@ -27,7 +27,7 @@ jobs:
|
|||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
- name: Cache Go Dependencies
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
|
@ -42,7 +42,7 @@ jobs:
|
|||
args: --verbose
|
||||
|
||||
unit-tests:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
@ -54,7 +54,7 @@ jobs:
|
|||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
- name: Cache Go Dependencies
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
|
|
|
@ -17,7 +17,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
@ -17,7 +17,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
name: E2E-Advanced-Deployment-1.26
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
pull_request: {}
|
||||
workflow_dispatch: {}
|
||||
|
||||
env:
|
||||
# Common versions
|
||||
GO_VERSION: '1.19'
|
||||
KIND_IMAGE: 'kindest/node:v1.26.3'
|
||||
KIND_CLUSTER_NAME: 'ci-testing'
|
||||
|
||||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
- name: Setup Kind Cluster
|
||||
uses: helm/kind-action@v1.6.0
|
||||
with:
|
||||
node_image: ${{ env.KIND_IMAGE }}
|
||||
cluster_name: ${{ env.KIND_CLUSTER_NAME }}
|
||||
config: ./test/kind-conf.yaml
|
||||
- name: Build image
|
||||
run: |
|
||||
export IMAGE="openkruise/kruise-rollout:e2e-${GITHUB_RUN_ID}"
|
||||
docker build --pull --no-cache . -t $IMAGE
|
||||
kind load docker-image --name=${KIND_CLUSTER_NAME} $IMAGE || { echo >&2 "kind not installed or error loading image: $IMAGE"; exit 1; }
|
||||
- name: Install Kruise
|
||||
run: |
|
||||
set -ex
|
||||
kubectl cluster-info
|
||||
make helm
|
||||
helm repo add openkruise https://openkruise.github.io/charts/
|
||||
helm repo update
|
||||
helm install kruise openkruise/kruise --version 1.7.0
|
||||
for ((i=1;i<10;i++));
|
||||
do
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-system | grep '1/1' | grep kruise-controller-manager | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "2" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-system | grep '1/1' | grep kruise-controller-manager | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "2" ]; then
|
||||
echo "Wait for kruise-manager ready successfully"
|
||||
else
|
||||
echo "Timeout to wait for kruise-manager ready"
|
||||
exit 1
|
||||
fi
|
||||
- name: Install Kruise Rollout
|
||||
run: |
|
||||
set -ex
|
||||
kubectl cluster-info
|
||||
IMG=openkruise/kruise-rollout:e2e-${GITHUB_RUN_ID} ./scripts/deploy_kind.sh
|
||||
for ((i=1;i<10;i++));
|
||||
do
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-rollout | grep '1/1' | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "1" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-rollout | grep '1/1' | wc -l)
|
||||
kubectl get node -o yaml
|
||||
kubectl get all -n kruise-rollout -o yaml
|
||||
set -e
|
||||
if [ "$PODS" -eq "1" ]; then
|
||||
echo "Wait for kruise-rollout ready successfully"
|
||||
else
|
||||
echo "Timeout to wait for kruise-rollout ready"
|
||||
exit 1
|
||||
fi
|
||||
- name: Run E2E Tests For Deployment Controller
|
||||
run: |
|
||||
export KUBECONFIG=/home/runner/.kube/config
|
||||
make ginkgo
|
||||
set +e
|
||||
./bin/ginkgo -timeout 60m -v --focus='Advanced Deployment' test/e2e
|
||||
retVal=$?
|
||||
# kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
restartCount=$(kubectl get pod -n kruise-rollout --no-headers | awk '{print $4}')
|
||||
if [ "${restartCount}" -eq "0" ];then
|
||||
echo "Kruise-rollout has not restarted"
|
||||
else
|
||||
kubectl get pod -n kruise-rollout --no-headers
|
||||
echo "Kruise-rollout has restarted, abort!!!"
|
||||
kubectl get pod -n kruise-rollout --no-headers| awk '{print $1}' | xargs kubectl logs -p -n kruise-rollout
|
||||
exit 1
|
||||
fi
|
||||
exit $retVal
|
||||
- name: Run E2E Tests For Control Plane
|
||||
run: |
|
||||
export KUBECONFIG=/home/runner/.kube/config
|
||||
make ginkgo
|
||||
set +e
|
||||
./bin/ginkgo -timeout 60m -v --focus='Advanced Deployment canary rollout with Ingress' test/e2e
|
||||
retVal=$?
|
||||
# kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
restartCount=$(kubectl get pod -n kruise-rollout --no-headers | awk '{print $4}')
|
||||
if [ "${restartCount}" -eq "0" ];then
|
||||
echo "Kruise-rollout has not restarted"
|
||||
else
|
||||
kubectl get pod -n kruise-rollout --no-headers
|
||||
echo "Kruise-rollout has restarted, abort!!!"
|
||||
kubectl get pod -n kruise-rollout --no-headers| awk '{print $1}' | xargs kubectl logs -p -n kruise-rollout
|
||||
exit 1
|
||||
fi
|
||||
exit $retVal
|
|
@ -17,7 +17,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
@ -17,7 +17,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
name: E2E-CloneSet-1.26
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
pull_request: {}
|
||||
workflow_dispatch: {}
|
||||
|
||||
env:
|
||||
# Common versions
|
||||
GO_VERSION: '1.19'
|
||||
KIND_IMAGE: 'kindest/node:v1.26.3'
|
||||
KIND_CLUSTER_NAME: 'ci-testing'
|
||||
|
||||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
- name: Setup Kind Cluster
|
||||
uses: helm/kind-action@v1.6.0
|
||||
with:
|
||||
node_image: ${{ env.KIND_IMAGE }}
|
||||
cluster_name: ${{ env.KIND_CLUSTER_NAME }}
|
||||
config: ./test/kind-conf.yaml
|
||||
- name: Build image
|
||||
run: |
|
||||
export IMAGE="openkruise/kruise-rollout:e2e-${GITHUB_RUN_ID}"
|
||||
docker build --pull --no-cache . -t $IMAGE
|
||||
kind load docker-image --name=${KIND_CLUSTER_NAME} $IMAGE || { echo >&2 "kind not installed or error loading image: $IMAGE"; exit 1; }
|
||||
- name: Install Kruise
|
||||
run: |
|
||||
set -ex
|
||||
kubectl cluster-info
|
||||
make helm
|
||||
helm repo add openkruise https://openkruise.github.io/charts/
|
||||
helm repo update
|
||||
helm install kruise openkruise/kruise --version 1.7.0
|
||||
for ((i=1;i<10;i++));
|
||||
do
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-system | grep '1/1' | grep kruise-controller-manager | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "2" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-system | grep '1/1' | grep kruise-controller-manager | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "2" ]; then
|
||||
echo "Wait for kruise-manager ready successfully"
|
||||
else
|
||||
echo "Timeout to wait for kruise-manager ready"
|
||||
exit 1
|
||||
fi
|
||||
- name: Install Kruise Rollout
|
||||
run: |
|
||||
set -ex
|
||||
kubectl cluster-info
|
||||
IMG=openkruise/kruise-rollout:e2e-${GITHUB_RUN_ID} ./scripts/deploy_kind.sh
|
||||
for ((i=1;i<10;i++));
|
||||
do
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-rollout | grep '1/1' | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "1" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-rollout | grep '1/1' | wc -l)
|
||||
kubectl get node -o yaml
|
||||
kubectl get all -n kruise-rollout -o yaml
|
||||
set -e
|
||||
if [ "$PODS" -eq "1" ]; then
|
||||
echo "Wait for kruise-rollout ready successfully"
|
||||
else
|
||||
echo "Timeout to wait for kruise-rollout ready"
|
||||
exit 1
|
||||
fi
|
||||
- name: Run E2E Tests
|
||||
run: |
|
||||
export KUBECONFIG=/home/runner/.kube/config
|
||||
make ginkgo
|
||||
set +e
|
||||
./bin/ginkgo -timeout 60m -v --focus='CloneSet canary rollout with Ingress' test/e2e
|
||||
retVal=$?
|
||||
# kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
restartCount=$(kubectl get pod -n kruise-rollout --no-headers | awk '{print $4}')
|
||||
if [ "${restartCount}" -eq "0" ];then
|
||||
echo "Kruise-rollout has not restarted"
|
||||
else
|
||||
kubectl get pod -n kruise-rollout --no-headers
|
||||
echo "Kruise-rollout has restarted, abort!!!"
|
||||
kubectl get pod -n kruise-rollout --no-headers| awk '{print $1}' | xargs kubectl logs -p -n kruise-rollout
|
||||
exit 1
|
||||
fi
|
||||
exit $retVal
|
|
@ -18,7 +18,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
@ -17,7 +17,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
@ -17,7 +17,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
name: E2E-DaemonSet-1.26
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
pull_request: {}
|
||||
workflow_dispatch: {}
|
||||
|
||||
env:
|
||||
# Common versions
|
||||
GO_VERSION: '1.19'
|
||||
KIND_IMAGE: 'kindest/node:v1.26.3'
|
||||
KIND_CLUSTER_NAME: 'ci-testing'
|
||||
|
||||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
- name: Setup Kind Cluster
|
||||
uses: helm/kind-action@v1.6.0
|
||||
with:
|
||||
node_image: ${{ env.KIND_IMAGE }}
|
||||
cluster_name: ${{ env.KIND_CLUSTER_NAME }}
|
||||
config: ./test/kind-conf.yaml
|
||||
- name: Build image
|
||||
run: |
|
||||
export IMAGE="openkruise/kruise-rollout:e2e-${GITHUB_RUN_ID}"
|
||||
docker build --pull --no-cache . -t $IMAGE
|
||||
kind load docker-image --name=${KIND_CLUSTER_NAME} $IMAGE || { echo >&2 "kind not installed or error loading image: $IMAGE"; exit 1; }
|
||||
- name: Install Kruise
|
||||
run: |
|
||||
set -ex
|
||||
kubectl cluster-info
|
||||
make helm
|
||||
helm repo add openkruise https://openkruise.github.io/charts/
|
||||
helm repo update
|
||||
helm install kruise openkruise/kruise --version 1.7.0
|
||||
for ((i=1;i<10;i++));
|
||||
do
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-system | grep '1/1' | grep kruise-controller-manager | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "2" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-system | grep '1/1' | grep kruise-controller-manager | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "2" ]; then
|
||||
echo "Wait for kruise-manager ready successfully"
|
||||
else
|
||||
echo "Timeout to wait for kruise-manager ready"
|
||||
exit 1
|
||||
fi
|
||||
- name: Install Kruise Rollout
|
||||
run: |
|
||||
set -ex
|
||||
kubectl cluster-info
|
||||
IMG=openkruise/kruise-rollout:e2e-${GITHUB_RUN_ID} ./scripts/deploy_kind.sh
|
||||
for ((i=1;i<10;i++));
|
||||
do
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-rollout | grep '1/1' | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "1" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-rollout | grep '1/1' | wc -l)
|
||||
kubectl get node -o yaml
|
||||
kubectl get all -n kruise-rollout -o yaml
|
||||
set -e
|
||||
if [ "$PODS" -eq "1" ]; then
|
||||
echo "Wait for kruise-rollout ready successfully"
|
||||
else
|
||||
echo "Timeout to wait for kruise-rollout ready"
|
||||
exit 1
|
||||
fi
|
||||
- name: Run E2E Tests
|
||||
run: |
|
||||
export KUBECONFIG=/home/runner/.kube/config
|
||||
make ginkgo
|
||||
set +e
|
||||
./bin/ginkgo -timeout 60m -v --focus='DaemonSet canary rollout' test/e2e
|
||||
retVal=$?
|
||||
# kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
restartCount=$(kubectl get pod -n kruise-rollout --no-headers | awk '{print $4}')
|
||||
if [ "${restartCount}" -eq "0" ];then
|
||||
echo "Kruise-rollout has not restarted"
|
||||
else
|
||||
kubectl get pod -n kruise-rollout --no-headers
|
||||
echo "Kruise-rollout has restarted, abort!!!"
|
||||
kubectl get pod -n kruise-rollout --no-headers| awk '{print $1}' | xargs kubectl logs -p -n kruise-rollout
|
||||
exit 1
|
||||
fi
|
||||
exit $retVal
|
|
@ -17,7 +17,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
@ -17,7 +17,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
name: E2E-Deployment-1.26
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
pull_request: {}
|
||||
workflow_dispatch: {}
|
||||
|
||||
env:
|
||||
# Common versions
|
||||
GO_VERSION: '1.19'
|
||||
KIND_IMAGE: 'kindest/node:v1.26.3'
|
||||
KIND_CLUSTER_NAME: 'ci-testing'
|
||||
|
||||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
- name: Setup Kind Cluster
|
||||
uses: helm/kind-action@v1.6.0
|
||||
with:
|
||||
node_image: ${{ env.KIND_IMAGE }}
|
||||
cluster_name: ${{ env.KIND_CLUSTER_NAME }}
|
||||
config: ./test/kind-conf.yaml
|
||||
- name: Build image
|
||||
run: |
|
||||
export IMAGE="openkruise/kruise-rollout:e2e-${GITHUB_RUN_ID}"
|
||||
docker build --pull --no-cache . -t $IMAGE
|
||||
kind load docker-image --name=${KIND_CLUSTER_NAME} $IMAGE || { echo >&2 "kind not installed or error loading image: $IMAGE"; exit 1; }
|
||||
- name: Install Kruise
|
||||
run: |
|
||||
set -ex
|
||||
kubectl cluster-info
|
||||
make helm
|
||||
helm repo add openkruise https://openkruise.github.io/charts/
|
||||
helm repo update
|
||||
helm install kruise openkruise/kruise --version 1.7.0
|
||||
for ((i=1;i<10;i++));
|
||||
do
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-system | grep '1/1' | grep kruise-controller-manager | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "2" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-system | grep '1/1' | grep kruise-controller-manager | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "2" ]; then
|
||||
echo "Wait for kruise-manager ready successfully"
|
||||
else
|
||||
echo "Timeout to wait for kruise-manager ready"
|
||||
exit 1
|
||||
fi
|
||||
- name: Install Kruise Rollout
|
||||
run: |
|
||||
set -ex
|
||||
kubectl cluster-info
|
||||
IMG=openkruise/kruise-rollout:e2e-${GITHUB_RUN_ID} ./scripts/deploy_kind.sh
|
||||
for ((i=1;i<10;i++));
|
||||
do
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-rollout | grep '1/1' | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "1" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-rollout | grep '1/1' | wc -l)
|
||||
kubectl get node -o yaml
|
||||
kubectl get all -n kruise-rollout -o yaml
|
||||
set -e
|
||||
if [ "$PODS" -eq "1" ]; then
|
||||
echo "Wait for kruise-rollout ready successfully"
|
||||
else
|
||||
echo "Timeout to wait for kruise-rollout ready"
|
||||
exit 1
|
||||
fi
|
||||
- name: Run E2E Tests
|
||||
run: |
|
||||
export KUBECONFIG=/home/runner/.kube/config
|
||||
make ginkgo
|
||||
set +e
|
||||
./bin/ginkgo -timeout 60m -v --focus='Deployment canary rollout with Ingress' test/e2e
|
||||
retVal=$?
|
||||
# kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
restartCount=$(kubectl get pod -n kruise-rollout --no-headers | awk '{print $4}')
|
||||
if [ "${restartCount}" -eq "0" ];then
|
||||
echo "Kruise-rollout has not restarted"
|
||||
else
|
||||
kubectl get pod -n kruise-rollout --no-headers
|
||||
echo "Kruise-rollout has restarted, abort!!!"
|
||||
kubectl get pod -n kruise-rollout --no-headers| awk '{print $1}' | xargs kubectl logs -p -n kruise-rollout
|
||||
exit 1
|
||||
fi
|
||||
exit $retVal
|
|
@ -17,7 +17,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
@ -18,7 +18,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
@ -17,7 +17,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
@ -17,7 +17,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
name: E2E-Others-1.26
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
pull_request: {}
|
||||
workflow_dispatch: {}
|
||||
|
||||
env:
|
||||
# Common versions
|
||||
GO_VERSION: '1.19'
|
||||
KIND_IMAGE: 'kindest/node:v1.26.3'
|
||||
KIND_CLUSTER_NAME: 'ci-testing'
|
||||
|
||||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
- name: Setup Kind Cluster
|
||||
uses: helm/kind-action@v1.6.0
|
||||
with:
|
||||
node_image: ${{ env.KIND_IMAGE }}
|
||||
cluster_name: ${{ env.KIND_CLUSTER_NAME }}
|
||||
config: ./test/kind-conf.yaml
|
||||
- name: Build image
|
||||
run: |
|
||||
export IMAGE="openkruise/kruise-rollout:e2e-${GITHUB_RUN_ID}"
|
||||
docker build --pull --no-cache . -t $IMAGE
|
||||
kind load docker-image --name=${KIND_CLUSTER_NAME} $IMAGE || { echo >&2 "kind not installed or error loading image: $IMAGE"; exit 1; }
|
||||
- name: Install Kruise
|
||||
run: |
|
||||
set -ex
|
||||
kubectl cluster-info
|
||||
make helm
|
||||
helm repo add openkruise https://openkruise.github.io/charts/
|
||||
helm repo update
|
||||
helm install kruise openkruise/kruise --version 1.7.0
|
||||
for ((i=1;i<10;i++));
|
||||
do
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-system | grep '1/1' | grep kruise-controller-manager | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "2" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-system | grep '1/1' | grep kruise-controller-manager | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "2" ]; then
|
||||
echo "Wait for kruise-manager ready successfully"
|
||||
else
|
||||
echo "Timeout to wait for kruise-manager ready"
|
||||
exit 1
|
||||
fi
|
||||
- name: Install Kruise Rollout
|
||||
run: |
|
||||
set -ex
|
||||
kubectl cluster-info
|
||||
IMG=openkruise/kruise-rollout:e2e-${GITHUB_RUN_ID} ./scripts/deploy_kind.sh
|
||||
for ((i=1;i<10;i++));
|
||||
do
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-rollout | grep '1/1' | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "1" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-rollout | grep '1/1' | wc -l)
|
||||
kubectl get node -o yaml
|
||||
kubectl get all -n kruise-rollout -o yaml
|
||||
set -e
|
||||
if [ "$PODS" -eq "1" ]; then
|
||||
echo "Wait for kruise-rollout ready successfully"
|
||||
else
|
||||
echo "Timeout to wait for kruise-rollout ready"
|
||||
exit 1
|
||||
fi
|
||||
- name: Run E2E Tests
|
||||
run: |
|
||||
export KUBECONFIG=/home/runner/.kube/config
|
||||
make ginkgo
|
||||
set +e
|
||||
./bin/ginkgo -timeout 60m -v --focus='Others' test/e2e
|
||||
retVal=$?
|
||||
# kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
restartCount=$(kubectl get pod -n kruise-rollout --no-headers | awk '{print $4}')
|
||||
if [ "${restartCount}" -eq "0" ];then
|
||||
echo "Kruise-rollout has not restarted"
|
||||
else
|
||||
kubectl get pod -n kruise-rollout --no-headers
|
||||
echo "Kruise-rollout has restarted, abort!!!"
|
||||
kubectl get pod -n kruise-rollout --no-headers| awk '{print $1}' | xargs kubectl logs -p -n kruise-rollout
|
||||
exit 1
|
||||
fi
|
||||
exit $retVal
|
|
@ -17,7 +17,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
@ -17,7 +17,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
name: E2E-StatefulSet-1.26
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
pull_request: {}
|
||||
workflow_dispatch: {}
|
||||
|
||||
env:
|
||||
# Common versions
|
||||
GO_VERSION: '1.19'
|
||||
KIND_IMAGE: 'kindest/node:v1.26.3'
|
||||
KIND_CLUSTER_NAME: 'ci-testing'
|
||||
|
||||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
- name: Setup Kind Cluster
|
||||
uses: helm/kind-action@v1.6.0
|
||||
with:
|
||||
node_image: ${{ env.KIND_IMAGE }}
|
||||
cluster_name: ${{ env.KIND_CLUSTER_NAME }}
|
||||
config: ./test/kind-conf.yaml
|
||||
- name: Build image
|
||||
run: |
|
||||
export IMAGE="openkruise/kruise-rollout:e2e-${GITHUB_RUN_ID}"
|
||||
docker build --pull --no-cache . -t $IMAGE
|
||||
kind load docker-image --name=${KIND_CLUSTER_NAME} $IMAGE || { echo >&2 "kind not installed or error loading image: $IMAGE"; exit 1; }
|
||||
- name: Install Kruise
|
||||
run: |
|
||||
set -ex
|
||||
kubectl cluster-info
|
||||
make helm
|
||||
helm repo add openkruise https://openkruise.github.io/charts/
|
||||
helm repo update
|
||||
helm install kruise openkruise/kruise --version 1.7.0
|
||||
for ((i=1;i<10;i++));
|
||||
do
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-system | grep '1/1' | grep kruise-controller-manager | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "2" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-system | grep '1/1' | grep kruise-controller-manager | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "2" ]; then
|
||||
echo "Wait for kruise-manager ready successfully"
|
||||
else
|
||||
echo "Timeout to wait for kruise-manager ready"
|
||||
exit 1
|
||||
fi
|
||||
- name: Install Kruise Rollout
|
||||
run: |
|
||||
set -ex
|
||||
kubectl cluster-info
|
||||
IMG=openkruise/kruise-rollout:e2e-${GITHUB_RUN_ID} ./scripts/deploy_kind.sh
|
||||
for ((i=1;i<10;i++));
|
||||
do
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-rollout | grep '1/1' | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "1" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-rollout | grep '1/1' | wc -l)
|
||||
kubectl get node -o yaml
|
||||
kubectl get all -n kruise-rollout -o yaml
|
||||
set -e
|
||||
if [ "$PODS" -eq "1" ]; then
|
||||
echo "Wait for kruise-rollout ready successfully"
|
||||
else
|
||||
echo "Timeout to wait for kruise-rollout ready"
|
||||
exit 1
|
||||
fi
|
||||
- name: Run E2E Tests
|
||||
run: |
|
||||
export KUBECONFIG=/home/runner/.kube/config
|
||||
make ginkgo
|
||||
set +e
|
||||
./bin/ginkgo -timeout 60m -v --focus='StatefulSet canary rollout with Ingress' test/e2e
|
||||
retVal=$?
|
||||
# kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
restartCount=$(kubectl get pod -n kruise-rollout --no-headers | awk '{print $4}')
|
||||
if [ "${restartCount}" -eq "0" ];then
|
||||
echo "Kruise-rollout has not restarted"
|
||||
else
|
||||
kubectl get pod -n kruise-rollout --no-headers
|
||||
echo "Kruise-rollout has restarted, abort!!!"
|
||||
kubectl get pod -n kruise-rollout --no-headers| awk '{print $1}' | xargs kubectl logs -p -n kruise-rollout
|
||||
exit 1
|
||||
fi
|
||||
exit $retVal
|
|
@ -17,7 +17,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
@ -97,7 +97,7 @@ jobs:
|
|||
set +e
|
||||
./bin/ginkgo -timeout 60m -v --focus='bluegreen disable hpa test case - autoscaling/v1 for v1.19' test/e2e
|
||||
retVal=$?
|
||||
# kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
restartCount=$(kubectl get pod -n kruise-rollout --no-headers | awk '{print $4}')
|
||||
if [ "${restartCount}" -eq "0" ];then
|
||||
echo "Kruise-rollout has not restarted"
|
||||
|
@ -115,7 +115,7 @@ jobs:
|
|||
set +e
|
||||
./bin/ginkgo -timeout 60m -v --focus='Bluegreen Release - Deployment - Ingress' test/e2e
|
||||
retVal=$?
|
||||
# kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
restartCount=$(kubectl get pod -n kruise-rollout --no-headers | awk '{print $4}')
|
||||
if [ "${restartCount}" -eq "0" ];then
|
||||
echo "Kruise-rollout has not restarted"
|
||||
|
@ -133,7 +133,7 @@ jobs:
|
|||
set +e
|
||||
./bin/ginkgo -timeout 60m -v --focus='Bluegreen Release - Cloneset - Ingress' test/e2e
|
||||
retVal=$?
|
||||
# kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
restartCount=$(kubectl get pod -n kruise-rollout --no-headers | awk '{print $4}')
|
||||
if [ "${restartCount}" -eq "0" ];then
|
||||
echo "Kruise-rollout has not restarted"
|
||||
|
|
|
@ -17,7 +17,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
@ -95,9 +95,9 @@ jobs:
|
|||
export KUBECONFIG=/home/runner/.kube/config
|
||||
make ginkgo
|
||||
set +e
|
||||
./bin/ginkgo -timeout 60m -v --focus='bluegreen delete rollout case - autoscaling/v2 for v1.23' test/e2e
|
||||
./bin/ginkgo -timeout 60m -v --focus='bluegreen disable hpa test case - autoscaling/v2 for v1.23' test/e2e
|
||||
retVal=$?
|
||||
# kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
restartCount=$(kubectl get pod -n kruise-rollout --no-headers | awk '{print $4}')
|
||||
if [ "${restartCount}" -eq "0" ];then
|
||||
echo "Kruise-rollout has not restarted"
|
||||
|
@ -115,7 +115,7 @@ jobs:
|
|||
set +e
|
||||
./bin/ginkgo -timeout 60m -v --focus='Bluegreen Release - Deployment - Ingress' test/e2e
|
||||
retVal=$?
|
||||
# kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
restartCount=$(kubectl get pod -n kruise-rollout --no-headers | awk '{print $4}')
|
||||
if [ "${restartCount}" -eq "0" ];then
|
||||
echo "Kruise-rollout has not restarted"
|
||||
|
@ -133,7 +133,7 @@ jobs:
|
|||
set +e
|
||||
./bin/ginkgo -timeout 60m -v --focus='Bluegreen Release - Cloneset - Ingress' test/e2e
|
||||
retVal=$?
|
||||
# kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
restartCount=$(kubectl get pod -n kruise-rollout --no-headers | awk '{print $4}')
|
||||
if [ "${restartCount}" -eq "0" ];then
|
||||
echo "Kruise-rollout has not restarted"
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
name: E2E-V1Beta1-BlueGreen-1.26
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
pull_request: {}
|
||||
workflow_dispatch: {}
|
||||
|
||||
env:
|
||||
# Common versions
|
||||
GO_VERSION: '1.19'
|
||||
KIND_IMAGE: 'kindest/node:v1.26.3'
|
||||
KIND_CLUSTER_NAME: 'ci-testing'
|
||||
|
||||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
- name: Setup Kind Cluster
|
||||
uses: helm/kind-action@v1.6.0
|
||||
with:
|
||||
node_image: ${{ env.KIND_IMAGE }}
|
||||
cluster_name: ${{ env.KIND_CLUSTER_NAME }}
|
||||
config: ./test/kind-conf.yaml
|
||||
- name: Build image
|
||||
run: |
|
||||
export IMAGE="openkruise/kruise-rollout:e2e-${GITHUB_RUN_ID}"
|
||||
docker build --pull --no-cache . -t $IMAGE
|
||||
kind load docker-image --name=${KIND_CLUSTER_NAME} $IMAGE || { echo >&2 "kind not installed or error loading image: $IMAGE"; exit 1; }
|
||||
- name: Install Kruise
|
||||
run: |
|
||||
set -ex
|
||||
kubectl cluster-info
|
||||
make helm
|
||||
helm repo add openkruise https://openkruise.github.io/charts/
|
||||
helm repo update
|
||||
helm install kruise openkruise/kruise --version 1.7.0
|
||||
for ((i=1;i<10;i++));
|
||||
do
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-system | grep '1/1' | grep kruise-controller-manager | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "2" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-system | grep '1/1' | grep kruise-controller-manager | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "2" ]; then
|
||||
echo "Wait for kruise-manager ready successfully"
|
||||
else
|
||||
echo "Timeout to wait for kruise-manager ready"
|
||||
exit 1
|
||||
fi
|
||||
- name: Install Kruise Rollout
|
||||
run: |
|
||||
set -ex
|
||||
kubectl cluster-info
|
||||
IMG=openkruise/kruise-rollout:e2e-${GITHUB_RUN_ID} ./scripts/deploy_kind.sh
|
||||
for ((i=1;i<10;i++));
|
||||
do
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-rollout | grep '1/1' | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "1" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-rollout | grep '1/1' | wc -l)
|
||||
kubectl get node -o yaml
|
||||
kubectl get all -n kruise-rollout -o yaml
|
||||
set -e
|
||||
if [ "$PODS" -eq "1" ]; then
|
||||
echo "Wait for kruise-rollout ready successfully"
|
||||
else
|
||||
echo "Timeout to wait for kruise-rollout ready"
|
||||
exit 1
|
||||
fi
|
||||
- name: Bluegreen Release Disable HPA
|
||||
run: |
|
||||
export KUBECONFIG=/home/runner/.kube/config
|
||||
make ginkgo
|
||||
set +e
|
||||
./bin/ginkgo -timeout 60m -v --focus='bluegreen disable hpa test case - autoscaling/v2 for v1.26' test/e2e
|
||||
retVal=$?
|
||||
kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
restartCount=$(kubectl get pod -n kruise-rollout --no-headers | awk '{print $4}')
|
||||
if [ "${restartCount}" -eq "0" ];then
|
||||
echo "Kruise-rollout has not restarted"
|
||||
else
|
||||
kubectl get pod -n kruise-rollout --no-headers
|
||||
echo "Kruise-rollout has restarted, abort!!!"
|
||||
kubectl get pod -n kruise-rollout --no-headers| awk '{print $1}' | xargs kubectl logs -p -n kruise-rollout
|
||||
exit 1
|
||||
fi
|
||||
exit $retVal
|
||||
- name: Deployment Bluegreen Release
|
||||
run: |
|
||||
export KUBECONFIG=/home/runner/.kube/config
|
||||
make ginkgo
|
||||
set +e
|
||||
./bin/ginkgo -timeout 60m -v --focus='Bluegreen Release - Deployment - Ingress' test/e2e
|
||||
retVal=$?
|
||||
kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
restartCount=$(kubectl get pod -n kruise-rollout --no-headers | awk '{print $4}')
|
||||
if [ "${restartCount}" -eq "0" ];then
|
||||
echo "Kruise-rollout has not restarted"
|
||||
else
|
||||
kubectl get pod -n kruise-rollout --no-headers
|
||||
echo "Kruise-rollout has restarted, abort!!!"
|
||||
kubectl get pod -n kruise-rollout --no-headers| awk '{print $1}' | xargs kubectl logs -p -n kruise-rollout
|
||||
exit 1
|
||||
fi
|
||||
exit $retVal
|
||||
- name: CloneSet Bluegreen Release
|
||||
run: |
|
||||
export KUBECONFIG=/home/runner/.kube/config
|
||||
make ginkgo
|
||||
set +e
|
||||
./bin/ginkgo -timeout 60m -v --focus='Bluegreen Release - Cloneset - Ingress' test/e2e
|
||||
retVal=$?
|
||||
kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
restartCount=$(kubectl get pod -n kruise-rollout --no-headers | awk '{print $4}')
|
||||
if [ "${restartCount}" -eq "0" ];then
|
||||
echo "Kruise-rollout has not restarted"
|
||||
else
|
||||
kubectl get pod -n kruise-rollout --no-headers
|
||||
echo "Kruise-rollout has restarted, abort!!!"
|
||||
kubectl get pod -n kruise-rollout --no-headers| awk '{print $1}' | xargs kubectl logs -p -n kruise-rollout
|
||||
exit 1
|
||||
fi
|
||||
exit $retVal
|
|
@ -17,7 +17,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
@ -17,7 +17,7 @@ env:
|
|||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
name: E2E-V1Beta1-JUMP-1.26
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- release-*
|
||||
pull_request: {}
|
||||
workflow_dispatch: {}
|
||||
|
||||
env:
|
||||
# Common versions
|
||||
GO_VERSION: '1.19'
|
||||
KIND_IMAGE: 'kindest/node:v1.26.3'
|
||||
KIND_CLUSTER_NAME: 'ci-testing'
|
||||
|
||||
jobs:
|
||||
|
||||
rollout:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
- name: Setup Kind Cluster
|
||||
uses: helm/kind-action@v1.6.0
|
||||
with:
|
||||
node_image: ${{ env.KIND_IMAGE }}
|
||||
cluster_name: ${{ env.KIND_CLUSTER_NAME }}
|
||||
config: ./test/kind-conf.yaml
|
||||
- name: Build image
|
||||
run: |
|
||||
export IMAGE="openkruise/kruise-rollout:e2e-${GITHUB_RUN_ID}"
|
||||
docker build --pull --no-cache . -t $IMAGE
|
||||
kind load docker-image --name=${KIND_CLUSTER_NAME} $IMAGE || { echo >&2 "kind not installed or error loading image: $IMAGE"; exit 1; }
|
||||
- name: Install Kruise
|
||||
run: |
|
||||
set -ex
|
||||
kubectl cluster-info
|
||||
make helm
|
||||
helm repo add openkruise https://openkruise.github.io/charts/
|
||||
helm repo update
|
||||
helm install kruise openkruise/kruise --version 1.7.0
|
||||
for ((i=1;i<10;i++));
|
||||
do
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-system | grep '1/1' | grep kruise-controller-manager | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "2" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-system | grep '1/1' | grep kruise-controller-manager | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "2" ]; then
|
||||
echo "Wait for kruise-manager ready successfully"
|
||||
else
|
||||
echo "Timeout to wait for kruise-manager ready"
|
||||
exit 1
|
||||
fi
|
||||
- name: Install Kruise Rollout
|
||||
run: |
|
||||
set -ex
|
||||
kubectl cluster-info
|
||||
IMG=openkruise/kruise-rollout:e2e-${GITHUB_RUN_ID} ./scripts/deploy_kind.sh
|
||||
for ((i=1;i<10;i++));
|
||||
do
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-rollout | grep '1/1' | wc -l)
|
||||
set -e
|
||||
if [ "$PODS" -eq "1" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
set +e
|
||||
PODS=$(kubectl get pod -n kruise-rollout | grep '1/1' | wc -l)
|
||||
kubectl get node -o yaml
|
||||
kubectl get all -n kruise-rollout -o yaml
|
||||
set -e
|
||||
if [ "$PODS" -eq "1" ]; then
|
||||
echo "Wait for kruise-rollout ready successfully"
|
||||
else
|
||||
echo "Timeout to wait for kruise-rollout ready"
|
||||
exit 1
|
||||
fi
|
||||
- name: Run E2E Tests
|
||||
run: |
|
||||
export KUBECONFIG=/home/runner/.kube/config
|
||||
make ginkgo
|
||||
set +e
|
||||
./bin/ginkgo -timeout 60m -v --focus='Step Jump' test/e2e
|
||||
retVal=$?
|
||||
# kubectl get pod -n kruise-rollout --no-headers | grep manager | awk '{print $1}' | xargs kubectl logs -n kruise-rollout
|
||||
restartCount=$(kubectl get pod -n kruise-rollout --no-headers | awk '{print $4}')
|
||||
if [ "${restartCount}" -eq "0" ];then
|
||||
echo "Kruise-rollout has not restarted"
|
||||
else
|
||||
kubectl get pod -n kruise-rollout --no-headers
|
||||
echo "Kruise-rollout has restarted, abort!!!"
|
||||
kubectl get pod -n kruise-rollout --no-headers| awk '{print $1}' | xargs kubectl logs -p -n kruise-rollout
|
||||
exit 1
|
||||
fi
|
||||
exit $retVal
|
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -1,5 +1,17 @@
|
|||
# Change Log
|
||||
|
||||
## v0.6.1
|
||||
### Key Features:
|
||||
- Introduced `rollout-batch-id` labeling for blue-green and canary style releases ([#250](https://github.com/openkruise/rollouts/pull/250),([#251](https://github.com/openkruise/rollouts/pull/251),[#261](https://github.com/openkruise/rollouts/pull/261),[@PersistentJZH](https://github.com/PersistentJZH),[@AiRanthem](https://github.com/AiRanthem))
|
||||
|
||||
### Bugfix:
|
||||
- The order of object in BatchRelease event handler is fixed ([#265](https://github.com/openkruise/rollouts/pull/265),[@z760087139](https://github.com/z760087139))
|
||||
|
||||
## v0.5.1
|
||||
### Bugfix:
|
||||
|
||||
- Fix Rollout v1alpha1 and v1beta1 version conversions with incorrectly converted partition fields. ([#200](https://github.com/openkruise/rollouts/pull/200),[@myname4423](https://github.com/myname4423))
|
||||
|
||||
## v0.6.0
|
||||
### Key Features:
|
||||
- 🎊 Support for blue-green style releases has been added ([#214](https://github.com/openkruise/rollouts/pull/214),[#229](https://github.com/openkruise/rollouts/pull/229),[#238](https://github.com/openkruise/rollouts/pull/238),[#220](https://github.com/openkruise/rollouts/pull/220),[@myname4423](https://github.com/myname4423))
|
||||
|
|
|
@ -145,8 +145,8 @@ func (w workloadEventHandler) Update(evt event.UpdateEvent, q workqueue.RateLimi
|
|||
return
|
||||
}
|
||||
|
||||
oldObject := evt.ObjectNew
|
||||
newObject := evt.ObjectOld
|
||||
newObject := evt.ObjectNew
|
||||
oldObject := evt.ObjectOld
|
||||
expectationObserved(newObject)
|
||||
if newObject.GetResourceVersion() == oldObject.GetResourceVersion() {
|
||||
return
|
||||
|
|
|
@ -160,7 +160,7 @@ func (r *Executor) progressBatches(release *v1beta1.BatchRelease, newStatus *v1b
|
|||
|
||||
case v1beta1.VerifyingBatchState:
|
||||
// replicas/partition has been modified, should wait pod ready in this state.
|
||||
err = workloadController.CheckBatchReady()
|
||||
err = workloadController.EnsureBatchPodsReadyAndLabeled()
|
||||
switch {
|
||||
case err != nil:
|
||||
// should go to upgrade state to do again to avoid dead wait.
|
||||
|
@ -175,7 +175,7 @@ func (r *Executor) progressBatches(release *v1beta1.BatchRelease, newStatus *v1b
|
|||
|
||||
case v1beta1.ReadyBatchState:
|
||||
// replicas/partition may be modified even though ready, should recheck in this state.
|
||||
err = workloadController.CheckBatchReady()
|
||||
err = workloadController.EnsureBatchPodsReadyAndLabeled()
|
||||
switch {
|
||||
case err != nil:
|
||||
// if the batch ready condition changed due to some reasons, just recalculate the current batch.
|
||||
|
|
|
@ -18,6 +18,7 @@ package bluegreenstyle
|
|||
|
||||
import (
|
||||
"github.com/openkruise/rollouts/api/v1beta1"
|
||||
"github.com/openkruise/rollouts/pkg/controller/batchrelease/context"
|
||||
"github.com/openkruise/rollouts/pkg/controller/batchrelease/control"
|
||||
"github.com/openkruise/rollouts/pkg/controller/batchrelease/labelpatch"
|
||||
"github.com/openkruise/rollouts/pkg/util"
|
||||
|
@ -40,7 +41,7 @@ type realBatchControlPlane struct {
|
|||
|
||||
type NewInterfaceFunc func(cli client.Client, key types.NamespacedName, gvk schema.GroupVersionKind) Interface
|
||||
|
||||
// NewControlPlane creates a new release controller with bluegreen-style to drive batch release state machine
|
||||
// NewControlPlane creates a new release controller with blue-green style to drive batch release state machine
|
||||
func NewControlPlane(f NewInterfaceFunc, cli client.Client, recorder record.EventRecorder, release *v1beta1.BatchRelease, newStatus *v1beta1.BatchReleaseStatus, key types.NamespacedName, gvk schema.GroupVersionKind) *realBatchControlPlane {
|
||||
return &realBatchControlPlane{
|
||||
Client: cli,
|
||||
|
@ -72,6 +73,15 @@ func (rc *realBatchControlPlane) Initialize() error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (rc *realBatchControlPlane) patchPodLabels(batchContext *context.BatchContext) error {
|
||||
pods, err := rc.ListOwnedPods() // add pods to rc for patching pod batch labels
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
batchContext.Pods = pods
|
||||
return rc.patcher.PatchPodBatchLabel(batchContext)
|
||||
}
|
||||
|
||||
func (rc *realBatchControlPlane) UpgradeBatch() error {
|
||||
controller, err := rc.BuildController()
|
||||
if err != nil {
|
||||
|
@ -97,7 +107,7 @@ func (rc *realBatchControlPlane) UpgradeBatch() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (rc *realBatchControlPlane) CheckBatchReady() error {
|
||||
func (rc *realBatchControlPlane) EnsureBatchPodsReadyAndLabeled() error {
|
||||
controller, err := rc.BuildController()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -116,7 +126,9 @@ func (rc *realBatchControlPlane) CheckBatchReady() error {
|
|||
|
||||
klog.Infof("BatchRelease %v calculated context when check batch ready: %s",
|
||||
klog.KObj(rc.release), batchContext.Log())
|
||||
|
||||
if err = rc.patchPodLabels(batchContext); err != nil {
|
||||
klog.ErrorS(err, "failed to patch pod labels", "release", klog.KObj(rc.release))
|
||||
}
|
||||
return batchContext.IsBatchReady()
|
||||
}
|
||||
|
||||
|
|
|
@ -103,14 +103,22 @@ func (rc *realCanaryController) UpgradeBatch() error {
|
|||
return fmt.Errorf("wait canary workload %v reconcile", canary.GetCanaryInfo().LogKey)
|
||||
}
|
||||
|
||||
batchContext := rc.CalculateBatchContext(rc.release)
|
||||
batchContext, err := rc.CalculateBatchContext(rc.release)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
klog.Infof("BatchRelease %v calculated context when upgrade batch: %s",
|
||||
klog.KObj(rc.release), batchContext.Log())
|
||||
|
||||
return canary.UpgradeBatch(batchContext)
|
||||
err = canary.UpgradeBatch(batchContext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rc *realCanaryController) CheckBatchReady() error {
|
||||
func (rc *realCanaryController) EnsureBatchPodsReadyAndLabeled() error {
|
||||
stable, err := rc.BuildStableController()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -129,10 +137,15 @@ func (rc *realCanaryController) CheckBatchReady() error {
|
|||
return fmt.Errorf("wait canary workload %v reconcile", canary.GetCanaryInfo().LogKey)
|
||||
}
|
||||
|
||||
batchContext := rc.CalculateBatchContext(rc.release)
|
||||
batchContext, err := rc.CalculateBatchContext(rc.release)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
klog.Infof("BatchRelease %v calculated context when check batch ready: %s",
|
||||
klog.KObj(rc.release), batchContext.Log())
|
||||
|
||||
if err = rc.patcher.PatchPodBatchLabel(batchContext); err != nil {
|
||||
klog.ErrorS(err, "failed to patch pod labels", "release", klog.KObj(rc.release))
|
||||
}
|
||||
return batchContext.IsBatchReady()
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ type realCanaryController struct {
|
|||
canaryObject *apps.Deployment
|
||||
canaryClient client.Client
|
||||
objectKey types.NamespacedName
|
||||
canaryPods []*corev1.Pod
|
||||
}
|
||||
|
||||
func newCanary(cli client.Client, key types.NamespacedName) realCanaryController {
|
||||
|
|
|
@ -27,6 +27,7 @@ import (
|
|||
"github.com/openkruise/rollouts/pkg/util"
|
||||
utilclient "github.com/openkruise/rollouts/pkg/util/client"
|
||||
apps "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
@ -82,19 +83,30 @@ func (rc *realController) BuildCanaryController(release *v1beta1.BatchRelease) (
|
|||
return rc, nil
|
||||
}
|
||||
|
||||
func (rc *realController) CalculateBatchContext(release *v1beta1.BatchRelease) *batchcontext.BatchContext {
|
||||
func (rc *realController) CalculateBatchContext(release *v1beta1.BatchRelease) (*batchcontext.BatchContext, error) {
|
||||
rolloutID := release.Spec.ReleasePlan.RolloutID
|
||||
if rolloutID != "" {
|
||||
// if rollout-id is set, the pod will be patched batch label,
|
||||
// so we have to list pod here.
|
||||
if _, err := rc.ListOwnedPods(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
replicas := *rc.stableObject.Spec.Replicas
|
||||
currentBatch := release.Status.CanaryStatus.CurrentBatch
|
||||
desiredUpdate := int32(control.CalculateBatchReplicas(release, int(replicas), int(currentBatch)))
|
||||
|
||||
return &batchcontext.BatchContext{
|
||||
Pods: rc.canaryPods,
|
||||
RolloutID: rolloutID,
|
||||
Replicas: replicas,
|
||||
UpdateRevision: release.Status.UpdateRevision,
|
||||
CurrentBatch: currentBatch,
|
||||
DesiredUpdatedReplicas: desiredUpdate,
|
||||
FailureThreshold: release.Spec.ReleasePlan.FailureThreshold,
|
||||
UpdatedReplicas: rc.canaryObject.Status.Replicas,
|
||||
UpdatedReadyReplicas: rc.canaryObject.Status.AvailableReplicas,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (rc *realController) getLatestTemplate() (*v1.PodTemplateSpec, error) {
|
||||
|
@ -104,3 +116,12 @@ func (rc *realController) getLatestTemplate() (*v1.PodTemplateSpec, error) {
|
|||
}
|
||||
return &rc.stableObject.Spec.Template, nil
|
||||
}
|
||||
|
||||
func (rc *realController) ListOwnedPods() ([]*corev1.Pod, error) {
|
||||
if rc.canaryPods != nil {
|
||||
return rc.canaryPods, nil
|
||||
}
|
||||
var err error
|
||||
rc.canaryPods, err = util.ListOwnedPods(rc.canaryClient, rc.canaryObject)
|
||||
return rc.canaryPods, err
|
||||
}
|
||||
|
|
|
@ -226,7 +226,9 @@ func TestCalculateBatchContext(t *testing.T) {
|
|||
canaryObject: canary,
|
||||
},
|
||||
}
|
||||
got := control.CalculateBatchContext(cs.release())
|
||||
got, err := control.CalculateBatchContext(cs.release())
|
||||
got.FilterFunc = nil
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(reflect.DeepEqual(got, cs.result)).Should(BeTrue())
|
||||
})
|
||||
}
|
||||
|
@ -290,7 +292,8 @@ func TestRealCanaryController(t *testing.T) {
|
|||
Expect(util.EqualIgnoreHash(&c.canaryObject.Spec.Template, &deployment.Spec.Template)).Should(BeTrue())
|
||||
|
||||
// check rolling
|
||||
batchContext := c.CalculateBatchContext(release)
|
||||
batchContext, err := c.CalculateBatchContext(release)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
err = controller.UpgradeBatch(batchContext)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
canary := getCanaryDeployment(release, deployment, c)
|
||||
|
|
|
@ -33,7 +33,7 @@ type Interface interface {
|
|||
BuildCanaryController(release *v1beta1.BatchRelease) (CanaryInterface, error)
|
||||
// CalculateBatchContext calculate the current batch context according to
|
||||
// our release plan and the statues of stable workload and canary workload.
|
||||
CalculateBatchContext(release *v1beta1.BatchRelease) *batchcontext.BatchContext
|
||||
CalculateBatchContext(release *v1beta1.BatchRelease) (*batchcontext.BatchContext, error)
|
||||
}
|
||||
|
||||
// CanaryInterface contains the methods about canary workload
|
||||
|
|
|
@ -52,10 +52,10 @@ type Interface interface {
|
|||
// it returns nil if the preparation is succeeded, else the preparation should retry.
|
||||
UpgradeBatch() error
|
||||
|
||||
// CheckBatchReady checks how many replicas are ready to serve requests in the current batch.
|
||||
// EnsureBatchPodsReadyAndLabeled checks how many replicas are ready to serve requests in the current batch.
|
||||
// this function is tasked to do any initialization work on the resources.
|
||||
// it returns nil if the preparation is succeeded, else the preparation should retry.
|
||||
CheckBatchReady() error
|
||||
EnsureBatchPodsReadyAndLabeled() error
|
||||
|
||||
// Finalize makes sure the resources are in a good final state.
|
||||
// this function is tasked to do any initialization work on the resources.
|
||||
|
|
|
@ -114,7 +114,7 @@ func (rc *realBatchControlPlane) UpgradeBatch() error {
|
|||
return rc.patcher.PatchPodBatchLabel(batchContext)
|
||||
}
|
||||
|
||||
func (rc *realBatchControlPlane) CheckBatchReady() error {
|
||||
func (rc *realBatchControlPlane) EnsureBatchPodsReadyAndLabeled() error {
|
||||
controller, err := rc.BuildController()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -226,7 +226,7 @@ func (rc *realBatchControlPlane) markNoNeedUpdatePodsIfNeeds() (*int32, error) {
|
|||
if !pods[i].DeletionTimestamp.IsZero() {
|
||||
continue
|
||||
}
|
||||
if !util.IsConsistentWithRevision(pods[i], rc.newStatus.UpdateRevision) {
|
||||
if !util.IsConsistentWithRevision(pods[i].GetLabels(), rc.newStatus.UpdateRevision) {
|
||||
continue
|
||||
}
|
||||
if pods[i].Labels[util.NoNeedUpdatePodLabel] == rolloutID {
|
||||
|
@ -273,7 +273,7 @@ func (rc *realBatchControlPlane) countAndUpdateNoNeedUpdateReplicas() error {
|
|||
if !pod.DeletionTimestamp.IsZero() {
|
||||
continue
|
||||
}
|
||||
if !util.IsConsistentWithRevision(pod, rc.release.Status.UpdateRevision) {
|
||||
if !util.IsConsistentWithRevision(pod.GetLabels(), rc.release.Status.UpdateRevision) {
|
||||
continue
|
||||
}
|
||||
id, ok := pod.Labels[util.NoNeedUpdatePodLabel]
|
||||
|
|
|
@ -67,7 +67,7 @@ func (rc *realController) BuildController() (partitionstyle.Interface, error) {
|
|||
if !pod.DeletionTimestamp.IsZero() {
|
||||
return false
|
||||
}
|
||||
if !util.IsConsistentWithRevision(pod, rc.WorkloadInfo.Status.UpdateRevision) {
|
||||
if !util.IsConsistentWithRevision(pod.GetLabels(), rc.WorkloadInfo.Status.UpdateRevision) {
|
||||
return false
|
||||
}
|
||||
return util.IsPodReady(pod)
|
||||
|
|
|
@ -77,7 +77,7 @@ func (rc *realController) BuildController() (partitionstyle.Interface, error) {
|
|||
if !pod.DeletionTimestamp.IsZero() {
|
||||
return false
|
||||
}
|
||||
if !util.IsConsistentWithRevision(pod, rc.WorkloadInfo.Status.UpdateRevision) {
|
||||
if !util.IsConsistentWithRevision(pod.GetLabels(), rc.WorkloadInfo.Status.UpdateRevision) {
|
||||
return false
|
||||
}
|
||||
return util.IsPodReady(pod)
|
||||
|
|
|
@ -57,7 +57,7 @@ func FilterPodsForUnorderedUpdate(pods []*corev1.Pod, ctx *batchcontext.BatchCon
|
|||
terminatingPods = append(terminatingPods, pod)
|
||||
continue
|
||||
}
|
||||
if !util.IsConsistentWithRevision(pod, ctx.UpdateRevision) {
|
||||
if !util.IsConsistentWithRevision(pod.GetLabels(), ctx.UpdateRevision) {
|
||||
continue
|
||||
}
|
||||
if pod.Labels[util.NoNeedUpdatePodLabel] == ctx.RolloutID && pod.Labels[v1beta1.RolloutIDLabel] != ctx.RolloutID {
|
||||
|
@ -113,7 +113,7 @@ func FilterPodsForOrderedUpdate(pods []*corev1.Pod, ctx *batchcontext.BatchConte
|
|||
terminatingPods = append(terminatingPods, pod)
|
||||
continue
|
||||
}
|
||||
if !util.IsConsistentWithRevision(pod, ctx.UpdateRevision) {
|
||||
if !util.IsConsistentWithRevision(pod.GetLabels(), ctx.UpdateRevision) {
|
||||
continue
|
||||
}
|
||||
if getPodOrdinal(pod) >= partition {
|
||||
|
|
|
@ -24,7 +24,9 @@ import (
|
|||
"github.com/openkruise/rollouts/api/v1beta1"
|
||||
batchcontext "github.com/openkruise/rollouts/pkg/controller/batchrelease/context"
|
||||
"github.com/openkruise/rollouts/pkg/util"
|
||||
v1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/klog/v2"
|
||||
|
@ -61,47 +63,94 @@ func (r *realPatcher) patchPodBatchLabel(pods []*corev1.Pod, ctx *batchcontext.B
|
|||
plannedUpdatedReplicasForBatches := r.calculatePlannedStepIncrements(r.batches, int(ctx.Replicas), int(ctx.CurrentBatch))
|
||||
var updatedButUnpatchedPods []*corev1.Pod
|
||||
|
||||
revisionHashCache := map[types.UID]string{} // to prevent duplicate computing for revision hash
|
||||
podsToPatchControllerRevision := map[*corev1.Pod]string{} // to record pods to patch controller-revision-hash
|
||||
for _, pod := range pods {
|
||||
if !pod.DeletionTimestamp.IsZero() {
|
||||
klog.InfoS("Pod is being deleted, skip patching", "pod", klog.KObj(pod), "rollout", r.logKey)
|
||||
continue
|
||||
}
|
||||
labels := make(map[string]string, len(pod.Labels))
|
||||
for k, v := range pod.Labels {
|
||||
labels[k] = v
|
||||
}
|
||||
if labels[v1.ControllerRevisionHashLabelKey] == "" {
|
||||
// For native deployment, we need to get the revision hash from ReplicaSet, which is exactly constants with the update revision
|
||||
// The reason is that, The status of the Deployment that KCM sees may differ from the Deployment seen by
|
||||
// the Rollouts controller due to some default values not being assigned yet. Therefore, even if both use
|
||||
// exactly the same algorithm, they cannot compute the same pod-template-hash. The fact that K8S does not
|
||||
// expose the method for computing the pod-template-hash also confirms that third-party components relying
|
||||
// on the pod-template-hash is not recommended. Thus, we use the CloneSet algorithm to compute the
|
||||
// controller-revision-hash: this method is fully defined by OpenKruise and can ensure that the same
|
||||
// ReplicaSet produces the same value.
|
||||
owner := metav1.GetControllerOf(pod)
|
||||
if owner != nil && owner.Kind == "ReplicaSet" {
|
||||
var hash string
|
||||
if cache, ok := revisionHashCache[owner.UID]; ok {
|
||||
hash = cache
|
||||
} else {
|
||||
rs := &v1.ReplicaSet{}
|
||||
if err := r.Get(context.Background(), types.NamespacedName{Namespace: pod.Namespace, Name: owner.Name}, rs); err != nil {
|
||||
klog.ErrorS(err, "Failed to get ReplicaSet", "pod", klog.KObj(pod), "rollout", r.logKey, "owner", owner.Name, "namespace", pod.Namespace)
|
||||
return err
|
||||
}
|
||||
delete(rs.Spec.Template.ObjectMeta.Labels, v1.DefaultDeploymentUniqueLabelKey)
|
||||
hash = util.ComputeHash(&rs.Spec.Template, nil)
|
||||
revisionHashCache[owner.UID] = hash
|
||||
}
|
||||
labels[v1.ControllerRevisionHashLabelKey] = hash
|
||||
podsToPatchControllerRevision[pod] = hash
|
||||
klog.InfoS("Pod controller-revision-hash updated", "pod", klog.KObj(pod), "rollout", r.logKey, "hash", hash)
|
||||
}
|
||||
}
|
||||
|
||||
// we don't patch label for the active old revision pod
|
||||
if !util.IsConsistentWithRevision(pod, ctx.UpdateRevision) {
|
||||
klog.InfoS("Pod is not consistent with revision, skip patching", "pod", klog.KObj(pod), "rollout", r.logKey)
|
||||
if !util.IsConsistentWithRevision(labels, ctx.UpdateRevision) {
|
||||
klog.InfoS("Pod is not consistent with revision, skip patching", "pod", klog.KObj(pod),
|
||||
"revision", ctx.UpdateRevision, "pod-template-hash", labels[v1.DefaultDeploymentUniqueLabelKey],
|
||||
"controller-revision-hash", labels[v1.ControllerRevisionHashLabelKey], "rollout", r.logKey)
|
||||
continue
|
||||
}
|
||||
if pod.Labels[v1beta1.RolloutIDLabel] != ctx.RolloutID {
|
||||
if labels[v1beta1.RolloutIDLabel] != ctx.RolloutID {
|
||||
// for example: new/recreated pods
|
||||
updatedButUnpatchedPods = append(updatedButUnpatchedPods, pod)
|
||||
klog.InfoS("Find a pod to add updatedButUnpatchedPods", "pod", klog.KObj(pod), "rollout", r.logKey)
|
||||
continue
|
||||
}
|
||||
|
||||
podBatchID, err := strconv.Atoi(pod.Labels[v1beta1.RolloutBatchIDLabel])
|
||||
podBatchID, err := strconv.Atoi(labels[v1beta1.RolloutBatchIDLabel])
|
||||
if err != nil {
|
||||
klog.InfoS("Pod batchID is not a number, skip patching", "pod", klog.KObj(pod), "rollout", r.logKey)
|
||||
continue
|
||||
}
|
||||
plannedUpdatedReplicasForBatches[podBatchID-1]--
|
||||
}
|
||||
klog.InfoS("updatedButUnpatchedPods amount calculated", "amount", len(updatedButUnpatchedPods), "rollout", r.logKey)
|
||||
klog.InfoS("updatedButUnpatchedPods amount calculated", "amount", len(updatedButUnpatchedPods),
|
||||
"rollout", r.logKey, "plan", plannedUpdatedReplicasForBatches)
|
||||
// patch the pods
|
||||
for i := len(plannedUpdatedReplicasForBatches) - 1; i >= 0; i-- {
|
||||
for ; plannedUpdatedReplicasForBatches[i] > 0; plannedUpdatedReplicasForBatches[i]-- {
|
||||
if len(updatedButUnpatchedPods) == 0 {
|
||||
klog.Warningf("no pods to patch for %v, batch %d", r.logKey, i+1)
|
||||
return nil
|
||||
i = -1
|
||||
break
|
||||
}
|
||||
// patch the updated but unpatced pod
|
||||
// patch the updated but unpatched pod
|
||||
pod := updatedButUnpatchedPods[len(updatedButUnpatchedPods)-1]
|
||||
clone := util.GetEmptyObjectWithKey(pod)
|
||||
by := fmt.Sprintf(`{"metadata":{"labels":{"%s":"%s","%s":"%d"}}}`,
|
||||
v1beta1.RolloutIDLabel, ctx.RolloutID, v1beta1.RolloutBatchIDLabel, i+1)
|
||||
if err := r.Patch(context.TODO(), clone, client.RawPatch(types.StrategicMergePatchType, []byte(by))); err != nil {
|
||||
var patchStr string
|
||||
if hash, ok := podsToPatchControllerRevision[pod]; ok {
|
||||
patchStr = fmt.Sprintf(`{"metadata":{"labels":{"%s":"%s","%s":"%d","%s":"%s"}}}`,
|
||||
v1beta1.RolloutIDLabel, ctx.RolloutID, v1beta1.RolloutBatchIDLabel, i+1, v1.ControllerRevisionHashLabelKey, hash)
|
||||
delete(podsToPatchControllerRevision, pod)
|
||||
} else {
|
||||
patchStr = fmt.Sprintf(`{"metadata":{"labels":{"%s":"%s","%s":"%d"}}}`,
|
||||
v1beta1.RolloutIDLabel, ctx.RolloutID, v1beta1.RolloutBatchIDLabel, i+1)
|
||||
}
|
||||
if err := r.Patch(context.TODO(), clone, client.RawPatch(types.StrategicMergePatchType, []byte(patchStr))); err != nil {
|
||||
return err
|
||||
}
|
||||
klog.InfoS("Successfully patch Pod batchID", "batchID", i+1, "pod", klog.KObj(pod), "rollout", r.logKey)
|
||||
klog.InfoS("Successfully patched Pod batchID", "batchID", i+1, "pod", klog.KObj(pod), "rollout", r.logKey)
|
||||
// update the counter
|
||||
updatedButUnpatchedPods = updatedButUnpatchedPods[:len(updatedButUnpatchedPods)-1]
|
||||
}
|
||||
|
@ -112,6 +161,18 @@ func (r *realPatcher) patchPodBatchLabel(pods []*corev1.Pod, ctx *batchcontext.B
|
|||
if len(updatedButUnpatchedPods) != 0 {
|
||||
klog.Warningf("still has %d pods to patch for %v", len(updatedButUnpatchedPods), r.logKey)
|
||||
}
|
||||
|
||||
// pods with controller-revision-hash label updated but not in the rollout release need to be patched too
|
||||
// We must promptly patch the computed controller-revision-hash label to the Pod so that it can be directly read
|
||||
// during frequent Reconcile processes, avoiding a large amount of redundant computation.
|
||||
for pod, hash := range podsToPatchControllerRevision {
|
||||
clone := util.GetEmptyObjectWithKey(pod)
|
||||
patchStr := fmt.Sprintf(`{"metadata":{"labels":{"%s":"%s"}}}`, v1.ControllerRevisionHashLabelKey, hash)
|
||||
if err := r.Patch(context.TODO(), clone, client.RawPatch(types.StrategicMergePatchType, []byte(patchStr))); err != nil {
|
||||
return err
|
||||
}
|
||||
klog.InfoS("Successfully patch Pod controller-revision-hash", "pod", klog.KObj(pod), "rollout", r.logKey, "hash", hash)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ package labelpatch
|
|||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
|
@ -25,11 +26,15 @@ import (
|
|||
. "github.com/onsi/gomega"
|
||||
"github.com/openkruise/rollouts/api/v1beta1"
|
||||
batchcontext "github.com/openkruise/rollouts/pkg/controller/batchrelease/context"
|
||||
apps "k8s.io/api/apps/v1"
|
||||
"github.com/openkruise/rollouts/pkg/util"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/apimachinery/pkg/util/rand"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/utils/pointer"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
)
|
||||
|
@ -39,7 +44,8 @@ var (
|
|||
)
|
||||
|
||||
func init() {
|
||||
corev1.AddToScheme(scheme)
|
||||
_ = corev1.AddToScheme(scheme)
|
||||
_ = appsv1.AddToScheme(scheme)
|
||||
}
|
||||
|
||||
func TestLabelPatcher(t *testing.T) {
|
||||
|
@ -240,7 +246,7 @@ func TestLabelPatcher(t *testing.T) {
|
|||
}
|
||||
cli := fake.NewClientBuilder().WithScheme(scheme).WithObjects(objects...).Build()
|
||||
patcher := NewLabelPatcher(cli, klog.ObjectRef{Name: "test"}, cs.Batches)
|
||||
patcher.patchPodBatchLabel(ctx.Pods, ctx)
|
||||
_ = patcher.patchPodBatchLabel(ctx.Pods, ctx)
|
||||
|
||||
podList := &corev1.PodList{}
|
||||
err := cli.List(context.TODO(), podList)
|
||||
|
@ -258,16 +264,308 @@ func TestLabelPatcher(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestDeploymentPatch(t *testing.T) {
|
||||
rs := &appsv1.ReplicaSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "rs-1",
|
||||
},
|
||||
Spec: appsv1.ReplicaSetSpec{
|
||||
Template: corev1.PodTemplateSpec{
|
||||
Spec: corev1.PodSpec{
|
||||
Containers: []corev1.Container{
|
||||
{
|
||||
Name: "nginx",
|
||||
Image: "nginx:1.14.2",
|
||||
Ports: []corev1.ContainerPort{
|
||||
{
|
||||
ContainerPort: 80,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
revision := util.ComputeHash(&rs.Spec.Template, nil)
|
||||
// randomly inserted to test cases, pods with this revision should be skipped and
|
||||
// the result should not be influenced
|
||||
skippedRevision := "should-skip"
|
||||
cases := map[string]struct {
|
||||
batchContext func() *batchcontext.BatchContext
|
||||
Batches []v1beta1.ReleaseBatch
|
||||
expectedPatched []int
|
||||
}{
|
||||
"10 pods, 0 patched, 5 new patched": {
|
||||
batchContext: func() *batchcontext.BatchContext {
|
||||
ctx := &batchcontext.BatchContext{
|
||||
RolloutID: "rollout-1",
|
||||
UpdateRevision: revision,
|
||||
PlannedUpdatedReplicas: 5,
|
||||
Replicas: 10,
|
||||
}
|
||||
pods := generateDeploymentPods(1, ctx.Replicas, 0, "", "")
|
||||
ctx.Pods = pods
|
||||
return ctx
|
||||
},
|
||||
Batches: []v1beta1.ReleaseBatch{
|
||||
{
|
||||
CanaryReplicas: intstr.FromInt(5),
|
||||
},
|
||||
},
|
||||
expectedPatched: []int{5},
|
||||
},
|
||||
"10 pods, 2 patched, 3 new patched": {
|
||||
batchContext: func() *batchcontext.BatchContext {
|
||||
ctx := &batchcontext.BatchContext{
|
||||
RolloutID: "rollout-1",
|
||||
UpdateRevision: revision,
|
||||
PlannedUpdatedReplicas: 5,
|
||||
Replicas: 10,
|
||||
}
|
||||
pods := generateDeploymentPods(1, ctx.Replicas, 2,
|
||||
ctx.RolloutID, strconv.Itoa(int(ctx.CurrentBatch+1)))
|
||||
ctx.Pods = pods
|
||||
return ctx
|
||||
},
|
||||
Batches: []v1beta1.ReleaseBatch{
|
||||
{
|
||||
CanaryReplicas: intstr.FromInt(5),
|
||||
},
|
||||
},
|
||||
expectedPatched: []int{5},
|
||||
},
|
||||
"10 pods, 5 patched, 0 new patched": {
|
||||
batchContext: func() *batchcontext.BatchContext {
|
||||
ctx := &batchcontext.BatchContext{
|
||||
RolloutID: "rollout-1",
|
||||
UpdateRevision: revision,
|
||||
PlannedUpdatedReplicas: 5,
|
||||
Replicas: 10,
|
||||
}
|
||||
pods := generateDeploymentPods(1, ctx.Replicas, 5,
|
||||
ctx.RolloutID, strconv.Itoa(int(ctx.CurrentBatch+1)))
|
||||
ctx.Pods = pods
|
||||
return ctx
|
||||
},
|
||||
Batches: []v1beta1.ReleaseBatch{
|
||||
{
|
||||
CanaryReplicas: intstr.FromInt(5),
|
||||
},
|
||||
},
|
||||
expectedPatched: []int{5},
|
||||
},
|
||||
"10 pods, 7 patched, 0 new patched": {
|
||||
batchContext: func() *batchcontext.BatchContext {
|
||||
ctx := &batchcontext.BatchContext{
|
||||
RolloutID: "rollout-1",
|
||||
UpdateRevision: revision,
|
||||
PlannedUpdatedReplicas: 5,
|
||||
Replicas: 10,
|
||||
}
|
||||
pods := generateDeploymentPods(1, ctx.Replicas, 7,
|
||||
ctx.RolloutID, strconv.Itoa(int(ctx.CurrentBatch+1)))
|
||||
ctx.Pods = pods
|
||||
return ctx
|
||||
},
|
||||
Batches: []v1beta1.ReleaseBatch{
|
||||
{
|
||||
CanaryReplicas: intstr.FromInt(5),
|
||||
},
|
||||
},
|
||||
expectedPatched: []int{7},
|
||||
},
|
||||
"2 pods, 0 patched, 2 new patched": {
|
||||
batchContext: func() *batchcontext.BatchContext {
|
||||
ctx := &batchcontext.BatchContext{
|
||||
RolloutID: "rollout-1",
|
||||
UpdateRevision: revision,
|
||||
PlannedUpdatedReplicas: 5,
|
||||
Replicas: 10,
|
||||
}
|
||||
pods := generateDeploymentPods(1, 2, 0,
|
||||
ctx.RolloutID, strconv.Itoa(int(ctx.CurrentBatch+1)))
|
||||
ctx.Pods = pods
|
||||
return ctx
|
||||
},
|
||||
Batches: []v1beta1.ReleaseBatch{
|
||||
{
|
||||
CanaryReplicas: intstr.FromInt(5),
|
||||
},
|
||||
},
|
||||
expectedPatched: []int{2},
|
||||
},
|
||||
"10 pods, 3 patched with old rollout-id, 5 new patched": {
|
||||
batchContext: func() *batchcontext.BatchContext {
|
||||
ctx := &batchcontext.BatchContext{
|
||||
RolloutID: "rollout-1",
|
||||
UpdateRevision: revision,
|
||||
PlannedUpdatedReplicas: 5,
|
||||
Replicas: 10,
|
||||
}
|
||||
pods := generateDeploymentPods(1, ctx.Replicas, 3,
|
||||
"previous-rollout-id", strconv.Itoa(int(ctx.CurrentBatch+1)))
|
||||
ctx.Pods = pods
|
||||
return ctx
|
||||
},
|
||||
Batches: []v1beta1.ReleaseBatch{
|
||||
{
|
||||
CanaryReplicas: intstr.FromInt(5),
|
||||
},
|
||||
},
|
||||
expectedPatched: []int{5},
|
||||
},
|
||||
"10 pods, 2 patched with batch-id:1, 3 new patched": {
|
||||
batchContext: func() *batchcontext.BatchContext {
|
||||
ctx := &batchcontext.BatchContext{
|
||||
RolloutID: "rollout-1",
|
||||
UpdateRevision: revision,
|
||||
PlannedUpdatedReplicas: 5,
|
||||
CurrentBatch: 1,
|
||||
Replicas: 10,
|
||||
}
|
||||
pods := generateDeploymentPods(1, 5, 2,
|
||||
"rollout-1", strconv.Itoa(1))
|
||||
ctx.Pods = pods
|
||||
return ctx
|
||||
},
|
||||
Batches: []v1beta1.ReleaseBatch{
|
||||
{CanaryReplicas: intstr.FromInt(2)},
|
||||
{CanaryReplicas: intstr.FromInt(5)},
|
||||
},
|
||||
expectedPatched: []int{2, 3},
|
||||
},
|
||||
"10 pods, 0 patched with batch-id:1, 5 new patched": {
|
||||
batchContext: func() *batchcontext.BatchContext {
|
||||
ctx := &batchcontext.BatchContext{
|
||||
RolloutID: "rollout-1",
|
||||
UpdateRevision: revision,
|
||||
PlannedUpdatedReplicas: 5,
|
||||
CurrentBatch: 1,
|
||||
Replicas: 10,
|
||||
}
|
||||
pods := generateDeploymentPods(1, 5, 0,
|
||||
"rollout-1", strconv.Itoa(1))
|
||||
ctx.Pods = pods
|
||||
return ctx
|
||||
},
|
||||
Batches: []v1beta1.ReleaseBatch{
|
||||
{CanaryReplicas: intstr.FromInt(2)},
|
||||
{CanaryReplicas: intstr.FromInt(5)},
|
||||
},
|
||||
expectedPatched: []int{2, 3},
|
||||
},
|
||||
"10 pods, 3 patched with batch-id:1, 2 new patched": {
|
||||
batchContext: func() *batchcontext.BatchContext {
|
||||
ctx := &batchcontext.BatchContext{
|
||||
RolloutID: "rollout-1",
|
||||
UpdateRevision: revision,
|
||||
PlannedUpdatedReplicas: 5,
|
||||
CurrentBatch: 1,
|
||||
Replicas: 10,
|
||||
}
|
||||
pods := generateDeploymentPods(1, 5, 3,
|
||||
"rollout-1", strconv.Itoa(1))
|
||||
ctx.Pods = pods
|
||||
return ctx
|
||||
},
|
||||
Batches: []v1beta1.ReleaseBatch{
|
||||
{CanaryReplicas: intstr.FromInt(2)},
|
||||
{CanaryReplicas: intstr.FromInt(5)},
|
||||
},
|
||||
expectedPatched: []int{3, 2},
|
||||
},
|
||||
}
|
||||
for name, cs := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
ctx := cs.batchContext()
|
||||
insertedSkippedPodNum := int32(rand.Intn(3))
|
||||
if insertedSkippedPodNum > 0 {
|
||||
ctx.Pods = append(ctx.Pods, generatePods(
|
||||
100, 99+insertedSkippedPodNum, 0, "doesn't matter", "1", skippedRevision)...)
|
||||
}
|
||||
t.Logf("%d should-skip pods inserted", insertedSkippedPodNum)
|
||||
if rand.Intn(2) > 0 {
|
||||
now := metav1.Now()
|
||||
ctx.Pods = append(ctx.Pods, &corev1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
DeletionTimestamp: &now,
|
||||
Labels: map[string]string{
|
||||
appsv1.ControllerRevisionHashLabelKey: skippedRevision,
|
||||
},
|
||||
},
|
||||
})
|
||||
t.Logf("deleted pod inserted")
|
||||
}
|
||||
var objects []client.Object
|
||||
for _, pod := range ctx.Pods {
|
||||
objects = append(objects, pod)
|
||||
}
|
||||
objects = append(objects, rs)
|
||||
cli := fake.NewClientBuilder().WithScheme(scheme).WithObjects(objects...).Build()
|
||||
patcher := NewLabelPatcher(cli, klog.ObjectRef{Name: "test"}, cs.Batches)
|
||||
if err := patcher.patchPodBatchLabel(ctx.Pods, ctx); err != nil {
|
||||
t.Fatalf("failed to patch pods: %v", err)
|
||||
}
|
||||
|
||||
podList := &corev1.PodList{}
|
||||
if err := cli.List(context.TODO(), podList); err != nil {
|
||||
t.Fatalf("failed to list pods: %v", err)
|
||||
}
|
||||
patched := make([]int, ctx.CurrentBatch+1)
|
||||
for _, pod := range podList.Items {
|
||||
if pod.Labels[v1beta1.RolloutIDLabel] == ctx.RolloutID {
|
||||
if batchID, err := strconv.Atoi(pod.Labels[v1beta1.RolloutBatchIDLabel]); err == nil {
|
||||
patched[batchID-1]++
|
||||
}
|
||||
}
|
||||
}
|
||||
if !reflect.DeepEqual(patched, cs.expectedPatched) {
|
||||
t.Fatalf("expected patched: %v, got: %v", cs.expectedPatched, patched)
|
||||
}
|
||||
for _, pod := range podList.Items {
|
||||
if pod.Labels[appsv1.ControllerRevisionHashLabelKey] != revision &&
|
||||
pod.Labels[appsv1.ControllerRevisionHashLabelKey] != skippedRevision {
|
||||
t.Fatalf("expected pod %s/%s to have revision %s, got %s", pod.Namespace, pod.Name, revision, pod.Labels[appsv1.ControllerRevisionHashLabelKey])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func generateDeploymentPods(ordinalBegin, ordinalEnd, labeled int32, rolloutID, batchID string) []*corev1.Pod {
|
||||
podsWithLabel := generateLabeledPods(map[string]string{
|
||||
v1beta1.RolloutIDLabel: rolloutID,
|
||||
v1beta1.RolloutBatchIDLabel: batchID,
|
||||
}, int(labeled), int(ordinalBegin))
|
||||
|
||||
total := ordinalEnd - ordinalBegin + 1
|
||||
podsWithoutLabel := generateLabeledPods(map[string]string{}, int(total-labeled), int(labeled+ordinalBegin))
|
||||
pods := append(podsWithoutLabel, podsWithLabel...)
|
||||
for _, pod := range pods {
|
||||
pod.OwnerReferences = []metav1.OwnerReference{
|
||||
{
|
||||
APIVersion: "apps/v1",
|
||||
Kind: "ReplicaSet",
|
||||
Name: "rs-1",
|
||||
UID: "123",
|
||||
Controller: pointer.Bool(true),
|
||||
},
|
||||
}
|
||||
}
|
||||
return pods
|
||||
}
|
||||
|
||||
func generatePods(ordinalBegin, ordinalEnd, labeled int32, rolloutID, batchID, version string) []*corev1.Pod {
|
||||
podsWithLabel := generateLabeledPods(map[string]string{
|
||||
v1beta1.RolloutIDLabel: rolloutID,
|
||||
v1beta1.RolloutBatchIDLabel: batchID,
|
||||
apps.ControllerRevisionHashLabelKey: version,
|
||||
v1beta1.RolloutIDLabel: rolloutID,
|
||||
v1beta1.RolloutBatchIDLabel: batchID,
|
||||
appsv1.ControllerRevisionHashLabelKey: version,
|
||||
}, int(labeled), int(ordinalBegin))
|
||||
|
||||
total := ordinalEnd - ordinalBegin + 1
|
||||
podsWithoutLabel := generateLabeledPods(map[string]string{
|
||||
apps.ControllerRevisionHashLabelKey: version,
|
||||
appsv1.ControllerRevisionHashLabelKey: version,
|
||||
}, int(total-labeled), int(labeled+ordinalBegin))
|
||||
return append(podsWithoutLabel, podsWithLabel...)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/*
|
||||
Copyright 2022 The Kruise Authors.
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/*
|
||||
Copyright 2022 The Kruise Authors.
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -68,15 +67,15 @@ func GetPodConditionFromList(conditions []v1.PodCondition, conditionType v1.PodC
|
|||
return -1, nil
|
||||
}
|
||||
|
||||
// IsConsistentWithRevision return true iff pod is match the revision
|
||||
func IsConsistentWithRevision(pod *v1.Pod, revision string) bool {
|
||||
if pod.Labels[appsv1.DefaultDeploymentUniqueLabelKey] != "" &&
|
||||
strings.HasSuffix(revision, pod.Labels[appsv1.DefaultDeploymentUniqueLabelKey]) {
|
||||
// IsConsistentWithRevision return true if pod is match the revision
|
||||
func IsConsistentWithRevision(labels map[string]string, revision string) bool {
|
||||
if labels[appsv1.DefaultDeploymentUniqueLabelKey] != "" &&
|
||||
strings.HasSuffix(revision, labels[appsv1.DefaultDeploymentUniqueLabelKey]) {
|
||||
return true
|
||||
}
|
||||
|
||||
if pod.Labels[appsv1.ControllerRevisionHashLabelKey] != "" &&
|
||||
strings.HasSuffix(revision, pod.Labels[appsv1.ControllerRevisionHashLabelKey]) {
|
||||
if labels[appsv1.ControllerRevisionHashLabelKey] != "" &&
|
||||
strings.HasSuffix(revision, labels[appsv1.ControllerRevisionHashLabelKey]) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/onsi/gomega/format"
|
||||
appsv1alpha1 "github.com/openkruise/kruise-api/apps/v1alpha1"
|
||||
appsv1beta1 "github.com/openkruise/kruise-api/apps/v1beta1"
|
||||
"github.com/openkruise/rollouts/api/v1beta1"
|
||||
|
@ -48,6 +49,7 @@ import (
|
|||
)
|
||||
|
||||
var _ = SIGDescribe("Rollout v1beta1", func() {
|
||||
format.MaxLength = 0
|
||||
var namespace string
|
||||
|
||||
DumpAllResources := func() {
|
||||
|
@ -131,25 +133,6 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
return clone
|
||||
}
|
||||
|
||||
// UpdateDaemonSet := func(object *appsv1alpha1.DaemonSet) *appsv1alpha1.DaemonSet {
|
||||
// var daemon *appsv1alpha1.DaemonSet
|
||||
// Expect(retry.RetryOnConflict(retry.DefaultRetry, func() error {
|
||||
// daemon = &appsv1alpha1.DaemonSet{}
|
||||
// err := GetObject(object.Name, daemon)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// // daemon.Spec.Replicas = utilpointer.Int32(*object.Spec.Replicas)
|
||||
// daemon.Spec.Template = *object.Spec.Template.DeepCopy()
|
||||
// daemon.Spec.UpdateStrategy = *object.Spec.UpdateStrategy.DeepCopy()
|
||||
// daemon.Labels = mergeMap(daemon.Labels, object.Labels)
|
||||
// daemon.Annotations = mergeMap(daemon.Annotations, object.Annotations)
|
||||
// return k8sClient.Update(context.TODO(), daemon)
|
||||
// })).NotTo(HaveOccurred())
|
||||
|
||||
// return daemon
|
||||
// }
|
||||
|
||||
UpdateNativeStatefulSet := func(object *apps.StatefulSet) *apps.StatefulSet {
|
||||
var clone *apps.StatefulSet
|
||||
Expect(retry.RetryOnConflict(retry.DefaultRetry, func() error {
|
||||
|
@ -292,25 +275,6 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
}, 20*time.Minute, 3*time.Second).Should(BeTrue())
|
||||
}
|
||||
|
||||
// WaitDaemonSetAllPodsReady := func(daemonset *appsv1alpha1.DaemonSet) {
|
||||
// Eventually(func() bool {
|
||||
// daemon := &appsv1alpha1.DaemonSet{}
|
||||
// Expect(GetObject(daemonset.Name, daemon)).NotTo(HaveOccurred())
|
||||
// klog.Infof("DaemonSet updateStrategy(%s) Generation(%d) ObservedGeneration(%d) DesiredNumberScheduled(%d) UpdatedNumberScheduled(%d) NumberReady(%d)",
|
||||
// util.DumpJSON(daemon.Spec.UpdateStrategy), daemon.Generation, daemon.Status.ObservedGeneration, daemon.Status.DesiredNumberScheduled, daemon.Status.UpdatedNumberScheduled, daemon.Status.NumberReady)
|
||||
// return daemon.Status.ObservedGeneration == daemon.Generation && daemon.Status.DesiredNumberScheduled == daemon.Status.UpdatedNumberScheduled && daemon.Status.DesiredNumberScheduled == daemon.Status.NumberReady
|
||||
// }, 5*time.Minute, time.Second).Should(BeTrue())
|
||||
// }
|
||||
|
||||
// WaitDeploymentCanaryReplicas := func(deployment *apps.Deployment) {
|
||||
// Eventually(func() bool {
|
||||
// clone := &apps.Deployment{}
|
||||
// Expect(GetObject(deployment.Name, clone)).NotTo(HaveOccurred())
|
||||
// return clone.Status.ObservedGeneration == clone.Generation &&
|
||||
// *clone.Spec.Replicas == clone.Status.ReadyReplicas && *clone.Spec.Replicas == clone.Status.Replicas
|
||||
// }, 10*time.Minute, time.Second).Should(BeTrue())
|
||||
// }
|
||||
|
||||
WaitDeploymentBlueGreenReplicas := func(deployment *apps.Deployment) {
|
||||
Eventually(func() bool {
|
||||
clone := &apps.Deployment{}
|
||||
|
@ -319,32 +283,6 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
}, 10*time.Minute, time.Second).Should(BeTrue())
|
||||
}
|
||||
|
||||
// WaitClonesetBlueGreenReplicas := func(cloneset *appsv1alpha1.CloneSet) {
|
||||
// Eventually(func() bool {
|
||||
// clone := &appsv1alpha1.CloneSet{}
|
||||
// Expect(GetObject(cloneset.Name, clone)).NotTo(HaveOccurred())
|
||||
// return clone.Status.ObservedGeneration == clone.Generation &&
|
||||
// *clone.Spec.Replicas == clone.Status.AvailableReplicas && clone.Status.ReadyReplicas == clone.Status.Replicas
|
||||
// }, 10*time.Minute, time.Second).Should(BeTrue())
|
||||
// }
|
||||
|
||||
// WaitRolloutStepUpgrade := func(name string, stepIndex int32) {
|
||||
// start := time.Now()
|
||||
// Eventually(func() bool {
|
||||
// if start.Add(time.Minute * 5).Before(time.Now()) {
|
||||
// DumpAllResources()
|
||||
// Expect(true).Should(BeFalse())
|
||||
// }
|
||||
// clone := &v1beta1.Rollout{}
|
||||
// Expect(GetObject(name, clone)).NotTo(HaveOccurred())
|
||||
// if clone.Status.GetSubStatus() == nil {
|
||||
// return false
|
||||
// }
|
||||
// klog.Infof("current step:%v target step:%v current step state %v", clone.Status.GetSubStatus().CurrentStepIndex, stepIndex, clone.Status.GetSubStatus().CurrentStepState)
|
||||
// return clone.Status.GetSubStatus().CurrentStepIndex == stepIndex && clone.Status.GetSubStatus().CurrentStepState == v1beta1.CanaryStepStateUpgrade
|
||||
// }, 20*time.Minute, time.Second).Should(BeTrue())
|
||||
// }
|
||||
|
||||
WaitRolloutStepPaused := func(name string, stepIndex int32) {
|
||||
start := time.Now()
|
||||
Eventually(func() bool {
|
||||
|
@ -439,6 +377,40 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(count).Should(BeNumerically("==", expected))
|
||||
}
|
||||
|
||||
// CheckPodBatchLabel cannot be located if error occurs. use this as Expect(CheckPodBatchLabelV2(...)).Should(Succeed())
|
||||
CheckPodBatchLabelV2 := func(namespace string, labelSelector *metav1.LabelSelector, rolloutID, batchID string, expected int) error {
|
||||
fn := func() error {
|
||||
pods, err := ListPods(namespace, labelSelector)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
count := 0
|
||||
podsMap := make(map[string]string)
|
||||
for _, pod := range pods {
|
||||
podsMap[pod.Name] = fmt.Sprintf("rolloutID:%s, batchID:%s, controllerRevisionHash:%s",
|
||||
pod.Labels[v1beta1.RolloutIDLabel], pod.Labels[v1beta1.RolloutBatchIDLabel], pod.Labels[apps.ControllerRevisionHashLabelKey])
|
||||
if pod.Labels[v1beta1.RolloutIDLabel] == rolloutID &&
|
||||
pod.Labels[v1beta1.RolloutBatchIDLabel] == batchID {
|
||||
count++
|
||||
}
|
||||
}
|
||||
if count != expected {
|
||||
return fmt.Errorf("expected %d pods with rolloutID %s and batchID %s, got %d; all pods info: %s", expected, rolloutID, batchID, count, podsMap)
|
||||
}
|
||||
klog.InfoS("check pod batch label success", "count", count, "rolloutID", rolloutID, "batchID", batchID)
|
||||
return nil
|
||||
}
|
||||
var err error
|
||||
for i := 0; i < 15; i++ {
|
||||
if err = fn(); err == nil {
|
||||
return nil
|
||||
}
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
ListReplicaSet := func(d *apps.Deployment) []*apps.ReplicaSet {
|
||||
var rss []*apps.ReplicaSet
|
||||
rsLister := &apps.ReplicaSetList{}
|
||||
|
@ -526,6 +498,7 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
},
|
||||
}
|
||||
Expect(k8sClient.Create(context.TODO(), &ns)).Should(SatisfyAny(BeNil()))
|
||||
klog.InfoS("Namespace created", "namespace", namespace)
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
|
@ -651,6 +624,9 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(GetObject(service.Name+"-canary", cIngress)).NotTo(HaveOccurred())
|
||||
Expect(cIngress.Annotations[fmt.Sprintf("%s/canary", nginxIngressAnnotationDefaultPrefix)]).Should(Equal("true"))
|
||||
Expect(cIngress.Annotations[fmt.Sprintf("%s/canary-weight", nginxIngressAnnotationDefaultPrefix)]).Should(Equal(removePercentageSign(*rollout.Spec.Strategy.Canary.Steps[3].Traffic)))
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.CanaryStatus.ObservedRolloutID, "1", 1))
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.CanaryStatus.ObservedRolloutID, "2", 1))
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.CanaryStatus.ObservedRolloutID, "3", 1))
|
||||
|
||||
// Jump to step 3
|
||||
By("Jump to step 3")
|
||||
|
@ -847,7 +823,11 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(string(cond.Status)).Should(Equal(string(metav1.ConditionTrue)))
|
||||
Expect(GetObject(workload.Name, workload)).NotTo(HaveOccurred())
|
||||
WaitRolloutWorkloadGeneration(rollout.Name, workload.Generation)
|
||||
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.CanaryStatus.ObservedRolloutID, "1", 1))
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.CanaryStatus.ObservedRolloutID, "2", 1))
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.CanaryStatus.ObservedRolloutID, "3", 1))
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.CanaryStatus.ObservedRolloutID, "4", 1))
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.CanaryStatus.ObservedRolloutID, "5", 1))
|
||||
})
|
||||
|
||||
// step1-> 2-> 3-> 4-> 3-(TrafficChange)-> 3-> 2-> 1-> 5
|
||||
|
@ -1588,6 +1568,9 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(GetObject(service.Name+"-canary", cIngress)).NotTo(HaveOccurred())
|
||||
Expect(cIngress.Annotations[fmt.Sprintf("%s/canary", nginxIngressAnnotationDefaultPrefix)]).Should(Equal("true"))
|
||||
Expect(cIngress.Annotations[fmt.Sprintf("%s/canary-weight", nginxIngressAnnotationDefaultPrefix)]).Should(Equal(removePercentageSign(*rollout.Spec.Strategy.Canary.Steps[2].Traffic)))
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.CanaryStatus.ObservedRolloutID, "1", 1))
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.CanaryStatus.ObservedRolloutID, "2", 1))
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.CanaryStatus.ObservedRolloutID, "3", 1))
|
||||
|
||||
// remove step 2 3 4
|
||||
By("Remove step 2 3 4")
|
||||
|
@ -1695,12 +1678,6 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
cService := &v1.Service{}
|
||||
Expect(GetObject(service.Name+"-canary", cService)).NotTo(HaveOccurred())
|
||||
Expect(cService.Spec.Selector[apps.DefaultDeploymentUniqueLabelKey]).Should(Equal(canaryRevision))
|
||||
// canary ingress
|
||||
// when traffic is 0%, ingress canary won't create and annotation won't be set (for ingress-nginx)
|
||||
// cIngress := &netv1.Ingress{}
|
||||
// Expect(GetObject(service.Name+"-canary", cIngress)).NotTo(HaveOccurred())
|
||||
// Expect(cIngress.Annotations[fmt.Sprintf("%s/canary", nginxIngressAnnotationDefaultPrefix)]).Should(Equal("true"))
|
||||
// Expect(cIngress.Annotations[fmt.Sprintf("%s/canary-weight", nginxIngressAnnotationDefaultPrefix)]).Should(Equal(removePercentageSign(*rollout.Spec.Strategy.BlueGreen.Steps[0].Traffic)))
|
||||
|
||||
// ------ step 2: replicas: 100%, traffic: 0% ------
|
||||
// resume rollout canary
|
||||
|
@ -1727,6 +1704,9 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(rollout.Status.BlueGreenStatus.UpdatedReplicas).Should(BeNumerically("==", 5))
|
||||
Expect(rollout.Status.BlueGreenStatus.UpdatedReadyReplicas).Should(BeNumerically("==", 5))
|
||||
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.BlueGreenStatus.ObservedRolloutID, "1", 3)).Should(Succeed())
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.BlueGreenStatus.ObservedRolloutID, "2", 2)).Should(Succeed())
|
||||
|
||||
// ------ step 3: replicas: 100%, traffic: 50% ------
|
||||
// resume rollout canary
|
||||
ResumeRollout(rollout.Name)
|
||||
|
@ -1940,12 +1920,6 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
cService := &v1.Service{}
|
||||
Expect(GetObject(service.Name+"-canary", cService)).NotTo(HaveOccurred())
|
||||
Expect(cService.Spec.Selector[apps.DefaultDeploymentUniqueLabelKey]).Should(Equal(canaryRevision))
|
||||
// canary ingress
|
||||
// when traffic is 0%, ingress canary won't create and annotation won't be set (for ingress-nginx)
|
||||
// cIngress := &netv1.Ingress{}
|
||||
// Expect(GetObject(service.Name+"-canary", cIngress)).NotTo(HaveOccurred())
|
||||
// Expect(cIngress.Annotations[fmt.Sprintf("%s/canary", nginxIngressAnnotationDefaultPrefix)]).Should(Equal("true"))
|
||||
// Expect(cIngress.Annotations[fmt.Sprintf("%s/canary-weight", nginxIngressAnnotationDefaultPrefix)]).Should(Equal(removePercentageSign(*rollout.Spec.Strategy.BlueGreen.Steps[0].Traffic)))
|
||||
|
||||
// ------ step 2: replicas: 100%, traffic: 0% ------
|
||||
// resume rollout canary
|
||||
|
@ -1972,6 +1946,10 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(rollout.Status.BlueGreenStatus.UpdatedReplicas).Should(BeNumerically("==", 5))
|
||||
Expect(rollout.Status.BlueGreenStatus.UpdatedReadyReplicas).Should(BeNumerically("==", 5))
|
||||
|
||||
By("checking pod labels")
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.BlueGreenStatus.ObservedRolloutID, "1", 3)).Should(Succeed())
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.BlueGreenStatus.ObservedRolloutID, "2", 2)).Should(Succeed())
|
||||
|
||||
// ------ step 3: replicas: 100%, traffic: 50% ------
|
||||
// resume rollout canary
|
||||
ResumeRollout(rollout.Name)
|
||||
|
@ -2134,7 +2112,7 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
|
||||
Expect(GetObject(rollout.Name, rollout)).NotTo(HaveOccurred())
|
||||
cond := getRolloutCondition(rollout.Status, v1beta1.RolloutConditionProgressing)
|
||||
Expect(string(cond.Reason)).Should(Equal(string(v1beta1.CanaryStepStateCompleted)))
|
||||
Expect(cond.Reason).Should(Equal(string(v1beta1.CanaryStepStateCompleted)))
|
||||
Expect(string(cond.Status)).Should(Equal(string(metav1.ConditionFalse)))
|
||||
// canary ingress and canary service should be deleted
|
||||
cIngress = &netv1.Ingress{}
|
||||
|
@ -2145,6 +2123,10 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
// check service update
|
||||
Expect(GetObject(service.Name, service)).NotTo(HaveOccurred())
|
||||
Expect(service.Spec.Selector[apps.DefaultDeploymentUniqueLabelKey]).Should(Equal(""))
|
||||
|
||||
By("checking pod labelsa after rollback")
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.BlueGreenStatus.ObservedRolloutID, "1", 0)).Should(Succeed())
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.BlueGreenStatus.ObservedRolloutID, "2", 0)).Should(Succeed())
|
||||
})
|
||||
|
||||
It("bluegreen deployment continuous rolling case", func() {
|
||||
|
@ -2335,29 +2317,31 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
WaitRolloutStepPaused(rollout.Name, 1)
|
||||
stableRevision := GetStableRSRevision(workload)
|
||||
By(stableRevision)
|
||||
Expect(GetObject(rollout.Name, rollout)).NotTo(HaveOccurred())
|
||||
Expect(rollout.Status.CanaryStatus).Should(BeNil())
|
||||
Expect(rollout.Status.BlueGreenStatus.StableRevision).Should(Equal(stableRevision))
|
||||
Eventually(func(g Gomega) {
|
||||
g.Expect(GetObject(rollout.Name, rollout)).NotTo(HaveOccurred())
|
||||
g.Expect(rollout.Status.CanaryStatus).Should(BeNil())
|
||||
g.Expect(rollout.Status.BlueGreenStatus.StableRevision).Should(Equal(stableRevision))
|
||||
|
||||
// check workload status & paused
|
||||
Expect(GetObject(workload.Name, workload)).NotTo(HaveOccurred())
|
||||
Expect(workload.Status.UpdatedReplicas).Should(BeNumerically("==", 3))
|
||||
Expect(workload.Status.UnavailableReplicas).Should(BeNumerically("==", 8))
|
||||
Expect(workload.Status.ReadyReplicas).Should(BeNumerically("==", 8))
|
||||
// check workload status & paused
|
||||
g.Expect(GetObject(workload.Name, workload)).NotTo(HaveOccurred())
|
||||
g.Expect(workload.Status.UpdatedReplicas).Should(BeNumerically("==", 3))
|
||||
g.Expect(workload.Status.UnavailableReplicas).Should(BeNumerically("==", 8))
|
||||
g.Expect(workload.Status.ReadyReplicas).Should(BeNumerically("==", 8))
|
||||
|
||||
// check rollout status
|
||||
Expect(GetObject(workload.Name, workload)).NotTo(HaveOccurred())
|
||||
Expect(GetObject(rollout.Name, rollout)).NotTo(HaveOccurred())
|
||||
Expect(rollout.Status.Phase).Should(Equal(v1beta1.RolloutPhaseProgressing))
|
||||
Expect(rollout.Status.BlueGreenStatus.RolloutHash).Should(Equal(rollout.Annotations[util.RolloutHashAnnotation]))
|
||||
Expect(rollout.Status.BlueGreenStatus.CurrentStepIndex).Should(BeNumerically("==", 1))
|
||||
Expect(rollout.Status.BlueGreenStatus.NextStepIndex).Should(BeNumerically("==", 2))
|
||||
Expect(rollout.Status.BlueGreenStatus.UpdatedReplicas).Should(BeNumerically("==", 3))
|
||||
Expect(rollout.Status.BlueGreenStatus.UpdatedReadyReplicas).Should(BeNumerically("==", 3))
|
||||
// check rollout status
|
||||
g.Expect(GetObject(workload.Name, workload)).NotTo(HaveOccurred())
|
||||
g.Expect(GetObject(rollout.Name, rollout)).NotTo(HaveOccurred())
|
||||
g.Expect(rollout.Status.Phase).Should(Equal(v1beta1.RolloutPhaseProgressing))
|
||||
g.Expect(rollout.Status.BlueGreenStatus.RolloutHash).Should(Equal(rollout.Annotations[util.RolloutHashAnnotation]))
|
||||
g.Expect(rollout.Status.BlueGreenStatus.CurrentStepIndex).Should(BeNumerically("==", 1))
|
||||
g.Expect(rollout.Status.BlueGreenStatus.NextStepIndex).Should(BeNumerically("==", 2))
|
||||
g.Expect(rollout.Status.BlueGreenStatus.UpdatedReplicas).Should(BeNumerically("==", 3))
|
||||
g.Expect(rollout.Status.BlueGreenStatus.UpdatedReadyReplicas).Should(BeNumerically("==", 3))
|
||||
}).WithTimeout(time.Second * 60).WithPolling(time.Second * 3).Should(Succeed())
|
||||
// ------ 50% maxSurge, scale up: from 5 to 6 ------
|
||||
By("50%, scale up from 5 to 6")
|
||||
workload.Spec.Replicas = utilpointer.Int32(6)
|
||||
UpdateDeployment(workload)
|
||||
By("scale up: from 5 to 6")
|
||||
time.Sleep(time.Second * 3)
|
||||
WaitDeploymentBlueGreenReplicas(workload)
|
||||
|
||||
|
@ -2372,8 +2356,10 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(workload.Status.UpdatedReplicas).Should(BeNumerically("==", 3))
|
||||
Expect(workload.Status.UnavailableReplicas).Should(BeNumerically("==", 9))
|
||||
Expect(workload.Status.ReadyReplicas).Should(BeNumerically("==", 9))
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.BlueGreenStatus.ObservedRolloutID, "1", 3)).Should(Succeed())
|
||||
|
||||
// ------ scale up: from 6 to 7 ------
|
||||
By("50%, scale up from 6 to 7")
|
||||
workload.Spec.Replicas = utilpointer.Int32(7)
|
||||
UpdateDeployment(workload)
|
||||
time.Sleep(time.Second * 3)
|
||||
|
@ -2387,11 +2373,12 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(workload.Status.UpdatedReplicas).Should(BeNumerically("==", 4))
|
||||
Expect(workload.Status.UnavailableReplicas).Should(BeNumerically("==", 11))
|
||||
Expect(workload.Status.ReadyReplicas).Should(BeNumerically("==", 11))
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.BlueGreenStatus.ObservedRolloutID, "1", 4)).Should(Succeed())
|
||||
|
||||
// ------ scale up: from 7 to 8 ------
|
||||
By("50%, scale up from 7 to 8")
|
||||
workload.Spec.Replicas = utilpointer.Int32(8)
|
||||
UpdateDeployment(workload)
|
||||
By("scale up: from 7 to 8")
|
||||
time.Sleep(time.Second * 3)
|
||||
WaitDeploymentBlueGreenReplicas(workload)
|
||||
// check rollout status
|
||||
|
@ -2403,11 +2390,12 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(workload.Status.UpdatedReplicas).Should(BeNumerically("==", 4))
|
||||
Expect(workload.Status.UnavailableReplicas).Should(BeNumerically("==", 12))
|
||||
Expect(workload.Status.ReadyReplicas).Should(BeNumerically("==", 12))
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.BlueGreenStatus.ObservedRolloutID, "1", 4)).Should(Succeed())
|
||||
|
||||
// ------ scale down: from 8 to 4 ------
|
||||
By("50%, scale down from 8 to 4")
|
||||
workload.Spec.Replicas = utilpointer.Int32(4)
|
||||
UpdateDeployment(workload)
|
||||
By("scale down: from 8 to 4")
|
||||
time.Sleep(time.Second * 3)
|
||||
WaitDeploymentBlueGreenReplicas(workload)
|
||||
// check rollout status
|
||||
|
@ -2419,6 +2407,7 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(workload.Status.UpdatedReplicas).Should(BeNumerically("==", 2))
|
||||
Expect(workload.Status.UnavailableReplicas).Should(BeNumerically("==", 6))
|
||||
Expect(workload.Status.ReadyReplicas).Should(BeNumerically("==", 6))
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.BlueGreenStatus.ObservedRolloutID, "1", 2)).Should(Succeed())
|
||||
|
||||
// ------ step 2: replicas: 100%, traffic: 0% ------
|
||||
// resume rollout canary
|
||||
|
@ -2427,25 +2416,28 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
WaitRolloutStepPaused(rollout.Name, 2)
|
||||
|
||||
// workload
|
||||
Expect(GetObject(workload.Name, workload)).NotTo(HaveOccurred())
|
||||
Expect(workload.Status.UpdatedReplicas).Should(BeNumerically("==", 4))
|
||||
Expect(workload.Status.UnavailableReplicas).Should(BeNumerically("==", 8))
|
||||
Expect(workload.Status.ReadyReplicas).Should(BeNumerically("==", 8))
|
||||
Expect(workload.Spec.Paused).Should(BeFalse())
|
||||
Expect(workload.Spec.Strategy.Type).Should(Equal(apps.RollingUpdateDeploymentStrategyType))
|
||||
Expect(workload.Spec.MinReadySeconds).Should(Equal(int32(v1beta1.MaxReadySeconds)))
|
||||
Expect(*workload.Spec.ProgressDeadlineSeconds).Should(Equal(int32(v1beta1.MaxProgressSeconds)))
|
||||
Expect(reflect.DeepEqual(workload.Spec.Strategy.RollingUpdate.MaxUnavailable, &intstr.IntOrString{Type: intstr.Int, IntVal: 0})).Should(BeTrue())
|
||||
Expect(reflect.DeepEqual(workload.Spec.Strategy.RollingUpdate.MaxSurge, &intstr.IntOrString{Type: intstr.String, StrVal: "100%"})).Should(BeTrue())
|
||||
Eventually(func(g Gomega) {
|
||||
g.Expect(GetObject(workload.Name, workload)).NotTo(HaveOccurred())
|
||||
g.Expect(workload.Status.UpdatedReplicas).Should(BeNumerically("==", 4))
|
||||
g.Expect(workload.Status.UnavailableReplicas).Should(BeNumerically("==", 8))
|
||||
g.Expect(workload.Status.ReadyReplicas).Should(BeNumerically("==", 8))
|
||||
g.Expect(workload.Spec.Paused).Should(BeFalse())
|
||||
g.Expect(workload.Spec.Strategy.Type).Should(Equal(apps.RollingUpdateDeploymentStrategyType))
|
||||
g.Expect(workload.Spec.MinReadySeconds).Should(Equal(int32(v1beta1.MaxReadySeconds)))
|
||||
g.Expect(*workload.Spec.ProgressDeadlineSeconds).Should(Equal(int32(v1beta1.MaxProgressSeconds)))
|
||||
g.Expect(reflect.DeepEqual(workload.Spec.Strategy.RollingUpdate.MaxUnavailable, &intstr.IntOrString{Type: intstr.Int, IntVal: 0})).Should(BeTrue())
|
||||
g.Expect(reflect.DeepEqual(workload.Spec.Strategy.RollingUpdate.MaxSurge, &intstr.IntOrString{Type: intstr.String, StrVal: "100%"})).Should(BeTrue())
|
||||
|
||||
// rollout
|
||||
Expect(GetObject(rollout.Name, rollout)).NotTo(HaveOccurred())
|
||||
Expect(rollout.Status.BlueGreenStatus.CurrentStepIndex).Should(BeNumerically("==", 2))
|
||||
Expect(rollout.Status.BlueGreenStatus.NextStepIndex).Should(BeNumerically("==", 3))
|
||||
Expect(rollout.Status.BlueGreenStatus.UpdatedReplicas).Should(BeNumerically("==", 4))
|
||||
Expect(rollout.Status.BlueGreenStatus.UpdatedReadyReplicas).Should(BeNumerically("==", 4))
|
||||
// rollout
|
||||
g.Expect(GetObject(rollout.Name, rollout)).NotTo(HaveOccurred())
|
||||
g.Expect(rollout.Status.BlueGreenStatus.CurrentStepIndex).Should(BeNumerically("==", 2))
|
||||
g.Expect(rollout.Status.BlueGreenStatus.NextStepIndex).Should(BeNumerically("==", 3))
|
||||
g.Expect(rollout.Status.BlueGreenStatus.UpdatedReplicas).Should(BeNumerically("==", 4))
|
||||
g.Expect(rollout.Status.BlueGreenStatus.UpdatedReadyReplicas).Should(BeNumerically("==", 4))
|
||||
}).WithTimeout(time.Second * 60).WithPolling(time.Second * 1).Should(Succeed())
|
||||
|
||||
// ------ scale up: from 4 to 7 ------
|
||||
By("100%, scale up from 4 to 7")
|
||||
workload.Spec.Replicas = utilpointer.Int32(7)
|
||||
UpdateDeployment(workload)
|
||||
time.Sleep(time.Second * 3)
|
||||
|
@ -2459,8 +2451,11 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(workload.Status.UpdatedReplicas).Should(BeNumerically("==", 7))
|
||||
Expect(workload.Status.UnavailableReplicas).Should(BeNumerically("==", 14))
|
||||
Expect(workload.Status.ReadyReplicas).Should(BeNumerically("==", 14))
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.BlueGreenStatus.ObservedRolloutID, "1", 4)).Should(Succeed())
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.BlueGreenStatus.ObservedRolloutID, "2", 3)).Should(Succeed())
|
||||
|
||||
// ------ scale up: from 7 to 8 ------
|
||||
By("100%, scale up from 7 to 8")
|
||||
workload.Spec.Replicas = utilpointer.Int32(8)
|
||||
UpdateDeployment(workload)
|
||||
time.Sleep(time.Second * 3)
|
||||
|
@ -2474,8 +2469,11 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(workload.Status.UpdatedReplicas).Should(BeNumerically("==", 8))
|
||||
Expect(workload.Status.UnavailableReplicas).Should(BeNumerically("==", 16))
|
||||
Expect(workload.Status.ReadyReplicas).Should(BeNumerically("==", 16))
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.BlueGreenStatus.ObservedRolloutID, "1", 4)).Should(Succeed())
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.BlueGreenStatus.ObservedRolloutID, "2", 4)).Should(Succeed())
|
||||
|
||||
// ------ scale down: from 8 to 4 ------
|
||||
By("100%, scale down from 8 to 4")
|
||||
workload.Spec.Replicas = utilpointer.Int32(4)
|
||||
UpdateDeployment(workload)
|
||||
time.Sleep(time.Second * 3)
|
||||
|
@ -2489,7 +2487,6 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(workload.Status.UpdatedReplicas).Should(BeNumerically("==", 4))
|
||||
Expect(workload.Status.UnavailableReplicas).Should(BeNumerically("==", 8))
|
||||
Expect(workload.Status.ReadyReplicas).Should(BeNumerically("==", 8))
|
||||
|
||||
})
|
||||
|
||||
It("bluegreen delete rollout case", func() {
|
||||
|
@ -2555,7 +2552,7 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(rollout.Status.BlueGreenStatus.UpdatedReadyReplicas).Should(BeNumerically("==", 3))
|
||||
|
||||
By("delete rollout and check deployment")
|
||||
k8sClient.Delete(context.TODO(), rollout)
|
||||
_ = k8sClient.Delete(context.TODO(), rollout)
|
||||
WaitRolloutNotFound(rollout.Name)
|
||||
Expect(GetObject(workload.Name, workload)).NotTo(HaveOccurred())
|
||||
// check annotation
|
||||
|
@ -2890,7 +2887,7 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(hpa.Spec.ScaleTargetRef.Name).Should(Equal(workload.Name + HPADisableSuffix))
|
||||
|
||||
By("delete rollout and check deployment")
|
||||
k8sClient.Delete(context.TODO(), rollout)
|
||||
_ = k8sClient.Delete(context.TODO(), rollout)
|
||||
WaitRolloutNotFound(rollout.Name)
|
||||
Expect(GetObject(workload.Name, workload)).NotTo(HaveOccurred())
|
||||
// check annotation
|
||||
|
@ -2957,10 +2954,13 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
WaitCloneSetAllPodsReady(workload)
|
||||
|
||||
// check rollout status
|
||||
Expect(GetObject(rollout.Name, rollout)).NotTo(HaveOccurred())
|
||||
Expect(GetObject(workload.Name, workload)).NotTo(HaveOccurred())
|
||||
Expect(rollout.Status.Phase).Should(Equal(v1beta1.RolloutPhaseHealthy))
|
||||
Expect(rollout.Status.BlueGreenStatus.StableRevision).Should(Equal(workload.Status.CurrentRevision[strings.LastIndex(workload.Status.CurrentRevision, "-")+1:]))
|
||||
Eventually(func(g Gomega) {
|
||||
g.Expect(GetObject(rollout.Name, rollout)).NotTo(HaveOccurred())
|
||||
g.Expect(GetObject(workload.Name, workload)).NotTo(HaveOccurred())
|
||||
g.Expect(rollout.Status.Phase).Should(Equal(v1beta1.RolloutPhaseHealthy))
|
||||
g.Expect(rollout.Status.BlueGreenStatus.StableRevision).Should(Equal(workload.Status.CurrentRevision[strings.LastIndex(workload.Status.CurrentRevision, "-")+1:]))
|
||||
}).WithTimeout(10 * time.Second).WithPolling(time.Second).Should(Succeed())
|
||||
|
||||
stableRevision := rollout.Status.BlueGreenStatus.StableRevision
|
||||
By("check rollout status & paused success")
|
||||
|
||||
|
@ -2991,6 +2991,7 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(rollout.Status.BlueGreenStatus.CurrentStepIndex).Should(BeNumerically("==", 1))
|
||||
Expect(rollout.Status.BlueGreenStatus.NextStepIndex).Should(BeNumerically("==", 2))
|
||||
Expect(rollout.Status.BlueGreenStatus.RolloutHash).Should(Equal(rollout.Annotations[util.RolloutHashAnnotation]))
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.BlueGreenStatus.ObservedRolloutID, "1", 5)).Should(Succeed())
|
||||
// check stable, canary service & ingress
|
||||
// stable service
|
||||
Expect(GetObject(service.Name, service)).NotTo(HaveOccurred())
|
||||
|
@ -3118,10 +3119,12 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
WaitCloneSetAllPodsReady(workload)
|
||||
|
||||
// check rollout status
|
||||
Expect(GetObject(rollout.Name, rollout)).NotTo(HaveOccurred())
|
||||
Expect(GetObject(workload.Name, workload)).NotTo(HaveOccurred())
|
||||
Expect(rollout.Status.Phase).Should(Equal(v1beta1.RolloutPhaseHealthy))
|
||||
Expect(rollout.Status.BlueGreenStatus.StableRevision).Should(Equal(workload.Status.CurrentRevision[strings.LastIndex(workload.Status.CurrentRevision, "-")+1:]))
|
||||
Eventually(func(g Gomega) {
|
||||
g.Expect(GetObject(rollout.Name, rollout)).NotTo(HaveOccurred())
|
||||
g.Expect(GetObject(workload.Name, workload)).NotTo(HaveOccurred())
|
||||
g.Expect(rollout.Status.Phase).Should(Equal(v1beta1.RolloutPhaseHealthy))
|
||||
g.Expect(rollout.Status.BlueGreenStatus.StableRevision).Should(Equal(workload.Status.CurrentRevision[strings.LastIndex(workload.Status.CurrentRevision, "-")+1:]))
|
||||
}).WithTimeout(time.Second * 30).WithPolling(time.Second).Should(Succeed())
|
||||
stableRevision := rollout.Status.BlueGreenStatus.StableRevision
|
||||
By("check rollout status & paused success")
|
||||
|
||||
|
@ -3152,6 +3155,7 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(rollout.Status.BlueGreenStatus.CurrentStepIndex).Should(BeNumerically("==", 1))
|
||||
Expect(rollout.Status.BlueGreenStatus.NextStepIndex).Should(BeNumerically("==", 2))
|
||||
Expect(rollout.Status.BlueGreenStatus.RolloutHash).Should(Equal(rollout.Annotations[util.RolloutHashAnnotation]))
|
||||
Expect(CheckPodBatchLabelV2(namespace, workload.Spec.Selector, rollout.Status.BlueGreenStatus.ObservedRolloutID, "1", 5)).Should(Succeed())
|
||||
// check stable, canary service & ingress
|
||||
// stable service
|
||||
Expect(GetObject(service.Name, service)).NotTo(HaveOccurred())
|
||||
|
@ -3259,6 +3263,7 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(rollout.Status.BlueGreenStatus.CurrentStepIndex).Should(BeNumerically("==", 1))
|
||||
Expect(rollout.Status.BlueGreenStatus.NextStepIndex).Should(BeNumerically("==", 2))
|
||||
Expect(rollout.Status.BlueGreenStatus.RolloutHash).Should(Equal(rollout.Annotations[util.RolloutHashAnnotation]))
|
||||
CheckPodBatchLabel(namespace, workload.Spec.Selector, rollout.Status.BlueGreenStatus.ObservedRolloutID, "1", 5)
|
||||
// if network configuration has restored
|
||||
cIngress = &netv1.Ingress{}
|
||||
Expect(GetObject(service.Name+"-canary", cIngress)).NotTo(HaveOccurred())
|
||||
|
@ -3275,7 +3280,7 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
|
||||
Expect(GetObject(rollout.Name, rollout)).NotTo(HaveOccurred())
|
||||
cond := getRolloutCondition(rollout.Status, v1beta1.RolloutConditionProgressing)
|
||||
Expect(string(cond.Reason)).Should(Equal(string(v1beta1.CanaryStepStateCompleted)))
|
||||
Expect(cond.Reason).Should(Equal(string(v1beta1.CanaryStepStateCompleted)))
|
||||
Expect(string(cond.Status)).Should(Equal(string(metav1.ConditionFalse)))
|
||||
CheckIngressRestored(service.Name)
|
||||
|
||||
|
@ -3285,6 +3290,7 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
Expect(workload.Status.UpdatedReplicas).Should(BeNumerically("==", 5))
|
||||
Expect(workload.Status.UpdatedReadyReplicas).Should(BeNumerically("==", 5))
|
||||
Expect(workload.Spec.UpdateStrategy.Paused).Should(BeFalse())
|
||||
CheckPodBatchLabel(namespace, workload.Spec.Selector, rollout.Status.BlueGreenStatus.ObservedRolloutID, "1", 0)
|
||||
})
|
||||
|
||||
It("bluegreen continuous rolling case for cloneset", func() {
|
||||
|
@ -3705,7 +3711,7 @@ var _ = SIGDescribe("Rollout v1beta1", func() {
|
|||
|
||||
// ------ delete rollout ------
|
||||
By("delete rollout and check deployment")
|
||||
k8sClient.Delete(context.TODO(), rollout)
|
||||
_ = k8sClient.Delete(context.TODO(), rollout)
|
||||
WaitRolloutNotFound(rollout.Name)
|
||||
Expect(GetObject(workload.Name, workload)).NotTo(HaveOccurred())
|
||||
// check workload annotation
|
||||
|
|
Loading…
Reference in New Issue