diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 075d150bb6..35e1e1f673 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,7 +12,7 @@ on: - "!deploy/iso/**" env: GOPROXY: https://proxy.golang.org - GO_VERSION: '1.18.1' + GO_VERSION: '1.18.2' permissions: contents: read @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -40,7 +40,7 @@ jobs: echo workspace $GITHUB_WORKSPACE echo "end of debug stuff" echo $(which jq) - - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: name: minikube_binaries path: out @@ -48,7 +48,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -67,7 +67,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index ad7960361f..0399df7fe4 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -6,7 +6,7 @@ on: - master env: GOPROXY: https://proxy.golang.org - GO_VERSION: '1.18.1' + GO_VERSION: '1.18.2' permissions: contents: read @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true diff --git a/.github/workflows/functional_verified.yml b/.github/workflows/functional_verified.yml index 70cfefc901..9e179dbdf3 100644 --- a/.github/workflows/functional_verified.yml +++ b/.github/workflows/functional_verified.yml @@ -22,7 +22,7 @@ on: - deleted env: GOPROXY: https://proxy.golang.org - GO_VERSION: '1.18.1' + GO_VERSION: '1.18.2' permissions: contents: read @@ -35,7 +35,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -47,7 +47,7 @@ jobs: sudo apt-get install -y libvirt-dev MINIKUBE_BUILD_IN_DOCKER=y make cross e2e-cross debs cp -r test/integration/testdata ./out - - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: name: minikube_binaries path: out @@ -94,7 +94,7 @@ jobs: - name: Install gopogh shell: bash run: | - curl -LO https://github.com/medyagh/gopogh/releases/download/v0.9.0/gopogh-linux-arm64 + curl -LO https://github.com/medyagh/gopogh/releases/download/v0.13.0/gopogh-linux-arm64 sudo install gopogh-linux-arm64 /usr/local/bin/gopogh - name: Docker Info @@ -115,8 +115,7 @@ jobs: echo "--------------------------" hostname || true echo "--------------------------" - # go 1.14.6+ is needed because of this bug https://github.com/golang/go/issues/39308 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -168,7 +167,7 @@ jobs: echo "${STAT}" >> $GITHUB_ENV echo 'EOF' >> $GITHUB_ENV - - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: name: functional_docker_ubuntu_arm64 path: minikube_binaries/report @@ -212,7 +211,7 @@ jobs: run: | mkdir -p all_reports cp -r ./functional_docker_ubuntu_arm64 ./all_reports/ - - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: name: all_reports path: all_reports diff --git a/.github/workflows/leaderboard.yml b/.github/workflows/leaderboard.yml index a18a3fd0c9..42d1c7eb70 100644 --- a/.github/workflows/leaderboard.yml +++ b/.github/workflows/leaderboard.yml @@ -7,7 +7,7 @@ on: release: types: [published] env: - GO_VERSION: '1.18.1' + GO_VERSION: '1.18.2' permissions: contents: read @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index 0ca6af5c87..ccb592bae4 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -14,7 +14,7 @@ on: - "!deploy/iso/**" env: GOPROXY: https://proxy.golang.org - GO_VERSION: '1.18.1' + GO_VERSION: '1.18.2' permissions: contents: read @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -44,7 +44,7 @@ jobs: echo workspace $GITHUB_WORKSPACE echo "end of debug stuff" echo $(which jq) - - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: name: minikube_binaries path: out @@ -52,7 +52,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -71,7 +71,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -119,8 +119,7 @@ jobs: echo "--------------------------" docker ps || true echo "--------------------------" - # go 1.14.6+ is needed because of this bug https://github.com/golang/go/issues/39308 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -128,7 +127,7 @@ jobs: shell: bash run: | - curl -LO https://github.com/medyagh/gopogh/releases/download/v0.9.0/gopogh-linux-amd64 + curl -LO https://github.com/medyagh/gopogh/releases/download/v0.13.0/gopogh-linux-amd64 sudo install gopogh-linux-amd64 /usr/local/bin/gopogh - name: Download Binaries uses: actions/download-artifact@fdafc3f9f2e2a522dc1d230e6a03de57a1e71c95 @@ -169,7 +168,7 @@ jobs: echo 'STAT<> $GITHUB_ENV echo "${STAT}" >> $GITHUB_ENV echo 'EOF' >> $GITHUB_ENV - - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: name: functional_docker_ubuntu path: minikube_binaries/report @@ -220,8 +219,7 @@ jobs: echo "--------------------------" docker ps || true echo "--------------------------" - # go 1.14.6+ is needed because of this bug https://github.com/golang/go/issues/39308 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -229,7 +227,7 @@ jobs: shell: bash run: | - curl -LO https://github.com/medyagh/gopogh/releases/download/v0.9.0/gopogh-linux-amd64 + curl -LO https://github.com/medyagh/gopogh/releases/download/v0.13.0/gopogh-linux-amd64 sudo install gopogh-linux-amd64 /usr/local/bin/gopogh - name: Download Binaries uses: actions/download-artifact@fdafc3f9f2e2a522dc1d230e6a03de57a1e71c95 @@ -270,7 +268,7 @@ jobs: echo 'STAT<> $GITHUB_ENV echo "${STAT}" >> $GITHUB_ENV echo 'EOF' >> $GITHUB_ENV - - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: name: functional_docker_containerd_ubuntu path: minikube_binaries/report @@ -325,15 +323,14 @@ jobs: echo "--------------------------" podman ps || true echo "--------------------------" - # go 1.14.6+ is needed because of this bug https://github.com/golang/go/issues/39308 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true - name: Install gopogh shell: bash run: | - curl -LO https://github.com/medyagh/gopogh/releases/download/v0.9.0/gopogh-linux-amd64 + curl -LO https://github.com/medyagh/gopogh/releases/download/v0.13.0/gopogh-linux-amd64 sudo install gopogh-linux-amd64 /usr/local/bin/gopogh - name: Download Binaries uses: actions/download-artifact@fdafc3f9f2e2a522dc1d230e6a03de57a1e71c95 @@ -374,7 +371,7 @@ jobs: echo 'STAT<> $GITHUB_ENV echo "${STAT}" >> $GITHUB_ENV echo 'EOF' >> $GITHUB_ENV - - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: name: functional_podman_ubuntu path: minikube_binaries/report @@ -412,8 +409,7 @@ jobs: curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/darwin/amd64/kubectl sudo install kubectl /usr/local/bin/kubectl kubectl version --client=true - # go 1.14.6+ is needed because of this bug https://github.com/golang/go/issues/39308 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -421,7 +417,7 @@ jobs: shell: bash run: | - curl -LO https://github.com/medyagh/gopogh/releases/download/v0.9.0/gopogh-darwin-amd64 + curl -LO https://github.com/medyagh/gopogh/releases/download/v0.13.0/gopogh-darwin-amd64 sudo install gopogh-darwin-amd64 /usr/local/bin/gopogh - name: Install docker shell: bash @@ -475,7 +471,7 @@ jobs: echo 'STAT<> $GITHUB_ENV echo "${STAT}" >> $GITHUB_ENV echo 'EOF' >> $GITHUB_ENV - - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: name: functional_virtualbox_macos path: minikube_binaries/report @@ -523,8 +519,7 @@ jobs: VERSION="v1.17.0" curl -L https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-${VERSION}-linux-amd64.tar.gz --output crictl-${VERSION}-linux-amd64.tar.gz sudo tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin - # go 1.14.6+ is needed because of this bug https://github.com/golang/go/issues/39308 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -532,7 +527,7 @@ jobs: shell: bash run: | - curl -LO https://github.com/medyagh/gopogh/releases/download/v0.9.0/gopogh-linux-amd64 + curl -LO https://github.com/medyagh/gopogh/releases/download/v0.13.0/gopogh-linux-amd64 sudo install gopogh-linux-amd64 /usr/local/bin/gopogh - name: Download Binaries uses: actions/download-artifact@fdafc3f9f2e2a522dc1d230e6a03de57a1e71c95 @@ -571,7 +566,7 @@ jobs: echo 'STAT<> $GITHUB_ENV echo "${STAT}" >> $GITHUB_ENV echo 'EOF' >> $GITHUB_ENV - - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: name: none_ubuntu18_04 path: minikube_binaries/report @@ -621,7 +616,7 @@ jobs: cp -r ./functional_virtualbox_macos ./all_reports/ cp -r ./functional_baremetal_ubuntu18_04 ./all_reports/ - - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: name: all_reports path: all_reports diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 023cacce10..9c3a3610e9 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -12,7 +12,7 @@ on: - "!deploy/iso/**" env: GOPROXY: https://proxy.golang.org - GO_VERSION: '1.18.1' + GO_VERSION: '1.18.2' permissions: contents: read @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -42,7 +42,7 @@ jobs: echo workspace $GITHUB_WORKSPACE echo "end of debug stuff" echo $(which jq) - - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: name: minikube_binaries path: out @@ -50,7 +50,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -69,7 +69,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -117,15 +117,14 @@ jobs: echo "--------------------------" docker ps || true echo "--------------------------" - # go 1.14.6+ is needed because of this bug https://github.com/golang/go/issues/39308 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true - name: Install gopogh shell: bash run: | - curl -LO https://github.com/medyagh/gopogh/releases/download/v0.9.0/gopogh-linux-amd64 + curl -LO https://github.com/medyagh/gopogh/releases/download/v0.13.0/gopogh-linux-amd64 sudo install gopogh-linux-amd64 /usr/local/bin/gopogh - name: Download Binaries uses: actions/download-artifact@fdafc3f9f2e2a522dc1d230e6a03de57a1e71c95 @@ -167,7 +166,7 @@ jobs: echo 'STAT<> $GITHUB_ENV echo "${STAT}" >> $GITHUB_ENV echo 'EOF' >> $GITHUB_ENV - - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: name: functional_docker_ubuntu path: minikube_binaries/report @@ -218,8 +217,7 @@ jobs: echo "--------------------------" docker ps || true echo "--------------------------" - # go 1.14.6+ is needed because of this bug https://github.com/golang/go/issues/39308 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -227,7 +225,7 @@ jobs: shell: bash run: | - curl -LO https://github.com/medyagh/gopogh/releases/download/v0.9.0/gopogh-linux-amd64 + curl -LO https://github.com/medyagh/gopogh/releases/download/v0.13.0/gopogh-linux-amd64 sudo install gopogh-linux-amd64 /usr/local/bin/gopogh - name: Download Binaries uses: actions/download-artifact@fdafc3f9f2e2a522dc1d230e6a03de57a1e71c95 @@ -269,7 +267,7 @@ jobs: echo 'STAT<> $GITHUB_ENV echo "${STAT}" >> $GITHUB_ENV echo 'EOF' >> $GITHUB_ENV - - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: name: functional_docker_containerd_ubuntu path: minikube_binaries/report @@ -324,15 +322,14 @@ jobs: echo "--------------------------" podman ps || true echo "--------------------------" - # go 1.14.6+ is needed because of this bug https://github.com/golang/go/issues/39308 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true - name: Install gopogh shell: bash run: | - curl -LO https://github.com/medyagh/gopogh/releases/download/v0.9.0/gopogh-linux-amd64 + curl -LO https://github.com/medyagh/gopogh/releases/download/v0.13.0/gopogh-linux-amd64 sudo install gopogh-linux-amd64 /usr/local/bin/gopogh - name: Download Binaries uses: actions/download-artifact@fdafc3f9f2e2a522dc1d230e6a03de57a1e71c95 @@ -374,7 +371,7 @@ jobs: echo 'STAT<> $GITHUB_ENV echo "${STAT}" >> $GITHUB_ENV echo 'EOF' >> $GITHUB_ENV - - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: name: functional_podman_ubuntu path: minikube_binaries/report @@ -412,8 +409,7 @@ jobs: curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/darwin/amd64/kubectl sudo install kubectl /usr/local/bin/kubectl kubectl version --client=true - # go 1.14.6+ is needed because of this bug https://github.com/golang/go/issues/39308 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -421,7 +417,7 @@ jobs: shell: bash run: | - curl -LO https://github.com/medyagh/gopogh/releases/download/v0.9.0/gopogh-darwin-amd64 + curl -LO https://github.com/medyagh/gopogh/releases/download/v0.13.0/gopogh-darwin-amd64 sudo install gopogh-darwin-amd64 /usr/local/bin/gopogh - name: Install docker shell: bash @@ -476,7 +472,7 @@ jobs: echo 'STAT<> $GITHUB_ENV echo "${STAT}" >> $GITHUB_ENV echo 'EOF' >> $GITHUB_ENV - - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: name: functional_virtualbox_macos path: minikube_binaries/report @@ -524,8 +520,7 @@ jobs: VERSION="v1.17.0" curl -L https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-${VERSION}-linux-amd64.tar.gz --output crictl-${VERSION}-linux-amd64.tar.gz sudo tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin - # go 1.14.6+ is needed because of this bug https://github.com/golang/go/issues/39308 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -533,7 +528,7 @@ jobs: shell: bash run: | - curl -LO https://github.com/medyagh/gopogh/releases/download/v0.9.0/gopogh-linux-amd64 + curl -LO https://github.com/medyagh/gopogh/releases/download/v0.13.0/gopogh-linux-amd64 sudo install gopogh-linux-amd64 /usr/local/bin/gopogh - name: Download Binaries uses: actions/download-artifact@fdafc3f9f2e2a522dc1d230e6a03de57a1e71c95 @@ -573,7 +568,7 @@ jobs: echo 'STAT<> $GITHUB_ENV echo "${STAT}" >> $GITHUB_ENV echo 'EOF' >> $GITHUB_ENV - - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: name: none_ubuntu18_04 path: minikube_binaries/report @@ -623,7 +618,7 @@ jobs: cp -r ./functional_virtualbox_macos ./all_reports/ cp -r ./functional_baremetal_ubuntu18_04 ./all_reports/ - - uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 + - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 with: name: all_reports path: all_reports diff --git a/.github/workflows/sync-minikube.yml b/.github/workflows/sync-minikube.yml index 3c7bb46649..79acd2022f 100644 --- a/.github/workflows/sync-minikube.yml +++ b/.github/workflows/sync-minikube.yml @@ -22,7 +22,7 @@ jobs: path: ./image-syncer - name: Set up Go - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: 1.17 diff --git a/.github/workflows/time-to-k8s-public-chart.yml b/.github/workflows/time-to-k8s-public-chart.yml index 7cb7762df4..18b765daf2 100644 --- a/.github/workflows/time-to-k8s-public-chart.yml +++ b/.github/workflows/time-to-k8s-public-chart.yml @@ -6,7 +6,7 @@ on: - cron: "0 2,14 * * *" env: GOPROXY: https://proxy.golang.org - GO_VERSION: '1.18.1' + GO_VERSION: '1.18.2' permissions: contents: read @@ -20,7 +20,7 @@ jobs: AWS_DEFAULT_REGION: 'us-west-1' steps: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -45,7 +45,7 @@ jobs: curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/darwin/amd64/kubectl sudo install kubectl /usr/local/bin/kubectl kubectl version --client=true - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true diff --git a/.github/workflows/time-to-k8s.yml b/.github/workflows/time-to-k8s.yml index d7d4ea3f76..41d4c6e37e 100644 --- a/.github/workflows/time-to-k8s.yml +++ b/.github/workflows/time-to-k8s.yml @@ -5,7 +5,7 @@ on: types: [released] env: GOPROXY: https://proxy.golang.org - GO_VERSION: '1.18.1' + GO_VERSION: '1.18.2' permissions: contents: read @@ -16,7 +16,7 @@ jobs: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - name: Checkout submodules run: git submodule update --init - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true diff --git a/.github/workflows/translations.yml b/.github/workflows/translations.yml index 1681e0f6e8..674cacd1cb 100644 --- a/.github/workflows/translations.yml +++ b/.github/workflows/translations.yml @@ -6,7 +6,7 @@ on: - "translations/**" env: GOPROXY: https://proxy.golang.org - GO_VERSION: '1.18.1' + GO_VERSION: '1.18.2' permissions: contents: read @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true diff --git a/.github/workflows/twitter-bot.yml b/.github/workflows/twitter-bot.yml index 8bad19d64f..10ad3f1a60 100644 --- a/.github/workflows/twitter-bot.yml +++ b/.github/workflows/twitter-bot.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: ethomson/send-tweet-action@288f9339e0412e3038dce350e0da5ecdf12133a6 with: - status: "minikube ${GITHUB_REF_NAME} was just released! Check it out: https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md" + status: "minikube ${{github.ref_name}} was just released! Check it out: https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md" consumer-key: ${{ secrets.TWITTER_API_KEY }} consumer-secret: ${{ secrets.TWITTER_API_SECRET }} access-token: ${{ secrets.TWITTER_ACCESS_TOKEN }} diff --git a/.github/workflows/update-golang-version.yml b/.github/workflows/update-golang-version.yml index 4888d97520..aa97fee86b 100644 --- a/.github/workflows/update-golang-version.yml +++ b/.github/workflows/update-golang-version.yml @@ -6,7 +6,7 @@ on: - cron: "0 9 * * 1" env: GOPROXY: https://proxy.golang.org - GO_VERSION: '1.18.1' + GO_VERSION: '1.18.2' permissions: contents: read @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -41,8 +41,4 @@ jobs: body: | Kubernetes Project just updated the [golang version](https://github.com/kubernetes/kubernetes/blob/master/build/build-image/cross/VERSION), updating minikube golang to match Kubernetes. - This PR was auto-generated by `make update-golang-version` using [update-golang-versions.yml](https://github.com/kubernetes/minikube/tree/master/.github/workflows/update-golang-version.yml) CI Workflow. - - - - + This PR was auto-generated by `make update-golang-version` using [update-golang-version.yml](https://github.com/kubernetes/minikube/tree/master/.github/workflows/update-golang-version.yml) CI Workflow. diff --git a/.github/workflows/update-golint-version.yml b/.github/workflows/update-golint-version.yml index 3f444a3a81..35a5a24871 100644 --- a/.github/workflows/update-golint-version.yml +++ b/.github/workflows/update-golint-version.yml @@ -6,7 +6,7 @@ on: - cron: "0 10 * * 1" env: GOPROXY: https://proxy.golang.org - GO_VERSION: '1.18.1' + GO_VERSION: '1.18.2' permissions: contents: read @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true diff --git a/.github/workflows/update-gopogh-version.yml b/.github/workflows/update-gopogh-version.yml new file mode 100644 index 0000000000..0631568152 --- /dev/null +++ b/.github/workflows/update-gopogh-version.yml @@ -0,0 +1,44 @@ +name: "update-gopogh-versions" +on: + workflow_dispatch: + schedule: + # every Monday at around 2 am pacific/9 am UTC + - cron: "0 9 * * 1" +env: + GOPROXY: https://proxy.golang.org + GO_VERSION: '1.18.2' +permissions: + contents: read + +jobs: + bump-gopogh-version: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 + with: + go-version: ${{env.GO_VERSION}} + stable: true + - name: Bump gopogh Versions + id: bumpGopogh + run: | + make update-gopogh-version + echo "::set-output name=changes::$(git status --porcelain)" + - name: Create PR + if: ${{ steps.bumpGopogh.outputs.changes != '' }} + uses: peter-evans/create-pull-request@f094b77505fb89581e68a1163fbd2fffece39da1 + with: + token: ${{ secrets.MINIKUBE_BOT_PAT }} + commit-message: bump gopogh versions + committer: minikube-bot + author: minikube-bot + branch: auto_bump_gopogh_version + push-to-fork: minikube-bot/minikube + base: master + delete-branch: true + title: 'bump gopogh version' + labels: ok-to-test + body: | + Gopogh Project released a [new version](https://github.com/medyagh/gopogh/releases), + + This PR was auto-generated by `make update-gopogh-version` using [update-gopogh-version.yml](https://github.com/kubernetes/minikube/tree/master/.github/workflows/update-gopogh-version.yml) CI Workflow. diff --git a/.github/workflows/update-gotestsum-version.yml b/.github/workflows/update-gotestsum-version.yml new file mode 100644 index 0000000000..00b0adda43 --- /dev/null +++ b/.github/workflows/update-gotestsum-version.yml @@ -0,0 +1,44 @@ +name: "update-gotestsum-version" +on: + workflow_dispatch: + schedule: + # every Monday at around 3 am pacific/10 am UTC + - cron: "0 10 * * 1" +env: + GOPROXY: https://proxy.golang.org + GO_VERSION: '1.18.2' +permissions: + contents: read + +jobs: + bump-gotestsum-version: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 + with: + go-version: ${{env.GO_VERSION}} + stable: true + - name: Bump Gotestsum Versions + id: bumpGotestsum + run: | + make update-gotestsum-version + echo "::set-output name=changes::$(git status --porcelain)" + - name: Create PR + if: ${{ steps.bumpGotestsum.outputs.changes != '' }} + uses: peter-evans/create-pull-request@f094b77505fb89581e68a1163fbd2fffece39da1 + with: + token: ${{ secrets.MINIKUBE_BOT_PAT }} + commit-message: bump gotestsum versions + committer: minikube-bot + author: minikube-bot + branch: auto_bump_gotestsum_version + push-to-fork: minikube-bot/minikube + base: master + delete-branch: true + title: 'bump gotestsum version' + labels: ok-to-test + body: | + Gotestsum Project release a [new version](https://github.com/gotestyourself/gotestsum/releases), + + This PR was auto-generated by `make update-gotestsum-version` using [update-gotestsum-version.yml](https://github.com/kubernetes/minikube/tree/master/.github/workflows/update-gotestsum-version.yml) CI Workflow. diff --git a/.github/workflows/update-k8s-versions.yml b/.github/workflows/update-k8s-versions.yml index e11daf7715..944351aa6a 100644 --- a/.github/workflows/update-k8s-versions.yml +++ b/.github/workflows/update-k8s-versions.yml @@ -6,7 +6,7 @@ on: - cron: "0 8 * * 1" env: GOPROXY: https://proxy.golang.org - GO_VERSION: '1.18.1' + GO_VERSION: '1.18.2' permissions: contents: read @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} - name: Bump Kubernetes Versions @@ -43,7 +43,7 @@ jobs: title: "${{ steps.bumpk8s.outputs.title }}" labels: ok-to-test body: | - This PR was auto-generated by `make update-kubernetes-version` using [update-k8s-versions.yml](https://github.com/kubernetes/minikube/tree/master/.github/workflows) CI Workflow. + This PR was auto-generated by `make update-kubernetes-version` using [update-k8s-versions.yml](https://github.com/kubernetes/minikube/tree/master/.github/workflows/update-k8s-versions.yml) CI Workflow. Please only merge if all the tests pass. ``` diff --git a/.github/workflows/update-kubadm-constants.yml b/.github/workflows/update-kubadm-constants.yml index 6f35be86f7..d1b60c8bf6 100644 --- a/.github/workflows/update-kubadm-constants.yml +++ b/.github/workflows/update-kubadm-constants.yml @@ -6,7 +6,7 @@ on: - cron: "0 6 * * 1" env: GOPROXY: https://proxy.golang.org - GO_VERSION: '1.18.1' + GO_VERSION: '1.18.2' permissions: contents: read @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@629c2de402a417ea7690ca6ce3f33229e27606a5 - - uses: actions/setup-go@f6164bd8c8acb4a71fb2791a8b6c4024ff038dab + - uses: actions/setup-go@fcdc43634adb5f7ae75a9d7a9b9361790f7293e2 with: go-version: ${{env.GO_VERSION}} stable: true @@ -42,10 +42,9 @@ jobs: title: 'Bump kubeadm constants for kubernetes images' labels: ok-to-test body: | - This PR was auto-generated by `make update-kubeadm-constants` using [update-kubeadm-constants.yml](https://github.com/kubernetes/minikube/tree/master/.github/workflows) CI Workflow. + This PR was auto-generated by `make update-kubeadm-constants` using [update-kubeadm-constants.yml](https://github.com/kubernetes/minikube/tree/master/.github/workflows/update-kubeadm-constants.yml) CI Workflow. Please only merge if all the tests pass. ``` ${{ steps.bumpKubAdmConsts.outputs.changes }} ``` - diff --git a/CHANGELOG.md b/CHANGELOG.md index 5da3c19ab1..a400053194 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,136 @@ # Release Notes +## Version 1.26.0-beta.1 - 2022-05-17 + +QEMU driver enhancements: +* fix qemu firmware path locations [#14182](https://github.com/kubernetes/minikube/pull/14182) +* re-establish apiserver tunnel on restart [#14183](https://github.com/kubernetes/minikube/pull/14183) + +Features: +* Add configure option to registry-aliases addon [#13912](https://github.com/kubernetes/minikube/pull/13912) + +For a more detailed changelog, including changes occuring in pre-release versions, see [CHANGELOG.md](https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md). + +Thank you to our contributors for this release! + +- Jack Zhang +- Pablo Caderno +- Sharif Elgamal +- Steven Powell +- Yuki Okushi +- loftkun + +Thank you to our PR reviewers for this release! + +- spowelljr (20 comments) +- afbjorklund (1 comments) +- sharifelgamal (1 comments) + +Thank you to our triage members for this release! + +- afbjorklund (4 comments) +- spowelljr (4 comments) +- Al4DIN (1 comments) +- Gimb0 (1 comments) +- Neandril (1 comments) + +## Version 1.26.0-beta.0 - 2022-05-13 + +Featues: +* Add support for the QEMU driver [#13639](https://github.com/kubernetes/minikube/pull/13639) +* Add support for building aarch64 ISO [#13762](https://github.com/kubernetes/minikube/pull/13762) +* Support rootless Podman driver (Usage: `minikube config set rootless true`) [#13829](https://github.com/kubernetes/minikube/pull/13829) + +Minor Improvements: +* Add JSON output to `minikube delete` [#13979](https://github.com/kubernetes/minikube/pull/13979) +* Add `--audit` flag to `minikube logs` command [#13991](https://github.com/kubernetes/minikube/pull/13991) +* Add `--disable-metrics` flag [#13802](https://github.com/kubernetes/minikube/pull/13802) +* Get latest valid tag for each image during caching [#14006](https://github.com/kubernetes/minikube/pull/14006) +* Remove docker requirement for none driver [#13885](https://github.com/kubernetes/minikube/pull/13885) +* Add 'subnet' flag for docker/podman driver [#13730](https://github.com/kubernetes/minikube/pull/13730) +* Don't write logs that contain environment variables [#13877](https://github.com/kubernetes/minikube/pull/13877) +* Implemented minimum and recommended Docker versions [#13842](https://github.com/kubernetes/minikube/pull/13842) + +Bug Fixes: +* Fix "Your cgroup does not allow setting memory" [#14115](https://github.com/kubernetes/minikube/pull/14115) +* Fix nvidia-gpu with kvm-driver [#13972](https://github.com/kubernetes/minikube/pull/13972) +* Fix `minikube delete` for Podman v4 [#13881](https://github.com/kubernetes/minikube/pull/13881) +* Fix pre command flags [#13995](https://github.com/kubernetes/minikube/pull/13995) +* Fix logging when JSON output selected [#13955](https://github.com/kubernetes/minikube/pull/13955) +* Fix port validation error on specifying tcp/udp or range of ports. [#13812](https://github.com/kubernetes/minikube/pull/13812) +* Fix not downloading kic for offline mode [#13910](https://github.com/kubernetes/minikube/pull/13910) +* Fix trying to pause multiple containers with runc [#13783](https://github.com/kubernetes/minikube/pull/13783) +* Fix `minikube servce` docker/port-forward issues [#13756](https://github.com/kubernetes/minikube/pull/13756) + +Version Upgrades: +* Upgrade Kubernetes default: v1.23.6 and latest: v1.23.6 [#14144](https://github.com/kubernetes/minikube/pull/14144) +* ISO/KIC: Upgrade buildkit from 0.9.0 to 0.10.3 [#13791](https://github.com/kubernetes/minikube/pull/13791) +* ISO: Upgrade Docker from 20.10.12 to 20.10.14 [#13860](https://github.com/kubernetes/minikube/pull/13860) +* ISO: Upgrade crio from 1.22.1 to 1.22.3 [#13800](https://github.com/kubernetes/minikube/pull/13800) +* ISO: Upgrade buildroot from 2021.02.4 to 2021.02.12 [#13814](https://github.com/kubernetes/minikube/pull/13814) +* Upgrade nginx image from 1.1.1 to 1.2.0 [#14028](https://github.com/kubernetes/minikube/pull/14028) +* ISO: Upgrade falco-module from 0.24.0 to 0.31.1 [#13659](https://github.com/kubernetes/minikube/pull/13659) +* Upgrade kubernetes dashboard from 2.3.1 to 2.5.1 [#13741](https://github.com/kubernetes/minikube/pull/13741) +* KIC: Upgrade kicbase base image from 20210401 to 20220316 [#13815](https://github.com/kubernetes/minikube/pull/13815) +* ISO: Upgrade Podman from 2.2.1 to 3.4.2 [#13126](https://github.com/kubernetes/minikube/pull/13126) +* ISO: Add packaging for crun [#11679](https://github.com/kubernetes/minikube/pull/11679) + +For a more detailed changelog, including changes occuring in pre-release versions, see [CHANGELOG.md](https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md). + +Thank you to our contributors for this release! + +- Akihiro Suda +- Akira Yoshiyama +- Anders F Björklund +- Ashwin Somasundara +- Carlos Eduardo Arango Gutierrez +- Daniel Petri +- F1ko +- Filip Nikolic +- Ileriayo Adebiyi +- Jeff MAURY +- Jin Zhang +- Medya Ghazizadeh +- Nikhil2001 +- Pablo Caderno +- Piotr Resztak +- Predrag Rogic +- Sean Wei +- Sharif Elgamal +- Steven Powell +- Tomohito YABU +- Toshiaki Inukai +- betaboon +- ckannon +- edwinwalela +- klaases +- naveensrinivasan +- staticdev +- ziyi-xie + +Thank you to our PR reviewers for this release! + +- spowelljr (55 comments) +- medyagh (39 comments) +- afbjorklund (14 comments) +- klaases (14 comments) +- jesperpedersen (9 comments) +- sharifelgamal (6 comments) +- atoato88 (3 comments) +- jepio (3 comments) +- mprimeaux (2 comments) +- shu-mutou (2 comments) +- t-inu (2 comments) +- AkihiroSuda (1 comments) + +Thank you to our triage members for this release! + +- afbjorklund (52 comments) +- klaases (39 comments) +- RA489 (28 comments) +- spowelljr (24 comments) +- zhan9san (24 comments) + ## Version 1.25.2 - 2022-02-23 Features: @@ -81,7 +212,7 @@ Thank you to our triage members for this release! - klaases (13 comments) - sharifelgamal (12 comments) -Check out our [contributions leaderboard](https://minikube.sigs.k8s.io/docs/contrib/leaderboard/v1.25.1/) for this release! +Check out our [contributions leaderboard](https://minikube.sigs.k8s.io/docs/contrib/leaderboard/v1.25.2/) for this release! ## Version 1.25.1 - 2022-01-20 diff --git a/Makefile b/Makefile index 9d68ffffaa..0605610288 100644 --- a/Makefile +++ b/Makefile @@ -14,8 +14,8 @@ # Bump these on release - and please check ISO_VERSION for correctness. VERSION_MAJOR ?= 1 -VERSION_MINOR ?= 25 -VERSION_BUILD ?= 2 +VERSION_MINOR ?= 26 +VERSION_BUILD ?= 0-beta.1 RAW_VERSION=$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_BUILD) VERSION ?= v$(RAW_VERSION) @@ -23,7 +23,7 @@ KUBERNETES_VERSION ?= $(shell egrep "DefaultKubernetesVersion =" pkg/minikube/co KIC_VERSION ?= $(shell egrep "Version =" pkg/drivers/kic/types.go | cut -d \" -f2) # Default to .0 for higher cache hit rates, as build increments typically don't require new ISO versions -ISO_VERSION ?= v1.26.0-1652914268-13807 +ISO_VERSION ?= v1.26.0-1652998508-14153 # Dashes are valid in semver, but not Linux packaging. Use ~ to delimit alpha/beta DEB_VERSION ?= $(subst -,~,$(RAW_VERSION)) DEB_REVISION ?= 0 @@ -33,9 +33,9 @@ RPM_REVISION ?= 0 # used by hack/jenkins/release_build_and_upload.sh and KVM_BUILD_IMAGE, see also BUILD_IMAGE below # update this only by running `make update-golang-version` -GO_VERSION ?= 1.18.1 +GO_VERSION ?= 1.18.2 # update this only by running `make update-golang-version` -GO_K8S_VERSION_PREFIX ?= v1.24.0 +GO_K8S_VERSION_PREFIX ?= v1.25.0 # replace "x.y.0" => "x.y". kube-cross and golang.org/dl use different formats for x.y.0 go versions KVM_GO_VERSION ?= $(GO_VERSION:.0=) @@ -76,7 +76,7 @@ MINIKUBE_RELEASES_URL=https://github.com/kubernetes/minikube/releases/download KERNEL_VERSION ?= 4.19.235 # latest from https://github.com/golangci/golangci-lint/releases # update this only by running `make update-golint-version` -GOLINT_VERSION ?= v1.45.2 +GOLINT_VERSION ?= v1.46.2 # Limit number of default jobs, to avoid the CI builds running out of memory GOLINT_JOBS ?= 4 # see https://github.com/golangci/golangci-lint#memory-usage-of-golangci-lint @@ -527,7 +527,8 @@ mdlint: .PHONY: verify-iso verify-iso: # Make sure the current ISO exists in the expected bucket - gsutil stat gs://$(ISO_BUCKET)/minikube-$(ISO_VERSION).iso + gsutil stat gs://$(ISO_BUCKET)/minikube-$(ISO_VERSION)-amd64.iso + gsutil stat gs://$(ISO_BUCKET)/minikube-$(ISO_VERSION)-arm64.iso out/docs/minikube.md: $(shell find "cmd") $(shell find "pkg/minikube/constants") go run -ldflags="$(MINIKUBE_LDFLAGS)" -tags gendocs hack/help_text/gen_help_text.go @@ -701,6 +702,11 @@ KICBASE_IMAGE_GCR ?= $(REGISTRY)/kicbase:$(KIC_VERSION) KICBASE_IMAGE_HUB ?= kicbase/stable:$(KIC_VERSION) KICBASE_IMAGE_REGISTRIES ?= $(KICBASE_IMAGE_GCR) $(KICBASE_IMAGE_HUB) +CRI_DOCKERD_VERSION ?= $(shell egrep "CRI_DOCKERD_VERSION=" deploy/kicbase/Dockerfile | cut -d \" -f2) +.PHONY: update-cri-dockerd +update-cri-dockerd: + hack/update/cri_dockerd/update_cri_dockerd.sh $(CRI_DOCKERD_VERSION) $(KICBASE_ARCH) + .PHONY: local-kicbase local-kicbase: ## Builds the kicbase image and tags it local/kicbase:latest and local/kicbase:$(KIC_VERSION)-$(COMMIT_SHORT) docker build -f ./deploy/kicbase/Dockerfile -t local/kicbase:$(KIC_VERSION) --build-arg COMMIT_SHA=${VERSION}-$(COMMIT) --cache-from $(KICBASE_IMAGE_GCR) . @@ -1038,3 +1044,8 @@ time-to-k8s-benchmark: update-gopogh-version: ## update gopogh version (cd hack/update/gopogh_version && \ go run update_gopogh_version.go) + +.PHONY: update-gotestsum-version +update-gotestsum-version: + (cd hack/update/gotestsum_version && \ + go run update_gotestsum_version.go) diff --git a/cmd/minikube/cmd/config/configure.go b/cmd/minikube/cmd/config/configure.go index baa1237dfc..c0d77e9cf7 100644 --- a/cmd/minikube/cmd/config/configure.go +++ b/cmd/minikube/cmd/config/configure.go @@ -23,6 +23,7 @@ import ( "github.com/spf13/cobra" "k8s.io/minikube/pkg/addons" + "k8s.io/minikube/pkg/minikube/assets" "k8s.io/minikube/pkg/minikube/config" "k8s.io/minikube/pkg/minikube/exit" "k8s.io/minikube/pkg/minikube/mustload" @@ -234,6 +235,26 @@ var addonsConfigureCmd = &cobra.Command{ if err := config.SaveProfile(profile, cfg); err != nil { out.ErrT(style.Fatal, "Failed to save config {{.profile}}", out.V{"profile": profile}) } + case "registry-aliases": + profile := ClusterFlagValue() + _, cfg := mustload.Partial(profile) + validator := func(s string) bool { + format := regexp.MustCompile(`^([a-zA-Z0-9-_]+\.[a-zA-Z0-9-_]+)+(\ [a-zA-Z0-9-_]+\.[a-zA-Z0-9-_]+)*$`) + return format.MatchString(s) + } + registryAliases := AskForStaticValidatedValue("-- Enter registry aliases separated by space: ", validator) + cfg.KubernetesConfig.RegistryAliases = registryAliases + + if err := config.SaveProfile(profile, cfg); err != nil { + out.ErrT(style.Fatal, "Failed to save config {{.profile}}", out.V{"profile": profile}) + } + addon := assets.Addons["registry-aliases"] + if addon.IsEnabled(cfg) { + // Re-enable registry-aliases addon in order to generate template manifest files with custom hosts + if err := addons.EnableOrDisableAddon(cfg, "registry-aliases", "true"); err != nil { + out.ErrT(style.Fatal, "Failed to configure registry-aliases {{.profile}}", out.V{"profile": profile}) + } + } default: out.FailureT("{{.name}} has no available configuration options", out.V{"name": addon}) diff --git a/cmd/minikube/cmd/service.go b/cmd/minikube/cmd/service.go index d6b48f3d19..bc1b7198ae 100644 --- a/cmd/minikube/cmd/service.go +++ b/cmd/minikube/cmd/service.go @@ -109,7 +109,7 @@ var serviceCmd = &cobra.Command{ services = newServices } - if services == nil || len(services) == 0 { + if len(services) == 0 { exit.Message(reason.SvcNotFound, `Service '{{.service}}' was not found in '{{.namespace}}' namespace. You may select another namespace by using 'minikube service {{.service}} -n '. Or list out all the services using 'minikube service list'`, out.V{"service": args[0], "namespace": namespace}) } diff --git a/deploy/addons/registry-aliases/registry-aliases-config.tmpl b/deploy/addons/registry-aliases/registry-aliases-config.tmpl index 61dcb76472..e43a218471 100644 --- a/deploy/addons/registry-aliases/registry-aliases-config.tmpl +++ b/deploy/addons/registry-aliases/registry-aliases-config.tmpl @@ -9,11 +9,14 @@ metadata: data: # Add additional hosts separated by new-line registryAliases: >- + {{- if .RegistryAliases}} + {{ .RegistryAliases}} + {{- else}} example.org example.com test.com test.org + {{- end}} registry.minikube # default registry address in minikube when enabled via minikube addons enable registry - registrySvc: registry.kube-system.svc.cluster.local - + registrySvc: registry.kube-system.svc.cluster.local \ No newline at end of file diff --git a/deploy/addons/storage-provisioner-gluster/storage-provisioner-glusterfile.yaml.tmpl b/deploy/addons/storage-provisioner-gluster/storage-provisioner-glusterfile.yaml.tmpl index 11048d25b9..7c5f45adaf 100644 --- a/deploy/addons/storage-provisioner-gluster/storage-provisioner-glusterfile.yaml.tmpl +++ b/deploy/addons/storage-provisioner-gluster/storage-provisioner-glusterfile.yaml.tmpl @@ -1,6 +1,6 @@ --- kind: StorageClass -apiVersion: storage.k8s.io/v1beta1 +apiVersion: storage.k8s.io/v1 metadata: name: glusterfile labels: diff --git a/deploy/iso/minikube-iso/arch/aarch64/package/containerd-bin-aarch64/containerd-bin.hash b/deploy/iso/minikube-iso/arch/aarch64/package/containerd-bin-aarch64/containerd-bin.hash index 50fff143ab..cf10f80480 100644 --- a/deploy/iso/minikube-iso/arch/aarch64/package/containerd-bin-aarch64/containerd-bin.hash +++ b/deploy/iso/minikube-iso/arch/aarch64/package/containerd-bin-aarch64/containerd-bin.hash @@ -14,3 +14,4 @@ sha256 3bb9f54be022067847f5930d21ebbfe4e7a67f589d78930aa0ac713492c28bcc v1.4.9.t sha256 85a531725f15e2d136131119d42af4507a5389e0947015152075c4c93816fb5c v1.4.12.tar.gz sha256 7507913ba169c103ab67bc51bec31cd977d4348d7bc842da32b7eab5f930a14b v1.5.10.tar.gz sha256 02b79d5e2b07b5e64cd28f1fe84395ee11eef95fc49fd923a9ab93022b148be6 v1.5.11.tar.gz +sha256 f422e21e35705d1e741c1f3280813e43f811eaff4dcc5cdafac8b8952b15f468 v1.6.4.tar.gz diff --git a/deploy/iso/minikube-iso/arch/aarch64/package/containerd-bin-aarch64/containerd-bin.mk b/deploy/iso/minikube-iso/arch/aarch64/package/containerd-bin-aarch64/containerd-bin.mk index 2862773751..5bc21069cd 100644 --- a/deploy/iso/minikube-iso/arch/aarch64/package/containerd-bin-aarch64/containerd-bin.mk +++ b/deploy/iso/minikube-iso/arch/aarch64/package/containerd-bin-aarch64/containerd-bin.mk @@ -3,8 +3,8 @@ # containerd # ################################################################################ -CONTAINERD_BIN_AARCH64_VERSION = v1.5.11 -CONTAINERD_BIN_AARCH64_COMMIT = 3df54a852345ae127d1fa3092b95168e4a88e2f8 +CONTAINERD_BIN_AARCH64_VERSION = v1.6.4 +CONTAINERD_BIN_AARCH64_COMMIT = 212e8b6fa2f44b9c21b2798135fc6fb7c53efc16 CONTAINERD_BIN_AARCH64_SITE = https://github.com/containerd/containerd/archive CONTAINERD_BIN_AARCH64_SOURCE = $(CONTAINERD_BIN_AARCH64_VERSION).tar.gz CONTAINERD_BIN_AARCH64_DEPENDENCIES = host-go libgpgme diff --git a/deploy/iso/minikube-iso/arch/aarch64/package/docker-bin-aarch64/docker-bin.hash b/deploy/iso/minikube-iso/arch/aarch64/package/docker-bin-aarch64/docker-bin.hash index 84b6060930..f0bc48bec2 100644 --- a/deploy/iso/minikube-iso/arch/aarch64/package/docker-bin-aarch64/docker-bin.hash +++ b/deploy/iso/minikube-iso/arch/aarch64/package/docker-bin-aarch64/docker-bin.hash @@ -1 +1,3 @@ sha256 ea971edc1179088bfd25edd04a0c12848143d15cb8202ebb93a6a08973464fd0 docker-20.10.14.tgz +sha256 46102273fab8d6b8a7cf248a928ebaa4bee43114001c593b0d07092a34a439e1 docker-20.10.15.tgz +sha256 2f35d8d422b63a59279084c159c9092b63b6d974a7fcd868167aee4cc5f79f3b docker-20.10.16.tgz diff --git a/deploy/iso/minikube-iso/arch/aarch64/package/docker-bin-aarch64/docker-bin.mk b/deploy/iso/minikube-iso/arch/aarch64/package/docker-bin-aarch64/docker-bin.mk index ab53ee5055..899fc5a49b 100644 --- a/deploy/iso/minikube-iso/arch/aarch64/package/docker-bin-aarch64/docker-bin.mk +++ b/deploy/iso/minikube-iso/arch/aarch64/package/docker-bin-aarch64/docker-bin.mk @@ -4,7 +4,7 @@ # ################################################################################ -DOCKER_BIN_AARCH64_VERSION = 20.10.14 +DOCKER_BIN_AARCH64_VERSION = 20.10.16 DOCKER_BIN_AARCH64_SITE = https://download.docker.com/linux/static/stable/aarch64 DOCKER_BIN_AARCH64_SOURCE = docker-$(DOCKER_BIN_AARCH64_VERSION).tgz diff --git a/deploy/iso/minikube-iso/arch/aarch64/package/runc-master-aarch64/runc-master.hash b/deploy/iso/minikube-iso/arch/aarch64/package/runc-master-aarch64/runc-master.hash index 4d904c3782..fe79ecbc65 100644 --- a/deploy/iso/minikube-iso/arch/aarch64/package/runc-master-aarch64/runc-master.hash +++ b/deploy/iso/minikube-iso/arch/aarch64/package/runc-master-aarch64/runc-master.hash @@ -13,3 +13,4 @@ sha256 821ff8629329b4b7e4ccf24b5bf369c9739887736be30ba06a0d8053eb0e0b23 b9ee9c63 sha256 50cc479cabf6e7edb9070a7c28b3460b0acc2a01650fc5934f5037cb96b9e2cf 4144b63817ebcc5b358fc2c8ef95f7cddd709aa7.tar.gz sha256 1f47e3ff66cdcca1f890b15e74e884c4ff81d16d1044cc9900a1eb10cfb3d8e7 52b36a2dd837e8462de8e01458bf02cf9eea47dd.tar.gz sha256 91525356b71fbf8e05deddc955d3f40e0d4aedcb15d26bdd2850a9986852ae5b f46b6ba2c9314cfc8caae24a32ec5fe9ef1059fe.tar.gz +sha256 49fbb25fda9fc416ec79a23e5382d504a8972a88247fe074f63ab71b6f38a0a0 52de29d7e0f8c0899bd7efb8810dd07f0073fa87.tar.gz diff --git a/deploy/iso/minikube-iso/arch/aarch64/package/runc-master-aarch64/runc-master.mk b/deploy/iso/minikube-iso/arch/aarch64/package/runc-master-aarch64/runc-master.mk index 3d1f6edc4f..eacfd46d42 100644 --- a/deploy/iso/minikube-iso/arch/aarch64/package/runc-master-aarch64/runc-master.mk +++ b/deploy/iso/minikube-iso/arch/aarch64/package/runc-master-aarch64/runc-master.mk @@ -4,8 +4,8 @@ # ################################################################################ -# As of 2021-12-03, v1.0.3 -RUNC_MASTER_AARCH64_VERSION = f46b6ba2c9314cfc8caae24a32ec5fe9ef1059fe +# As of 2022-03-28, v1.1.1 +RUNC_MASTER_AARCH64_VERSION = 52de29d7e0f8c0899bd7efb8810dd07f0073fa87 RUNC_MASTER_AARCH64_SITE = https://github.com/opencontainers/runc/archive RUNC_MASTER_AARCH64_SOURCE = $(RUNC_MASTER_AARCH64_VERSION).tar.gz RUNC_MASTER_AARCH64_LICENSE = Apache-2.0 diff --git a/deploy/iso/minikube-iso/arch/x86_64/package/containerd-bin/containerd-bin.hash b/deploy/iso/minikube-iso/arch/x86_64/package/containerd-bin/containerd-bin.hash index 50fff143ab..cf10f80480 100644 --- a/deploy/iso/minikube-iso/arch/x86_64/package/containerd-bin/containerd-bin.hash +++ b/deploy/iso/minikube-iso/arch/x86_64/package/containerd-bin/containerd-bin.hash @@ -14,3 +14,4 @@ sha256 3bb9f54be022067847f5930d21ebbfe4e7a67f589d78930aa0ac713492c28bcc v1.4.9.t sha256 85a531725f15e2d136131119d42af4507a5389e0947015152075c4c93816fb5c v1.4.12.tar.gz sha256 7507913ba169c103ab67bc51bec31cd977d4348d7bc842da32b7eab5f930a14b v1.5.10.tar.gz sha256 02b79d5e2b07b5e64cd28f1fe84395ee11eef95fc49fd923a9ab93022b148be6 v1.5.11.tar.gz +sha256 f422e21e35705d1e741c1f3280813e43f811eaff4dcc5cdafac8b8952b15f468 v1.6.4.tar.gz diff --git a/deploy/iso/minikube-iso/arch/x86_64/package/containerd-bin/containerd-bin.mk b/deploy/iso/minikube-iso/arch/x86_64/package/containerd-bin/containerd-bin.mk index 0d729d6c9c..8cb5501d2a 100644 --- a/deploy/iso/minikube-iso/arch/x86_64/package/containerd-bin/containerd-bin.mk +++ b/deploy/iso/minikube-iso/arch/x86_64/package/containerd-bin/containerd-bin.mk @@ -3,8 +3,8 @@ # containerd # ################################################################################ -CONTAINERD_BIN_VERSION = v1.5.11 -CONTAINERD_BIN_COMMIT = 3df54a852345ae127d1fa3092b95168e4a88e2f8 +CONTAINERD_BIN_VERSION = v1.6.4 +CONTAINERD_BIN_COMMIT = 212e8b6fa2f44b9c21b2798135fc6fb7c53efc16 CONTAINERD_BIN_SITE = https://github.com/containerd/containerd/archive CONTAINERD_BIN_SOURCE = $(CONTAINERD_BIN_VERSION).tar.gz CONTAINERD_BIN_DEPENDENCIES = host-go libgpgme diff --git a/deploy/iso/minikube-iso/arch/x86_64/package/docker-bin/docker-bin.hash b/deploy/iso/minikube-iso/arch/x86_64/package/docker-bin/docker-bin.hash index e6c61f195a..daeaddd23b 100644 --- a/deploy/iso/minikube-iso/arch/x86_64/package/docker-bin/docker-bin.hash +++ b/deploy/iso/minikube-iso/arch/x86_64/package/docker-bin/docker-bin.hash @@ -35,3 +35,5 @@ sha256 7ea11ecb100fdc085dbfd9ab1ff380e7f99733c890ed815510a5952e5d6dd7e0 docker- sha256 ee9b5be14e54bf92f48c82c2e6a83fbdd1c5329e8f247525a9ed2fe90d9f89a5 docker-20.10.12.tgz sha256 39edf7c8d773939ff5e4d318ae565691a9c7e754ed768e172757e58898fb7079 docker-20.10.13.tgz sha256 7ca4aeeed86619909ae584ce3405da3766d495f98904ffbd9d859add26b83af5 docker-20.10.14.tgz +sha256 9ccfc39305ae1d8882d18c9c431544fca82913d6df717409ac2244ac58c4f070 docker-20.10.15.tgz +sha256 b43ac6c4d2f0b64e445c6564860e4fccd6331f4a61815a60642c7748b53c59ff docker-20.10.16.tgz diff --git a/deploy/iso/minikube-iso/arch/x86_64/package/docker-bin/docker-bin.mk b/deploy/iso/minikube-iso/arch/x86_64/package/docker-bin/docker-bin.mk index f683d631d0..997b5e41f8 100644 --- a/deploy/iso/minikube-iso/arch/x86_64/package/docker-bin/docker-bin.mk +++ b/deploy/iso/minikube-iso/arch/x86_64/package/docker-bin/docker-bin.mk @@ -4,7 +4,7 @@ # ################################################################################ -DOCKER_BIN_VERSION = 20.10.14 +DOCKER_BIN_VERSION = 20.10.16 DOCKER_BIN_SITE = https://download.docker.com/linux/static/stable/x86_64 DOCKER_BIN_SOURCE = docker-$(DOCKER_BIN_VERSION).tgz diff --git a/deploy/iso/minikube-iso/arch/x86_64/package/runc-master/runc-master.hash b/deploy/iso/minikube-iso/arch/x86_64/package/runc-master/runc-master.hash index 4d904c3782..fe79ecbc65 100644 --- a/deploy/iso/minikube-iso/arch/x86_64/package/runc-master/runc-master.hash +++ b/deploy/iso/minikube-iso/arch/x86_64/package/runc-master/runc-master.hash @@ -13,3 +13,4 @@ sha256 821ff8629329b4b7e4ccf24b5bf369c9739887736be30ba06a0d8053eb0e0b23 b9ee9c63 sha256 50cc479cabf6e7edb9070a7c28b3460b0acc2a01650fc5934f5037cb96b9e2cf 4144b63817ebcc5b358fc2c8ef95f7cddd709aa7.tar.gz sha256 1f47e3ff66cdcca1f890b15e74e884c4ff81d16d1044cc9900a1eb10cfb3d8e7 52b36a2dd837e8462de8e01458bf02cf9eea47dd.tar.gz sha256 91525356b71fbf8e05deddc955d3f40e0d4aedcb15d26bdd2850a9986852ae5b f46b6ba2c9314cfc8caae24a32ec5fe9ef1059fe.tar.gz +sha256 49fbb25fda9fc416ec79a23e5382d504a8972a88247fe074f63ab71b6f38a0a0 52de29d7e0f8c0899bd7efb8810dd07f0073fa87.tar.gz diff --git a/deploy/iso/minikube-iso/arch/x86_64/package/runc-master/runc-master.mk b/deploy/iso/minikube-iso/arch/x86_64/package/runc-master/runc-master.mk index 8729a23eae..b183eb370e 100644 --- a/deploy/iso/minikube-iso/arch/x86_64/package/runc-master/runc-master.mk +++ b/deploy/iso/minikube-iso/arch/x86_64/package/runc-master/runc-master.mk @@ -4,8 +4,8 @@ # ################################################################################ -# As of 2021-12-03, v1.0.3 -RUNC_MASTER_VERSION = f46b6ba2c9314cfc8caae24a32ec5fe9ef1059fe +# As of 2022-03-28, v1.1.1 +RUNC_MASTER_VERSION = 52de29d7e0f8c0899bd7efb8810dd07f0073fa87 RUNC_MASTER_SITE = https://github.com/opencontainers/runc/archive RUNC_MASTER_SOURCE = $(RUNC_MASTER_VERSION).tar.gz RUNC_MASTER_LICENSE = Apache-2.0 diff --git a/deploy/kicbase/Dockerfile b/deploy/kicbase/Dockerfile index 4c434061bd..bfeb2b3b14 100644 --- a/deploy/kicbase/Dockerfile +++ b/deploy/kicbase/Dockerfile @@ -18,27 +18,31 @@ # https://systemd.io/CONTAINER_INTERFACE/ -# multi-tage docker build so we can build auto-pause for arm64 -FROM golang:1.17 +# multi-stage docker build so we can build auto-pause for arm64 +FROM golang:1.17 as auto-pause WORKDIR /src -# becaue auto-pause binary depends on minikube's code we need to pass the whole source code as the context -ADD . . +# auto-pause depends on core minikube code so we need to pass the whole source code as the context +# copy in the minimal amount of source code possible +COPY pkg/ ./pkg +COPY cmd/ ./cmd +COPY deploy/addons ./deploy/addons +COPY translations/ ./translations +COPY third_party/ ./third_party +COPY go.mod go.sum ./ +ARG TARGETARCH +ENV GOARCH=${TARGETARCH} RUN cd ./cmd/auto-pause/ && go build -# cri-dockerd static -FROM golang:1.16 -RUN git clone -n https://github.com/Mirantis/cri-dockerd && \ - cd cri-dockerd && git checkout a4d1895a2659ea9974bd7528a706592ab8b74181 && \ - cd src && env CGO_ENABLED=0 go build -ldflags '-X github.com/Mirantis/cri-dockerd/version.GitCommit=a4d1895' -o cri-dockerd - # start from ubuntu 20.04, this image is reasonably small as a starting point # for a kubernetes node image, it doesn't contain much we don't need -FROM ubuntu:focal-20220316 +FROM ubuntu:focal-20220316 as kicbase ARG BUILDKIT_VERSION="v0.10.3" ARG FUSE_OVERLAYFS_VERSION="v1.7.1" ARG CONTAINERD_FUSE_OVERLAYFS_VERSION="1.0.3" ARG CRIO_VERSION="1.22" +ARG CRI_DOCKERD_VERSION="a4d1895a2659ea9974bd7528a706592ab8b74181" +ARG TARGETARCH # copy in static files (configs, scripts) COPY deploy/kicbase/10-network-security.conf /etc/sysctl.d/10-network-security.conf @@ -47,10 +51,8 @@ COPY deploy/kicbase/02-crio.conf /etc/crio/crio.conf.d/02-crio.conf COPY deploy/kicbase/containerd.toml /etc/containerd/config.toml COPY deploy/kicbase/clean-install /usr/local/bin/clean-install COPY deploy/kicbase/entrypoint /usr/local/bin/entrypoint -COPY --from=0 /src/cmd/auto-pause/auto-pause /bin/auto-pause -COPY --from=1 /go/cri-dockerd/src/cri-dockerd /usr/bin/cri-dockerd -COPY --from=1 /go/cri-dockerd/packaging/systemd/cri-docker.service /usr/lib/systemd/system/cri-docker.service -COPY --from=1 /go/cri-dockerd/packaging/systemd/cri-docker.socket /usr/lib/systemd/system/cri-docker.socket +COPY --from=auto-pause /src/cmd/auto-pause/auto-pause /bin/auto-pause + # Install dependencies, first from apt, then from release tarballs. # NOTE: we use one RUN to minimize layers. @@ -119,6 +121,12 @@ ARG COMMIT_SHA # could be changed to any debian that can run systemd USER root +# Install cri-dockerd from pre-compiled binaries stored in GCS, this is way faster than building from source in multi-arch +RUN echo "Installing cri-dockerd" && \ + curl -L "https://storage.googleapis.com/kicbase-artifacts/cri-dockerd/${CRI_DOCKERD_VERSION}/${TARGETARCH}/cri-dockerd" -o /usr/bin/cri-dockerd && \ + curl -L "https://storage.googleapis.com/kicbase-artifacts/cri-dockerd/${CRI_DOCKERD_VERSION}/cri-docker.socket" -o /usr/lib/systemd/system/cri-docker.socket && \ + curl -L "https://storage.googleapis.com/kicbase-artifacts/cri-dockerd/${CRI_DOCKERD_VERSION}/cri-docker.service" -o /usr/lib/systemd/system/cri-docker.service + # install system requirements from the regular distro repositories RUN clean-install \ lz4 \ @@ -163,9 +171,9 @@ RUN export ARCH=$(dpkg --print-architecture | sed 's/ppc64el/ppc64le/') && \ curl -LO https://downloadcontent.opensuse.org/repositories/devel:kubic:libcontainers:stable/xUbuntu_20.04/Release.key && \ apt-key add - < Release.key && \ if [ "$ARCH" != "ppc64le" ]; then \ - clean-install containers-common catatonit conmon containernetworking-plugins cri-tools podman-plugins crun; \ + clean-install containers-common catatonit conmon containernetworking-plugins cri-tools podman-plugins crun; \ else \ - clean-install containers-common conmon containernetworking-plugins crun; \ + clean-install containers-common conmon containernetworking-plugins crun; \ fi # install cri-o based on https://github.com/cri-o/cri-o/blob/release-1.22/README.md#installing-cri-o diff --git a/deploy/minikube/releases-beta-v2.json b/deploy/minikube/releases-beta-v2.json index 3a372d48d0..5eb84727c3 100644 --- a/deploy/minikube/releases-beta-v2.json +++ b/deploy/minikube/releases-beta-v2.json @@ -1,34 +1,86 @@ [ -{ - "name": "v1.24.0-beta.0", - "checksums": { - "darwin": "f8b0a2d0ca7435e98fff553702ed4977e33b301d0316ee4512d28b485701613e", - "linux": "8cd17a9fb5c73f9cab97754bd6ed725cb2b1fe9faa02f7f75a9cf5566b6f8716", - "windows": "ba87d2ef329db940890f8970afce1a6654814e0e427f91b9d5347496d4e7d1a3" - } - }, - { - "name": "v1.22.0-beta.0", - "checksums": { - "darwin": "1ec06c37be5c6c79a7255da09ff83490a44d1e8cd2b2f45e4b489edfdeacde94", - "linux": "c9d9ac605a94748379188cced6b832037b8069441744b889214990c4ca3485a5", - "windows": "68fb9c24f0ea55b985856d0cce9fa0c288b8a4d7e13519d6f0790038165d7ef1" - } - }, - { - "name": "v1.21.0-beta.0", - "checksums": { - "darwin": "69ab001eb4984d09ed731d5ac92afd8310e5c7672c2275b39d7a4c7e2dcfb4c6", - "linux": "41a26190c6774e1f3cc568986d4043431022d5dff4a619f131e9bb49d13e2874", - "windows": "e7d41c8c40e33633d47976047a48600ff23657c824db7e60fe5a4f2d2daeb135" - } - }, - { - "name": "v1.20.0-beta.0", - "checksums": { - "darwin": "686f8d7c06c93f28543f982ec56a68544ab2ad6c7f70b39ede5174d7bac29651", - "linux": "fe0796852c9ef266597fc93fa4b7a88d2cab9ba7008f0e9f644b633c51d269a1", - "windows": "84a0686c90ab88d04a0aab57b8cadacf9197d3ea6b467f9f807d071efe7fad3c" - } - } -] + { + "checksums": { + "amd64": { + "darwin": "a1cbd7847462f6c693e6df13033036ea2401ac4c9cac3186e0c494022021defa", + "linux": "8dc0f14a1c6db1b009128ad1a7fab28a49c29dd46f8d90eb1429dacda8e8d948", + "windows": "a327ccc5009ba45b7c2f668af110c9b414ae847c23e4a38b812ef69de9e396fb" + }, + "arm": { + "linux": "19c9b82491ff02cf1844ae2ea705d8970882d1f40d96ce0777f7084cb7aaa7ac" + }, + "arm64": { + "darwin": "ab973bb05305d725c194c358f723504f4a2891a035482fc352f2cfbc3654a526", + "linux": "8ef60a1369080fe1b12831b307dfb7b87e2b6f100c47226468f6eb0b84ea82aa" + }, + "ppc64le": { + "linux": "2018960bf1918b4d80ef63b236d9c107f5747799432c45a10c1b262e487c2203" + }, + "s390x": { + "linux": "4325510e5dd9955c13a3ce9fd273745dd55bd9ab6910c6667b5feb0f912ce28b" + }, + "darwin": "a1cbd7847462f6c693e6df13033036ea2401ac4c9cac3186e0c494022021defa", + "linux": "8dc0f14a1c6db1b009128ad1a7fab28a49c29dd46f8d90eb1429dacda8e8d948", + "windows": "a327ccc5009ba45b7c2f668af110c9b414ae847c23e4a38b812ef69de9e396fb" + }, + "name": "v1.26.0-beta.1" + }, + { + "checksums": { + "amd64": { + "darwin": "96a8cbb6fe8e8fd629fd49cd222358ceaee2fbac946f86da9113925d3f8d685b", + "linux": "c4576588f6c746ffcf9d8f768a0ca929b63d15652c230e15163f8ccf212bcae5", + "windows": "09c83da4d1e1712175a199452076e1cdb77662d15725da8fc0704528f15e4d7a" + }, + "arm": { + "linux": "baaaa5bb066faea551158551aad5e9e547fbc05769e59adec54433118a6a5dc6" + }, + "arm64": { + "darwin": "ef7dfe41df9b8ebb5a5f836c9255d355ba9e664cd2e8db6f5377d24b2b2ceb14", + "linux": "27561719a6164079966bba0648ce704140462b46cac9257cb2f98367f674208a" + }, + "ppc64le": { + "linux": "2747ed3a01d5d2c3fa576acc5a1e3aa431cebec0e4f92e498b53ce9e892f6c6c" + }, + "s390x": { + "linux": "dc8f2475e87eafbedfcabad2bb56b283c7151529029dd1bde749736dd56d9eab" + }, + "darwin": "96a8cbb6fe8e8fd629fd49cd222358ceaee2fbac946f86da9113925d3f8d685b", + "linux": "c4576588f6c746ffcf9d8f768a0ca929b63d15652c230e15163f8ccf212bcae5", + "windows": "09c83da4d1e1712175a199452076e1cdb77662d15725da8fc0704528f15e4d7a" + }, + "name": "v1.26.0-beta.0" + }, + { + "checksums": { + "darwin": "f8b0a2d0ca7435e98fff553702ed4977e33b301d0316ee4512d28b485701613e", + "linux": "8cd17a9fb5c73f9cab97754bd6ed725cb2b1fe9faa02f7f75a9cf5566b6f8716", + "windows": "ba87d2ef329db940890f8970afce1a6654814e0e427f91b9d5347496d4e7d1a3" + }, + "name": "v1.24.0-beta.0" + }, + { + "checksums": { + "darwin": "1ec06c37be5c6c79a7255da09ff83490a44d1e8cd2b2f45e4b489edfdeacde94", + "linux": "c9d9ac605a94748379188cced6b832037b8069441744b889214990c4ca3485a5", + "windows": "68fb9c24f0ea55b985856d0cce9fa0c288b8a4d7e13519d6f0790038165d7ef1" + }, + "name": "v1.22.0-beta.0" + }, + { + "checksums": { + "darwin": "69ab001eb4984d09ed731d5ac92afd8310e5c7672c2275b39d7a4c7e2dcfb4c6", + "linux": "41a26190c6774e1f3cc568986d4043431022d5dff4a619f131e9bb49d13e2874", + "windows": "e7d41c8c40e33633d47976047a48600ff23657c824db7e60fe5a4f2d2daeb135" + }, + "name": "v1.21.0-beta.0" + }, + { + "checksums": { + "darwin": "686f8d7c06c93f28543f982ec56a68544ab2ad6c7f70b39ede5174d7bac29651", + "linux": "fe0796852c9ef266597fc93fa4b7a88d2cab9ba7008f0e9f644b633c51d269a1", + "windows": "84a0686c90ab88d04a0aab57b8cadacf9197d3ea6b467f9f807d071efe7fad3c" + }, + "name": "v1.20.0-beta.0" + } +] \ No newline at end of file diff --git a/deploy/minikube/releases-beta.json b/deploy/minikube/releases-beta.json index 3a372d48d0..b025a885ac 100644 --- a/deploy/minikube/releases-beta.json +++ b/deploy/minikube/releases-beta.json @@ -1,34 +1,50 @@ [ -{ - "name": "v1.24.0-beta.0", - "checksums": { - "darwin": "f8b0a2d0ca7435e98fff553702ed4977e33b301d0316ee4512d28b485701613e", - "linux": "8cd17a9fb5c73f9cab97754bd6ed725cb2b1fe9faa02f7f75a9cf5566b6f8716", - "windows": "ba87d2ef329db940890f8970afce1a6654814e0e427f91b9d5347496d4e7d1a3" - } - }, - { - "name": "v1.22.0-beta.0", - "checksums": { - "darwin": "1ec06c37be5c6c79a7255da09ff83490a44d1e8cd2b2f45e4b489edfdeacde94", - "linux": "c9d9ac605a94748379188cced6b832037b8069441744b889214990c4ca3485a5", - "windows": "68fb9c24f0ea55b985856d0cce9fa0c288b8a4d7e13519d6f0790038165d7ef1" - } - }, - { - "name": "v1.21.0-beta.0", - "checksums": { - "darwin": "69ab001eb4984d09ed731d5ac92afd8310e5c7672c2275b39d7a4c7e2dcfb4c6", - "linux": "41a26190c6774e1f3cc568986d4043431022d5dff4a619f131e9bb49d13e2874", - "windows": "e7d41c8c40e33633d47976047a48600ff23657c824db7e60fe5a4f2d2daeb135" - } - }, - { - "name": "v1.20.0-beta.0", - "checksums": { - "darwin": "686f8d7c06c93f28543f982ec56a68544ab2ad6c7f70b39ede5174d7bac29651", - "linux": "fe0796852c9ef266597fc93fa4b7a88d2cab9ba7008f0e9f644b633c51d269a1", - "windows": "84a0686c90ab88d04a0aab57b8cadacf9197d3ea6b467f9f807d071efe7fad3c" - } - } -] + { + "checksums": { + "darwin": "a1cbd7847462f6c693e6df13033036ea2401ac4c9cac3186e0c494022021defa", + "linux": "8dc0f14a1c6db1b009128ad1a7fab28a49c29dd46f8d90eb1429dacda8e8d948", + "windows": "a327ccc5009ba45b7c2f668af110c9b414ae847c23e4a38b812ef69de9e396fb" + }, + "name": "v1.26.0-beta.1" + }, + { + "checksums": { + "darwin": "96a8cbb6fe8e8fd629fd49cd222358ceaee2fbac946f86da9113925d3f8d685b", + "linux": "c4576588f6c746ffcf9d8f768a0ca929b63d15652c230e15163f8ccf212bcae5", + "windows": "09c83da4d1e1712175a199452076e1cdb77662d15725da8fc0704528f15e4d7a" + }, + "name": "v1.26.0-beta.0" + }, + { + "checksums": { + "darwin": "f8b0a2d0ca7435e98fff553702ed4977e33b301d0316ee4512d28b485701613e", + "linux": "8cd17a9fb5c73f9cab97754bd6ed725cb2b1fe9faa02f7f75a9cf5566b6f8716", + "windows": "ba87d2ef329db940890f8970afce1a6654814e0e427f91b9d5347496d4e7d1a3" + }, + "name": "v1.24.0-beta.0" + }, + { + "checksums": { + "darwin": "1ec06c37be5c6c79a7255da09ff83490a44d1e8cd2b2f45e4b489edfdeacde94", + "linux": "c9d9ac605a94748379188cced6b832037b8069441744b889214990c4ca3485a5", + "windows": "68fb9c24f0ea55b985856d0cce9fa0c288b8a4d7e13519d6f0790038165d7ef1" + }, + "name": "v1.22.0-beta.0" + }, + { + "checksums": { + "darwin": "69ab001eb4984d09ed731d5ac92afd8310e5c7672c2275b39d7a4c7e2dcfb4c6", + "linux": "41a26190c6774e1f3cc568986d4043431022d5dff4a619f131e9bb49d13e2874", + "windows": "e7d41c8c40e33633d47976047a48600ff23657c824db7e60fe5a4f2d2daeb135" + }, + "name": "v1.21.0-beta.0" + }, + { + "checksums": { + "darwin": "686f8d7c06c93f28543f982ec56a68544ab2ad6c7f70b39ede5174d7bac29651", + "linux": "fe0796852c9ef266597fc93fa4b7a88d2cab9ba7008f0e9f644b633c51d269a1", + "windows": "84a0686c90ab88d04a0aab57b8cadacf9197d3ea6b467f9f807d071efe7fad3c" + }, + "name": "v1.20.0-beta.0" + } +] \ No newline at end of file diff --git a/gui/advancedview.cpp b/gui/advancedview.cpp new file mode 100644 index 0000000000..94e1ba78de --- /dev/null +++ b/gui/advancedview.cpp @@ -0,0 +1,281 @@ +#include "advancedview.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +AdvancedView::AdvancedView(QIcon icon) +{ + m_icon = icon; + + advancedView = new QWidget(); + advancedView->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + + ClusterList clusters; + m_clusterModel = new ClusterModel(clusters); + + clusterListView = new QTableView(); + clusterListView->setModel(m_clusterModel); + clusterListView->setSelectionMode(QAbstractItemView::SingleSelection); + clusterListView->setSelectionBehavior(QAbstractItemView::SelectRows); + clusterListView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + clusterListView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents); + clusterListView->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents); + clusterListView->horizontalHeader()->setSectionResizeMode(3, QHeaderView::ResizeToContents); + clusterListView->horizontalHeader()->setSectionResizeMode(4, QHeaderView::ResizeToContents); + clusterListView->horizontalHeader()->setSectionResizeMode(5, QHeaderView::ResizeToContents); + clusterListView->horizontalHeader()->setSectionResizeMode(6, QHeaderView::ResizeToContents); + setSelectedClusterName("default"); + + startButton = new QPushButton(tr("Start")); + stopButton = new QPushButton(tr("Stop")); + pauseButton = new QPushButton(tr("Pause")); + deleteButton = new QPushButton(tr("Delete")); + refreshButton = new QPushButton(tr("Refresh")); + createButton = new QPushButton(tr("Create")); + sshButton = new QPushButton(tr("SSH")); + dashboardButton = new QPushButton(tr("Dashboard")); + basicButton = new QPushButton(tr("Basic View")); + + disableButtons(); + + QHBoxLayout *topButtonLayout = new QHBoxLayout; + topButtonLayout->addWidget(createButton); + topButtonLayout->addWidget(refreshButton); + topButtonLayout->addWidget(basicButton); + topButtonLayout->addSpacing(340); + + QHBoxLayout *bottomButtonLayout = new QHBoxLayout; + bottomButtonLayout->addWidget(startButton); + bottomButtonLayout->addWidget(stopButton); + bottomButtonLayout->addWidget(pauseButton); + bottomButtonLayout->addWidget(deleteButton); + bottomButtonLayout->addWidget(sshButton); + bottomButtonLayout->addWidget(dashboardButton); + + QVBoxLayout *clusterLayout = new QVBoxLayout; + clusterLayout->addLayout(topButtonLayout); + clusterLayout->addWidget(clusterListView); + clusterLayout->addLayout(bottomButtonLayout); + advancedView->setLayout(clusterLayout); + + QFont *loadingFont = new QFont(); + loadingFont->setPointSize(30); + loading = new QLabel("Loading..."); + loading->setFont(*loadingFont); + loading->setParent(clusterListView); + loading->setHidden(true); + + connect(startButton, &QAbstractButton::clicked, this, &AdvancedView::start); + connect(stopButton, &QAbstractButton::clicked, this, &AdvancedView::stop); + connect(pauseButton, &QAbstractButton::clicked, this, &AdvancedView::pause); + connect(deleteButton, &QAbstractButton::clicked, this, &AdvancedView::delete_); + connect(refreshButton, &QAbstractButton::clicked, this, &AdvancedView::refresh); + connect(createButton, &QAbstractButton::clicked, this, &AdvancedView::askName); + connect(sshButton, &QAbstractButton::clicked, this, &AdvancedView::ssh); + connect(dashboardButton, &QAbstractButton::clicked, this, &AdvancedView::dashboard); + connect(basicButton, &QAbstractButton::clicked, this, &AdvancedView::basic); +} + +static QString getPauseLabel(bool isPaused) +{ + if (isPaused) { + return "Unpause"; + } + return "Pause"; +} + +static QString getStartLabel(bool isRunning) +{ + if (isRunning) { + return "Reload"; + } + return "Start"; +} + +void AdvancedView::update(Cluster cluster) +{ + basicButton->setEnabled(true); + createButton->setEnabled(true); + refreshButton->setEnabled(true); + bool exists = !cluster.isEmpty(); + bool isRunning = cluster.status() == "Running"; + bool isPaused = cluster.status() == "Paused"; + startButton->setEnabled(exists); + stopButton->setEnabled(isRunning || isPaused); + pauseButton->setEnabled(isRunning || isPaused); + deleteButton->setEnabled(exists); + dashboardButton->setEnabled(isRunning); +#if __linux__ || __APPLE__ + sshButton->setEnabled(exists); +#else + sshButton->setEnabled(false); +#endif + pauseButton->setText(getPauseLabel(isPaused)); + startButton->setText(getStartLabel(isRunning)); +} + +void AdvancedView::setSelectedClusterName(QString cluster) +{ + QAbstractItemModel *model = clusterListView->model(); + QModelIndex start = model->index(0, 0); + QModelIndexList index = model->match(start, Qt::DisplayRole, cluster); + if (index.size() == 0) { + return; + } + clusterListView->setCurrentIndex(index[0]); +} + +QString AdvancedView::selectedClusterName() +{ + QModelIndex index = clusterListView->currentIndex(); + QVariant variant = index.siblingAtColumn(0).data(Qt::DisplayRole); + if (variant.isNull()) { + return QString(); + } + return variant.toString(); +} + +void AdvancedView::updateClustersTable(ClusterList clusterList) +{ + QString cluster = selectedClusterName(); + m_clusterModel->setClusters(clusterList); + setSelectedClusterName(cluster); +} + +static int getCenter(int widgetSize, int parentSize) +{ + return parentSize / 2 - widgetSize / 2; +} + +void AdvancedView::showLoading() +{ + clusterListView->setEnabled(false); + loading->setHidden(false); + loading->raise(); + int width = getCenter(loading->width(), clusterListView->width()); + int height = getCenter(loading->height(), clusterListView->height()); + loading->move(width, height); +} + +void AdvancedView::hideLoading() +{ + loading->setHidden(true); + clusterListView->setEnabled(true); +} + +static QString profile = "minikube"; +static int cpus = 2; +static int memory = 2400; +static QString driver = ""; +static QString containerRuntime = ""; +static QString k8sVersion = ""; + +void AdvancedView::askName() +{ + QDialog dialog; + dialog.setWindowTitle(tr("Create minikube Cluster")); + dialog.setWindowIcon(m_icon); + dialog.setModal(true); + + QFormLayout form(&dialog); + QDialogButtonBox buttonBox(Qt::Horizontal, &dialog); + QLineEdit profileField(profile, &dialog); + form.addRow(new QLabel(tr("Profile")), &profileField); + buttonBox.addButton(QString(tr("Use Default Values")), QDialogButtonBox::AcceptRole); + connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); + buttonBox.addButton(QString(tr("Set Custom Values")), QDialogButtonBox::RejectRole); + connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); + form.addRow(&buttonBox); + + int code = dialog.exec(); + profile = profileField.text(); + if (code == QDialog::Accepted) { + QStringList args = { "-p", profile }; + emit createCluster(args); + } else if (code == QDialog::Rejected) { + askCustom(); + } +} + +void AdvancedView::askCustom() +{ + QDialog dialog; + dialog.setWindowTitle(tr("Set Cluster Values")); + dialog.setWindowIcon(m_icon); + dialog.setModal(true); + + QFormLayout form(&dialog); + QComboBox *driverComboBox = new QComboBox; + driverComboBox->addItems({ "docker", "virtualbox", "vmware", "podman" }); +#if __linux__ + driverComboBox->addItem("kvm2"); +#elif __APPLE__ + driverComboBox->addItems({ "hyperkit", "parallels" }); +#else + driverComboBox->addItem("hyperv"); +#endif + form.addRow(new QLabel(tr("Driver")), driverComboBox); + QComboBox *containerRuntimeComboBox = new QComboBox; + containerRuntimeComboBox->addItems({ "docker", "containerd", "crio" }); + form.addRow(new QLabel(tr("Container Runtime")), containerRuntimeComboBox); + QComboBox *k8sVersionComboBox = new QComboBox; + k8sVersionComboBox->addItems({ "stable", "latest", "none" }); + form.addRow(new QLabel(tr("Kubernetes Version")), k8sVersionComboBox); + QLineEdit cpuField(QString::number(cpus), &dialog); + form.addRow(new QLabel(tr("CPUs")), &cpuField); + QLineEdit memoryField(QString::number(memory), &dialog); + form.addRow(new QLabel(tr("Memory")), &memoryField); + + QDialogButtonBox buttonBox(Qt::Horizontal, &dialog); + buttonBox.addButton(QString(tr("Create")), QDialogButtonBox::AcceptRole); + connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); + buttonBox.addButton(QString(tr("Cancel")), QDialogButtonBox::RejectRole); + connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); + form.addRow(&buttonBox); + + int code = dialog.exec(); + if (code == QDialog::Accepted) { + driver = driverComboBox->itemText(driverComboBox->currentIndex()); + containerRuntime = + containerRuntimeComboBox->itemText(containerRuntimeComboBox->currentIndex()); + k8sVersion = k8sVersionComboBox->itemText(k8sVersionComboBox->currentIndex()); + if (k8sVersion == "none") { + k8sVersion = "v0.0.0"; + } + cpus = cpuField.text().toInt(); + memory = memoryField.text().toInt(); + QStringList args = { "-p", + profile, + "--driver", + driver, + "--container-runtime", + containerRuntime, + "--kubernetes-version", + k8sVersion, + "--cpus", + QString::number(cpus), + "--memory", + QString::number(memory) }; + emit createCluster(args); + } +} + +void AdvancedView::disableButtons() +{ + startButton->setEnabled(false); + stopButton->setEnabled(false); + pauseButton->setEnabled(false); + deleteButton->setEnabled(false); + sshButton->setEnabled(false); + dashboardButton->setEnabled(false); + basicButton->setEnabled(false); + createButton->setEnabled(false); + refreshButton->setEnabled(false); +} diff --git a/gui/advancedview.h b/gui/advancedview.h new file mode 100644 index 0000000000..93e4f0167a --- /dev/null +++ b/gui/advancedview.h @@ -0,0 +1,59 @@ +#ifndef ADVANCEDVIEW_H +#define ADVANCEDVIEW_H + +#include "cluster.h" + +#include +#include +#include +#include + +class AdvancedView : public QObject +{ + Q_OBJECT + +public: + explicit AdvancedView(QIcon icon); + QWidget *advancedView; + QTableView *clusterListView; + + QString selectedClusterName(); + void updateClustersTable(ClusterList clusters); + void showLoading(); + void hideLoading(); + void disableButtons(); + +public slots: + void update(Cluster cluster); + +signals: + void start(); + void stop(); + void pause(); + void delete_(); + void refresh(); + void ssh(); + void dashboard(); + void basic(); + void createCluster(QStringList args); + +private: + void setSelectedClusterName(QString cluster); + void askName(); + void askCustom(); + + QPushButton *startButton; + QPushButton *stopButton; + QPushButton *pauseButton; + QPushButton *deleteButton; + QPushButton *refreshButton; + QPushButton *sshButton; + QPushButton *dashboardButton; + QPushButton *basicButton; + QPushButton *createButton; + QLabel *loading; + ClusterModel *m_clusterModel; + QIcon m_icon; +}; + +#endif // ADVANCEDVIEW_H diff --git a/gui/basicview.cpp b/gui/basicview.cpp new file mode 100644 index 0000000000..f0e4b1ead2 --- /dev/null +++ b/gui/basicview.cpp @@ -0,0 +1,90 @@ +#include "basicview.h" + +#include + +BasicView::BasicView() +{ + basicView = new QWidget(); + + startButton = new QPushButton(tr("Start")); + stopButton = new QPushButton(tr("Stop")); + pauseButton = new QPushButton(tr("Pause")); + deleteButton = new QPushButton(tr("Delete")); + refreshButton = new QPushButton(tr("Refresh")); + sshButton = new QPushButton(tr("SSH")); + dashboardButton = new QPushButton(tr("Dashboard")); + advancedButton = new QPushButton(tr("Advanced View")); + + disableButtons(); + + QVBoxLayout *buttonLayout = new QVBoxLayout; + basicView->setLayout(buttonLayout); + buttonLayout->addWidget(startButton); + buttonLayout->addWidget(stopButton); + buttonLayout->addWidget(pauseButton); + buttonLayout->addWidget(deleteButton); + buttonLayout->addWidget(refreshButton); + buttonLayout->addWidget(sshButton); + buttonLayout->addWidget(dashboardButton); + buttonLayout->addWidget(advancedButton); + basicView->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + + connect(startButton, &QPushButton::clicked, this, &BasicView::start); + connect(stopButton, &QAbstractButton::clicked, this, &BasicView::stop); + connect(pauseButton, &QAbstractButton::clicked, this, &BasicView::pause); + connect(deleteButton, &QAbstractButton::clicked, this, &BasicView::delete_); + connect(refreshButton, &QAbstractButton::clicked, this, &BasicView::refresh); + connect(sshButton, &QAbstractButton::clicked, this, &BasicView::ssh); + connect(dashboardButton, &QAbstractButton::clicked, this, &BasicView::dashboard); + connect(advancedButton, &QAbstractButton::clicked, this, &BasicView::advanced); +} + +static QString getPauseLabel(bool isPaused) +{ + if (isPaused) { + return "Unpause"; + } + return "Pause"; +} + +static QString getStartLabel(bool isRunning) +{ + if (isRunning) { + return "Reload"; + } + return "Start"; +} + +void BasicView::update(Cluster cluster) +{ + + startButton->setEnabled(true); + advancedButton->setEnabled(true); + refreshButton->setEnabled(true); + bool exists = !cluster.isEmpty(); + bool isRunning = cluster.status() == "Running"; + bool isPaused = cluster.status() == "Paused"; + stopButton->setEnabled(isRunning || isPaused); + pauseButton->setEnabled(isRunning || isPaused); + deleteButton->setEnabled(exists); + dashboardButton->setEnabled(isRunning); +#if __linux__ || __APPLE__ + sshButton->setEnabled(exists); +#else + sshButton->setEnabled(false); +#endif + pauseButton->setText(getPauseLabel(isPaused)); + startButton->setText(getStartLabel(isRunning)); +} + +void BasicView::disableButtons() +{ + startButton->setEnabled(false); + stopButton->setEnabled(false); + deleteButton->setEnabled(false); + pauseButton->setEnabled(false); + sshButton->setEnabled(false); + dashboardButton->setEnabled(false); + advancedButton->setEnabled(false); + refreshButton->setEnabled(false); +} diff --git a/gui/basicview.h b/gui/basicview.h new file mode 100644 index 0000000000..4d93e62c4d --- /dev/null +++ b/gui/basicview.h @@ -0,0 +1,40 @@ +#ifndef BASICVIEW_H +#define BASICVIEW_H + +#include "cluster.h" + +#include +#include + +class BasicView : public QObject +{ + Q_OBJECT + +public: + explicit BasicView(); + QWidget *basicView; + void update(Cluster cluster); + void disableButtons(); + +signals: + void start(); + void stop(); + void pause(); + void delete_(); + void refresh(); + void ssh(); + void dashboard(); + void advanced(); + +private: + QPushButton *startButton; + QPushButton *stopButton; + QPushButton *pauseButton; + QPushButton *deleteButton; + QPushButton *refreshButton; + QPushButton *sshButton; + QPushButton *dashboardButton; + QPushButton *advancedButton; +}; + +#endif // BASICVIEW_H diff --git a/gui/commandrunner.cpp b/gui/commandrunner.cpp new file mode 100644 index 0000000000..3c460971b0 --- /dev/null +++ b/gui/commandrunner.cpp @@ -0,0 +1,214 @@ +#include "commandrunner.h" + +#include +#include +#include +#include +#include + +CommandRunner::CommandRunner(QDialog *parent) +{ + m_env = QProcessEnvironment::systemEnvironment(); + m_parent = parent; + minikubePath(); +#if __APPLE__ + setMinikubePath(); +#endif +} + +void CommandRunner::executeMinikubeCommand(QStringList args) +{ + m_output = ""; + QStringList userArgs = { "--user", "minikube-gui" }; + args << userArgs; + m_process = new QProcess(m_parent); + connect(m_process, QOverload::of(&QProcess::finished), this, &CommandRunner::executionCompleted); + connect(m_process, &QProcess::readyReadStandardError, this, &CommandRunner::errorReady); + connect(m_process, &QProcess::readyReadStandardOutput, this, &CommandRunner::outputReady); + m_process->setProcessEnvironment(m_env); + m_process->start(m_minikubePath, args); + emit CommandRunner::startingExecution(); +} + +void CommandRunner::startMinikube(QStringList args) +{ + m_command = "start"; + QStringList baseArgs = { "start", "-o", "json" }; + baseArgs << args; + m_args = baseArgs; + executeMinikubeCommand(baseArgs); + emit startCommandStarting(); +} + +void CommandRunner::stopMinikube(QStringList args) +{ + QStringList baseArgs = { "stop" }; + baseArgs << args; + executeMinikubeCommand(baseArgs); +} + +void CommandRunner::pauseMinikube(QStringList args) +{ + QStringList baseArgs = { "pause" }; + baseArgs << args; + executeMinikubeCommand(baseArgs); +} + +void CommandRunner::unpauseMinikube(QStringList args) +{ + QStringList baseArgs = { "unpause" }; + baseArgs << args; + executeMinikubeCommand(baseArgs); +} + +void CommandRunner::deleteMinikube(QStringList args) +{ + m_command = "delete"; + QStringList baseArgs = { "delete" }; + baseArgs << args; + executeMinikubeCommand(baseArgs); +} + +void CommandRunner::stopCommand() +{ + m_process->terminate(); +} + +static Cluster createClusterObject(QJsonObject obj) +{ + QString name; + if (obj.contains("Name")) { + name = obj["Name"].toString(); + } + Cluster cluster(name); + if (obj.contains("Status")) { + QString status = obj["Status"].toString(); + cluster.setStatus(status); + } + if (!obj.contains("Config")) { + return cluster; + } + QJsonObject config = obj["Config"].toObject(); + if (config.contains("CPUs")) { + int cpus = config["CPUs"].toInt(); + cluster.setCpus(cpus); + } + if (config.contains("Memory")) { + int memory = config["Memory"].toInt(); + cluster.setMemory(memory); + } + if (config.contains("Driver")) { + QString driver = config["Driver"].toString(); + cluster.setDriver(driver); + } + if (!config.contains("KubernetesConfig")) { + return cluster; + } + QJsonObject k8sConfig = config["KubernetesConfig"].toObject(); + if (k8sConfig.contains("ContainerRuntime")) { + QString containerRuntime = k8sConfig["ContainerRuntime"].toString(); + cluster.setContainerRuntime(containerRuntime); + } + if (k8sConfig.contains("KubernetesVersion")) { + QString k8sVersion = k8sConfig["KubernetesVersion"].toString(); + cluster.setK8sVersion(k8sVersion); + } + return cluster; +} + +static ClusterList jsonToClusterList(QString text) +{ + ClusterList clusters; + QStringList lines; +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + lines = text.split("\n", Qt::SkipEmptyParts); +#else + lines = text.split("\n", QString::SkipEmptyParts); +#endif + for (int i = 0; i < lines.size(); i++) { + QString line = lines.at(i); + QJsonParseError error; + QJsonDocument json = QJsonDocument::fromJson(line.toUtf8(), &error); + if (json.isNull()) { + qDebug() << error.errorString(); + continue; + } + if (!json.isObject()) { + continue; + } + QJsonObject par = json.object(); + QJsonArray valid = par["valid"].toArray(); + QJsonArray invalid = par["invalid"].toArray(); + for (int i = 0; i < valid.size(); i++) { + QJsonObject obj = valid[i].toObject(); + Cluster cluster = createClusterObject(obj); + clusters << cluster; + } + for (int i = 0; i < invalid.size(); i++) { + QJsonObject obj = invalid[i].toObject(); + Cluster cluster = createClusterObject(obj); + cluster.setStatus("Invalid"); + clusters << cluster; + } + } + return clusters; +} + +void CommandRunner::requestClusters() +{ + m_command = "cluster"; + QStringList args = { "profile", "list", "-o", "json" }; + executeMinikubeCommand(args); +} + +void CommandRunner::executionCompleted() +{ + QString cmd = m_command; + m_command = ""; + QString output = m_output; + int exitCode = m_process->exitCode(); + delete m_process; + if (cmd != "cluster") { + emit executionEnded(); + } + if (cmd == "start" && exitCode != 0) { + emit error(m_args, output); + } + if (cmd == "cluster") { + ClusterList clusterList = jsonToClusterList(output); + emit updatedClusters(clusterList); + } +} + +void CommandRunner::errorReady() +{ + QString text = m_process->readAllStandardError(); + m_output.append(text); + emit output(text); +} + +void CommandRunner::outputReady() +{ + QString text = m_process->readAllStandardOutput(); + m_output.append(text); + emit output(text); +} + +#if __APPLE__ +void CommandRunner::setMinikubePath() +{ + m_env = QProcessEnvironment::systemEnvironment(); + QString path = m_env.value("PATH") + ":/usr/local/bin"; + m_env.insert("PATH", path); +} +#endif + +void CommandRunner::minikubePath() +{ + m_minikubePath = QStandardPaths::findExecutable("minikube"); + if (!m_minikubePath.isEmpty()) { + return; + } + QStringList path = { "/usr/local/bin" }; + m_minikubePath = QStandardPaths::findExecutable("minikube", path); +} diff --git a/gui/commandrunner.h b/gui/commandrunner.h new file mode 100644 index 0000000000..ddf8cfbaca --- /dev/null +++ b/gui/commandrunner.h @@ -0,0 +1,58 @@ +#ifndef COMMANDRUNNER_H +#define COMMANDRUNNER_H + +#include "cluster.h" + +#include +#include +#include +#include +#include +#include +#include + +class CommandRunner : public QObject +{ + Q_OBJECT + +public: + CommandRunner(QDialog *parent); + + void startMinikube(QStringList args); + void stopMinikube(QStringList args); + void pauseMinikube(QStringList args); + void unpauseMinikube(QStringList args); + void deleteMinikube(QStringList args); + void stopCommand(); + void requestClusters(); + +signals: + void startingExecution(); + void executionEnded(); + void output(QString text); + void error(QStringList args, QString text); + void updatedClusters(ClusterList clusterList); + void startCommandStarting(); + +private slots: + void executionCompleted(); + void outputReady(); + void errorReady(); + +private: + void executeMinikubeCommand(QStringList args); + void minikubePath(); +#if __APPLE__ + void setMinikubePath(); +#endif + + QProcess *m_process; + QProcessEnvironment m_env; + QString m_output; + QString m_minikubePath; + QString m_command; + QDialog *m_parent; + QStringList m_args; +}; + +#endif // COMMANDRUNNER_H diff --git a/gui/errormessage.cpp b/gui/errormessage.cpp new file mode 100644 index 0000000000..375eb77eee --- /dev/null +++ b/gui/errormessage.cpp @@ -0,0 +1,63 @@ +#include "errormessage.h" + +#include +#include +#include +#include +#include +#include + +ErrorMessage::ErrorMessage(QDialog *parent, QIcon icon) +{ + m_parent = parent; + m_icon = icon; +} + +void ErrorMessage::error(QString errorCode, QString advice, QString message, QString url, QString issues) +{ + + m_dialog = new QDialog(m_parent); + m_dialog->setWindowTitle(tr("minikube start failed")); + m_dialog->setWindowIcon(m_icon); + m_dialog->setFixedWidth(600); + m_dialog->setModal(true); + QFormLayout form(m_dialog); + createLabel("Error Code", errorCode, &form, false); + createLabel("Advice", advice, &form, false); + QTextEdit *errorMessage = new QTextEdit(); + errorMessage->setText(message); + errorMessage->setWordWrapMode(QTextOption::WrapAnywhere); + int pointSize = errorMessage->font().pointSize(); + errorMessage->setFont(QFont("Courier", pointSize)); + errorMessage->setAutoFillBackground(true); + errorMessage->setReadOnly(true); + form.addRow(errorMessage); + createLabel("Link to documentation", url, &form, true); + createLabel("Link to related issue", issues, &form, true); + QLabel *fileLabel = new QLabel(); + fileLabel->setOpenExternalLinks(true); + fileLabel->setWordWrap(true); + QString logFile = QDir::homePath() + "/.minikube/logs/lastStart.txt"; + fileLabel->setText("View log file"); + form.addRow(fileLabel); + QDialogButtonBox buttonBox(Qt::Horizontal, m_dialog); + buttonBox.addButton(QString(tr("OK")), QDialogButtonBox::AcceptRole); + connect(&buttonBox, &QDialogButtonBox::accepted, m_dialog, &QDialog::accept); + form.addRow(&buttonBox); + m_dialog->exec(); +} + +QLabel *ErrorMessage::createLabel(QString title, QString text, QFormLayout *form, bool isLink) +{ + QLabel *label = new QLabel(); + if (!text.isEmpty()) { + form->addRow(label); + } + if (isLink) { + label->setOpenExternalLinks(true); + text = "" + text + ""; + } + label->setWordWrap(true); + label->setText(title + ": " + text); + return label; +} diff --git a/gui/errormessage.h b/gui/errormessage.h new file mode 100644 index 0000000000..dfab8e1db6 --- /dev/null +++ b/gui/errormessage.h @@ -0,0 +1,26 @@ +#ifndef ERRORMESSAGE_H +#define ERRORMESSAGE_H + +#include +#include +#include +#include +#include + +class ErrorMessage : public QObject +{ + Q_OBJECT + +public: + explicit ErrorMessage(QDialog *parent, QIcon icon); + + void error(QString errorCode, QString advice, QString errorMessage, QString url, QString issues); + QLabel *createLabel(QString title, QString text, QFormLayout *form, bool isLink); + +private: + QDialog *m_dialog; + QIcon m_icon; + QDialog *m_parent; +}; + +#endif // ERRORMESSAGE_H diff --git a/gui/hyperkit.cpp b/gui/hyperkit.cpp new file mode 100644 index 0000000000..d79803b9a4 --- /dev/null +++ b/gui/hyperkit.cpp @@ -0,0 +1,57 @@ +#include "hyperkit.h" + +#include +#include + +HyperKit::HyperKit(QIcon icon) +{ + m_icon = icon; +} + +#if __APPLE__ +bool HyperKit::hyperkitPermissionFix(QStringList args, QString text) +{ + if (!text.contains("docker-machine-driver-hyperkit needs to run with elevated permissions")) { + return false; + } + if (!showHyperKitMessage()) { + return false; + } + + hyperkitPermission(); + emit rerun(args); + return true; +} + +void HyperKit::hyperkitPermission() +{ + QString command = "sudo chown root:wheel ~/.minikube/bin/docker-machine-driver-hyperkit && " + "sudo chmod u+s ~/.minikube/bin/docker-machine-driver-hyperkit && exit"; + QStringList arguments = { "-e", "tell app \"Terminal\"", + "-e", "set w to do script \"" + command + "\"", + "-e", "activate", + "-e", "repeat", + "-e", "delay 0.1", + "-e", "if not busy of w then exit repeat", + "-e", "end repeat", + "-e", "end tell" }; + QProcess *process = new QProcess(); + process->start("/usr/bin/osascript", arguments); + process->waitForFinished(-1); +} + +bool HyperKit::showHyperKitMessage() +{ + QMessageBox msgBox; + msgBox.setWindowTitle("HyperKit Permissions Required"); + msgBox.setWindowIcon(m_icon); + msgBox.setModal(true); + msgBox.setText("The HyperKit driver requires a one-time sudo permission.\n\nIf you'd like " + "to proceed, press OK and then enter your password into the terminal prompt, " + "the start will resume after."); + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Ok); + int code = msgBox.exec(); + return code == QMessageBox::Ok; +} +#endif diff --git a/gui/hyperkit.h b/gui/hyperkit.h new file mode 100644 index 0000000000..94a768b5a5 --- /dev/null +++ b/gui/hyperkit.h @@ -0,0 +1,25 @@ +#ifndef HYPERKIT_H +#define HYPERKIT_H + +#include +#include +#include + +class HyperKit : public QObject +{ + Q_OBJECT + +public: + explicit HyperKit(QIcon icon); + bool hyperkitPermissionFix(QStringList args, QString text); + +signals: + void rerun(QStringList args); + +private: + void hyperkitPermission(); + bool showHyperKitMessage(); + QIcon m_icon; +}; + +#endif // HYPERKIT_H diff --git a/gui/operator.cpp b/gui/operator.cpp new file mode 100644 index 0000000000..61b7b4918e --- /dev/null +++ b/gui/operator.cpp @@ -0,0 +1,363 @@ +#include "operator.h" + +#include +#include +#include +#include + +Operator::Operator(AdvancedView *advancedView, BasicView *basicView, CommandRunner *commandRunner, ErrorMessage *errorMessage, ProgressWindow *progressWindow, Tray *tray, HyperKit *hyperKit, Updater *updater, QStackedWidget *stackedWidget, QDialog *parent) +{ + m_advancedView = advancedView; + m_basicView = basicView; + m_commandRunner = commandRunner; + m_errorMessage = errorMessage; + m_progressWindow = progressWindow; + m_tray = tray; + m_hyperKit = hyperKit; + m_updater = updater; + m_stackedWidget = stackedWidget; + m_parent = parent; + m_isBasicView = true; + + connect(m_basicView, &BasicView::start, this, &Operator::startMinikube); + connect(m_basicView, &BasicView::stop, this, &Operator::stopMinikube); + connect(m_basicView, &BasicView::pause, this, &Operator::pauseOrUnpauseMinikube); + connect(m_basicView, &BasicView::delete_, this, &Operator::deleteMinikube); + connect(m_basicView, &BasicView::refresh, this, &Operator::updateClusters); + connect(m_basicView, &BasicView::ssh, this, &Operator::sshConsole); + connect(m_basicView, &BasicView::dashboard, this, &Operator::dashboardBrowser); + connect(m_basicView, &BasicView::advanced, this, &Operator::toAdvancedView); + + connect(m_advancedView, &AdvancedView::start, this, &Operator::startMinikube); + connect(m_advancedView, &AdvancedView::stop, this, &Operator::stopMinikube); + connect(m_advancedView, &AdvancedView::pause, this, &Operator::pauseOrUnpauseMinikube); + connect(m_advancedView, &AdvancedView::delete_, this, &Operator::deleteMinikube); + connect(m_advancedView, &AdvancedView::refresh, this, &Operator::updateClusters); + connect(m_advancedView, &AdvancedView::ssh, this, &Operator::sshConsole); + connect(m_advancedView, &AdvancedView::dashboard, this, &Operator::dashboardBrowser); + connect(m_advancedView, &AdvancedView::basic, this, &Operator::toBasicView); + connect(m_advancedView, &AdvancedView::createCluster, this, &Operator::createCluster); + connect(m_advancedView->clusterListView, SIGNAL(clicked(QModelIndex)), this, SLOT(updateButtons())); + + connect(m_commandRunner, &CommandRunner::startingExecution, this, &Operator::commandStarting); + connect(m_commandRunner, &CommandRunner::executionEnded, this, &Operator::commandEnding); + connect(m_commandRunner, &CommandRunner::output, this, &Operator::commandOutput); + connect(m_commandRunner, &CommandRunner::error, this, &Operator::commandError); + connect(m_commandRunner, &CommandRunner::updatedClusters, this, &Operator::clustersReceived); + connect(m_commandRunner, &CommandRunner::startCommandStarting, this, &Operator::startCommandStarting); + + connect(m_progressWindow, &ProgressWindow::cancelled, this, &Operator::cancelCommand); + + connect(m_tray, &Tray::restoreWindow, this, &Operator::restoreWindow); + connect(m_tray, &Tray::hideWindow, this, &Operator::hideWindow); + connect(m_tray, &Tray::start, this, &Operator::startMinikube); + connect(m_tray, &Tray::stop, this, &Operator::stopMinikube); + connect(m_tray, &Tray::pauseOrUnpause, this, &Operator::pauseOrUnpauseMinikube); + + connect(m_hyperKit, &HyperKit::rerun, this, &Operator::createCluster); + + updateClusters(); +} + +QStringList Operator::getCurrentClusterFlags() +{ + return { "-p", selectedClusterName() }; +} + +void Operator::startMinikube() +{ + m_commandRunner->startMinikube(getCurrentClusterFlags()); +} + +void Operator::stopMinikube() +{ + m_commandRunner->stopMinikube(getCurrentClusterFlags()); +} + +void Operator::pauseOrUnpauseMinikube() +{ + Cluster cluster = selectedCluster(); + if (cluster.status() == "Paused") { + unpauseMinikube(); + return; + } + pauseMinikube(); +} + +void Operator::pauseMinikube() +{ + m_commandRunner->pauseMinikube(getCurrentClusterFlags()); +} + +void Operator::unpauseMinikube() +{ + m_commandRunner->unpauseMinikube(getCurrentClusterFlags()); +} + +void Operator::deleteMinikube() +{ + m_commandRunner->deleteMinikube(getCurrentClusterFlags()); +} + +void Operator::createCluster(QStringList args) +{ + m_commandRunner->startMinikube(args); +} + +void Operator::startCommandStarting() +{ + commandStarting(); + m_progressWindow->setText("Starting..."); + m_progressWindow->show(); +} + +void Operator::commandStarting() +{ + m_advancedView->showLoading(); + m_tray->disableActions(); + m_parent->setCursor(Qt::WaitCursor); + disableButtons(); +} + +void Operator::disableButtons() +{ + if (m_isBasicView) { + m_basicView->disableButtons(); + } else { + m_advancedView->disableButtons(); + } +} + +void Operator::commandEnding() +{ + m_progressWindow->done(); + updateClusters(); +} + +void Operator::toAdvancedView() +{ + m_isBasicView = false; + m_stackedWidget->setCurrentIndex(1); + m_parent->resize(670, 400); + updateButtons(); +} + +void Operator::toBasicView() +{ + m_isBasicView = true; + m_stackedWidget->setCurrentIndex(0); + m_parent->resize(200, 275); + updateButtons(); +} + +void Operator::updateClusters() +{ + m_commandRunner->requestClusters(); +} + +void Operator::clustersReceived(ClusterList clusterList) +{ + m_clusterList = clusterList; + m_advancedView->updateClustersTable(m_clusterList); + updateButtons(); + m_advancedView->hideLoading(); + m_parent->unsetCursor(); + m_updater->checkForUpdates(); +} + +void Operator::updateButtons() +{ + Cluster cluster = selectedCluster(); + if (m_isBasicView) { + m_basicView->update(cluster); + } else { + m_advancedView->update(cluster); + } + m_tray->updateTrayActions(cluster); + m_tray->updateStatus(cluster); +} + +void Operator::restoreWindow() +{ + bool wasVisible = m_parent->isVisible(); + m_parent->showNormal(); + m_parent->activateWindow(); + if (wasVisible) { + return; + } + updateClusters(); +} + +void Operator::hideWindow() +{ + m_parent->hide(); +} + +void Operator::commandOutput(QString text) +{ + QStringList lines; +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + lines = text.split("\n", Qt::SkipEmptyParts); +#else + lines = text.split("\n", QString::SkipEmptyParts); +#endif + for (int i = 0; i < lines.size(); i++) { + QJsonDocument json = QJsonDocument::fromJson(lines[i].toUtf8()); + QJsonObject object = json.object(); + QString type = object["type"].toString(); + if (type != "io.k8s.sigs.minikube.step") { + return; + } + QJsonObject data = object["data"].toObject(); + QString stringStep = data["currentstep"].toString(); + int currStep = stringStep.toInt(); + QString totalString = data["totalsteps"].toString(); + int totalSteps = totalString.toInt(); + QString message = data["message"].toString(); + m_progressWindow->setBarMaximum(totalSteps); + m_progressWindow->setBarValue(currStep); + m_progressWindow->setText(message); + } +} + +void Operator::commandError(QStringList args, QString text) +{ +#if __APPLE__ + if (m_hyperKit->hyperkitPermissionFix(args, text)) { + return; + } +#endif + QStringList lines; +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + lines = text.split("\n", Qt::SkipEmptyParts); +#else + lines = text.split("\n", QString::SkipEmptyParts); +#endif + for (int i = 0; i < lines.size(); i++) { + QString line = lines.at(i); + QJsonParseError error; + QJsonDocument json = QJsonDocument::fromJson(line.toUtf8(), &error); + if (json.isNull() || !json.isObject()) { + continue; + } + QJsonObject par = json.object(); + QJsonObject data = par["data"].toObject(); + if (!data.contains("exitcode")) { + continue; + } + QString advice = data["advice"].toString(); + QString message = data["message"].toString(); + QString name = data["name"].toString(); + QString url = data["url"].toString(); + QString issues = data["issues"].toString(); + + m_errorMessage->error(name, advice, message, url, issues); + break; + } +} + +void Operator::cancelCommand() +{ + m_commandRunner->stopCommand(); +} + +QString Operator::selectedClusterName() +{ + if (m_isBasicView) { + return "minikube"; + } + return m_advancedView->selectedClusterName(); +} + +Cluster Operator::selectedCluster() +{ + QString clusterName = selectedClusterName(); + if (clusterName.isEmpty()) { + return Cluster(); + } + ClusterList clusters = m_clusterList; + ClusterHash clusterHash; + for (int i = 0; i < clusters.size(); i++) { + Cluster cluster = clusters.at(i); + clusterHash[cluster.name()] = cluster; + } + return clusterHash[clusterName]; +} + +static QString minikubePath() +{ + QString minikubePath = QStandardPaths::findExecutable("minikube"); + if (!minikubePath.isEmpty()) { + return minikubePath; + } + QStringList path = { "/usr/local/bin" }; + return QStandardPaths::findExecutable("minikube", path); +} + +void Operator::sshConsole() +{ + QString program = minikubePath(); +#ifndef QT_NO_TERMWIDGET + QMainWindow *mainWindow = new QMainWindow(); + int startnow = 0; // set shell program first + + QTermWidget *console = new QTermWidget(startnow); + + QFont font = QApplication::font(); + font.setFamily("Monospace"); + font.setPointSize(10); + + console->setTerminalFont(font); + console->setColorScheme("Tango"); + console->setShellProgram(program); + QStringList args = { "ssh", "-p", selectedClusterName() }; + console->setArgs(args); + console->startShellProgram(); + + QObject::connect(console, SIGNAL(finished()), mainWindow, SLOT(close())); + + mainWindow->setWindowTitle(nameLabel->text()); + mainWindow->resize(800, 400); + mainWindow->setCentralWidget(console); + mainWindow->show(); +#elif __APPLE__ + QString command = program + " ssh -p " + selectedClusterName(); + QStringList arguments = { "-e", "tell app \"Terminal\"", "-e", "activate", + "-e", "do script \"" + command + "\"", "-e", "end tell" }; + QProcess *process = new QProcess(this); + process->start("/usr/bin/osascript", arguments); +#else + QString terminal = qEnvironmentVariable("TERMINAL"); + if (terminal.isEmpty()) { + terminal = "x-terminal-emulator"; + if (QStandardPaths::findExecutable(terminal).isEmpty()) { + terminal = "xterm"; + } + } + + QStringList arguments = { "-e", QString("%1 ssh -p %2").arg(program, selectedClusterName()) }; + QProcess *process = new QProcess(this); + process->start(QStandardPaths::findExecutable(terminal), arguments); +#endif +} + +void Operator::dashboardBrowser() +{ + dashboardClose(); + + QString program = minikubePath(); + QProcess *process = new QProcess(this); + QStringList arguments = { "dashboard", "-p", selectedClusterName() }; + process->start(program, arguments); + + dashboardProcess = process; + dashboardProcess->waitForStarted(); +} + +void Operator::dashboardClose() +{ + if (dashboardProcess) { + dashboardProcess->terminate(); + dashboardProcess->waitForFinished(); + } +} diff --git a/gui/operator.h b/gui/operator.h new file mode 100644 index 0000000000..eb1490c423 --- /dev/null +++ b/gui/operator.h @@ -0,0 +1,71 @@ +#ifndef OPERATOR_H +#define OPERATOR_H + +#include "advancedview.h" +#include "basicview.h" +#include "cluster.h" +#include "commandrunner.h" +#include "errormessage.h" +#include "progresswindow.h" +#include "tray.h" +#include "hyperkit.h" +#include "updater.h" + +#include + +class Operator : public QObject +{ + Q_OBJECT + +public: + Operator(AdvancedView *advancedView, BasicView *basicView, CommandRunner *commandRunner, ErrorMessage *errorMessage, ProgressWindow *progressWindow, Tray *tray, HyperKit *hyperKit, Updater *updater, QStackedWidget *stackedWidget, QDialog *parent); + +public slots: + void startMinikube(); + void stopMinikube(); + void pauseOrUnpauseMinikube(); + void deleteMinikube(); + +private slots: + void commandStarting(); + void commandEnding(); + void commandOutput(QString text); + void commandError(QStringList args, QString text); + void cancelCommand(); + void toBasicView(); + void toAdvancedView(); + void createCluster(QStringList args); + void updateButtons(); + void clustersReceived(ClusterList clusterList); + void startCommandStarting(); + +private: + QStringList getCurrentClusterFlags(); + void updateClusters(); + QString selectedClusterName(); + Cluster selectedCluster(); + void sshConsole(); + void dashboardBrowser(); + void dashboardClose(); + void pauseMinikube(); + void unpauseMinikube(); + void restoreWindow(); + void hideWindow(); + void disableButtons(); + + AdvancedView *m_advancedView; + BasicView *m_basicView; + CommandRunner *m_commandRunner; + ErrorMessage *m_errorMessage; + ProgressWindow *m_progressWindow; + ClusterList m_clusterList; + Tray *m_tray; + HyperKit *m_hyperKit; + Updater *m_updater; + bool m_isBasicView; + QProcess *dashboardProcess; + QStackedWidget *m_stackedWidget; + QDialog *m_parent; +}; + +#endif // OPERATOR_H diff --git a/gui/progresswindow.cpp b/gui/progresswindow.cpp new file mode 100644 index 0000000000..ae8da892fe --- /dev/null +++ b/gui/progresswindow.cpp @@ -0,0 +1,65 @@ +#include "progresswindow.h" + +#include +#include + +ProgressWindow::ProgressWindow(QWidget *parent, QIcon icon) +{ + m_icon = icon; + + m_dialog = new QDialog(parent); + m_dialog->setWindowIcon(m_icon); + m_dialog->resize(300, 150); + m_dialog->setWindowFlags(Qt::FramelessWindowHint); + m_dialog->setModal(true); + + QVBoxLayout form(m_dialog); + + m_text = new QLabel(); + m_text->setWordWrap(true); + form.addWidget(m_text); + + m_progressBar = new QProgressBar(); + form.addWidget(m_progressBar); + + m_cancelButton = new QPushButton(); + m_cancelButton->setText(tr("Cancel")); + connect(m_cancelButton, &QAbstractButton::clicked, this, &ProgressWindow::cancel); + form.addWidget(m_cancelButton); + + // if the dialog isn't opened now it breaks formatting + m_dialog->open(); + m_dialog->hide(); +} + +void ProgressWindow::setBarMaximum(int max) +{ + m_progressBar->setMaximum(max); +} + +void ProgressWindow::setBarValue(int value) +{ + m_progressBar->setValue(value); +} + +void ProgressWindow::setText(QString text) +{ + m_text->setText(text); +} + +void ProgressWindow::show() +{ + m_dialog->open(); +} + +void ProgressWindow::cancel() +{ + done(); + emit cancelled(); +} + +void ProgressWindow::done() +{ + m_dialog->hide(); + m_progressBar->setValue(0); +} diff --git a/gui/progresswindow.h b/gui/progresswindow.h new file mode 100644 index 0000000000..7d016f5022 --- /dev/null +++ b/gui/progresswindow.h @@ -0,0 +1,38 @@ +#ifndef PROGRESSWINDOW_H +#define PROGRESSWINDOW_H + +#include +#include +#include +#include +#include +#include +#include + +class ProgressWindow : public QObject +{ + Q_OBJECT + +public: + explicit ProgressWindow(QWidget *parent, QIcon icon); + + void setBarMaximum(int max); + void setBarValue(int value); + void setText(QString text); + void show(); + void done(); + +signals: + void cancelled(); + +private: + void cancel(); + + QDialog *m_dialog; + QLabel *m_text; + QProgressBar *m_progressBar; + QPushButton *m_cancelButton; + QIcon m_icon; +}; + +#endif // PROGRESSWINDOW_H diff --git a/gui/systray.pro b/gui/systray.pro index 45c3639daf..9430a3673e 100644 --- a/gui/systray.pro +++ b/gui/systray.pro @@ -1,7 +1,25 @@ HEADERS = window.h \ - cluster.h + advancedview.h \ + basicview.h \ + cluster.h \ + commandrunner.h \ + errormessage.h \ + hyperkit.h \ + operator.h \ + progresswindow.h \ + tray.h \ + updater.h SOURCES = main.cpp \ + advancedview.cpp \ + basicview.cpp \ cluster.cpp \ + commandrunner.cpp \ + errormessage.cpp \ + hyperkit.cpp \ + operator.cpp \ + progresswindow.cpp \ + tray.cpp \ + updater.cpp \ window.cpp RESOURCES = systray.qrc ICON = images/minikube.icns diff --git a/gui/tray.cpp b/gui/tray.cpp new file mode 100644 index 0000000000..30717fe562 --- /dev/null +++ b/gui/tray.cpp @@ -0,0 +1,116 @@ +#include "tray.h" + +#include +#include +#include + +Tray::Tray(QIcon icon) +{ + m_icon = icon; + + trayIconMenu = new QMenu(); + trayIcon = new QSystemTrayIcon(this); + + connect(trayIcon, &QSystemTrayIcon::activated, this, &Tray::iconActivated); + + minimizeAction = new QAction(tr("Mi&nimize"), this); + connect(minimizeAction, &QAction::triggered, this, &Tray::hideWindow); + + restoreAction = new QAction(tr("&Restore"), this); + connect(restoreAction, &QAction::triggered, this, &Tray::restoreWindow); + + quitAction = new QAction(tr("&Quit"), this); + connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit); + + startAction = new QAction(tr("Start"), this); + connect(startAction, &QAction::triggered, this, &Tray::start); + + pauseAction = new QAction(tr("Pause"), this); + connect(pauseAction, &QAction::triggered, this, &Tray::pauseOrUnpause); + + stopAction = new QAction(tr("Stop"), this); + connect(stopAction, &QAction::triggered, this, &Tray::stop); + + statusAction = new QAction(tr("Status:"), this); + statusAction->setEnabled(false); + + trayIconMenu->addAction(statusAction); + trayIconMenu->addSeparator(); + trayIconMenu->addAction(startAction); + trayIconMenu->addAction(pauseAction); + trayIconMenu->addAction(stopAction); + trayIconMenu->addSeparator(); + trayIconMenu->addAction(minimizeAction); + trayIconMenu->addAction(restoreAction); + trayIconMenu->addSeparator(); + trayIconMenu->addAction(quitAction); + + trayIcon->setContextMenu(trayIconMenu); + trayIcon->setIcon(m_icon); + trayIcon->show(); +} + +void Tray::iconActivated(QSystemTrayIcon::ActivationReason reason) +{ + switch (reason) { + case QSystemTrayIcon::Trigger: + case QSystemTrayIcon::DoubleClick: + emit restoreWindow(); + break; + default:; + } +} + +void Tray::updateStatus(Cluster cluster) +{ + QString status = cluster.status(); + if (status.isEmpty()) { + status = "Stopped"; + } + statusAction->setText("Status: " + status); +} + +bool Tray::isVisible() +{ + return trayIcon->isVisible(); +} + +void Tray::setVisible(bool visible) +{ + minimizeAction->setEnabled(visible); + restoreAction->setEnabled(!visible); +} + +static QString getPauseLabel(bool isPaused) +{ + if (isPaused) { + return "Unpause"; + } + return "Pause"; +} + +static QString getStartLabel(bool isRunning) +{ + if (isRunning) { + return "Reload"; + } + return "Start"; +} + +void Tray::updateTrayActions(Cluster cluster) +{ + startAction->setEnabled(true); + bool isRunning = cluster.status() == "Running"; + bool isPaused = cluster.status() == "Paused"; + pauseAction->setEnabled(isRunning || isPaused); + stopAction->setEnabled(isRunning || isPaused); + pauseAction->setText(getPauseLabel(isPaused)); + startAction->setText(getStartLabel(isRunning)); +} + +void Tray::disableActions() +{ + startAction->setEnabled(false); + stopAction->setEnabled(false); + pauseAction->setEnabled(false); +} diff --git a/gui/tray.h b/gui/tray.h new file mode 100644 index 0000000000..afa3788df6 --- /dev/null +++ b/gui/tray.h @@ -0,0 +1,45 @@ +#ifndef TRAY_H +#define TRAY_H + +#include "cluster.h" + +#include +#include + +class Tray : public QObject +{ + Q_OBJECT + +public: + explicit Tray(QIcon icon); + bool isVisible(); + void setVisible(bool visible); + void updateStatus(Cluster cluster); + void updateTrayActions(Cluster cluster); + void disableActions(); + +signals: + void restoreWindow(); + void showWindow(); + void hideWindow(); + void start(); + void stop(); + void pauseOrUnpause(); + +private: + void createTrayIcon(); + void createActions(); + void iconActivated(QSystemTrayIcon::ActivationReason reason); + QAction *minimizeAction; + QAction *restoreAction; + QAction *quitAction; + QAction *startAction; + QAction *pauseAction; + QAction *stopAction; + QAction *statusAction; + QSystemTrayIcon *trayIcon; + QMenu *trayIconMenu; + QIcon m_icon; +}; + +#endif // TRAY_H diff --git a/gui/updater.cpp b/gui/updater.cpp new file mode 100644 index 0000000000..ea18e2b279 --- /dev/null +++ b/gui/updater.cpp @@ -0,0 +1,117 @@ +#include "updater.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +Updater::Updater(QVersionNumber version, QIcon icon) +{ + m_version = version; + m_icon = icon; +} + +static bool checkedForUpdateRecently() +{ + QString filePath = QStandardPaths::locate(QStandardPaths::HomeLocation, "/.minikube-gui/last_update_check"); + if (filePath == "") { + return false; + } + QFile file(filePath); + if (!file.open(QIODevice::ReadOnly)) { + return false; + } + QTextStream in(&file); + QString line = in.readLine(); + QDateTime nextCheck = QDateTime::fromString(line).addSecs(60*60*24); + QDateTime now = QDateTime::currentDateTime(); + return nextCheck > now; +} + +static void logUpdateCheck() +{ + QDir dir = QDir(QDir::homePath() + "/.minikube-gui"); + if (!dir.exists()) { + dir.mkpath("."); + } + QString filePath = dir.filePath("last_update_check"); + QFile file(filePath); + if (!file.open(QIODevice::WriteOnly)) { + return; + } + QTextStream stream(&file); + stream << QDateTime::currentDateTime().toString() << Qt::endl; +} + +void Updater::checkForUpdates() +{ + if (checkedForUpdateRecently()) { + return; + } + logUpdateCheck(); + QString releases = getRequest("https://storage.googleapis.com/minikube-gui/releases.json"); + QJsonObject latestRelease = + QJsonDocument::fromJson(releases.toUtf8()).array().first().toObject(); + QString latestReleaseVersion = latestRelease["name"].toString(); + QVersionNumber latestReleaseVersionNumber = QVersionNumber::fromString(latestReleaseVersion); + if (m_version >= latestReleaseVersionNumber) { + return; + } + QJsonObject links = latestRelease["links"].toObject(); + QString key; +#if __linux__ + key = "linux"; +#elif __APPLE__ + key = "darwin"; +#else + key = "windows"; +#endif + QString link = links[key].toString(); + notifyUpdate(latestReleaseVersion, link); +} + +void Updater::notifyUpdate(QString latest, QString link) +{ + QDialog dialog; + dialog.setWindowTitle(tr("minikube GUI Update Available")); + dialog.setWindowIcon(m_icon); + dialog.setModal(true); + QFormLayout form(&dialog); + QLabel *msgLabel = new QLabel(); + msgLabel->setText("Version " + latest + + " of minikube GUI is now available!\n\nDownload the update from:"); + form.addWidget(msgLabel); + QLabel *linkLabel = new QLabel(); + linkLabel->setOpenExternalLinks(true); + linkLabel->setText("" + link + ""); + form.addWidget(linkLabel); + QDialogButtonBox buttonBox(Qt::Horizontal, &dialog); + buttonBox.addButton(QString(tr("OK")), QDialogButtonBox::AcceptRole); + connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); + form.addRow(&buttonBox); + dialog.exec(); +} + +QString Updater::getRequest(QString url) +{ + QNetworkAccessManager *manager = new QNetworkAccessManager(); + QObject::connect(manager, &QNetworkAccessManager::finished, this, [=](QNetworkReply *reply) { + if (reply->error()) { + qDebug() << reply->errorString(); + } + }); + QNetworkReply *resp = manager->get(QNetworkRequest(QUrl(url))); + QEventLoop loop; + connect(resp, &QNetworkReply::finished, &loop, &QEventLoop::quit); + loop.exec(); + return resp->readAll(); +} diff --git a/gui/updater.h b/gui/updater.h new file mode 100644 index 0000000000..2836a63ee9 --- /dev/null +++ b/gui/updater.h @@ -0,0 +1,23 @@ +#ifndef UPDATER_H +#define UPDATER_H + +#include +#include +#include + +class Updater : public QObject +{ + Q_OBJECT + +public: + explicit Updater(QVersionNumber version, QIcon icon); + void checkForUpdates(); + +private: + void notifyUpdate(QString latest, QString link); + QString getRequest(QString url); + QVersionNumber m_version; + QIcon m_icon; +}; + +#endif // UPDATER_H diff --git a/gui/window.cpp b/gui/window.cpp index 175c9e3475..4f54c63e44 100644 --- a/gui/window.cpp +++ b/gui/window.cpp @@ -97,109 +97,32 @@ Window::Window() { trayIconIcon = new QIcon(":/images/minikube.png"); checkForMinikube(); - isBasicView = true; stackedWidget = new QStackedWidget; - QVBoxLayout *layout = new QVBoxLayout; - dashboardProcess = 0; + commandRunner = new CommandRunner(this); + basicView = new BasicView(); + advancedView = new AdvancedView(*trayIconIcon); + errorMessage = new ErrorMessage(this, *trayIconIcon); + progressWindow = new ProgressWindow(this, *trayIconIcon); + tray = new Tray(*trayIconIcon); + hyperKit = new HyperKit(*trayIconIcon); + updater = new Updater(version, *trayIconIcon); - createClusterGroupBox(); + op = new Operator(advancedView, basicView, commandRunner, errorMessage, progressWindow, tray, hyperKit, updater, stackedWidget, this); - createActions(); - createTrayIcon(); - - createBasicView(); - createAdvancedView(); - trayIcon->show(); - updateButtons(); + stackedWidget->addWidget(basicView->basicView); + stackedWidget->addWidget(advancedView->advancedView); + layout = new QVBoxLayout; layout->addWidget(stackedWidget); setLayout(layout); resize(200, 275); - setWindowTitle(tr("minikube")); setWindowIcon(*trayIconIcon); - checkForUpdates(); -} - -QProcessEnvironment Window::setMacEnv() -{ - QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); - QString path = env.value("PATH"); - env.insert("PATH", path + ":/usr/local/bin"); - return env; -} - -void Window::createBasicView() -{ - QWidget *basicView = new QWidget(); - - basicStartButton = new QPushButton(tr("Start")); - basicStopButton = new QPushButton(tr("Stop")); - basicPauseButton = new QPushButton(tr("Pause")); - basicDeleteButton = new QPushButton(tr("Delete")); - basicRefreshButton = new QPushButton(tr("Refresh")); - basicSSHButton = new QPushButton(tr("SSH")); - basicDashboardButton = new QPushButton(tr("Dashboard")); - QPushButton *advancedViewButton = new QPushButton(tr("Advanced View")); - - QVBoxLayout *buttonLayout = new QVBoxLayout; - basicView->setLayout(buttonLayout); - buttonLayout->addWidget(basicStartButton); - buttonLayout->addWidget(basicStopButton); - buttonLayout->addWidget(basicPauseButton); - buttonLayout->addWidget(basicDeleteButton); - buttonLayout->addWidget(basicRefreshButton); - buttonLayout->addWidget(basicSSHButton); - buttonLayout->addWidget(basicDashboardButton); - buttonLayout->addWidget(advancedViewButton); - basicView->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); - stackedWidget->addWidget(basicView); - - connect(basicSSHButton, &QAbstractButton::clicked, this, &Window::sshConsole); - connect(basicDashboardButton, &QAbstractButton::clicked, this, &Window::dashboardBrowser); - connect(basicStartButton, &QAbstractButton::clicked, this, &Window::startSelectedMinikube); - connect(basicStopButton, &QAbstractButton::clicked, this, &Window::stopMinikube); - connect(basicPauseButton, &QAbstractButton::clicked, this, &Window::pauseOrUnpauseMinikube); - connect(basicDeleteButton, &QAbstractButton::clicked, this, &Window::deleteMinikube); - connect(basicRefreshButton, &QAbstractButton::clicked, this, &Window::updateClustersTable); - connect(advancedViewButton, &QAbstractButton::clicked, this, &Window::toAdvancedView); -} - -void Window::toAdvancedView() -{ - isBasicView = false; - stackedWidget->setCurrentIndex(1); - resize(670, 400); - updateButtons(); -} - -void Window::toBasicView() -{ - isBasicView = true; - stackedWidget->setCurrentIndex(0); - resize(200, 275); - updateButtons(); -} - -void Window::createAdvancedView() -{ - connect(sshButton, &QAbstractButton::clicked, this, &Window::sshConsole); - connect(dashboardButton, &QAbstractButton::clicked, this, &Window::dashboardBrowser); - connect(startButton, &QAbstractButton::clicked, this, &Window::startSelectedMinikube); - connect(stopButton, &QAbstractButton::clicked, this, &Window::stopMinikube); - connect(pauseButton, &QAbstractButton::clicked, this, &Window::pauseOrUnpauseMinikube); - connect(deleteButton, &QAbstractButton::clicked, this, &Window::deleteMinikube); - connect(refreshButton, &QAbstractButton::clicked, this, &Window::updateClustersTable); - connect(createButton, &QAbstractButton::clicked, this, &Window::initMachine); - - advancedView->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); - stackedWidget->addWidget(advancedView); } void Window::setVisible(bool visible) { - minimizeAction->setEnabled(visible); - restoreAction->setEnabled(!visible); + tray->setVisible(visible); QDialog::setVisible(visible); } @@ -210,7 +133,7 @@ void Window::closeEvent(QCloseEvent *event) return; } #endif - if (trayIcon->isVisible()) { + if (tray->isVisible()) { QMessageBox::information(this, tr("Systray"), tr("The program will keep running in the " "system tray. To terminate the program, " @@ -221,881 +144,14 @@ void Window::closeEvent(QCloseEvent *event) } } -void Window::messageClicked() -{ - QMessageBox::information(0, tr("Systray"), - tr("Sorry, I already gave what help I could.\n" - "Maybe you should try asking a human?")); -} - -void Window::createActions() -{ - minimizeAction = new QAction(tr("Mi&nimize"), this); - connect(minimizeAction, &QAction::triggered, this, &QWidget::hide); - - restoreAction = new QAction(tr("&Restore"), this); - connect(restoreAction, &QAction::triggered, this, &Window::restoreWindow); - - quitAction = new QAction(tr("&Quit"), this); - connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit); - - startAction = new QAction(tr("Start"), this); - connect(startAction, &QAction::triggered, this, &Window::startSelectedMinikube); - - pauseAction = new QAction(tr("Pause"), this); - connect(pauseAction, &QAction::triggered, this, &Window::pauseOrUnpauseMinikube); - - stopAction = new QAction(tr("Stop"), this); - connect(stopAction, &QAction::triggered, this, &Window::stopMinikube); - - statusAction = new QAction(tr("Status:"), this); - statusAction->setEnabled(false); -} - -void Window::updateStatus(Cluster cluster) -{ - QString status = cluster.status(); - if (status.isEmpty()) { - status = "Stopped"; - } - statusAction->setText("Status: " + status); -} - -void Window::iconActivated(QSystemTrayIcon::ActivationReason reason) -{ - switch (reason) { - case QSystemTrayIcon::Trigger: - case QSystemTrayIcon::DoubleClick: - Window::restoreWindow(); - break; - default:; - } -} - -void Window::restoreWindow() -{ - bool wasVisible = isVisible(); - QWidget::showNormal(); - activateWindow(); - if (wasVisible) { - return; - } - // without this delay window doesn't render until updateClusters() completes - delay(); - updateClustersTable(); -} - -void Window::delay() -{ - QCoreApplication::processEvents(QEventLoop::AllEvents, 100); -} - static QString minikubePath() { - QString program = QStandardPaths::findExecutable("minikube"); - if (program.isEmpty()) { - QStringList paths = { "/usr/local/bin" }; - program = QStandardPaths::findExecutable("minikube", paths); - } - return program; -} - -void Window::createTrayIcon() -{ - trayIconMenu = new QMenu(this); - trayIconMenu->addAction(statusAction); - trayIconMenu->addSeparator(); - trayIconMenu->addAction(startAction); - trayIconMenu->addAction(pauseAction); - trayIconMenu->addAction(stopAction); - trayIconMenu->addSeparator(); - trayIconMenu->addAction(minimizeAction); - trayIconMenu->addAction(restoreAction); - trayIconMenu->addSeparator(); - trayIconMenu->addAction(quitAction); - - trayIcon = new QSystemTrayIcon(this); - trayIcon->setContextMenu(trayIconMenu); - trayIcon->setIcon(*trayIconIcon); - - connect(trayIcon, &QSystemTrayIcon::activated, this, &Window::iconActivated); -} - -void Window::startMinikube(QStringList moreArgs) -{ - QString text; - QStringList args = { "start", "-o", "json" }; - args << moreArgs; - bool success = sendMinikubeStart(args, text); -#if __APPLE__ - hyperkitPermissionFix(args, text); -#endif - updateClustersTable(); - if (success) { - return; - } - outputFailedStart(text); -} - -void Window::startSelectedMinikube() -{ - QStringList args = { "-p", selectedClusterName() }; - return startMinikube(args); -} - -void Window::stopMinikube() -{ - QStringList args = { "stop", "-p", selectedClusterName() }; - sendMinikubeCommand(args); - updateClustersTable(); -} - -void Window::pauseMinikube() -{ - QStringList args = { "pause", "-p", selectedClusterName() }; - sendMinikubeCommand(args); - updateClustersTable(); -} - -void Window::unpauseMinikube() -{ - QStringList args = { "unpause", "-p", selectedClusterName() }; - sendMinikubeCommand(args); - updateClustersTable(); -} - -void Window::deleteMinikube() -{ - QStringList args = { "delete", "-p", selectedClusterName() }; - sendMinikubeCommand(args); - updateClustersTable(); -} - -void Window::updateClustersTable() -{ - showLoading(); - QString cluster = selectedClusterName(); - updateClusterList(); - clusterModel->setClusters(clusterList); - setSelectedClusterName(cluster); - updateButtons(); - loading->setHidden(true); - clusterListView->setEnabled(true); - hideLoading(); -} - -void Window::showLoading() -{ - clusterListView->setEnabled(false); - loading->setHidden(false); - loading->raise(); - int width = getCenter(loading->width(), clusterListView->width()); - int height = getCenter(loading->height(), clusterListView->height()); - loading->move(width, height); - delay(); -} - -void Window::hideLoading() -{ - loading->setHidden(true); - clusterListView->setEnabled(true); -} - -int Window::getCenter(int widgetSize, int parentSize) -{ - return parentSize / 2 - widgetSize / 2; -} - -void Window::updateClusterList() -{ - ClusterList clusters; - QStringList args = { "profile", "list", "-o", "json" }; - QString text; - sendMinikubeCommand(args, text); - QStringList lines; -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - lines = text.split("\n", Qt::SkipEmptyParts); -#else - lines = text.split("\n", QString::SkipEmptyParts); -#endif - for (int i = 0; i < lines.size(); i++) { - QString line = lines.at(i); - QJsonParseError error; - QJsonDocument json = QJsonDocument::fromJson(line.toUtf8(), &error); - if (json.isNull()) { - qDebug() << error.errorString(); - continue; - } - if (!json.isObject()) { - continue; - } - QJsonObject par = json.object(); - QJsonArray valid = par["valid"].toArray(); - QJsonArray invalid = par["invalid"].toArray(); - for (int i = 0; i < valid.size(); i++) { - QJsonObject obj = valid[i].toObject(); - Cluster cluster = createClusterObject(obj); - clusters << cluster; - } - for (int i = 0; i < invalid.size(); i++) { - QJsonObject obj = invalid[i].toObject(); - Cluster cluster = createClusterObject(obj); - cluster.setStatus("Invalid"); - clusters << cluster; - } - } - clusterList = clusters; -} - -Cluster Window::createClusterObject(QJsonObject obj) -{ - QString name; - if (obj.contains("Name")) { - name = obj["Name"].toString(); - } - Cluster cluster(name); - if (obj.contains("Status")) { - QString status = obj["Status"].toString(); - cluster.setStatus(status); - } - if (!obj.contains("Config")) { - return cluster; - } - QJsonObject config = obj["Config"].toObject(); - if (config.contains("CPUs")) { - int cpus = config["CPUs"].toInt(); - cluster.setCpus(cpus); - } - if (config.contains("Memory")) { - int memory = config["Memory"].toInt(); - cluster.setMemory(memory); - } - if (config.contains("Driver")) { - QString driver = config["Driver"].toString(); - cluster.setDriver(driver); - } - if (!config.contains("KubernetesConfig")) { - return cluster; - } - QJsonObject k8sConfig = config["KubernetesConfig"].toObject(); - if (k8sConfig.contains("ContainerRuntime")) { - QString containerRuntime = k8sConfig["ContainerRuntime"].toString(); - cluster.setContainerRuntime(containerRuntime); - } - if (k8sConfig.contains("KubernetesVersion")) { - QString k8sVersion = k8sConfig["KubernetesVersion"].toString(); - cluster.setK8sVersion(k8sVersion); - } - return cluster; -} - -QString Window::selectedClusterName() -{ - if (isBasicView) { - return "minikube"; - } - QModelIndex index = clusterListView->currentIndex(); - QVariant variant = index.siblingAtColumn(0).data(Qt::DisplayRole); - if (variant.isNull()) { - return QString(); - } - return variant.toString(); -} - -void Window::setSelectedClusterName(QString cluster) -{ - QAbstractItemModel *model = clusterListView->model(); - QModelIndex start = model->index(0, 0); - QModelIndexList index = model->match(start, Qt::DisplayRole, cluster); - if (index.size() == 0) { - return; - } - clusterListView->setCurrentIndex(index[0]); -} - -void Window::createClusterGroupBox() -{ - advancedView = new QWidget(); - - updateClusterList(); - ClusterList clusters = clusterList; - clusterModel = new ClusterModel(clusters); - - clusterListView = new QTableView(); - clusterListView->setModel(clusterModel); - clusterListView->setSelectionMode(QAbstractItemView::SingleSelection); - clusterListView->setSelectionBehavior(QAbstractItemView::SelectRows); - clusterListView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); - clusterListView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents); - clusterListView->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents); - clusterListView->horizontalHeader()->setSectionResizeMode(3, QHeaderView::ResizeToContents); - clusterListView->horizontalHeader()->setSectionResizeMode(4, QHeaderView::ResizeToContents); - clusterListView->horizontalHeader()->setSectionResizeMode(5, QHeaderView::ResizeToContents); - clusterListView->horizontalHeader()->setSectionResizeMode(6, QHeaderView::ResizeToContents); - setSelectedClusterName("default"); - - connect(clusterListView, SIGNAL(clicked(QModelIndex)), this, SLOT(updateButtons())); - - startButton = new QPushButton(tr("Start")); - stopButton = new QPushButton(tr("Stop")); - pauseButton = new QPushButton(tr("Pause")); - deleteButton = new QPushButton(tr("Delete")); - refreshButton = new QPushButton(tr("Refresh")); - createButton = new QPushButton(tr("Create")); - sshButton = new QPushButton(tr("SSH")); - dashboardButton = new QPushButton(tr("Dashboard")); - QPushButton *basicViewButton = new QPushButton(tr("Basic View")); - connect(basicViewButton, &QAbstractButton::clicked, this, &Window::toBasicView); - - QHBoxLayout *topButtonLayout = new QHBoxLayout; - topButtonLayout->addWidget(createButton); - topButtonLayout->addWidget(refreshButton); - topButtonLayout->addWidget(basicViewButton); - topButtonLayout->addSpacing(340); - - QHBoxLayout *bottomButtonLayout = new QHBoxLayout; - bottomButtonLayout->addWidget(startButton); - bottomButtonLayout->addWidget(stopButton); - bottomButtonLayout->addWidget(pauseButton); - bottomButtonLayout->addWidget(deleteButton); - bottomButtonLayout->addWidget(sshButton); - bottomButtonLayout->addWidget(dashboardButton); - - QVBoxLayout *clusterLayout = new QVBoxLayout; - clusterLayout->addLayout(topButtonLayout); - clusterLayout->addWidget(clusterListView); - clusterLayout->addLayout(bottomButtonLayout); - advancedView->setLayout(clusterLayout); - - QFont *loadingFont = new QFont(); - loadingFont->setPointSize(30); - loading = new QLabel("Loading..."); - loading->setFont(*loadingFont); - loading->setParent(clusterListView); - loading->setHidden(true); -} - -void Window::updateButtons() -{ - Cluster cluster = selectedCluster(); - if (isBasicView) { - updateBasicButtons(cluster); - } else { - updateAdvancedButtons(cluster); - } - updateTrayActions(cluster); - updateStatus(cluster); -} - -void Window::updateTrayActions(Cluster cluster) -{ - bool isRunning = cluster.status() == "Running"; - bool isPaused = cluster.status() == "Paused"; - pauseAction->setEnabled(isRunning || isPaused); - stopAction->setEnabled(isRunning || isPaused); - pauseAction->setText(getPauseLabel(isPaused)); - startAction->setText(getStartLabel(isRunning)); -} - -Cluster Window::selectedCluster() -{ - QString clusterName = selectedClusterName(); - if (clusterName.isEmpty()) { - return Cluster(); - } - ClusterList clusters = clusterList; - ClusterHash clusterHash; - for (int i = 0; i < clusters.size(); i++) { - Cluster cluster = clusters.at(i); - clusterHash[cluster.name()] = cluster; - } - return clusterHash[clusterName]; -} - -void Window::updateBasicButtons(Cluster cluster) -{ - bool exists = !cluster.isEmpty(); - bool isRunning = cluster.status() == "Running"; - bool isPaused = cluster.status() == "Paused"; - basicStopButton->setEnabled(isRunning || isPaused); - basicPauseButton->setEnabled(isRunning || isPaused); - basicDeleteButton->setEnabled(exists); - basicDashboardButton->setEnabled(isRunning); -#if __linux__ || __APPLE__ - basicSSHButton->setEnabled(exists); -#else - basicSSHButton->setEnabled(false); -#endif - basicPauseButton->setText(getPauseLabel(isPaused)); - basicStartButton->setText(getStartLabel(isRunning)); -} - -QString Window::getPauseLabel(bool isPaused) -{ - if (isPaused) { - return tr("Unpause"); - } - return tr("Pause"); -} - -QString Window::getStartLabel(bool isRunning) -{ - if (isRunning) { - return tr("Reload"); - } - return tr("Start"); -} - -void Window::pauseOrUnpauseMinikube() -{ - Cluster cluster = selectedCluster(); - if (cluster.status() == "Paused") { - unpauseMinikube(); - return; - } - pauseMinikube(); -} - -void Window::updateAdvancedButtons(Cluster cluster) -{ - bool exists = !cluster.isEmpty(); - bool isRunning = cluster.status() == "Running"; - bool isPaused = cluster.status() == "Paused"; - startButton->setEnabled(exists); - stopButton->setEnabled(isRunning || isPaused); - pauseButton->setEnabled(isRunning || isPaused); - deleteButton->setEnabled(exists); - dashboardButton->setEnabled(isRunning); -#if __linux__ || __APPLE__ - sshButton->setEnabled(exists); -#else - sshButton->setEnabled(false); -#endif - pauseButton->setText(getPauseLabel(isPaused)); - startButton->setText(getStartLabel(isRunning)); -} - -bool Window::sendMinikubeCommand(QStringList cmds) -{ - QString text; - return sendMinikubeCommand(cmds, text); -} - -bool Window::sendMinikubeCommand(QStringList cmds, QString &text) -{ - QString program = minikubePath(); - if (program.isEmpty()) { - return false; - } - QStringList arguments = { "--user", "minikube-gui" }; - arguments << cmds; - - QProcess *process = new QProcess(this); -#if __APPLE__ - if (env.isEmpty()) { - env = setMacEnv(); - } - process->setProcessEnvironment(env); -#endif - process->start(program, arguments); - this->setCursor(Qt::WaitCursor); - bool timedOut = process->waitForFinished(300 * 1000); - int exitCode = process->exitCode(); - bool success = !timedOut && exitCode == 0; - this->unsetCursor(); - - text = process->readAllStandardOutput(); - if (success) { - } else { - qDebug() << text; - qDebug() << process->readAllStandardError(); - } - delete process; - return success; -} - -bool Window::sendMinikubeStart(QStringList cmds, QString &text) -{ - QString program = minikubePath(); - if (program.isEmpty()) { - return false; - } - QStringList arguments = { "--user", "minikube-gui" }; - arguments << cmds; - - QProcess *process = new QProcess(this); - connect(process, &QProcess::readyReadStandardOutput, - [process, this]() { startStep(process->readAllStandardOutput()); }); - startProcess = process; -#if __APPLE__ - if (env.isEmpty()) { - env = setMacEnv(); - } - startProcess->setProcessEnvironment(env); -#endif - this->setCursor(Qt::WaitCursor); - startProcess->start(program, arguments); - startProgress(); - while (startProcess->state() != QProcess::NotRunning) { - delay(); - } - endProgress(); - int exitCode = startProcess->exitCode(); - bool success = exitCode == 0; - this->unsetCursor(); - - text = startProcess->readAllStandardOutput(); - if (success) { - } else { - qDebug() << text; - qDebug() << startProcess->readAllStandardError(); - } - delete startProcess; - return success; -} - -void Window::startProgress() -{ - progressDialog = new QDialog(this); - progressDialog->resize(300, 150); - progressDialog->setWindowTitle(tr("minikube start Progress")); - progressDialog->setWindowIcon(*trayIconIcon); - progressDialog->setWindowFlags(Qt::FramelessWindowHint); - progressDialog->setModal(true); - - QVBoxLayout form(progressDialog); - progressText = new QLabel(); - progressText->setText("Starting..."); - progressText->setWordWrap(true); - form.addWidget(progressText); - progressBar.setMaximum(19); - form.addWidget(&progressBar); - QPushButton *cancel = new QPushButton(tr("Cancel")); - connect(cancel, &QAbstractButton::clicked, startProcess, &QProcess::kill); - form.addWidget(cancel); - - progressDialog->open(); -} - -void Window::endProgress() -{ - progressDialog->hide(); - progressBar.setValue(0); -} - -void Window::startStep(QString step) -{ - QStringList lines; -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - lines = step.split("\n", Qt::SkipEmptyParts); -#else - lines = step.split("\n", QString::SkipEmptyParts); -#endif - for (int i = 0; i < lines.size(); i++) { - QJsonDocument json = QJsonDocument::fromJson(lines[i].toUtf8()); - QJsonObject object = json.object(); - QString type = object["type"].toString(); - if (type != "io.k8s.sigs.minikube.step") { - return; - } - QJsonObject data = object["data"].toObject(); - QString stringStep = data["currentstep"].toString(); - int currStep = stringStep.toInt(); - QString message = data["message"].toString(); - progressBar.setValue(currStep); - progressText->setText(message); - } -} - -static QString profile = "minikube"; -static int cpus = 2; -static int memory = 2400; -static QString driver = ""; -static QString containerRuntime = ""; -static QString k8sVersion = ""; - -void Window::askName() -{ - QDialog dialog; - dialog.setWindowTitle(tr("Create minikube Cluster")); - dialog.setWindowIcon(*trayIconIcon); - dialog.setModal(true); - - QFormLayout form(&dialog); - QDialogButtonBox buttonBox(Qt::Horizontal, &dialog); - QLineEdit profileField(profile, &dialog); - form.addRow(new QLabel(tr("Profile")), &profileField); - buttonBox.addButton(QString(tr("Use Default Values")), QDialogButtonBox::AcceptRole); - connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); - buttonBox.addButton(QString(tr("Set Custom Values")), QDialogButtonBox::RejectRole); - connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); - form.addRow(&buttonBox); - - int code = dialog.exec(); - profile = profileField.text(); - if (code == QDialog::Accepted) { - QStringList args = { "-p", profile }; - startMinikube(args); - } else if (code == QDialog::Rejected) { - askCustom(); - } -} - -void Window::askCustom() -{ - QDialog dialog; - dialog.setWindowTitle(tr("Set Cluster Values")); - dialog.setWindowIcon(*trayIconIcon); - dialog.setModal(true); - - QFormLayout form(&dialog); - driverComboBox = new QComboBox; - driverComboBox->addItems({ "docker", "virtualbox", "vmware", "podman" }); -#if __linux__ - driverComboBox->addItem("kvm2"); -#elif __APPLE__ - driverComboBox->addItems({ "hyperkit", "parallels" }); -#else - driverComboBox->addItem("hyperv"); -#endif - form.addRow(new QLabel(tr("Driver")), driverComboBox); - containerRuntimeComboBox = new QComboBox; - containerRuntimeComboBox->addItems({ "docker", "containerd", "crio" }); - form.addRow(new QLabel(tr("Container Runtime")), containerRuntimeComboBox); - k8sVersionComboBox = new QComboBox; - k8sVersionComboBox->addItems({ "stable", "latest", "none" }); - form.addRow(new QLabel(tr("Kubernetes Version")), k8sVersionComboBox); - QLineEdit cpuField(QString::number(cpus), &dialog); - form.addRow(new QLabel(tr("CPUs")), &cpuField); - QLineEdit memoryField(QString::number(memory), &dialog); - form.addRow(new QLabel(tr("Memory")), &memoryField); - - QDialogButtonBox buttonBox(Qt::Horizontal, &dialog); - buttonBox.addButton(QString(tr("Create")), QDialogButtonBox::AcceptRole); - connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); - buttonBox.addButton(QString(tr("Cancel")), QDialogButtonBox::RejectRole); - connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); - form.addRow(&buttonBox); - - int code = dialog.exec(); - if (code == QDialog::Accepted) { - driver = driverComboBox->itemText(driverComboBox->currentIndex()); - containerRuntime = - containerRuntimeComboBox->itemText(containerRuntimeComboBox->currentIndex()); - k8sVersion = k8sVersionComboBox->itemText(k8sVersionComboBox->currentIndex()); - if (k8sVersion == "none") { - k8sVersion = "v0.0.0"; - } - cpus = cpuField.text().toInt(); - memory = memoryField.text().toInt(); - QStringList args = { "-p", - profile, - "--driver", - driver, - "--container-runtime", - containerRuntime, - "--kubernetes-version", - k8sVersion, - "--cpus", - QString::number(cpus), - "--memory", - QString::number(memory) }; - startMinikube(args); - } -} - -void Window::outputFailedStart(QString text) -{ - QStringList lines; -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - lines = text.split("\n", Qt::SkipEmptyParts); -#else - lines = text.split("\n", QString::SkipEmptyParts); -#endif - for (int i = 0; i < lines.size(); i++) { - QString line = lines.at(i); - QJsonParseError error; - QJsonDocument json = QJsonDocument::fromJson(line.toUtf8(), &error); - if (json.isNull() || !json.isObject()) { - continue; - } - QJsonObject par = json.object(); - QJsonObject data = par["data"].toObject(); - if (!data.contains("exitcode")) { - continue; - } - QString advice = data["advice"].toString(); - QString message = data["message"].toString(); - QString name = data["name"].toString(); - QString url = data["url"].toString(); - QString issues = data["issues"].toString(); - - QDialog dialog; - dialog.setWindowTitle(tr("minikube start failed")); - dialog.setWindowIcon(*trayIconIcon); - dialog.setFixedWidth(600); - dialog.setModal(true); - QFormLayout form(&dialog); - createLabel("Error Code", name, &form, false); - createLabel("Advice", advice, &form, false); - QTextEdit *errorMessage = new QTextEdit(); - errorMessage->setText(message); - errorMessage->setWordWrapMode(QTextOption::WrapAnywhere); - int pointSize = errorMessage->font().pointSize(); - errorMessage->setFont(QFont("Courier", pointSize)); - errorMessage->setAutoFillBackground(true); - errorMessage->setReadOnly(true); - form.addRow(errorMessage); - createLabel("Link to documentation", url, &form, true); - createLabel("Link to related issue", issues, &form, true); - QLabel *fileLabel = new QLabel(this); - fileLabel->setOpenExternalLinks(true); - fileLabel->setWordWrap(true); - QString logFile = QDir::homePath() + "/.minikube/logs/lastStart.txt"; - fileLabel->setText("View log file"); - form.addRow(fileLabel); - QDialogButtonBox buttonBox(Qt::Horizontal, &dialog); - buttonBox.addButton(QString(tr("OK")), QDialogButtonBox::AcceptRole); - connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); - form.addRow(&buttonBox); - dialog.exec(); - } -} - -QLabel *Window::createLabel(QString title, QString text, QFormLayout *form, bool isLink) -{ - QLabel *label = new QLabel(this); - if (!text.isEmpty()) { - form->addRow(label); - } - if (isLink) { - label->setOpenExternalLinks(true); - text = "" + text + ""; - } - label->setWordWrap(true); - label->setText(title + ": " + text); - return label; -} - -void Window::initMachine() -{ - askName(); - updateClustersTable(); -} - -void Window::sshConsole() -{ - QString program = minikubePath(); -#ifndef QT_NO_TERMWIDGET - QMainWindow *mainWindow = new QMainWindow(); - int startnow = 0; // set shell program first - - QTermWidget *console = new QTermWidget(startnow); - - QFont font = QApplication::font(); - font.setFamily("Monospace"); - font.setPointSize(10); - - console->setTerminalFont(font); - console->setColorScheme("Tango"); - console->setShellProgram(program); - QStringList args = { "ssh", "-p", selectedClusterName() }; - console->setArgs(args); - console->startShellProgram(); - - QObject::connect(console, SIGNAL(finished()), mainWindow, SLOT(close())); - - mainWindow->setWindowTitle(nameLabel->text()); - mainWindow->resize(800, 400); - mainWindow->setCentralWidget(console); - mainWindow->show(); -#elif __APPLE__ - QString command = program + " ssh -p " + selectedClusterName(); - QStringList arguments = { "-e", "tell app \"Terminal\"", "-e", "activate", - "-e", "do script \"" + command + "\"", "-e", "end tell" }; - QProcess *process = new QProcess(this); - process->start("/usr/bin/osascript", arguments); -#else - QString terminal = qEnvironmentVariable("TERMINAL"); - if (terminal.isEmpty()) { - terminal = "x-terminal-emulator"; - if (QStandardPaths::findExecutable(terminal).isEmpty()) { - terminal = "xterm"; - } - } - - QStringList arguments = { "-e", QString("%1 ssh -p %2").arg(program, selectedClusterName()) }; - QProcess *process = new QProcess(this); - process->start(QStandardPaths::findExecutable(terminal), arguments); -#endif -} - -#if __APPLE__ -bool Window::hyperkitPermissionFix(QStringList args, QString text) -{ - if (!text.contains("docker-machine-driver-hyperkit needs to run with elevated permissions")) { - return false; - } - if (!showHyperKitMessage()) { - return false; - } - - hyperkitPermission(); - return sendMinikubeCommand(args, text); -} - -void Window::hyperkitPermission() -{ - QString command = "sudo chown root:wheel ~/.minikube/bin/docker-machine-driver-hyperkit && " - "sudo chmod u+s ~/.minikube/bin/docker-machine-driver-hyperkit && exit"; - QStringList arguments = { "-e", "tell app \"Terminal\"", - "-e", "set w to do script \"" + command + "\"", - "-e", "activate", - "-e", "repeat", - "-e", "delay 0.1", - "-e", "if not busy of w then exit repeat", - "-e", "end repeat", - "-e", "end tell" }; - QProcess *process = new QProcess(this); - process->start("/usr/bin/osascript", arguments); - process->waitForFinished(-1); -} - -bool Window::showHyperKitMessage() -{ - QMessageBox msgBox; - msgBox.setWindowTitle(tr("HyperKit Permissions Required")); - msgBox.setWindowIcon(*trayIconIcon); - msgBox.setModal(true); - msgBox.setText(tr("The HyperKit driver requires a one-time sudo permission.\n\nIf you'd like " - "to proceed, press OK and then enter your password into the terminal prompt, " - "the start will resume after.")); - msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); - msgBox.setDefaultButton(QMessageBox::Ok); - int code = msgBox.exec(); - return code == QMessageBox::Ok; -} -#endif - -void Window::dashboardBrowser() -{ - dashboardClose(); - - QString program = minikubePath(); - QProcess *process = new QProcess(this); - QStringList arguments = { "dashboard", "-p", selectedClusterName() }; - process->start(program, arguments); - - dashboardProcess = process; - dashboardProcess->waitForStarted(); -} - -void Window::dashboardClose() -{ - if (dashboardProcess) { - dashboardProcess->terminate(); - dashboardProcess->waitForFinished(); + QString minikubePath = QStandardPaths::findExecutable("minikube"); + if (!minikubePath.isEmpty()) { + return minikubePath; } + QStringList path = { "/usr/local/bin" }; + return QStandardPaths::findExecutable("minikube", path); } void Window::checkForMinikube() @@ -1128,64 +184,4 @@ void Window::checkForMinikube() exit(EXIT_FAILURE); } -void Window::checkForUpdates() -{ - QString releases = getRequest("https://storage.googleapis.com/minikube-gui/releases.json"); - QJsonObject latestRelease = - QJsonDocument::fromJson(releases.toUtf8()).array().first().toObject(); - QString latestReleaseVersion = latestRelease["name"].toString(); - QVersionNumber latestReleaseVersionNumber = QVersionNumber::fromString(latestReleaseVersion); - if (version >= latestReleaseVersionNumber) { - return; - } - QJsonObject links = latestRelease["links"].toObject(); - QString key; -#if __linux__ - key = "linux"; -#elif __APPLE__ - key = "darwin"; -#else - key = "windows"; -#endif - QString link = links[key].toString(); - notifyUpdate(latestReleaseVersion, link); -} - -void Window::notifyUpdate(QString latest, QString link) -{ - QDialog dialog; - dialog.setWindowTitle(tr("minikube GUI Update Available")); - dialog.setWindowIcon(*trayIconIcon); - dialog.setModal(true); - QFormLayout form(&dialog); - QLabel *msgLabel = new QLabel(this); - msgLabel->setText("Version " + latest - + " of minikube GUI is now available!\n\nDownload the update from:"); - form.addWidget(msgLabel); - QLabel *linkLabel = new QLabel(this); - linkLabel->setOpenExternalLinks(true); - linkLabel->setText("" + link + ""); - form.addWidget(linkLabel); - QDialogButtonBox buttonBox(Qt::Horizontal, &dialog); - buttonBox.addButton(QString(tr("OK")), QDialogButtonBox::AcceptRole); - connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); - form.addRow(&buttonBox); - dialog.exec(); -} - -QString Window::getRequest(QString url) -{ - QNetworkAccessManager *manager = new QNetworkAccessManager(); - QObject::connect(manager, &QNetworkAccessManager::finished, this, [=](QNetworkReply *reply) { - if (reply->error()) { - qDebug() << reply->errorString(); - } - }); - QNetworkReply *resp = manager->get(QNetworkRequest(QUrl(url))); - QEventLoop loop; - connect(resp, &QNetworkReply::finished, &loop, &QEventLoop::quit); - loop.exec(); - return resp->readAll(); -} - #endif diff --git a/gui/window.h b/gui/window.h index dba9f1f95d..55a120ce77 100644 --- a/gui/window.h +++ b/gui/window.h @@ -84,6 +84,14 @@ class QProcess; QT_END_NAMESPACE #include "cluster.h" +#include "basicview.h" +#include "advancedview.h" +#include "progresswindow.h" +#include "operator.h" +#include "errormessage.h" +#include "tray.h" +#include "hyperkit.h" +#include "updater.h" class Window : public QDialog { @@ -93,128 +101,30 @@ public: Window(); void setVisible(bool visible) override; + void restoreWindow(); protected: void closeEvent(QCloseEvent *event) override; -private slots: - void messageClicked(); - void updateButtons(); - void dashboardClose(); - private: - // Tray icon - void createTrayIcon(); - void createActions(); - void updateStatus(Cluster cluster); - void updateTrayActions(Cluster cluster); - void iconActivated(QSystemTrayIcon::ActivationReason reason); - QAction *minimizeAction; - QAction *restoreAction; - QAction *quitAction; - QAction *startAction; - QAction *pauseAction; - QAction *stopAction; - QAction *statusAction; - QSystemTrayIcon *trayIcon; - QMenu *trayIconMenu; QIcon *trayIconIcon; - // Basic view - void createBasicView(); - void toBasicView(); - void updateBasicButtons(Cluster cluster); - QPushButton *basicStartButton; - QPushButton *basicStopButton; - QPushButton *basicPauseButton; - QPushButton *basicDeleteButton; - QPushButton *basicRefreshButton; - QPushButton *basicSSHButton; - QPushButton *basicDashboardButton; - - // Advanced view - void createAdvancedView(); - void toAdvancedView(); - void createClusterGroupBox(); - void updateAdvancedButtons(Cluster cluster); - QPushButton *startButton; - QPushButton *stopButton; - QPushButton *pauseButton; - QPushButton *deleteButton; - QPushButton *refreshButton; - QPushButton *createButton; - QPushButton *sshButton; - QPushButton *dashboardButton; - QWidget *advancedView; - - // Cluster table - QString selectedClusterName(); - void setSelectedClusterName(QString cluster); - Cluster selectedCluster(); - void updateClusterList(); - void updateClustersTable(); - void showLoading(); - void hideLoading(); - ClusterModel *clusterModel; - QTableView *clusterListView; - ClusterList clusterList; - QLabel *loading; - - // Create cluster - void askCustom(); - void askName(); - QComboBox *driverComboBox; - QComboBox *containerRuntimeComboBox; - QComboBox *k8sVersionComboBox; - - // Start Commands - void startMinikube(QStringList args); - void startSelectedMinikube(); - bool sendMinikubeStart(QStringList cmds, QString &text); - void startProgress(); - void endProgress(); - void startStep(QString step); - QDialog *progressDialog; - QProgressBar progressBar; - QLabel *progressText; - QProcess *startProcess; - - // Other Commands - void stopMinikube(); - void pauseMinikube(); - void unpauseMinikube(); - void pauseOrUnpauseMinikube(); - void deleteMinikube(); - bool sendMinikubeCommand(QStringList cmds); - bool sendMinikubeCommand(QStringList cmds, QString &text); - void initMachine(); - void sshConsole(); - void dashboardBrowser(); - Cluster createClusterObject(QJsonObject obj); - QProcess *dashboardProcess; - QProcessEnvironment env; -#if __APPLE__ - void hyperkitPermission(); - bool hyperkitPermissionFix(QStringList args, QString text); - bool showHyperKitMessage(); -#endif - - // Error messaging - void outputFailedStart(QString text); - QLabel *createLabel(QString title, QString text, QFormLayout *form, bool isLink); - void checkForMinikube(); - void restoreWindow(); - QString getPauseLabel(bool isPaused); - QString getStartLabel(bool isRunning); - QProcessEnvironment setMacEnv(); QStackedWidget *stackedWidget; - bool isBasicView; - void delay(); - int getCenter(int widgetSize, int parentSize); void checkForUpdates(); QString getRequest(QString url); void notifyUpdate(QString latest, QString link); + + BasicView *basicView; + AdvancedView *advancedView; + Operator *op; + CommandRunner *commandRunner; + ErrorMessage *errorMessage; + ProgressWindow *progressWindow; + Tray *tray; + HyperKit *hyperKit; + Updater *updater; + QVBoxLayout *layout; }; #endif // QT_NO_SYSTEMTRAYICON diff --git a/hack/jenkins/common.ps1 b/hack/jenkins/common.ps1 index da1201176f..dc8418a6ae 100644 --- a/hack/jenkins/common.ps1 +++ b/hack/jenkins/common.ps1 @@ -30,9 +30,11 @@ function Write-GithubStatus { $env:SHORT_COMMIT=$env:COMMIT.substring(0, 7) $gcs_bucket="minikube-builds/logs/$env:MINIKUBE_LOCATION/$env:ROOT_JOB_ID" $env:MINIKUBE_SUPPRESS_DOCKER_PERFORMANCE="true" +$GoVersion = "1.18.2" # Docker's kubectl breaks things, and comes earlier in the path than the regular kubectl. So download the expected kubectl and replace Docker's version. -(New-Object Net.WebClient).DownloadFile("https://dl.k8s.io/release/v1.20.0/bin/windows/amd64/kubectl.exe", "C:\Program Files\Docker\Docker\resources\bin\kubectl.exe") +$KubeVersion = (Invoke-WebRequest -Uri 'https://storage.googleapis.com/kubernetes-release/release/stable.txt' -UseBasicParsing).Content +(New-Object Net.WebClient).DownloadFile("https://dl.k8s.io/release/$KubeVersion/bin/windows/amd64/kubectl.exe", "C:\Program Files\Docker\Docker\resources\bin\kubectl.exe") # Setup the cleanup and reboot cron gsutil.cmd -m cp -r gs://minikube-builds/$env:MINIKUBE_LOCATION/windows_cleanup_and_reboot.ps1 C:\jenkins @@ -52,9 +54,21 @@ If ($lastexitcode -gt 0) { Exit $lastexitcode } +# Download Go +$CurrentGo = go version +if ($CurrentGo -NotLike "*$GoVersion*") { + (New-Object Net.WebClient).DownloadFile("https://go.dev/dl/go$GoVersion.windows-amd64.zip", "$env:TEMP\golang.zip") + Remove-Item "c:\Program Files\Go\*" -Recurse + Add-Type -Assembly "System.IO.Compression.Filesystem" + [System.IO.Compression.ZipFile]::ExtractToDirectory("$env:TEMP\golang.zip", "$env:TEMP\golang") + Copy-Item -Path "$env:TEMP\golang\go\*" -Destination "c:\Program Files\Go\" -Recurse + Remove-Item "$env:TEMP\golang" -Recurse + Remove-Item "$env:TEMP\golang.zip" +} + # Download gopogh and gotestsum -(New-Object Net.WebClient).DownloadFile("https://github.com/medyagh/gopogh/releases/download/v0.9.0/gopogh.exe", "C:\Go\bin\gopogh.exe") -(New-Object Net.WebClient).DownloadFile("https://github.com/gotestyourself/gotestsum/releases/download/v1.6.4/gotestsum_1.6.4_windows_amd64.tar.gz", "$env:TEMP\gotestsum.tar.gz") +(New-Object Net.WebClient).DownloadFile("https://github.com/medyagh/gopogh/releases/download/v0.13.0/gopogh.exe", "C:\Go\bin\gopogh.exe") +(New-Object Net.WebClient).DownloadFile("https://github.com/gotestyourself/gotestsum/releases/download/v1.8.1/gotestsum_1.8.1_windows_amd64.tar.gz", "$env:TEMP\gotestsum.tar.gz") tar --directory "C:\Go\bin\" -xzvf "$env:TEMP\gotestsum.tar.gz" "gotestsum.exe" # Grab all the scripts we'll need for integration tests diff --git a/hack/jenkins/common.sh b/hack/jenkins/common.sh index ccc6a70812..8b6fa75a98 100755 --- a/hack/jenkins/common.sh +++ b/hack/jenkins/common.sh @@ -421,7 +421,7 @@ if ! type "jq" > /dev/null; then fi echo ">> Installing gopogh" -curl -LO "https://github.com/medyagh/gopogh/releases/download/v0.9.0/gopogh-${OS_ARCH}" +curl -LO "https://github.com/medyagh/gopogh/releases/download/v0.13.0/gopogh-${OS_ARCH}" sudo install "gopogh-${OS_ARCH}" /usr/local/bin/gopogh diff --git a/hack/jenkins/installers/check_install_golang.sh b/hack/jenkins/installers/check_install_golang.sh index 37dea2c673..a07bb7ab4d 100755 --- a/hack/jenkins/installers/check_install_golang.sh +++ b/hack/jenkins/installers/check_install_golang.sh @@ -22,12 +22,12 @@ if (($# < 1)); then exit 1 fi -VERSION_TO_INSTALL=1.18.1 +VERSION_TO_INSTALL=1.18.2 INSTALL_PATH=${1} function current_arch() { case $(arch) in - "x86_64") + "x86_64" | "i386") echo "amd64" ;; "aarch64") diff --git a/hack/jenkins/installers/check_install_gotestsum.sh b/hack/jenkins/installers/check_install_gotestsum.sh index 4a99d7ca1c..2d58d7e6b5 100755 --- a/hack/jenkins/installers/check_install_gotestsum.sh +++ b/hack/jenkins/installers/check_install_gotestsum.sh @@ -18,7 +18,7 @@ set -eux -o pipefail function install_gotestsum() { rm -f $(which gotestsum) - GOBIN="$GOROOT/bin" go install gotest.tools/gotestsum@v1.6.4 + GOBIN="$GOROOT/bin" go install gotest.tools/gotestsum@v1.8.1 } which gotestsum || install_gotestsum diff --git a/hack/jenkins/installers/check_install_osx_crons.sh b/hack/jenkins/installers/check_install_osx_crons.sh index 1378bf63d1..2b6877f0a7 100755 --- a/hack/jenkins/installers/check_install_osx_crons.sh +++ b/hack/jenkins/installers/check_install_osx_crons.sh @@ -18,7 +18,6 @@ set -e mkdir -p cron && gsutil -qm rsync "gs://minikube-builds/${MINIKUBE_LOCATION}/cron" cron || echo "FAILED TO GET CRON FILES" install cron/cleanup_and_reboot_Darwin.sh $HOME/cleanup_and_reboot.sh || echo "FAILED TO INSTALL CLEANUP AND REBOOT" -echo "*/30 * * * * $HOME/cleanup_and_reboot.sh" | crontab install cron/cleanup_go_modules.sh $HOME/cleanup_go_modules.sh || echo "FAILED TO INSTALL GO MODULES CLEANUP" -echo "0 0 1 * * $HOME/cleanup_go_modules.sh" | crontab +echo "*/30 * * * * $HOME/cleanup_and_reboot.sh\n0 0 1 * * $HOME/cleanup_go_modules.sh" | crontab crontab -l diff --git a/hack/jenkins/release_github_page.sh b/hack/jenkins/release_github_page.sh index 932c9134d0..c4ddbbaf82 100755 --- a/hack/jenkins/release_github_page.sh +++ b/hack/jenkins/release_github_page.sh @@ -21,7 +21,8 @@ # VERSION_MAJOR: The major version of the tag to be released. # VERSION_MINOR: The minor version of the tag to be released. # VERSION_BUILD: The build version of the tag to be released. -# ISO_SHA256: The sha 256 of the minikube-iso for the current release. +# ISO_SHA256_AMD64: The sha 256 of the amd64 minikube-iso for the current release. +# ISO_SHA256_ARM64: The sha 256 of the arm64 minikube-iso for the current release. # GITHUB_TOKEN: The GitHub API access token. Injected by the Jenkins credential provider. set -eux -o pipefail @@ -62,7 +63,8 @@ See [Getting Started](https://minikube.sigs.k8s.io/docs/start/) ## ISO Checksum -\`${ISO_SHA256}\`" +amd64: \`${ISO_SHA256_AMD64}\` +arm64: \`${ISO_SHA256_ARM64}\`" # ================================================================================ # Deleting release from github before creating new one diff --git a/hack/update/cri_dockerd/update_cri_dockerd.sh b/hack/update/cri_dockerd/update_cri_dockerd.sh new file mode 100755 index 0000000000..f6ea8e841d --- /dev/null +++ b/hack/update/cri_dockerd/update_cri_dockerd.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# Copyright 2022 The Kubernetes Authors All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eux -o pipefail + +if [ "$#" -ne 2 ]; then + echo "Usage: update_cri_dockerd.sh " >&2 + exit 1 +fi + +readonly version=$1 +archlist=$2 + +IFS=, read -a archarray <<< "$archlist" + +tmpdir=$(mktemp -d) +pushd $tmpdir +git clone -n https://github.com/Mirantis/cri-dockerd +cd cri-dockerd +git checkout $version +cd src + +for (( i=0; i < ${#archarray[*]}; i++ )) +do + arch=${archarray[i]#"linux/"} + env GOOS=linux GOARCH=$arch CGO_ENABLED=0 go build -ldflags "-X github.com/Mirantis/cri-dockerd/version.GitCommit=${version:0:7}" -o cri-dockerd-$arch + gsutil cp cri-dockerd-$arch gs://kicbase-artifacts/cri-dockerd/$version/$arch/cri-dockerd + +done + +cd .. +gsutil cp ./packaging/systemd/cri-docker.service gs://kicbase-artifacts/cri-dockerd/$version/cri-docker.service +gsutil cp ./packaging/systemd/cri-docker.socket gs://kicbase-artifacts/cri-dockerd/$version/cri-docker.socket + +popd +rm -rf $tmpdir diff --git a/hack/update/golang_version/update_golang_version.go b/hack/update/golang_version/update_golang_version.go index 879639a122..b574ce79fc 100644 --- a/hack/update/golang_version/update_golang_version.go +++ b/hack/update/golang_version/update_golang_version.go @@ -100,7 +100,11 @@ var ( `GO_VERSION: .*`: `GO_VERSION: '{{.StableVersion}}'`, }, }, - + ".github/workflows/update-gopogh-version.yml": { + Replace: map[string]string{ + `GO_VERSION: .*`: `GO_VERSION: '{{.StableVersion}}'`, + }, + }, ".github/workflows/time-to-k8s-public-chart.yml": { Replace: map[string]string{ `GO_VERSION: .*`: `GO_VERSION: '{{.StableVersion}}'`, @@ -111,6 +115,11 @@ var ( `GO_VERSION: .*`: `GO_VERSION: '{{.StableVersion}}'`, }, }, + ".github/workflows/update-gotestsum-version.yml": { + Replace: map[string]string{ + `GO_VERSION: .*`: `GO_VERSION: '{{.StableVersion}}'`, + }, + }, "go.mod": { Replace: map[string]string{ `(?m)^go .*`: `go {{.StableVersionMM}}`, @@ -128,6 +137,11 @@ var ( `VERSION_TO_INSTALL=.*`: `VERSION_TO_INSTALL={{.StableVersion}}`, }, }, + "hack/jenkins/common.ps1": { + Replace: map[string]string{ + `GoVersion = ".*"`: `GoVersion = "{{.StableVersion}}"`, + }, + }, } // PR data diff --git a/hack/update/gopogh_version/update_gopogh_version.go b/hack/update/gopogh_version/update_gopogh_version.go index aca9092abe..c99c987919 100644 --- a/hack/update/gopogh_version/update_gopogh_version.go +++ b/hack/update/gopogh_version/update_gopogh_version.go @@ -99,7 +99,7 @@ func main() { // gopoghVersion returns gopogh stable version in semver format. func gopoghVersion(ctx context.Context, owner, repo string) (stable string, err error) { - // get Kubernetes versions from GitHub Releases + // get gopogh versions from GitHub Releases stable, _, _, err = update.GHReleases(ctx, owner, repo) if err != nil || !semver.IsValid(stable) { return "", err diff --git a/hack/update/gotestsum_version/update_gotestsum_version.go b/hack/update/gotestsum_version/update_gotestsum_version.go new file mode 100644 index 0000000000..8e00573a4a --- /dev/null +++ b/hack/update/gotestsum_version/update_gotestsum_version.go @@ -0,0 +1,94 @@ +/* +Copyright 2022 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Script expects the following env variables: + - UPDATE_TARGET=: optional - if unset/absent, default option is "fs"; valid options are: + - "fs" - update only local filesystem repo files [default] + - "gh" - update only remote GitHub repo files and create PR (if one does not exist already) + - "all" - update local and remote repo files and create PR (if one does not exist already) + - GITHUB_TOKEN=: GitHub [personal] access token + - note: GITHUB_TOKEN is required if UPDATE_TARGET is "gh" or "all" +*/ + +package main + +import ( + "context" + "strings" + "time" + + "golang.org/x/mod/semver" + "k8s.io/klog/v2" + + "k8s.io/minikube/hack/update" +) + +const ( + // default context timeout + cxTimeout = 300 * time.Second +) + +var ( + schema = map[string]update.Item{ + "hack/jenkins/common.ps1": { + Replace: map[string]string{ + `(?U)https://github.com/gotestyourself/gotestsum/releases/download/.*/gotestsum_.*_`: `https://github.com/gotestyourself/gotestsum/releases/download/v{{.StableVersion}}/gotestsum_{{.StableVersion}}_`, + }, + }, + "hack/jenkins/installers/check_install_gotestsum.sh": { + Replace: map[string]string{ + `gotest.tools/gotestsum@.*`: `gotest.tools/gotestsum@v{{.StableVersion}}`, + }, + }, + } + + // PR data + prBranchPrefix = "update-gotestsum-version_" // will be appended with first 7 characters of the PR commit SHA + prTitle = `update_gotestsum_version: {stable: "{{.StableVersion}}"}` + prIssue = 14224 +) + +// Data holds stable gotestsum version in semver format. +type Data struct { + StableVersion string `json:"stableVersion"` +} + +func main() { + // set a context with defined timeout + ctx, cancel := context.WithTimeout(context.Background(), cxTimeout) + defer cancel() + + // get gotestsum stable version from https://github.com/gotestyourself/gotestsum + stable, err := gotestsumVersion(ctx, "gotestyourself", "gotestsum") + if err != nil || stable == "" { + klog.Fatalf("Unable to get gotestsum stable version: %v", err) + } + data := Data{StableVersion: strings.TrimPrefix(stable, "v")} + klog.Infof("gotestsum stable version: %s", data.StableVersion) + + update.Apply(ctx, schema, data, prBranchPrefix, prTitle, prIssue) +} + +// gotestsumVersion returns gotestsum stable version in semver format. +func gotestsumVersion(ctx context.Context, owner, repo string) (stable string, err error) { + // get gotestsum versions from GitHub Releases + stable, _, _, err = update.GHReleases(ctx, owner, repo) + if err != nil || !semver.IsValid(stable) { + return "", err + } + return stable, nil +} diff --git a/pkg/drivers/kic/oci/cgroups_linux.go b/pkg/drivers/kic/oci/cgroups_linux.go index c31c87284c..2ced555223 100644 --- a/pkg/drivers/kic/oci/cgroups_linux.go +++ b/pkg/drivers/kic/oci/cgroups_linux.go @@ -22,29 +22,18 @@ import ( "fmt" "os" "path" - "syscall" "github.com/opencontainers/runc/libcontainer/cgroups" - "golang.org/x/sys/unix" "k8s.io/klog/v2" ) -// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode. -func IsCgroup2UnifiedMode() (bool, error) { - var st syscall.Statfs_t - if err := syscall.Statfs("/sys/fs/cgroup", &st); err != nil { - return false, err - } - return st.Type == unix.CGROUP2_SUPER_MAGIC, nil -} - // findCgroupMountpoints returns the cgroups mount point // defined in docker engine engine/pkg/sysinfo/sysinfo_linux.go func findCgroupMountpoints() (map[string]string, error) { cgMounts, err := cgroups.GetCgroupMounts(false) if err != nil { - return nil, fmt.Errorf("Failed to parse cgroup information: %v", err) + return nil, fmt.Errorf("failed to parse cgroup information: %v", err) } mps := make(map[string]string) for _, m := range cgMounts { diff --git a/pkg/drivers/kic/oci/cgroups_other.go b/pkg/drivers/kic/oci/cgroups_other.go index 55dc8b8175..db124317a6 100644 --- a/pkg/drivers/kic/oci/cgroups_other.go +++ b/pkg/drivers/kic/oci/cgroups_other.go @@ -18,17 +18,6 @@ limitations under the License. package oci -import ( - "runtime" - - "github.com/pkg/errors" -) - -// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 cgroup2 mode. -func IsCgroup2UnifiedMode() (bool, error) { - return false, errors.Errorf("Not supported on %s", runtime.GOOS) -} - func HasMemoryCgroup() bool { return true } diff --git a/pkg/drivers/kic/types.go b/pkg/drivers/kic/types.go index 3b33b239f8..2de298b003 100644 --- a/pkg/drivers/kic/types.go +++ b/pkg/drivers/kic/types.go @@ -24,13 +24,13 @@ import ( const ( // Version is the current version of kic - Version = "v0.0.31" + Version = "v0.0.31-1653596720-14230" // SHA of the kic base image - baseImageSHA = "470039ae4fb6cd41e5a15e80280a7f154e46b4b943abca039049973628947f0b" + baseImageSHA = "e953786303ac8350802546ee187d34e89f0007072a54fdbcc2f86a1fb8575418" // The name of the GCR kicbase repository - gcrRepo = "gcr.io/k8s-minikube/kicbase" + gcrRepo = "gcr.io/k8s-minikube/kicbase-builds" // The name of the Dockerhub kicbase repository - dockerhubRepo = "docker.io/kicbase/stable" + dockerhubRepo = "docker.io/kicbase/build" ) var ( diff --git a/pkg/drivers/qemu/qemu.go b/pkg/drivers/qemu/qemu.go index 08ceb5441d..2919735d9c 100644 --- a/pkg/drivers/qemu/qemu.go +++ b/pkg/drivers/qemu/qemu.go @@ -38,6 +38,7 @@ import ( "github.com/docker/machine/libmachine/mcnutils" "github.com/docker/machine/libmachine/ssh" "github.com/docker/machine/libmachine/state" + "github.com/pkg/errors" pkgdrivers "k8s.io/minikube/pkg/drivers" ) @@ -79,13 +80,9 @@ type Driver struct { DiskPath string CacheMode string IOMode string - connectionString string - // conn *libvirt.Connect - // VM *libvirt.Domain - vmLoaded bool - UserDataFile string - CloudConfigRoot string - LocalPorts string + UserDataFile string + CloudConfigRoot string + LocalPorts string } func (d *Driver) GetMachineName() string { @@ -273,21 +270,25 @@ func parsePortRange(rawPortRange string) (int, int, error) { portRange := strings.Split(rawPortRange, "-") + if len(portRange) < 2 { + return 0, 0, errors.New("Invalid port range, must be at least of length 2") + } + minPort, err := strconv.Atoi(portRange[0]) if err != nil { - return 0, 0, fmt.Errorf("Invalid port range") + return 0, 0, errors.Wrap(err, "Invalid port range") } maxPort, err := strconv.Atoi(portRange[1]) if err != nil { - return 0, 0, fmt.Errorf("Invalid port range") + return 0, 0, errors.Wrap(err, "Invalid port range") } if maxPort < minPort { - return 0, 0, fmt.Errorf("Invalid port range") + return 0, 0, errors.New("Invalid port range") } if maxPort-minPort < 2 { - return 0, 0, fmt.Errorf("Port range must be minimum 2 ports") + return 0, 0, errors.New("Port range must be minimum 2 ports") } return minPort, maxPort, nil @@ -327,7 +328,7 @@ func getAvailableTCPPortFromRange(minPort int, maxPort int) (int, error) { port = p return port, nil } - time.Sleep(1) + time.Sleep(1 * time.Second) } return 0, fmt.Errorf("unable to allocate tcp port") } @@ -340,10 +341,6 @@ func (d *Driver) Start() error { if d.MachineType != "" { machineType := d.MachineType - if runtime.GOOS == "darwin" { - // highmem=off needed, see https://patchwork.kernel.org/project/qemu-devel/patch/20201126215017.41156-9-agraf@csgraf.de/#23800615 for details - machineType += ",accel=hvf,highmem=off" - } startCmd = append(startCmd, "-M", machineType, ) @@ -368,9 +365,8 @@ func (d *Driver) Start() error { startCmd = append(startCmd, "-display", d.DisplayType, ) - } else { - // Use the default graphic output } + // else use the default graphic output } else { if d.Nographic { startCmd = append(startCmd, @@ -383,6 +379,13 @@ func (d *Driver) Start() error { } } + // hardware acceleration is important, it increases performance by 10x + if runtime.GOOS == "darwin" { + startCmd = append(startCmd, "-accel", "hvf") + } else if _, err := os.Stat("/dev/kvm"); err == nil && runtime.GOOS == "linux" { + startCmd = append(startCmd, "-accel", "kvm") + } + startCmd = append(startCmd, "-m", fmt.Sprintf("%d", d.Memory), "-smp", fmt.Sprintf("%d", d.CPU), @@ -422,12 +425,6 @@ func (d *Driver) Start() error { startCmd = append(startCmd, "-daemonize") - // other options - // "-enable-kvm" if its available - if _, err := os.Stat("/dev/kvm"); err == nil { - startCmd = append(startCmd, "-enable-kvm") - } - if d.CloudConfigRoot != "" { startCmd = append(startCmd, "-fsdev", @@ -490,17 +487,17 @@ func (d *Driver) Stop() error { func (d *Driver) Remove() error { s, err := d.GetState() if err != nil { - return err + return errors.Wrap(err, "get state") } if s == state.Running { if err := d.Kill(); err != nil { - return err + return errors.Wrap(err, "kill") } } if s != state.Stopped { _, err = d.RunQMPCommand("quit") if err != nil { - return err + return errors.Wrap(err, "quit") } } return nil diff --git a/pkg/minikube/assets/addons.go b/pkg/minikube/assets/addons.go index 371e0e7bb7..8fbeb0b662 100755 --- a/pkg/minikube/assets/addons.go +++ b/pkg/minikube/assets/addons.go @@ -813,6 +813,7 @@ func GenerateTemplateData(addon *Addon, cfg config.KubernetesConfig, netInfo Net CustomIngressCert string IngressAPIVersion string ContainerRuntime string + RegistryAliases string Images map[string]string Registries map[string]string CustomRegistries map[string]string @@ -825,6 +826,7 @@ func GenerateTemplateData(addon *Addon, cfg config.KubernetesConfig, netInfo Net LoadBalancerStartIP: cfg.LoadBalancerStartIP, LoadBalancerEndIP: cfg.LoadBalancerEndIP, CustomIngressCert: cfg.CustomIngressCert, + RegistryAliases: cfg.RegistryAliases, IngressAPIVersion: "v1", // api version for ingress (eg, "v1beta1"; defaults to "v1" for k8s 1.19+) ContainerRuntime: cfg.ContainerRuntime, Images: images, diff --git a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go index 05c5ac1acf..65a51c8162 100644 --- a/pkg/minikube/bootstrapper/kubeadm/kubeadm.go +++ b/pkg/minikube/bootstrapper/kubeadm/kubeadm.go @@ -290,6 +290,10 @@ func (k *Bootstrapper) init(cfg config.ClusterConfig) error { }() wg.Wait() + // Tunnel apiserver to guest, if necessary + if cfg.APIServerPort != 0 { + k.tunnelToAPIServer(cfg) + } return nil } @@ -399,6 +403,10 @@ func (k *Bootstrapper) StartCluster(cfg config.ClusterConfig) error { } if err := bsutil.ExistingConfig(k.c); err == nil { + // If the guest already exists and was stopped, re-establish the apiserver tunnel so checks pass + if cfg.APIServerPort != 0 { + k.tunnelToAPIServer(cfg) + } klog.Infof("found existing configuration files, will attempt cluster restart") rerr := k.restartControlPlane(cfg) if rerr == nil { @@ -433,6 +441,22 @@ func (k *Bootstrapper) StartCluster(cfg config.ClusterConfig) error { return err } +func (k *Bootstrapper) tunnelToAPIServer(cfg config.ClusterConfig) { + m, err := machine.NewAPIClient() + if err != nil { + klog.Warningf("libmachine API failed: %v", err) + } + cp, err := config.PrimaryControlPlane(&cfg) + if err != nil { + klog.Warningf("finding control plane failed: %v", err) + } + args := []string{"-f", "-NTL", fmt.Sprintf("%d:localhost:8443", cfg.APIServerPort)} + err = machine.CreateSSHShell(m, cfg, cp, args, false) + if err != nil { + klog.Warningf("apiserver tunnel failed: %v", err) + } +} + // client sets and returns a Kubernetes client to use to speak to a kubeadm launched apiserver func (k *Bootstrapper) client(ip string, port int) (*kubernetes.Clientset, error) { if k.k8sClient != nil { @@ -569,6 +593,7 @@ func (k *Bootstrapper) needsReconfigure(conf string, hostname string, port int, klog.Infof("needs reconfigure: configs differ:\n%s", rr.Output()) return true } + // cruntime.Enable() may restart kube-apiserver but does not wait for it to return back apiStatusTimeout := 3000 * time.Millisecond st, err := kverify.WaitForAPIServerStatus(k.c, apiStatusTimeout, hostname, port) diff --git a/pkg/minikube/config/types.go b/pkg/minikube/config/types.go index 4566aeb27b..7c3b5b0786 100644 --- a/pkg/minikube/config/types.go +++ b/pkg/minikube/config/types.go @@ -120,6 +120,7 @@ type KubernetesConfig struct { LoadBalancerStartIP string // currently only used by MetalLB addon LoadBalancerEndIP string // currently only used by MetalLB addon CustomIngressCert string // used by Ingress addon + RegistryAliases string // currently only used by registry-aliases addon ExtraOptions ExtraOptionSlice ShouldLoadCachedImages bool diff --git a/pkg/minikube/download/iso.go b/pkg/minikube/download/iso.go index dcbe6c9089..a5ecc47cf0 100644 --- a/pkg/minikube/download/iso.go +++ b/pkg/minikube/download/iso.go @@ -41,7 +41,7 @@ const fileScheme = "file" // DefaultISOURLs returns a list of ISO URL's to consult by default, in priority order func DefaultISOURLs() []string { v := version.GetISOVersion() - isoBucket := "minikube-builds/iso/13807" + isoBucket := "minikube-builds/iso/14153" return []string{ fmt.Sprintf("https://storage.googleapis.com/%s/minikube-%s-%s.iso", isoBucket, v, runtime.GOARCH), fmt.Sprintf("https://github.com/kubernetes/minikube/releases/download/%s/minikube-%s-%s.iso", v, v, runtime.GOARCH), diff --git a/pkg/minikube/node/start.go b/pkg/minikube/node/start.go index b721f04361..730bb6f03d 100644 --- a/pkg/minikube/node/start.go +++ b/pkg/minikube/node/start.go @@ -253,15 +253,6 @@ func handleAPIServer(starter Starter, cr cruntime.Manager, hostIP net.IP) (*kube return nil, bs, err } - // Tunnel apiserver to guest, if needed - if starter.Cfg.APIServerPort != 0 { - args := []string{"-f", "-NTL", fmt.Sprintf("%d:localhost:8443", starter.Cfg.APIServerPort)} - err := machine.CreateSSHShell(starter.MachineAPI, *starter.Cfg, *starter.Node, args, false) - if err != nil { - klog.Warningf("apiserver tunnel failed: %v", err) - } - } - // Write the kubeconfig to the file system after everything required (like certs) are created by the bootstrapper. if err := kubeconfig.Update(kcs); err != nil { return nil, bs, errors.Wrap(err, "Failed kubeconfig update") diff --git a/pkg/minikube/registry/drvs/qemu2/qemu2.go b/pkg/minikube/registry/drvs/qemu2/qemu2.go index 229f3ba3cc..5cd70e58f1 100644 --- a/pkg/minikube/registry/drvs/qemu2/qemu2.go +++ b/pkg/minikube/registry/drvs/qemu2/qemu2.go @@ -18,8 +18,10 @@ package qemu2 import ( "fmt" + "io/ioutil" "os" "os/exec" + "path" "path/filepath" "runtime" @@ -64,17 +66,35 @@ func qemuSystemProgram() (string, error) { func qemuFirmwarePath() (string, error) { arch := runtime.GOARCH + // For macOS, find the correct brew installation path for qemu firmware + if runtime.GOOS == "darwin" { + var p, fw string + switch arch { + case "amd64": + p = "/usr/local/Cellar/qemu" + fw = "share/qemu/edk2-x86_64-code.fd" + case "arm64": + p = "/opt/homebrew/Cellar/qemu" + fw = "share/qemu/edk2-aarch64-code.fd" + default: + return "", fmt.Errorf("unknown arch: %s", arch) + } + + v, err := ioutil.ReadDir(p) + if err != nil { + return "", fmt.Errorf("lookup qemu: %v", err) + } + for _, version := range v { + if version.IsDir() { + return path.Join(p, version.Name(), fw), nil + } + } + } + switch arch { case "amd64": - // on macOS, we assume qemu is installed via homebrew for simplicity - if runtime.GOOS == "darwin" { - return "/usr/local/Cellar/qemu/6.2.0_1/share/qemu/edk2-x86_64-code.fd", nil - } return "/usr/share/OVMF/OVMF_CODE.fd", nil case "arm64": - if runtime.GOOS == "darwin" { - return "/opt/homebrew/Cellar/qemu/6.2.0_1/share/qemu/edk2-aarch64-code.fd", nil - } return "/usr/share/AAVMF/AAVMF_CODE.fd", nil default: return "", fmt.Errorf("unknown arch: %s", arch) @@ -96,6 +116,13 @@ func configure(cc config.ClusterConfig, n config.Node) (interface{}, error) { case "arm64": qemuMachine = "virt" qemuCPU = "cortex-a72" + // highmem=off needed, see https://patchwork.kernel.org/project/qemu-devel/patch/20201126215017.41156-9-agraf@csgraf.de/#23800615 for details + if runtime.GOOS == "darwin" { + qemuMachine = "virt,highmem=off" + } else if _, err := os.Stat("/dev/kvm"); err == nil { + qemuMachine = "virt,gic-version=3" + qemuCPU = "host" + } default: return nil, fmt.Errorf("unknown arch: %s", runtime.GOARCH) } diff --git a/site/content/en/docs/commands/start.md b/site/content/en/docs/commands/start.md index d158043482..7c75a3dc22 100644 --- a/site/content/en/docs/commands/start.md +++ b/site/content/en/docs/commands/start.md @@ -26,7 +26,7 @@ minikube start [flags] --apiserver-names strings A set of apiserver names which are used in the generated certificate for kubernetes. This can be used if you want to make the apiserver available from outside the machine --apiserver-port int The apiserver listening port (default 8443) --auto-update-drivers If set, automatically updates drivers to the latest version. Defaults to true. (default true) - --base-image string The base image to use for docker/podman drivers. Intended for local development. (default "gcr.io/k8s-minikube/kicbase:v0.0.31@sha256:470039ae4fb6cd41e5a15e80280a7f154e46b4b943abca039049973628947f0b") + --base-image string The base image to use for docker/podman drivers. Intended for local development. (default "gcr.io/k8s-minikube/kicbase-builds:v0.0.31-1653596720-14230@sha256:e953786303ac8350802546ee187d34e89f0007072a54fdbcc2f86a1fb8575418") --binary-mirror string Location to fetch kubectl, kubelet, & kubeadm binaries from. --cache-images If true, cache docker images for the current bootstrapper and load them into the machine. Always false with --driver=none. (default true) --cert-expiration duration Duration until minikube certificate expiration, defaults to three years (26280h). (default 26280h0m0s) @@ -69,7 +69,7 @@ minikube start [flags] --insecure-registry strings Insecure Docker registries to pass to the Docker daemon. The default service CIDR range will automatically be added. --install-addons If set, install addons. Defaults to true. (default true) --interactive Allow user prompts for more information (default true) - --iso-url strings Locations to fetch the minikube ISO from. (default [https://storage.googleapis.com/minikube-builds/iso/13807/minikube-v1.26.0-1652914268-13807-amd64.iso,https://github.com/kubernetes/minikube/releases/download/v1.26.0-1652914268-13807/minikube-v1.26.0-1652914268-13807-amd64.iso,https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.26.0-1652914268-13807-amd64.iso,https://storage.googleapis.com/minikube-builds/iso/13807/minikube-v1.26.0-1652914268-13807.iso,https://github.com/kubernetes/minikube/releases/download/v1.26.0-1652914268-13807/minikube-v1.26.0-1652914268-13807.iso,https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.26.0-1652914268-13807.iso]) + --iso-url strings Locations to fetch the minikube ISO from. (default [https://storage.googleapis.com/minikube-builds/iso/14153/minikube-v1.26.0-1652998508-14153-amd64.iso,https://github.com/kubernetes/minikube/releases/download/v1.26.0-1652998508-14153/minikube-v1.26.0-1652998508-14153-amd64.iso,https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.26.0-1652998508-14153-amd64.iso,https://storage.googleapis.com/minikube-builds/iso/14153/minikube-v1.26.0-1652998508-14153.iso,https://github.com/kubernetes/minikube/releases/download/v1.26.0-1652998508-14153/minikube-v1.26.0-1652998508-14153.iso,https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.26.0-1652998508-14153.iso]) --keep-context This will keep the existing kubectl context and will create a minikube context. --kubernetes-version string The Kubernetes version that the minikube VM will use (ex: v1.2.3, 'stable' for v1.23.6, 'latest' for v1.23.6). Defaults to 'stable'. --kvm-gpu Enable experimental NVIDIA GPU support in minikube diff --git a/site/content/en/docs/contrib/releasing/binaries.md b/site/content/en/docs/contrib/releasing/binaries.md index ed54e1e85a..983bcaa39d 100644 --- a/site/content/en/docs/contrib/releasing/binaries.md +++ b/site/content/en/docs/contrib/releasing/binaries.md @@ -72,7 +72,8 @@ This step uses the git tag to publish new binaries to GCS and create a GitHub re * Ensure that you are logged in (top right) * Click "▶️ Build with Parameters" (left) * `VERSION_MAJOR`, `VERSION_MINOR`, and `VERSION_BUILD` should reflect the values in your Makefile -* For `ISO_SHA256`, run: `gsutil cat gs://minikube/iso/minikube-v.iso.sha256` +* For `ISO_SHA256_AMD64`, run: `gsutil cat gs://minikube/iso/minikube-v-amd64.iso.sha256` +* For `ISO_SHA256_ARM64`, run: `gsutil cat gs://minikube/iso/minikube-v-arm64.iso.sha256` * Click *Build* ## Check the release logs diff --git a/site/content/en/docs/handbook/accessing.md b/site/content/en/docs/handbook/accessing.md index 09a77f9a2c..9ad403b6fb 100644 --- a/site/content/en/docs/handbook/accessing.md +++ b/site/content/en/docs/handbook/accessing.md @@ -25,10 +25,77 @@ A NodePort service is the most basic way to get external traffic directly to you We also have a shortcut for fetching the minikube IP and a service's `NodePort`: ```shell -minikube service --url +minikube service --url ``` -## Getting the NodePort using kubectl +### Using `minikube service` with tunnel + +The network is limited if using the Docker driver on Darwin, Windows, or WSL, and the Node IP is not reachable directly. + +Running minikube on Linux with the Docker driver will result in no tunnel being created. + +Services of type `NodePort` can be exposed via the `minikube service --url` command. It must be run in a separate terminal window to keep the [tunnel](https://en.wikipedia.org/wiki/Port_forwarding#Local_port_forwarding) open. Ctrl-C in the terminal can be used to terminate the process at which time the network routes will be cleaned up. + +### Example of NodePort + +1. Create a Kubernetes deployment + + ```shell + kubectl create deployment hello-minikube1 --image=k8s.gcr.io/echoserver:1.4 + ``` + +2. Create a Kubernetes service type NodePort + + ```shell + kubectl expose deployment hello-minikube1 --type=NodePort --port=8080 + ``` + +3. Check Node Port + + ```shell + kubectl get svc + ``` +
+    $ kc get svc
+    AME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
+    hello-minikube1   NodePort    10.100.238.34           8080:31389/TCP   3s
+    
+ +4. Run service tunnel + + ```shell + minikube service hello-minikube1 --url + ``` + + `minikube service hello-minikube1 --url` runs as a process, creating a [tunnel](https://en.wikipedia.org/wiki/Port_forwarding#Local_port_forwarding) to the cluster. The command exposes the service directly to any program running on the host operating system. + +
+ + service output example + +
+    $ minikube service hello-minikube1 --url
+    http://127.0.0.1:57123
+    ❗  Because you are using a Docker driver on darwin, the terminal needs to be open to run it.
+    
+
+ + Check ssh tunnel in another terminal + + ```shell + $ ps -ef | grep docker@127.0.0.1 + ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -N docker@127.0.0.1 -p 55972 -i /Users/FOO/.minikube/machines/minikube/id_rsa -L TUNNEL_PORT:CLUSTER_IP:TARGET_PORT + ``` + +5. Try in your browser + + Open in your browser (ensure there is no proxy set) + + ```shell + http://127.0.0.1:TUNNEL_PORT + ``` + +### Getting the NodePort using kubectl The minikube VM is exposed to the host system via a host-only IP address, that can be obtained with the `minikube ip` command. Any services of type `NodePort` can be accessed over that IP address, on the NodePort. @@ -54,77 +121,78 @@ This flag also accepts a comma separated list of ports and port ranges. A LoadBalancer service is the standard way to expose a service to the internet. With this method, each service gets its own IP address. -## Using `minikube tunnel` +### Using `minikube tunnel` Services of type `LoadBalancer` can be exposed via the `minikube tunnel` command. It must be run in a separate terminal window to keep the `LoadBalancer` running. Ctrl-C in the terminal can be used to terminate the process at which time the network routes will be cleaned up. -## Example +### Example of LoadBalancer -#### Run tunnel in a separate terminal +1. Run the tunnel in a separate terminal -it will ask for password. + It will ask for a password. -```shell -minikube tunnel -``` + ```shell + minikube tunnel + ``` -`minikube tunnel` runs as a process, creating a network route on the host to the service CIDR of the cluster using the cluster's IP address as a gateway. The tunnel command exposes the external IP directly to any program running on the host operating system. + `minikube tunnel` runs as a process, creating a network route on the host to the service CIDR of the cluster using the cluster's IP address as a gateway. The tunnel command exposes the external IP directly to any program running on the host operating system. -
- -tunnel output example - -
-Password:
-Status:
- machine: minikube
- pid: 39087
- route: 10.96.0.0/12 -> 192.168.64.194
- minikube: Running
- services: [hello-minikube]
-    errors:
-  minikube: no errors
-  router: no errors
-  loadbalancer emulator: no errors
-...
-...
-...
-
-
+
+ + tunnel output example + +
+    Password:
+    Status:
+    machine: minikube
+    pid: 39087
+    route: 10.96.0.0/12 -> 192.168.64.194
+    minikube: Running
+    services: [hello-minikube]
+        errors:
+      minikube: no errors
+      router: no errors
+      loadbalancer emulator: no errors
+    ...
+    ...
+    ...
+    
+
-#### Create a kubernetes deployment +2. Create a Kubernetes deployment -```shell -kubectl create deployment hello-minikube1 --image=k8s.gcr.io/echoserver:1.4 -``` + ```shell + kubectl create deployment hello-minikube1 --image=k8s.gcr.io/echoserver:1.4 + ``` -#### Create a kubernetes service type LoadBalancer +3. Create a Kubernetes service with type LoadBalancer -```shell -kubectl expose deployment hello-minikube1 --type=LoadBalancer --port=8080 -``` + ```shell + kubectl expose deployment hello-minikube1 --type=LoadBalancer --port=8080 + ``` -### Check external IP +4. Check the external IP -```shell -kubectl get svc -``` -
-$ kc get svc
-NAME              TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
-hello-minikube1   LoadBalancer   10.96.184.178   10.96.184.178   8080:30791/TCP   40s
-
+ ```shell + kubectl get svc + ``` +
+    $ kc get svc
+    NAME              TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
+    hello-minikube1   LoadBalancer   10.96.184.178   10.96.184.178   8080:30791/TCP   40s
+    
-note that without minikube tunnel, kubernetes would be showing external IP as "pending". + Note that without minikube tunnel, Kubernetes will show the external IP as "pending". -### Try in your browser +5. Try in your browser -open in your browser (make sure there is no proxy set) -``` -http://REPLACE_WITH_EXTERNAL_IP:8080 -``` + Open in your browser (ensure there is no proxy set) -Each service will get its own external ip. + ```shell + http://REPLACE_WITH_EXTERNAL_IP:8080 + ``` + + Each service will get its own external IP. ---- @@ -150,12 +218,12 @@ Adding a route requires root privileges for the user, and thus there are differe - ### Access to ports <1024 on Windows requires root permission + If you are using Docker driver on Windows, there is a chance that you have an old version of SSH client you might get an error like - `Privileged ports can only be forwarded by root.` or you might not be able to access the service even after `minikube tunnel` if the access port is less than 1024 but for ports greater than 1024 works fine. In order to resolve this, ensure that you are running the latest version of SSH client. You can install the latest version of the SSH client on Windows by running the following in a Command Prompt with an Administrator Privileges (Requires [chocolatey package manager](https://chocolatey.org/install)) -``` +```cmd choco install openssh ``` -The latest version (`OpenSSH_for_Windows_7.7p1, LibreSSL 2.6.5`) which is available on Windows 10 by default doesn't work. You can track the issue with this over here - https://github.com/PowerShell/Win32-OpenSSH/issues/1693 \ No newline at end of file +The latest version (`OpenSSH_for_Windows_7.7p1, LibreSSL 2.6.5`) which is available on Windows 10 by default doesn't work. You can track the issue with this over here - https://github.com/PowerShell/Win32-OpenSSH/issues/1693 diff --git a/site/content/en/docs/start/_index.md b/site/content/en/docs/start/_index.md index 95581fe416..7e245b8de9 100644 --- a/site/content/en/docs/start/_index.md +++ b/site/content/en/docs/start/_index.md @@ -438,7 +438,7 @@ choco install minikube {{% /quiz_instruction %}} {{% quiz_instruction id="/Windows/x86-64/Stable/.exe download" %}} -1. Download the [latest release](https://storage.googleapis.com/minikube/releases/latest/minikube-installer.exe). +1. Download and run the installer for the [latest release](https://storage.googleapis.com/minikube/releases/latest/minikube-installer.exe).
Or if using `PowerShell`, use this command: ```powershell @@ -446,7 +446,7 @@ choco install minikube Invoke-WebRequest -OutFile 'c:\minikube\minikube.exe' -Uri 'https://github.com/kubernetes/minikube/releases/latest/download/minikube-windows-amd64.exe' -UseBasicParsing ``` -2. Add the binary in to your `PATH`. +2. Add the `minikube.exe` binary to your `PATH`.
_Make sure to run PowerShell as Administrator._ ```powershell @@ -459,7 +459,7 @@ choco install minikube {{% /quiz_instruction %}} {{% quiz_instruction id="/Windows/x86-64/Beta/.exe download" %}} -1. Download the latest beta release. +1. Download and run the installer for the latest beta release.
Or if using `PowerShell`, use this command: ```powershell @@ -470,7 +470,7 @@ choco install minikube Invoke-WebRequest -Uri $item.browser_download_url -OutFile 'c:\minikube\minikube.exe' -UseBasicParsing ``` -2. Add the binary in to your `PATH`. +2. Add the `minikube.exe` binary to your `PATH`.
_Make sure to run PowerShell as Administrator._ ```powershell diff --git a/test/integration/functional_test.go b/test/integration/functional_test.go index b04df234f5..a3109b1b70 100644 --- a/test/integration/functional_test.go +++ b/test/integration/functional_test.go @@ -49,7 +49,7 @@ import ( "github.com/blang/semver/v4" "github.com/elazarl/goproxy" "github.com/hashicorp/go-retryablehttp" - "github.com/otiai10/copy" + cp "github.com/otiai10/copy" "github.com/phayes/freeport" "github.com/pkg/errors" "golang.org/x/build/kubernetes/api" @@ -480,10 +480,7 @@ func validateDockerEnv(ctx context.Context, t *testing.T, profile string) { defer cancel() command := make([]string, len(tc.commandPrefix)+1) - // Would use "copy" built-in here, but that is shadowed by "copy" package - for i, v := range tc.commandPrefix { - command[i] = v - } + copy(command, tc.commandPrefix) formattedArg := fmt.Sprintf(tc.formatArg, Target(), profile) @@ -1783,7 +1780,7 @@ func setupFileSync(ctx context.Context, t *testing.T, profile string) { p := localSyncTestPath() t.Logf("local sync path: %s", p) syncFile := filepath.Join(*testdataDir, "sync.test") - err := copy.Copy(syncFile, p) + err := cp.Copy(syncFile, p) if err != nil { t.Fatalf("failed to copy testdata/sync.test: %v", err) } @@ -1792,7 +1789,7 @@ func setupFileSync(ctx context.Context, t *testing.T, profile string) { // Write to a temp file for an atomic write tmpPem := localTestCertPath() + ".pem" - if err := copy.Copy(testPem, tmpPem); err != nil { + if err := cp.Copy(testPem, tmpPem); err != nil { t.Fatalf("failed to copy %s: %v", testPem, err) } @@ -1816,7 +1813,7 @@ func setupFileSync(ctx context.Context, t *testing.T, profile string) { testPem2 := filepath.Join(*testdataDir, "minikube_test2.pem") tmpPem2 := localTestCertFilesPath() + ".pem" - if err := copy.Copy(testPem2, tmpPem2); err != nil { + if err := cp.Copy(testPem2, tmpPem2); err != nil { t.Fatalf("failed to copy %s: %v", testPem2, err) } diff --git a/test/integration/net_test.go b/test/integration/net_test.go index 834c5e9097..4556172302 100644 --- a/test/integration/net_test.go +++ b/test/integration/net_test.go @@ -61,7 +61,7 @@ func TestNetworkPlugins(t *testing.T) { {"flannel", []string{"--cni=flannel"}, "cni", "app=flannel", true}, {"kindnet", []string{"--cni=kindnet"}, "cni", "app=kindnet", true}, {"false", []string{"--cni=false"}, "", "", false}, - {"custom-weave", []string{fmt.Sprintf("--cni=%s", filepath.Join(*testdataDir, "weavenet.yaml"))}, "cni", "", true}, + {"custom-flannel", []string{fmt.Sprintf("--cni=%s", filepath.Join(*testdataDir, "kube-flannel.yaml"))}, "cni", "", true}, {"calico", []string{"--cni=calico"}, "cni", "k8s-app=calico-node", true}, {"cilium", []string{"--cni=cilium"}, "cni", "k8s-app=cilium", true}, } diff --git a/test/integration/start_stop_delete_test.go b/test/integration/start_stop_delete_test.go index 75e2595479..807c6a82bc 100644 --- a/test/integration/start_stop_delete_test.go +++ b/test/integration/start_stop_delete_test.go @@ -120,7 +120,7 @@ func TestStartStop(t *testing.T) { } if version.GTE(semver.MustParse("1.24.0-alpha.2")) { args := []string{} - for _, arg := range args { + for _, arg := range startArgs { if arg == "--extra-config=kubelet.network-plugin=cni" { continue } diff --git a/test/integration/testdata/kube-flannel.yaml b/test/integration/testdata/kube-flannel.yaml new file mode 100644 index 0000000000..e5b98de1ff --- /dev/null +++ b/test/integration/testdata/kube-flannel.yaml @@ -0,0 +1,248 @@ +--- +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: psp.flannel.unprivileged + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default + seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default + apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default + apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default +spec: + privileged: false + volumes: + - configMap + - secret + - emptyDir + - hostPath + allowedHostPaths: + - pathPrefix: "/etc/cni/net.d" + - pathPrefix: "/etc/kube-flannel" + - pathPrefix: "/run/flannel" + readOnlyRootFilesystem: false + # Users and groups + runAsUser: + rule: RunAsAny + supplementalGroups: + rule: RunAsAny + fsGroup: + rule: RunAsAny + # Privilege Escalation + allowPrivilegeEscalation: false + defaultAllowPrivilegeEscalation: false + # Capabilities + allowedCapabilities: ['NET_ADMIN', 'NET_RAW'] + defaultAddCapabilities: [] + requiredDropCapabilities: [] + # Host namespaces + hostPID: false + hostIPC: false + hostNetwork: true + hostPorts: + - min: 0 + max: 65535 + # SELinux + seLinux: + # SELinux is unused in CaaSP + rule: 'RunAsAny' +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: flannel +rules: +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: ['psp.flannel.unprivileged'] +- apiGroups: + - "" + resources: + - pods + verbs: + - get +- apiGroups: + - "" + resources: + - nodes + verbs: + - list + - watch +- apiGroups: + - "" + resources: + - nodes/status + verbs: + - patch +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: flannel +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: flannel +subjects: +- kind: ServiceAccount + name: flannel + namespace: kube-system +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: flannel + namespace: kube-system +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: kube-flannel-cfg + namespace: kube-system + labels: + tier: node + app: flannel +data: + cni-conf.json: | + { + "name": "cbr0", + "cniVersion": "0.3.1", + "plugins": [ + { + "type": "flannel", + "delegate": { + "hairpinMode": true, + "isDefaultGateway": true + } + }, + { + "type": "portmap", + "capabilities": { + "portMappings": true + } + } + ] + } + net-conf.json: | + { + "Network": "10.244.0.0/16", + "Backend": { + "Type": "vxlan" + } + } +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: kube-flannel-ds + namespace: kube-system + labels: + tier: node + app: flannel +spec: + selector: + matchLabels: + app: flannel + template: + metadata: + labels: + tier: node + app: flannel + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/os + operator: In + values: + - linux + hostNetwork: true + priorityClassName: system-node-critical + tolerations: + - operator: Exists + effect: NoSchedule + serviceAccountName: flannel + initContainers: + - name: install-cni-plugin + #image: flannelcni/flannel-cni-plugin:v1.0.1 for ppc64le and mips64le (dockerhub limitations may apply) + image: rancher/mirrored-flannelcni-flannel-cni-plugin:v1.0.1 + command: + - cp + args: + - -f + - /flannel + - /opt/cni/bin/flannel + volumeMounts: + - name: cni-plugin + mountPath: /opt/cni/bin + - name: install-cni + #image: flannelcni/flannel:v0.17.0 for ppc64le and mips64le (dockerhub limitations may apply) + image: rancher/mirrored-flannelcni-flannel:v0.17.0 + command: + - cp + args: + - -f + - /etc/kube-flannel/cni-conf.json + - /etc/cni/net.d/10-flannel.conflist + volumeMounts: + - name: cni + mountPath: /etc/cni/net.d + - name: flannel-cfg + mountPath: /etc/kube-flannel/ + containers: + - name: kube-flannel + #image: flannelcni/flannel:v0.17.0 for ppc64le and mips64le (dockerhub limitations may apply) + image: rancher/mirrored-flannelcni-flannel:v0.17.0 + command: + - /opt/bin/flanneld + args: + - --ip-masq + - --kube-subnet-mgr + resources: + requests: + cpu: "100m" + memory: "50Mi" + limits: + cpu: "100m" + memory: "50Mi" + securityContext: + privileged: false + capabilities: + add: ["NET_ADMIN", "NET_RAW"] + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: EVENT_QUEUE_DEPTH + value: "5000" + volumeMounts: + - name: run + mountPath: /run/flannel + - name: flannel-cfg + mountPath: /etc/kube-flannel/ + - name: xtables-lock + mountPath: /run/xtables.lock + volumes: + - name: run + hostPath: + path: /run/flannel + - name: cni-plugin + hostPath: + path: /opt/cni/bin + - name: cni + hostPath: + path: /etc/cni/net.d + - name: flannel-cfg + configMap: + name: kube-flannel-cfg + - name: xtables-lock + hostPath: + path: /run/xtables.lock + type: FileOrCreate diff --git a/test/integration/testdata/weavenet.yaml b/test/integration/testdata/weavenet.yaml deleted file mode 100644 index 8918cf2a95..0000000000 --- a/test/integration/testdata/weavenet.yaml +++ /dev/null @@ -1,255 +0,0 @@ -apiVersion: v1 -kind: List -items: - - apiVersion: v1 - kind: ServiceAccount - metadata: - name: weave-net - annotations: - cloud.weave.works/launcher-info: |- - { - "original-request": { - "url": "/k8s/v1.16/net.yaml?k8s-version=Q2xpZW50IFZlcnNpb246IHZlcnNpb24uSW5mb3tNYWpvcjoiMSIsIE1pbm9yOiIxOCIsIEdpdFZlcnNpb246InYxLjE4LjAiLCBHaXRDb21taXQ6IjllOTkxNDE1Mzg2ZTRjZjE1NWEyNGIxZGExNWJlY2FhMzkwNDM4ZDgiLCBHaXRUcmVlU3RhdGU6ImNsZWFuIiwgQnVpbGREYXRlOiIyMDIwLTAzLTI2VDA2OjE2OjE1WiIsIEdvVmVyc2lvbjoiZ28xLjE0IiwgQ29tcGlsZXI6ImdjIiwgUGxhdGZvcm06ImRhcndpbi9hbWQ2NCJ9ClNlcnZlciBWZXJzaW9uOiB2ZXJzaW9uLkluZm97TWFqb3I6IjEiLCBNaW5vcjoiMTgiLCBHaXRWZXJzaW9uOiJ2MS4xOC4zIiwgR2l0Q29tbWl0OiIyZTc5OTZlM2UyNzEyNjg0YmM3M2YwZGVjMDIwMGQ2NGVlYzdmZTQwIiwgR2l0VHJlZVN0YXRlOiJjbGVhbiIsIEJ1aWxkRGF0ZToiMjAyMC0wNS0yMFQxMjo0MzozNFoiLCBHb1ZlcnNpb246ImdvMS4xMy45IiwgQ29tcGlsZXI6ImdjIiwgUGxhdGZvcm06ImxpbnV4L2FtZDY0In0K", - "date": "Tue Jun 23 2020 02:18:50 GMT+0000 (UTC)" - }, - "email-address": "support@weave.works" - } - labels: - name: weave-net - namespace: kube-system - - apiVersion: rbac.authorization.k8s.io/v1 - kind: ClusterRole - metadata: - name: weave-net - annotations: - cloud.weave.works/launcher-info: |- - { - "original-request": { - "url": "/k8s/v1.16/net.yaml?k8s-version=Q2xpZW50IFZlcnNpb246IHZlcnNpb24uSW5mb3tNYWpvcjoiMSIsIE1pbm9yOiIxOCIsIEdpdFZlcnNpb246InYxLjE4LjAiLCBHaXRDb21taXQ6IjllOTkxNDE1Mzg2ZTRjZjE1NWEyNGIxZGExNWJlY2FhMzkwNDM4ZDgiLCBHaXRUcmVlU3RhdGU6ImNsZWFuIiwgQnVpbGREYXRlOiIyMDIwLTAzLTI2VDA2OjE2OjE1WiIsIEdvVmVyc2lvbjoiZ28xLjE0IiwgQ29tcGlsZXI6ImdjIiwgUGxhdGZvcm06ImRhcndpbi9hbWQ2NCJ9ClNlcnZlciBWZXJzaW9uOiB2ZXJzaW9uLkluZm97TWFqb3I6IjEiLCBNaW5vcjoiMTgiLCBHaXRWZXJzaW9uOiJ2MS4xOC4zIiwgR2l0Q29tbWl0OiIyZTc5OTZlM2UyNzEyNjg0YmM3M2YwZGVjMDIwMGQ2NGVlYzdmZTQwIiwgR2l0VHJlZVN0YXRlOiJjbGVhbiIsIEJ1aWxkRGF0ZToiMjAyMC0wNS0yMFQxMjo0MzozNFoiLCBHb1ZlcnNpb246ImdvMS4xMy45IiwgQ29tcGlsZXI6ImdjIiwgUGxhdGZvcm06ImxpbnV4L2FtZDY0In0K", - "date": "Tue Jun 23 2020 02:18:50 GMT+0000 (UTC)" - }, - "email-address": "support@weave.works" - } - labels: - name: weave-net - rules: - - apiGroups: - - '' - resources: - - pods - - namespaces - - nodes - verbs: - - get - - list - - watch - - apiGroups: - - networking.k8s.io - resources: - - networkpolicies - verbs: - - get - - list - - watch - - apiGroups: - - '' - resources: - - nodes/status - verbs: - - patch - - update - - apiVersion: rbac.authorization.k8s.io/v1 - kind: ClusterRoleBinding - metadata: - name: weave-net - annotations: - cloud.weave.works/launcher-info: |- - { - "original-request": { - "url": "/k8s/v1.16/net.yaml?k8s-version=Q2xpZW50IFZlcnNpb246IHZlcnNpb24uSW5mb3tNYWpvcjoiMSIsIE1pbm9yOiIxOCIsIEdpdFZlcnNpb246InYxLjE4LjAiLCBHaXRDb21taXQ6IjllOTkxNDE1Mzg2ZTRjZjE1NWEyNGIxZGExNWJlY2FhMzkwNDM4ZDgiLCBHaXRUcmVlU3RhdGU6ImNsZWFuIiwgQnVpbGREYXRlOiIyMDIwLTAzLTI2VDA2OjE2OjE1WiIsIEdvVmVyc2lvbjoiZ28xLjE0IiwgQ29tcGlsZXI6ImdjIiwgUGxhdGZvcm06ImRhcndpbi9hbWQ2NCJ9ClNlcnZlciBWZXJzaW9uOiB2ZXJzaW9uLkluZm97TWFqb3I6IjEiLCBNaW5vcjoiMTgiLCBHaXRWZXJzaW9uOiJ2MS4xOC4zIiwgR2l0Q29tbWl0OiIyZTc5OTZlM2UyNzEyNjg0YmM3M2YwZGVjMDIwMGQ2NGVlYzdmZTQwIiwgR2l0VHJlZVN0YXRlOiJjbGVhbiIsIEJ1aWxkRGF0ZToiMjAyMC0wNS0yMFQxMjo0MzozNFoiLCBHb1ZlcnNpb246ImdvMS4xMy45IiwgQ29tcGlsZXI6ImdjIiwgUGxhdGZvcm06ImxpbnV4L2FtZDY0In0K", - "date": "Tue Jun 23 2020 02:18:50 GMT+0000 (UTC)" - }, - "email-address": "support@weave.works" - } - labels: - name: weave-net - roleRef: - kind: ClusterRole - name: weave-net - apiGroup: rbac.authorization.k8s.io - subjects: - - kind: ServiceAccount - name: weave-net - namespace: kube-system - - apiVersion: rbac.authorization.k8s.io/v1 - kind: Role - metadata: - name: weave-net - annotations: - cloud.weave.works/launcher-info: |- - { - "original-request": { - "url": "/k8s/v1.16/net.yaml?k8s-version=Q2xpZW50IFZlcnNpb246IHZlcnNpb24uSW5mb3tNYWpvcjoiMSIsIE1pbm9yOiIxOCIsIEdpdFZlcnNpb246InYxLjE4LjAiLCBHaXRDb21taXQ6IjllOTkxNDE1Mzg2ZTRjZjE1NWEyNGIxZGExNWJlY2FhMzkwNDM4ZDgiLCBHaXRUcmVlU3RhdGU6ImNsZWFuIiwgQnVpbGREYXRlOiIyMDIwLTAzLTI2VDA2OjE2OjE1WiIsIEdvVmVyc2lvbjoiZ28xLjE0IiwgQ29tcGlsZXI6ImdjIiwgUGxhdGZvcm06ImRhcndpbi9hbWQ2NCJ9ClNlcnZlciBWZXJzaW9uOiB2ZXJzaW9uLkluZm97TWFqb3I6IjEiLCBNaW5vcjoiMTgiLCBHaXRWZXJzaW9uOiJ2MS4xOC4zIiwgR2l0Q29tbWl0OiIyZTc5OTZlM2UyNzEyNjg0YmM3M2YwZGVjMDIwMGQ2NGVlYzdmZTQwIiwgR2l0VHJlZVN0YXRlOiJjbGVhbiIsIEJ1aWxkRGF0ZToiMjAyMC0wNS0yMFQxMjo0MzozNFoiLCBHb1ZlcnNpb246ImdvMS4xMy45IiwgQ29tcGlsZXI6ImdjIiwgUGxhdGZvcm06ImxpbnV4L2FtZDY0In0K", - "date": "Tue Jun 23 2020 02:18:50 GMT+0000 (UTC)" - }, - "email-address": "support@weave.works" - } - labels: - name: weave-net - namespace: kube-system - rules: - - apiGroups: - - '' - resourceNames: - - weave-net - resources: - - configmaps - verbs: - - get - - update - - apiGroups: - - '' - resources: - - configmaps - verbs: - - create - - apiVersion: rbac.authorization.k8s.io/v1 - kind: RoleBinding - metadata: - name: weave-net - annotations: - cloud.weave.works/launcher-info: |- - { - "original-request": { - "url": "/k8s/v1.16/net.yaml?k8s-version=Q2xpZW50IFZlcnNpb246IHZlcnNpb24uSW5mb3tNYWpvcjoiMSIsIE1pbm9yOiIxOCIsIEdpdFZlcnNpb246InYxLjE4LjAiLCBHaXRDb21taXQ6IjllOTkxNDE1Mzg2ZTRjZjE1NWEyNGIxZGExNWJlY2FhMzkwNDM4ZDgiLCBHaXRUcmVlU3RhdGU6ImNsZWFuIiwgQnVpbGREYXRlOiIyMDIwLTAzLTI2VDA2OjE2OjE1WiIsIEdvVmVyc2lvbjoiZ28xLjE0IiwgQ29tcGlsZXI6ImdjIiwgUGxhdGZvcm06ImRhcndpbi9hbWQ2NCJ9ClNlcnZlciBWZXJzaW9uOiB2ZXJzaW9uLkluZm97TWFqb3I6IjEiLCBNaW5vcjoiMTgiLCBHaXRWZXJzaW9uOiJ2MS4xOC4zIiwgR2l0Q29tbWl0OiIyZTc5OTZlM2UyNzEyNjg0YmM3M2YwZGVjMDIwMGQ2NGVlYzdmZTQwIiwgR2l0VHJlZVN0YXRlOiJjbGVhbiIsIEJ1aWxkRGF0ZToiMjAyMC0wNS0yMFQxMjo0MzozNFoiLCBHb1ZlcnNpb246ImdvMS4xMy45IiwgQ29tcGlsZXI6ImdjIiwgUGxhdGZvcm06ImxpbnV4L2FtZDY0In0K", - "date": "Tue Jun 23 2020 02:18:50 GMT+0000 (UTC)" - }, - "email-address": "support@weave.works" - } - labels: - name: weave-net - namespace: kube-system - roleRef: - kind: Role - name: weave-net - apiGroup: rbac.authorization.k8s.io - subjects: - - kind: ServiceAccount - name: weave-net - namespace: kube-system - - apiVersion: apps/v1 - kind: DaemonSet - metadata: - name: weave-net - annotations: - cloud.weave.works/launcher-info: |- - { - "original-request": { - "url": "/k8s/v1.16/net.yaml?k8s-version=Q2xpZW50IFZlcnNpb246IHZlcnNpb24uSW5mb3tNYWpvcjoiMSIsIE1pbm9yOiIxOCIsIEdpdFZlcnNpb246InYxLjE4LjAiLCBHaXRDb21taXQ6IjllOTkxNDE1Mzg2ZTRjZjE1NWEyNGIxZGExNWJlY2FhMzkwNDM4ZDgiLCBHaXRUcmVlU3RhdGU6ImNsZWFuIiwgQnVpbGREYXRlOiIyMDIwLTAzLTI2VDA2OjE2OjE1WiIsIEdvVmVyc2lvbjoiZ28xLjE0IiwgQ29tcGlsZXI6ImdjIiwgUGxhdGZvcm06ImRhcndpbi9hbWQ2NCJ9ClNlcnZlciBWZXJzaW9uOiB2ZXJzaW9uLkluZm97TWFqb3I6IjEiLCBNaW5vcjoiMTgiLCBHaXRWZXJzaW9uOiJ2MS4xOC4zIiwgR2l0Q29tbWl0OiIyZTc5OTZlM2UyNzEyNjg0YmM3M2YwZGVjMDIwMGQ2NGVlYzdmZTQwIiwgR2l0VHJlZVN0YXRlOiJjbGVhbiIsIEJ1aWxkRGF0ZToiMjAyMC0wNS0yMFQxMjo0MzozNFoiLCBHb1ZlcnNpb246ImdvMS4xMy45IiwgQ29tcGlsZXI6ImdjIiwgUGxhdGZvcm06ImxpbnV4L2FtZDY0In0K", - "date": "Tue Jun 23 2020 02:18:50 GMT+0000 (UTC)" - }, - "email-address": "support@weave.works" - } - labels: - name: weave-net - namespace: kube-system - spec: - minReadySeconds: 5 - selector: - matchLabels: - name: weave-net - template: - metadata: - labels: - name: weave-net - spec: - containers: - - name: weave - command: - - /home/weave/launch.sh - env: - - name: HOSTNAME - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: spec.nodeName - image: 'docker.io/weaveworks/weave-kube:2.6.5' - readinessProbe: - httpGet: - host: 127.0.0.1 - path: /status - port: 6784 - resources: - requests: - cpu: 10m - securityContext: - privileged: true - volumeMounts: - - name: weavedb - mountPath: /weavedb - - name: cni-bin - mountPath: /host/opt - - name: cni-bin2 - mountPath: /host/home - - name: cni-conf - mountPath: /host/etc - - name: dbus - mountPath: /host/var/lib/dbus - - name: lib-modules - mountPath: /lib/modules - - name: xtables-lock - mountPath: /run/xtables.lock - - name: weave-npc - env: - - name: HOSTNAME - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: spec.nodeName - image: 'docker.io/weaveworks/weave-npc:2.6.5' - resources: - requests: - cpu: 10m - securityContext: - privileged: true - volumeMounts: - - name: xtables-lock - mountPath: /run/xtables.lock - dnsPolicy: ClusterFirstWithHostNet - hostNetwork: true - hostPID: true - priorityClassName: system-node-critical - restartPolicy: Always - securityContext: - seLinuxOptions: {} - serviceAccountName: weave-net - tolerations: - - effect: NoSchedule - operator: Exists - - effect: NoExecute - operator: Exists - volumes: - - name: weavedb - hostPath: - path: /var/lib/weave - - name: cni-bin - hostPath: - path: /opt - - name: cni-bin2 - hostPath: - path: /home - - name: cni-conf - hostPath: - path: /etc - - name: dbus - hostPath: - path: /var/lib/dbus - - name: lib-modules - hostPath: - path: /lib/modules - - name: xtables-lock - hostPath: - path: /run/xtables.lock - type: FileOrCreate - updateStrategy: - type: RollingUpdate diff --git a/translations/de.json b/translations/de.json index cc063fb109..dc13eb9dd3 100644 --- a/translations/de.json +++ b/translations/de.json @@ -245,6 +245,7 @@ "Failed to check main repository and mirrors for images": "Prüfen des Haupt-Repositories und der Mirrors für Images fehlgeschlagen", "Failed to configure metallb IP {{.profile}}": "Konfiguration der metallb IP {{.profile}} fehlgeschlagen", "Failed to configure network plugin": "", + "Failed to configure registry-aliases {{.profile}}": "", "Failed to create file": "Erstellen der Datei fehlgeschlagen", "Failed to create runtime": "Erstellen der Runtime fehlgeschlagen", "Failed to delete cluster {{.name}}, proceeding with retry anyway.": "Löschen des Clusters {{.name}} fehlgeschlagen, versuche es dennoch erneut.", diff --git a/translations/es.json b/translations/es.json index 282860686d..62ac409130 100644 --- a/translations/es.json +++ b/translations/es.json @@ -254,6 +254,7 @@ "Failed to check main repository and mirrors for images": "", "Failed to configure metallb IP {{.profile}}": "", "Failed to configure network plugin": "", + "Failed to configure registry-aliases {{.profile}}": "", "Failed to create file": "No se pudo crear el fichero", "Failed to create runtime": "", "Failed to delete cluster {{.name}}, proceeding with retry anyway.": "", diff --git a/translations/fr.json b/translations/fr.json index d9125ff7fa..541597f76e 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -240,6 +240,7 @@ "Failed to check main repository and mirrors for images": "Échec de la vérification du référentiel principal et des miroirs pour les images", "Failed to configure metallb IP {{.profile}}": "Échec de la configuration de metallb IP {{.profile}}", "Failed to configure network plugin": "Échec de la configuration du plug-in réseau", + "Failed to configure registry-aliases {{.profile}}": "Échec de la configuration des alias de registre {{.profile}}", "Failed to create file": "La création du fichier a échoué", "Failed to create runtime": "Échec de la création de l'environnement d'exécution", "Failed to delete cluster {{.name}}, proceeding with retry anyway.": "Échec de la suppression du cluster {{.name}}, réessayez quand même.", @@ -855,7 +856,7 @@ "addon '{{.name}}' is currently not enabled.\nTo enable this addon run:\nminikube addons enable {{.name}}": "Le module '{{.name}}' n'est actuellement pas activé.\nPour activer ce module, exécutez :\nminikube addons enable {{.name}}", "addon '{{.name}}' is not a valid addon packaged with minikube.\nTo see the list of available addons run:\nminikube addons list": "Le module '{{.name}}' n'est pas un module valide fourni avec minikube.\nPour voir la liste des modules disponibles, exécutez :\nminikube addons list", "addons modifies minikube addons files using subcommands like \"minikube addons enable dashboard\"": "addons modifie les fichiers de modules minikube à l'aide de sous-commandes telles que \"minikube addons enable dashboard\"", - "arm64 VM drivers do not currently support containerd or crio container runtimes. See https://github.com/kubernetes/minikube/issues/14146 for details.": "", + "arm64 VM drivers do not currently support containerd or crio container runtimes. See https://github.com/kubernetes/minikube/issues/14146 for details.": "Les pilotes de machine virtuelle arm64 ne prennent actuellement pas en charge les runtimes de conteneur containerd ou crio. Voir https://github.com/kubernetes/minikube/issues/14146 pour plus de détails.", "auto-pause addon is an alpha feature and still in early development. Please file issues to help us make it better.": "Le module auto-pause est une fonctionnalité alpha et encore en développement précoce. Veuillez signaler les problèmes pour nous aider à l'améliorer.", "bash completion failed": "échec de la complétion bash", "bash completion.": "complétion bash", @@ -915,10 +916,10 @@ "minikube profile was successfully set to {{.profile_name}}": "Le profil de minikube a été défini avec succès sur {{.profile_name}}", "minikube provisions and manages local Kubernetes clusters optimized for development workflows.": "minikube provisionne et gère des clusters Kubernetes locaux optimisés pour les workflows de développement.", "minikube quickly sets up a local Kubernetes cluster": "minikube configure rapidement un cluster Kubernetes local", - "minikube service is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "", + "minikube service is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "Le service minikube n'est actuellement pas implémenté avec le pilote qemu2. Voir https://github.com/kubernetes/minikube/issues/14146 pour plus de détails.", "minikube skips various validations when --force is supplied; this may lead to unexpected behavior": "minikube ignore diverses validations lorsque --force est fourni ; cela peut conduire à un comportement inattendu", "minikube status --output OUTPUT. json, text": "état minikube --sortie SORTIE. json, texte", - "minikube tunnel is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "", + "minikube tunnel is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "Le tunnel minikube n'est actuellement pas implémenté avec le pilote qemu2. Voir https://github.com/kubernetes/minikube/issues/14146 pour plus de détails.", "minikube {{.version}} is available! Download it: {{.url}}": "minikube {{.version}} est disponible ! Téléchargez-le ici : {{.url}}", "mkcmp is used to compare performance of two minikube binaries": "mkcmp est utilisé pour comparer les performances de deux binaires minikube", "mount argument \"{{.value}}\" must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "argument de montage \"{{.value}}\" doit être de la forme : \u003cdossier source\u003e:\u003cdossier de destination\u003e", diff --git a/translations/ja.json b/translations/ja.json index ea8e63563c..ca2561498d 100644 --- a/translations/ja.json +++ b/translations/ja.json @@ -246,6 +246,7 @@ "Failed to check main repository and mirrors for images": "メインリポジトリーとミラーのイメージのチェックに失敗しました", "Failed to configure metallb IP {{.profile}}": "metallb IP {{.profile}} の設定に失敗しました", "Failed to configure network plugin": "", + "Failed to configure registry-aliases {{.profile}}": "", "Failed to create file": "ファイルの作成に失敗しました", "Failed to create runtime": "ランタイムの作成に失敗しました", "Failed to delete cluster {{.name}}, proceeding with retry anyway.": "{{.name}} クラスターを削除できませんでしたが、処理を続行します。", diff --git a/translations/ko.json b/translations/ko.json index 94258c16f4..551947c123 100644 --- a/translations/ko.json +++ b/translations/ko.json @@ -267,6 +267,7 @@ "Failed to check main repository and mirrors for images": "", "Failed to configure metallb IP {{.profile}}": "", "Failed to configure network plugin": "", + "Failed to configure registry-aliases {{.profile}}": "", "Failed to create file": "", "Failed to create runtime": "", "Failed to delete cluster {{.name}}, proceeding with retry anyway.": "", diff --git a/translations/pl.json b/translations/pl.json index 7e657a8c22..7a6850d76b 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -256,6 +256,7 @@ "Failed to check main repository and mirrors for images": "", "Failed to configure metallb IP {{.profile}}": "", "Failed to configure network plugin": "", + "Failed to configure registry-aliases {{.profile}}": "", "Failed to create file": "", "Failed to create runtime": "", "Failed to delete cluster {{.name}}, proceeding with retry anyway.": "", diff --git a/translations/ru.json b/translations/ru.json index 09629a62ca..b336a0e471 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -230,6 +230,7 @@ "Failed to check main repository and mirrors for images": "", "Failed to configure metallb IP {{.profile}}": "", "Failed to configure network plugin": "", + "Failed to configure registry-aliases {{.profile}}": "", "Failed to create file": "", "Failed to create runtime": "", "Failed to delete cluster {{.name}}, proceeding with retry anyway.": "", diff --git a/translations/strings.txt b/translations/strings.txt index 33d64ccf9f..c0e6441dc2 100644 --- a/translations/strings.txt +++ b/translations/strings.txt @@ -230,6 +230,7 @@ "Failed to check main repository and mirrors for images": "", "Failed to configure metallb IP {{.profile}}": "", "Failed to configure network plugin": "", + "Failed to configure registry-aliases {{.profile}}": "", "Failed to create file": "", "Failed to create runtime": "", "Failed to delete cluster {{.name}}, proceeding with retry anyway.": "", diff --git a/translations/zh-CN.json b/translations/zh-CN.json index 5a4828e0e9..390d7611eb 100644 --- a/translations/zh-CN.json +++ b/translations/zh-CN.json @@ -315,6 +315,7 @@ "Failed to check main repository and mirrors for images for images": "无法检测主仓库和镜像仓库中的镜像", "Failed to configure metallb IP {{.profile}}": "", "Failed to configure network plugin": "", + "Failed to configure registry-aliases {{.profile}}": "", "Failed to create file": "", "Failed to create runtime": "", "Failed to delete cluster {{.name}}, proceeding with retry anyway.": "",