Compare commits

...

17 Commits
v0.4.1 ... main

Author SHA1 Message Date
Yuxing Deng
5f51b892a9 fix: the usage is not compatible with old version 2024-11-25 09:43:22 +08:00
Yuxing Deng
a434be5b81 fix: wrong branch name 2024-10-21 21:52:17 +08:00
Yuxing Deng
a7787ce013 fix: add release-v branch to push workflow 2024-10-21 21:52:17 +08:00
Yuxing Deng
b8f1ad6f9e fix: CROSS push 2024-10-21 21:45:17 +08:00
Yuxing Deng
1633838017 fix: aliyun-metadata should have registry name for image 2024-10-21 21:14:13 +08:00
Yuxing Deng
4d17a53d3e feat: use goreleaser to build binaries 2024-10-21 16:29:04 +08:00
Yuxing Deng
4c1db385fc fix: Should handle stale socket file
Added a lock file to hold make sure that it's safe to rebuild socket file
2024-10-10 21:21:35 +08:00
Yuxing Deng
8d1433b07d feat: Support to serve http via socket 2024-10-09 22:53:08 +08:00
Yuxing Deng
db2728f0ed fix(docs): enhance Readme 2024-10-09 09:12:48 +08:00
Yuxing Deng
4f18ac4ae8 feat(ui): bump ui version to v2.9.2 2024-09-27 17:37:50 +08:00
Yuxing Deng
faee269cc1 feat(deps): bump golang & steve version 2024-09-27 17:37:50 +08:00
Yuxing Deng
9ce631d30f fix: use local version package 2024-09-26 10:29:40 +08:00
Yuxing Deng
2d512c0a72 fix: version is not parsed into build info 2024-09-26 09:49:16 +08:00
Yuxing Deng
5c987cd193 fix: Bump steve to fix the crd issue 2024-08-07 09:08:22 +08:00
Yuxing Deng
85925bbac7 fix: no need to new workflow file for release branch 2024-07-30 10:34:57 +08:00
Yuxing Deng
f435a24814 fix: Rename release branch ci name 2024-07-30 10:32:06 +08:00
Yuxing Deng
fb1f38e1ef feat: Add release branch ci 2024-07-30 10:31:00 +08:00
20 changed files with 406 additions and 141 deletions

View File

@ -16,6 +16,4 @@ jobs:
- name: Commitsar check - name: Commitsar check
uses: aevea/commitsar@v0.20.2 uses: aevea/commitsar@v0.20.2
- name: Build to test - name: Build to test
env:
SKIP_COMPRESS: "true"
run: make ci run: make ci

View File

@ -3,9 +3,14 @@ name: Push to Master
on: on:
push: push:
branches: branches:
- release/v*
- main - main
- "release/v*"
tags: tags:
- 'v*.*.*' # Matches any tag that starts with 'v' and follows semantic versioning - "v*.*.*" # Matches any tag that starts with 'v' and follows semantic versioning
env:
ALIYUN_REGISTRY: ${{ vars.ALIYUN_REGISTRY || '' }}
jobs: jobs:
build-and-deploy: build-and-deploy:
@ -15,63 +20,69 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: CI
env:
SKIP_PACKAGE: "true"
run: make ci
- name: Prepare for packaging image
run: cp dist/* package/
# aliyun image to test the docker build is ok
- name: Login to Aliyun ACR - name: Login to Aliyun ACR
if: ${{ vars.ALIYUN_REGISTRY != '' }}
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: registry.cn-shenzhen.aliyuncs.com registry: ${{ env.ALIYUN_REGISTRY }}
username: ${{ secrets.ACR_USERNAME }} username: ${{ secrets.ACR_USERNAME }}
password: ${{ secrets.ACR_TOKEN }} password: ${{ secrets.ACR_TOKEN }}
if: ${{ vars.ALIYUN == 'true' }} - name: Aliyun image docker meta
if: ${{ vars.ALIYUN_REGISTRY != '' }}
id: aliyun-meta
uses: docker/metadata-action@v5
with:
images: ${{ env.ALIYUN_REGISTRY }}/${{ vars.REPO || 'cnrancher' }}/${{ vars.IMAGE || 'kube-explorer' }}
tags: |
type=ref,event=tag
type=ref,event=branch,suffix=-head
- name: Build to Aliyun
if: ${{ vars.ALIYUN_REGISTRY != '' }}
uses: docker/build-push-action@v6
with:
labels: ${{ steps.aliyun-meta.outputs.labels }}
tags: "${{ steps.aliyun-meta.outputs.tags }}"
context: package
push: true
# docker hub multi-arch image
- name: Login to Dockerhub - name: Login to Dockerhub
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: CI - name: Docker meta
if: startsWith(github.ref, 'refs/heads/') id: meta
env: uses: docker/metadata-action@v5
CROSS: push with:
run: make github_ci images: ${{ vars.REPO || 'cnrancher' }}/${{ vars.IMAGE || 'kube-explorer' }}
tags: |
- name: CI type=ref,event=tag
if: startsWith(github.ref, 'refs/tags/') type=ref,event=branch,suffix=-head
env: - name: Set up QEMU
CROSS: tag
run: |
make github_ci
make release-note
- name: Prepare for packaging image
run: cp dist/* package/
- name: Set docker iamge name
id: image-name
env:
REPO_OVERRIDE: ${{ vars.REPO || 'cnrancher' }}
IMAGE_OVERRIDE: ${{ vars.IMAGE || 'kube-explorer' }}
run: |
tag_name=latest;
if [[ ${GITHUB_REF} == refs/tags/* ]]; then tag_name=${GITHUB_REF#refs/tags/}; fi;
echo "image_name=${REPO_OVERRIDE}/${IMAGE_OVERRIDE}:${tag_name}" >> $GITHUB_OUTPUT;
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3 uses: docker/setup-qemu-action@v3
- - name: Set up Docker Buildx
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Build to Dockerhub - name: Build to Dockerhub
uses: docker/build-push-action@v6 uses: docker/build-push-action@v6
with: with:
platforms: linux/amd64,linux/arm64/v8 platforms: linux/amd64,linux/arm64/v8
tags: "${{ steps.image-name.outputs.image_name }}" labels: ${{ steps.meta.outputs.labels }}
tags: "${{ steps.meta.outputs.tags }}"
context: package context: package
push: true push: true
- name: Build to Aliyun
uses: docker/build-push-action@v6 - name: Make release note
with: if: startsWith(github.ref, 'refs/tags/')
tags: registry.cn-shenzhen.aliyuncs.com/${{ steps.image-name.outputs.image_name }} run: |
context: package make release-note
push: true
if: ${{ vars.ALIYUN == 'true' }}
- name: Release - name: Release
uses: softprops/action-gh-release@v2 uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')

4
.gitignore vendored
View File

@ -23,3 +23,7 @@
/.vscode /.vscode
/vendor /vendor
/internal/ui/ui/ /internal/ui/ui/
**/Dockerfile.dapper*
!**/Dockerfile.dapper
dist/

75
.goreleaser.yaml Normal file
View File

@ -0,0 +1,75 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com
# The lines below are called `modelines`. See `:help modeline`
# Feel free to remove those if you don't want/need to use them.
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
version: 2
dist: bin
before:
hooks:
# You may remove this if you don't use go modules.
- go mod tidy
builds:
- id: prod
env:
- CGO_ENABLED=0
targets:
- "darwin_amd64"
- "darwin_arm64"
- "linux_amd64"
- "linux_arm64"
- "linux_arm"
- "windows_amd64"
flags:
- -tags=embed
binary: '{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}'
ldflags: |
{{ if ne .Os "darwin" }}
-extldflags -static -s
{{ else }}
-s -w
{{ end }}
-X github.com/cnrancher/kube-explorer/internal/version.Version={{ .Env.VERSION }}
-X github.com/cnrancher/kube-explorer/internal/version.GitCommit={{ .Env.COMMIT }}
-X github.com/cnrancher/kube-explorer/internal/config.APIUIVersion={{ .Env.CATTLE_API_UI_VERSION }}
no_unique_dist_dir: true
- id: dev
env:
- CGO_ENABLED=0
targets:
- "linux_amd64"
- "linux_arm64"
flags:
- -tags=embed
binary: '{{ .ProjectName }}-{{ .Os }}-{{ .Arch }}'
ldflags: |
{{ if ne .Os "darwin" }}
-extldflags -static -s
{{ else }}
-s -w
{{ end }}
-X github.com/cnrancher/kube-explorer/internal/version.Version={{ .Env.VERSION }}
-X github.com/cnrancher/kube-explorer/internal/version.GitCommit={{ .Env.COMMIT }}
-X github.com/cnrancher/kube-explorer/internal/config.APIUIVersion={{ .Env.CATTLE_API_UI_VERSION }}
no_unique_dist_dir: true
upx:
- compress: "5"
ids:
- prod
enabled: true
goos:
- linux
- windows
changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"

View File

@ -1,6 +1,7 @@
FROM goreleaser/goreleaser:v2.3.2 as goreleaser
FROM aevea/release-notary:0.9.2 as tools FROM aevea/release-notary:0.9.2 as tools
FROM registry.suse.com/bci/golang:1.22 FROM registry.suse.com/bci/golang:1.23
ARG PROXY ARG PROXY
ARG GOPROXY ARG GOPROXY
ARG DAPPER_HOST_ARCH ARG DAPPER_HOST_ARCH
@ -8,21 +9,21 @@ ENV HOST_ARCH=${DAPPER_HOST_ARCH} ARCH=${DAPPER_HOST_ARCH}
ENV https_proxy=${PROXY} \ ENV https_proxy=${PROXY} \
http_proxy=${PROXY} http_proxy=${PROXY}
RUN zypper -n install ca-certificates git-core wget curl unzip tar vim less file xz RUN zypper -n install ca-certificates git-core wget curl unzip tar vim less file xz cosign docker
RUN zypper install -y -f docker
ENV UPX_VERSION 4.2.1 ENV UPX_VERSION 4.2.1
RUN curl -sL https://github.com/upx/upx/releases/download/v${UPX_VERSION}/upx-${UPX_VERSION}-${ARCH}_linux.tar.xz | tar xvJf - --strip-components=1 -C /tmp && \ RUN curl -sL https://github.com/upx/upx/releases/download/v${UPX_VERSION}/upx-${UPX_VERSION}-${ARCH}_linux.tar.xz | tar xvJf - --strip-components=1 -C /tmp && \
mv /tmp/upx /usr/bin/ mv /tmp/upx /usr/bin/
RUN if [ "${ARCH}" == "amd64" ]; then \ RUN if [ "${ARCH}" == "amd64" ]; then \
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.54.2; \ curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.61.0; \
fi fi
COPY --from=goreleaser /usr/bin/goreleaser /usr/bin/goreleaser
COPY --from=tools /app/release-notary /usr/local/bin/ COPY --from=tools /app/release-notary /usr/local/bin/
ENV CATTLE_DASHBOARD_UI_VERSION="v2.8.0-kube-explorer-ui-rc3" ENV CATTLE_DASHBOARD_UI_VERSION="v2.9.2-kube-explorer-ui-rc1"
ENV CATTLE_API_UI_VERSION="1.1.11" ENV CATTLE_API_UI_VERSION="1.1.11"
ENV DAPPER_ENV REPO TAG DRONE_TAG CROSS GOPROXY SKIP_COMPRESS GITHUB_REPOSITORY GITHUB_TOKEN ENV DAPPER_ENV REPO TAG DRONE_TAG CROSS GOPROXY GITHUB_TOKEN GITHUB_REF GITHUB_REF_NAME BUILD_TARGET SKIP_PACKAGE
ENV DAPPER_SOURCE /go/src/github.com/cnrancher/kube-explorer ENV DAPPER_SOURCE /go/src/github.com/cnrancher/kube-explorer
ENV DAPPER_OUTPUT ./bin ./dist ENV DAPPER_OUTPUT ./bin ./dist
ENV DAPPER_DOCKER_SOCKET true ENV DAPPER_DOCKER_SOCKET true

View File

@ -10,7 +10,7 @@ Please download the binary from the [release page](https://github.com/cnrancher/
To run an HTTP only server: To run an HTTP only server:
``` ```bash
./kube-explorer --kubeconfig=xxxx --http-listen-port=9898 --https-listen-port=0 ./kube-explorer --kubeconfig=xxxx --http-listen-port=9898 --https-listen-port=0
``` ```
@ -22,20 +22,47 @@ Then, open the browser to visit http://x.x.x.x:9898 .
To debug on an AMD64 Linux host: To debug on an AMD64 Linux host:
``` ```bash
make dev make dev
# $basedir=/opt/ui/dist/ # $basedir=/opt/ui/dist/
# prepare the file trees like this # prepare the file trees like this
# $basedir/dashboard/ # $basedir/dashboard/
# $basedir/api-ui/
# $basedir/index.html # $basedir/index.html
# good to go! # good to go!
./kube-explorer --debug --ui-path /opt/ui/dist/ --http-listen-port=9898 --https-listen-port=0 ./bin/kube-explorer --debug --ui-path /opt/ui/dist/ --http-listen-port=9898 --https-listen-port=0
``` ```
To build all cross-platform binaries: To build all cross-platform binaries:
```bash
CROSS=tag make
``` ```
CROSS=1 make
``` ## Supported features
- Specified system default registry for shell image, e.g. `--system-default-registry`
- Specified shell image name, e.g. `--pod-image`
- Deployed behind proxy
- [Behind ingress with dns name](./deploy/kubectl/README.md)
- [Behind ingress with dns name and path prefix](./deploy/kubectl/path-prefix/Readme.md)
- Base auth via ingress such as [nginx](./deploy/kubectl/nginx-auth/README.md), [traefik-v1](./deploy/kubectl/traefik-v1-auth/README.md) and [traefik-v2](./deploy/kubectl/traefik-v2-auth/README.md)
## Support Matrix
Currently, there are several major versions under maintenance, each tailored to different Kubernetes version ranges due to the use of varying steve and client-go versions.
| Major | Target Rancher Branch | K8s version range |
| ----- | --------------------- | ----------------- |
| v0.4 | v2.8.x | >= 1.25 <= 1.28 |
| v0.5 | v2.9.x | >= 1.27 <= 1.30 |
Please use the proper kube-explorer version for your k8s setup.
## Related Projects
- kube-explorer ui([https://github.com/cnrancher/kube-explorer-ui](https://github.com/cnrancher/kube-explorer-ui))
- autok3s([https://github.com/cnrancher/autok3s](https://github.com/cnrancher/autok3s))
- api-ui([https://github.com/rancher/api-ui](https://github.com/rancher/api-ui))

5
go.mod
View File

@ -5,9 +5,11 @@ go 1.22.0
replace k8s.io/client-go => k8s.io/client-go v0.30.1 replace k8s.io/client-go => k8s.io/client-go v0.30.1
require ( require (
github.com/Microsoft/go-winio v0.6.2
github.com/gorilla/mux v1.8.1 github.com/gorilla/mux v1.8.1
github.com/rancher/apiserver v0.0.0-20240708202538-39a6f2535146 github.com/rancher/apiserver v0.0.0-20240708202538-39a6f2535146
github.com/rancher/steve v0.0.0-20240709130809-47871606146c github.com/rancher/dynamiclistener v0.6.0-rc2
github.com/rancher/steve v0.0.0-20240911190153-79304d93b49b
github.com/rancher/wrangler/v3 v3.0.0 github.com/rancher/wrangler/v3 v3.0.0
github.com/sirupsen/logrus v1.9.3 github.com/sirupsen/logrus v1.9.3
github.com/urfave/cli v1.22.15 github.com/urfave/cli v1.22.15
@ -62,7 +64,6 @@ require (
github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect github.com/prometheus/procfs v0.10.1 // indirect
github.com/rancher/dynamiclistener v0.6.0-rc2 // indirect
github.com/rancher/kubernetes-provider-detector v0.1.5 // indirect github.com/rancher/kubernetes-provider-detector v0.1.5 // indirect
github.com/rancher/lasso v0.0.0-20240705194423-b2a060d103c1 // indirect github.com/rancher/lasso v0.0.0-20240705194423-b2a060d103c1 // indirect
github.com/rancher/norman v0.0.0-20240708202514-a0127673d1b9 // indirect github.com/rancher/norman v0.0.0-20240708202514-a0127673d1b9 // indirect

6
go.sum
View File

@ -601,6 +601,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
@ -1029,8 +1031,8 @@ github.com/rancher/norman v0.0.0-20240708202514-a0127673d1b9 h1:AlRMRs5mHJcdiK83
github.com/rancher/norman v0.0.0-20240708202514-a0127673d1b9/go.mod h1:dyjfXBsNiroPWOdUZe7diUOUSLf6HQ/r2kEpwH/8zas= github.com/rancher/norman v0.0.0-20240708202514-a0127673d1b9/go.mod h1:dyjfXBsNiroPWOdUZe7diUOUSLf6HQ/r2kEpwH/8zas=
github.com/rancher/remotedialer v0.3.2 h1:kstZbRwPS5gPWpGg8VjEHT2poHtArs+Fc317YM8JCzU= github.com/rancher/remotedialer v0.3.2 h1:kstZbRwPS5gPWpGg8VjEHT2poHtArs+Fc317YM8JCzU=
github.com/rancher/remotedialer v0.3.2/go.mod h1:Ys004RpJuTLSm+k4aYUCoFiOOad37ubYev3TkOFg/5w= github.com/rancher/remotedialer v0.3.2/go.mod h1:Ys004RpJuTLSm+k4aYUCoFiOOad37ubYev3TkOFg/5w=
github.com/rancher/steve v0.0.0-20240709130809-47871606146c h1:PIaN0/KUyGcqEcT6GyjUidld2lgGkGxS4dmC3Je3dFs= github.com/rancher/steve v0.0.0-20240911190153-79304d93b49b h1:2DhkNKDgKPI2PcJRGacpJ9dX9SWgKuhwbz5GlpHS1No=
github.com/rancher/steve v0.0.0-20240709130809-47871606146c/go.mod h1:Za4nSt0V6kIHRfUo6jTXKkv6ABMMCHINA8EzhzygCfk= github.com/rancher/steve v0.0.0-20240911190153-79304d93b49b/go.mod h1:cXF0TFURkjN98p/0nt7Y8F1IEtT1nZTSYrQu6HQqL14=
github.com/rancher/wrangler/v3 v3.0.0 h1:IHHCA+vrghJDPxjtLk4fmeSCFhNe9fFzLFj3m2B0YpA= github.com/rancher/wrangler/v3 v3.0.0 h1:IHHCA+vrghJDPxjtLk4fmeSCFhNe9fFzLFj3m2B0YpA=
github.com/rancher/wrangler/v3 v3.0.0/go.mod h1:Dfckuuq7MJk2JWVBDywRlZXMxEyPxHy4XqGrPEzu5Eg= github.com/rancher/wrangler/v3 v3.0.0/go.mod h1:Dfckuuq7MJk2JWVBDywRlZXMxEyPxHy4XqGrPEzu5Eg=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=

View File

@ -8,6 +8,7 @@ var InsecureSkipTLSVerify bool
var SystemDefaultRegistry string var SystemDefaultRegistry string
var APIUIVersion = "1.1.11" var APIUIVersion = "1.1.11"
var ShellPodImage string var ShellPodImage string
var BindAddress string
func Flags() []cli.Flag { func Flags() []cli.Flag {
return []cli.Flag{ return []cli.Flag{
@ -30,5 +31,10 @@ func Flags() []cli.Flag {
Destination: &APIUIVersion, Destination: &APIUIVersion,
Value: APIUIVersion, Value: APIUIVersion,
}, },
cli.StringFlag{
Name: "bind-address",
Destination: &BindAddress,
Usage: `Bind address with url format. The supported schemes are unix, tcp and namedpipe, e.g. unix:///path/to/kube-explorer.sock or namedpipe:/\.\pipe\kube-explorer`,
},
} }
} }

View File

@ -0,0 +1,52 @@
package server
import (
"context"
"log"
"net"
"net/http"
"github.com/cnrancher/kube-explorer/internal/config"
dynamicserver "github.com/rancher/dynamiclistener/server"
"github.com/rancher/steve/pkg/server"
"github.com/sirupsen/logrus"
)
func Serve(ctx context.Context, server *server.Server) error {
listener, ipOrPath, err := ensureListener(ctx)
if err != nil {
return err
}
if listener != nil {
defer listener.Close()
return serveSocket(ctx, ipOrPath, listener, server)
}
return server.ListenAndServe(ctx, config.Steve.HTTPSListenPort, config.Steve.HTTPListenPort, &dynamicserver.ListenOpts{
BindHost: ipOrPath,
})
}
func serveSocket(ctx context.Context, socketPath string, listener net.Listener, handler http.Handler) error {
logger := logrus.StandardLogger()
errorLog := log.New(logger.WriterLevel(logrus.DebugLevel), "", log.LstdFlags)
socketServer := &http.Server{
Handler: handler,
ErrorLog: errorLog,
BaseContext: func(_ net.Listener) context.Context {
return ctx
},
}
go func() {
logrus.Infof("Listening on %s", socketPath)
err := socketServer.Serve(listener)
if err != http.ErrServerClosed && err != nil {
logrus.Fatalf("https server failed: %v", err)
}
}()
go func() {
<-ctx.Done()
_ = socketServer.Shutdown(context.Background())
}()
<-ctx.Done()
return ctx.Err()
}

View File

@ -0,0 +1,99 @@
//go:build unix
// +build unix
package server
import (
"context"
"errors"
"fmt"
"net"
"net/url"
"os"
"path/filepath"
"strings"
"syscall"
"github.com/cnrancher/kube-explorer/internal/config"
"github.com/sirupsen/logrus"
)
var _ net.Listener = &closerListener{}
type closerListener struct {
listener net.Listener
lockFile *os.File
}
func (l *closerListener) Accept() (net.Conn, error) {
return l.listener.Accept()
}
func (l *closerListener) Close() error {
return errors.Join(
l.listener.Close(),
l.lockFile.Close(),
os.RemoveAll(l.lockFile.Name()),
)
}
func (l *closerListener) Addr() net.Addr {
return l.listener.Addr()
}
func ensureListener(ctx context.Context) (net.Listener, string, error) {
if config.BindAddress == "" {
return nil, "", nil
}
u, err := url.Parse(config.BindAddress)
if err != nil {
return nil, "", err
}
switch u.Scheme {
case "":
return nil, config.BindAddress, nil
case "tcp":
return nil, u.Host, nil
case "unix":
listener, err := createCloserListener(ctx, u.Path)
if err != nil {
return nil, "", err
}
return listener, u.Path, err
default:
return nil, "", fmt.Errorf("Unsupported scheme %s, only tcp and unix are supported in UNIX OS", u.Scheme)
}
}
func createCloserListener(ctx context.Context, socketPath string) (net.Listener, error) {
lockFilePath := getLockFileName(socketPath)
lockFile, err := os.OpenFile(lockFilePath, os.O_RDONLY|os.O_CREATE, 0600)
if err != nil {
return nil, err
}
lockErr := syscall.Flock(int(lockFile.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
if lockErr != nil {
return nil, fmt.Errorf("Socket file %s is in use, exiting", socketPath)
}
if _, err := os.Stat(socketPath); err == nil {
logrus.Infof("Removing stale socket file %s", socketPath)
_ = os.Remove(socketPath)
}
var lc net.ListenConfig
listener, err := lc.Listen(ctx, "unix", socketPath)
if err != nil {
return nil, err
}
return &closerListener{
listener: listener,
lockFile: lockFile,
}, nil
}
func getLockFileName(socketPath string) string {
return strings.TrimSuffix(socketPath, filepath.Ext(socketPath)) + ".lock"
}

View File

@ -0,0 +1,35 @@
//go:build windows
// +build windows
package server
import (
"context"
"fmt"
"net"
"net/url"
"github.com/Microsoft/go-winio"
"github.com/cnrancher/kube-explorer/internal/config"
)
func ensureListener(_ context.Context) (net.Listener, string, error) {
if config.BindAddress == "" {
return nil, "", nil
}
u, err := url.Parse(config.BindAddress)
if err != nil {
return nil, "", err
}
switch u.Scheme {
case "":
return nil, config.BindAddress, nil
case "tcp":
return nil, u.Host, nil
case "namedpipe":
listener, err := winio.ListenPipe(u.Path, nil)
return listener, u.Path, err
default:
return nil, "", fmt.Errorf("Unsupported scheme %s, only tcp and namedpipe are supported in windows", u.Scheme)
}
}

View File

@ -3,9 +3,9 @@ package main
import ( import (
"os" "os"
"github.com/cnrancher/kube-explorer/internal/version"
"github.com/rancher/steve/pkg/debug" "github.com/rancher/steve/pkg/debug"
stevecli "github.com/rancher/steve/pkg/server/cli" stevecli "github.com/rancher/steve/pkg/server/cli"
"github.com/rancher/steve/pkg/version"
"github.com/rancher/wrangler/v3/pkg/signals" "github.com/rancher/wrangler/v3/pkg/signals"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -38,7 +38,7 @@ func run(_ *cli.Context) error {
if err != nil { if err != nil {
return err return err
} }
return s.ListenAndServe(ctx, keconfig.Steve.HTTPSListenPort, keconfig.Steve.HTTPListenPort, nil) return server.Serve(ctx, s)
} }
func joinFlags(flags ...[]cli.Flag) []cli.Flag { func joinFlags(flags ...[]cli.Flag) []cli.Flag {

View File

@ -4,5 +4,4 @@ ARG TARGETOS
ENV ARCH=${TARGETARCH:-"amd64"} OS=${TARGETOS:-"linux"} ENV ARCH=${TARGETARCH:-"amd64"} OS=${TARGETOS:-"linux"}
RUN zypper install -y catatonit RUN zypper install -y catatonit
COPY kube-explorer-${OS}-${ARCH} /usr/bin/kube-explorer COPY kube-explorer-${OS}-${ARCH} /usr/bin/kube-explorer
ENTRYPOINT [ "/usr/bin/catatonit", "--" ] ENTRYPOINT [ "/usr/bin/catatonit", "--", "kube-explorer" ]
CMD [ "kube-explorer" ]

View File

@ -6,77 +6,33 @@ cd "$(dirname $0)/.."
rm -rf ./bin/* ./dist/* rm -rf ./bin/* ./dist/*
OS_ARCH_ARG_LINUX="amd64 arm arm64" BUILD_TARGET="${BUILD_TARGET:-dev}"
OS_ARCH_ARG_DARWIN="amd64 arm64" CROSS=${CROSS:-}
OS_ARCH_ARG_WINDOWS="amd64"
LD_INJECT_VALUES="-X github.com/cnrancher/kube-explorer/internal/version.Version=$VERSION if [[ ${GITHUB_REF} == refs/tags/* ]]; then
-X github.com/cnrancher/kube-explorer/internal/version.GitCommit=$COMMIT CROSS=tag
-X github.com/cnrancher/kube-explorer/internal/config.APIUIVersion=$CATTLE_API_UI_VERSION" elif [ -n "${GITHUB_REF}" ]; then
CROSS=push
[ "$(uname)" != "Darwin" ] && LINKFLAGS="-extldflags -static -s" fi
case "$CROSS" in case "$CROSS" in
"push")
for ARCH in ${OS_ARCH_ARG_LINUX}; do
OUTPUT_BIN="bin/kube-explorer-linux-$ARCH"
echo "Building binary for linux/$ARCH..."
GOARCH=$ARCH GOOS=linux CGO_ENABLED=0 go build -tags embed \
-ldflags \
"$LD_INJECT_VALUES $LINKFLAGS" \
-o ${OUTPUT_BIN}
done
;;
"tag") "tag")
for ARCH in ${OS_ARCH_ARG_LINUX}; do BUILD_TARGET="prod"
OUTPUT_BIN="bin/kube-explorer-linux-$ARCH" ;;
echo "Building binary for linux/$ARCH..." "push")
GOARCH=$ARCH GOOS=linux CGO_ENABLED=0 go build -tags embed \ ;;
-ldflags \
"$LD_INJECT_VALUES $LINKFLAGS" \
-o ${OUTPUT_BIN}
done
for ARCH in ${OS_ARCH_ARG_DARWIN}; do
OUTPUT_BIN="bin/kube-explorer-darwin-$ARCH"
echo "Building binary for darwin/$ARCH..."
GOARCH=$ARCH GOOS=darwin CGO_ENABLED=0 go build -tags embed \
-ldflags \
"$LD_INJECT_VALUES" \
-o ${OUTPUT_BIN}
done
for ARCH in ${OS_ARCH_ARG_WINDOWS}; do
OUTPUT_BIN="bin/kube-explorer-windows-$ARCH.exe"
echo "Building binary for windows/$ARCH..."
GOARCH=$ARCH GOOS=windows CGO_ENABLED=0 go build -tags embed \
-ldflags \
"$LD_INJECT_VALUES" \
-o ${OUTPUT_BIN}
done
;;
*) *)
# only build one for current platform BUILD_ARG="${BUILD_ARG} --single-target"
CGO_ENABLED=0 go build -tags embed \ ;;
-ldflags \
"$LD_INJECT_VALUES $LINKFLAGS" \
-o "bin/kube-explorer-$(uname | tr '[:upper:]' '[:lower:]')-${ARCH}"
;;
esac esac
BUILD_ARG="${BUILD_ARG:-} --skip validate --id ${BUILD_TARGET}"
mkdir -p "./bin" mkdir -p "./bin"
# upx is handled by goreleaser
VERSION=${VERSION} COMMIT=${COMMIT} goreleaser build $BUILD_ARG
mkdir -p "./dist" mkdir -p "./dist"
for f in ./bin/*; do cp -r bin/kube-explorer-* dist/
filename=$(basename "$f")
if [[ $filename != *darwin* && -z "$SKIP_COMPRESS" ]]; then
if upx -o "./dist/$filename" "$f"; then
echo "UPX done for $filename!"
else
echo "UPX failed for $filename, copying original file."
cp "$f" "./dist/$filename"
fi
else
cp "$f" "./dist/$filename"
fi
done

View File

@ -6,4 +6,6 @@ cd $(dirname $0)
./download ./download
./validate ./validate
./build ./build
./package if [ -z "${SKIP_PACKAGE}" ]; then
./package
fi

View File

@ -1,8 +1,10 @@
#!/bin/bash #!/bin/bash
set -e set -e
cd $(dirname $0) cd "$(dirname $0)/.."
./download ./scripts/download
source $(dirname $0)/version
[ "$(uname)" != "Darwin" ] && LINKFLAGS="-extldflags -static -s" [ "$(uname)" != "Darwin" ] && LINKFLAGS="-extldflags -static -s"

View File

@ -14,7 +14,7 @@ rm -rf internal/ui/ui/*
mkdir -p internal/ui/ui/dashboard mkdir -p internal/ui/ui/dashboard
cd internal/ui/ui/dashboard || exit 1; cd internal/ui/ui/dashboard || exit 1;
curl -sL https://pandaria-dashboard-ui.s3.ap-southeast-2.amazonaws.com/release-2.8-cn/kube-explorer-ui/${CATTLE_DASHBOARD_UI_VERSION}.tar.gz | $TAR_CMD xvzf - --strip-components=2 curl -sL https://pandaria-dashboard-ui.s3.ap-southeast-2.amazonaws.com/release-2.9-cn/kube-explorer-ui/${CATTLE_DASHBOARD_UI_VERSION}.tar.gz | $TAR_CMD xvzf - --strip-components=2
cp index.html ../index.html cp index.html ../index.html
mkdir ../api-ui mkdir ../api-ui

View File

@ -1,9 +0,0 @@
#!/bin/bash
set -e
cd $(dirname $0)
./download
./validate
./build

View File

@ -1,11 +1,15 @@
#!/bin/bash #!/bin/bash
if [[ ${GITHUB_REF} == refs/tags/* ]]; then
GIT_TAG=${GIT_TAG:-${GITHUB_REF_NAME}}
fi
if [ -n "$(git status --porcelain --untracked-files=no)" ]; then if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
DIRTY="-dirty" DIRTY="-dirty"
fi fi
COMMIT=$(git rev-parse --short HEAD) COMMIT=$(git rev-parse --short HEAD)
GIT_TAG=${DRONE_TAG:-$(git tag -l --contains HEAD | head -n 1)} GIT_TAG=${GIT_TAG:-$(git tag -l --contains HEAD | head -n 1)}
if [[ -z "$DIRTY" && -n "$GIT_TAG" ]]; then if [[ -z "$DIRTY" && -n "$GIT_TAG" ]]; then
VERSION=$GIT_TAG VERSION=$GIT_TAG