diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index a4108e6762..5c062f2935 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -35,6 +35,15 @@ jobs: yarn | "$(Agent.OS)" path: $(YARN_CACHE_FOLDER) displayName: Cache Yarn packages + - bash: | + set -e + git clone "https://${GH_TOKEN}@github.com/lensapp/lens-ide.git" .lens-ide-overlay + rm -rf .lens-ide-overlay/.git + cp -r .lens-ide-overlay/* ./ + cp build/package.json.patch . && patch package.json package.json.patch + displayName: Customize config + env: + GH_TOKEN: $(LENS_IDE_GH_TOKEN) - script: make node_modules displayName: Install dependencies - script: make build-npm @@ -51,7 +60,6 @@ jobs: env: WIN_CSC_LINK: $(WIN_CSC_LINK) WIN_CSC_KEY_PASSWORD: $(WIN_CSC_KEY_PASSWORD) - GH_TOKEN: $(GH_TOKEN) AWS_ACCESS_KEY_ID: $(AWS_ACCESS_KEY_ID) AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY) - job: macOS @@ -76,6 +84,15 @@ jobs: yarn | "$(Agent.OS)" path: $(YARN_CACHE_FOLDER) displayName: Cache Yarn packages + - bash: | + set -e + git clone "https://${GH_TOKEN}@github.com/lensapp/lens-ide.git" .lens-ide-overlay + rm -rf .lens-ide-overlay/.git + cp -r .lens-ide-overlay/* ./ + cp build/package.json.patch . && patch package.json package.json.patch + displayName: Customize config + env: + GH_TOKEN: $(LENS_IDE_GH_TOKEN) - script: make node_modules displayName: Install dependencies - script: make build-npm @@ -94,7 +111,6 @@ jobs: APPLEIDPASS: $(APPLEIDPASS) CSC_LINK: $(CSC_LINK) CSC_KEY_PASSWORD: $(CSC_KEY_PASSWORD) - GH_TOKEN: $(GH_TOKEN) AWS_ACCESS_KEY_ID: $(AWS_ACCESS_KEY_ID) AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY) - job: Linux @@ -119,6 +135,15 @@ jobs: yarn | "$(Agent.OS)" path: $(YARN_CACHE_FOLDER) displayName: Cache Yarn packages + - bash: | + set -e + git clone "https://${GH_TOKEN}@github.com/lensapp/lens-ide.git" .lens-ide-overlay + rm -rf .lens-ide-overlay/.git + cp -r .lens-ide-overlay/* ./ + cp build/package.json.patch . && patch package.json package.json.patch + displayName: Customize config + env: + GH_TOKEN: $(LENS_IDE_GH_TOKEN) - script: make node_modules displayName: Install dependencies - script: make build-npm @@ -143,7 +168,6 @@ jobs: displayName: Build condition: "and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/'))" env: - GH_TOKEN: $(GH_TOKEN) AWS_ACCESS_KEY_ID: $(AWS_ACCESS_KEY_ID) AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY) - script: make publish-npm diff --git a/.bundled-extensions.json b/.bundled-extensions.json new file mode 100644 index 0000000000..f521c01dfd --- /dev/null +++ b/.bundled-extensions.json @@ -0,0 +1,8 @@ +{ + "extensions": [ + "pod-menu", + "node-menu", + "metrics-cluster-feature", + "kube-object-event-status" + ] +} diff --git a/.eslintrc.js b/.eslintrc.js index 57ee07348f..4854713f0e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -79,6 +79,8 @@ module.exports = { sourceType: "module", }, rules: { + "no-invalid-this": "off", + "@typescript-eslint/no-invalid-this": ["error"], "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/explicit-module-boundary-types": "off", @@ -137,6 +139,8 @@ module.exports = { jsx: true, }, rules: { + "no-invalid-this": "off", + "@typescript-eslint/no-invalid-this": ["error"], "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/no-explicit-any": "off", "@typescript-eslint/interface-name-prefix": "off", diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e6dbf72784..c4a43f6eb4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,6 +1,11 @@ name: Test on: - - pull_request + pull_request: + branches: + - "*" + push: + branches: + - master jobs: build: name: Test @@ -15,19 +20,46 @@ jobs: with: fetch-depth: 0 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + if: runner.os == 'Linux' + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + - name: Using Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - - run: make node_modules + - name: Get yarn cache directory path + id: yarn-cache-dir-path + run: echo "::set-output name=dir::$(yarn cache dir)" + + - uses: actions/cache@v2 + id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - uses: nick-invision/retry@v2 name: Install dependencies + with: + timeout_minutes: 10 + max_attempts: 3 + retry_on: error + command: make node_modules - run: make build-npm name: Generate npm package - - run: make -j2 build-extensions + - uses: nick-invision/retry@v2 name: Build bundled extensions + with: + timeout_minutes: 15 + max_attempts: 3 + retry_on: error + command: make -j2 build-extensions - run: make test name: Run tests @@ -45,27 +77,15 @@ jobs: sudo chown -R $USER $HOME/.kube $HOME/.minikube name: Install integration test dependencies if: runner.os == 'Linux' - - run: | - set -e - rm -rf extensions/telemetry - xvfb-run --auto-servernum --server-args='-screen 0, 1600x900x24' make integration-linux - git checkout extensions/telemetry + - run: xvfb-run --auto-servernum --server-args='-screen 0, 1600x900x24' make integration-linux name: Run Linux integration tests if: runner.os == 'Linux' - - run: | - set -e - rm -rf extensions/telemetry - make integration-win - git checkout extensions/telemetry + - run: make integration-win name: Run Windows integration tests shell: bash if: runner.os == 'Windows' - - run: | - set -e - rm -rf extensions/telemetry - make integration-mac - git checkout extensions/telemetry + - run: make integration-mac name: Run macOS integration tests if: runner.os == 'macOS' diff --git a/LICENSE b/LICENSE index 37da2d2e07..208e7c2e9c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,11 +1,9 @@ -Copyright (c) 2021 Mirantis, Inc. +Copyright (c) 2021 OpenLens Authors. Portions of this software are licensed as follows: * All content residing under the "docs/" directory of this repository, if that directory exists, is licensed under "Creative Commons: CC BY-SA 4.0 license". -* All third party components incorporated into the Lens Software are licensed -under the original license provided by the owner of the applicable component. * Content outside of the above mentioned directories or restrictions above is available under the "MIT" license as defined below. diff --git a/Makefile b/Makefile index 658be09690..cdbcc94f85 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ binaries/client: node_modules yarn download-bins node_modules: yarn.lock - yarn install --frozen-lockfile + yarn install --frozen-lockfile --network-timeout=100000 yarn check --verify-tree --integrity static/build/LensDev.html: node_modules @@ -65,10 +65,11 @@ integration-win: binaries/client build-extension-types build-extensions .PHONY: build build: node_modules binaries/client build-extensions + yarn run compile ifeq "$(DETECTED_OS)" "Windows" - yarn dist:win + ./node_modules/.bin/electron-builder --publish onTag --x64 --ia32 else - yarn dist + ./node_modules/.bin/electron-builder --publish onTag endif $(extension_node_modules): diff --git a/README.md b/README.md index dc018b3ac2..595def597b 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,22 @@ -# Lens | The Kubernetes IDE +# Lens Open Source Project (OpenLens) -[](https://dev.azure.com/lensapp/lensapp/_build/latest?definitionId=1&branchName=master) -[](https://github.com/lensapp/lens/releases?label=Downloads) +[](https://github.com/lensapp/lens/actions/workflows/test.yml) [](https://join.slack.com/t/k8slens/shared_invite/enQtOTc5NjAyNjYyOTk4LWU1NDQ0ZGFkOWJkNTRhYTc2YjVmZDdkM2FkNGM5MjhiYTRhMDU2NDQ1MzIyMDA4ZGZlNmExOTc0N2JmY2M3ZGI) -Lens provides the full situational awareness for everything that runs in Kubernetes. It's lowering the barrier of entry for people just getting started and radically improving productivity for people with more experience. +## The Repository -The Lens open source project is backed by a number of Kubernetes and cloud native ecosystem pioneers. It's a standalone application for MacOS, Windows and Linux operating systems. Lens is 100% open source and free of charge for any purpose. +This repository ("OpenLens") is where Team Lens develops the [Lens IDE](https://k8slens.dev) product together with the community. It is backed by a number of Kubernetes and cloud native ecosystem pioneers. This source code is available to everyone under the [MIT license](./LICENSE). + +## Lens - The Kubernetes IDE + +Lens - The Kubernetes IDE ("Lens IDE") is a distribution of the OpenLens repository with Team Lens specific customizations released under a traditional [EULA](https://k8slens.dev/licenses/eula). + +Lens IDE provides the full situational awareness for everything that runs in Kubernetes. It's lowering the barrier of entry for people just getting started and radically improving productivity for people with more experience. + +Lens IDE a standalone application for MacOS, Windows and Linux operating systems. You can download it free of charge for Windows, MacOS, and Linux from [Lens IDE website](https://k8slens.dev). [](https://www.youtube.com/watch?v=eeDwdVXattc) -## What makes Lens special? - -* Amazing usability and end-user experience -* Unified, secure, multi-cluster management on any platform: support for hundreds of clusters -* Standalone application: no need to install anything in-cluster -* Lens installs anywhere, elimanting the need to wrangle credentials -* Real-time cluster state visualization -* Resource utilization charts and trends with history powered by built-in Prometheus -* Smart terminal access to nodes and containers -* Clusters can be local (e.g. minikube) or external (e.g. EKS, GKE, AKS) -* Performance optimized to handle massive clusters (tested with a cluster running 25k pods) -* RBAC security is preserved, as Lens uses the standard Kubernetes API -* Lens Extensions are used to add custom visualizations and functionality to accelerate development workflows for all the technologies and services that integrate with Kubernetes -* Port forwarding -* Helm package deployment: Browse and deploy Helm charts with one click-Install -* Extensions via Lens Extensions API - ## Installation See [Getting Started](https://docs.k8slens.dev/latest/getting-started/) page. diff --git a/docs/extensions/capabilities/common-capabilities.md b/docs/extensions/capabilities/common-capabilities.md index 1410dfc148..676603ce21 100644 --- a/docs/extensions/capabilities/common-capabilities.md +++ b/docs/extensions/capabilities/common-capabilities.md @@ -1,10 +1,13 @@ # Common Capabilities -Here we will discuss common and important building blocks for your extensions, and explain how you can use them. Almost all extensions use some of these functionalities. +Here we will discuss common and important building blocks for your extensions, and explain how you can use them. +Almost all extensions use some of these functionalities. ## Main Extension -The main extension runs in the background. It adds app menu items to the Lens UI. In order to see logs from this extension, you need to start Lens from the command line. +The main extension runs in the background. +It adds app menu items to the Lens UI. +In order to see logs from this extension, you need to start Lens from the command line. ### Activate @@ -58,7 +61,8 @@ export default class ExampleMainExtension extends LensMainExtension { ## Renderer Extension -The renderer extension runs in a browser context, and is visible in Lens's main window. In order to see logs from this extension you need to check them via **View** > **Toggle Developer Tools** > **Console**. +The renderer extension runs in a browser context, and is visible in Lens's main window. +In order to see logs from this extension you need to check them via **View** > **Toggle Developer Tools** > **Console**. ### Activate @@ -90,7 +94,8 @@ export default class ExampleMainExtension extends LensRendererExtension { ### Global Pages -This extension can register custom global pages (views) to Lens's main window. The global page is a full-screen page that hides all other content from a window. +This extension can register custom global pages (views) to Lens's main window. +The global page is a full-screen page that hides all other content from a window. ```typescript import React from "react" @@ -121,7 +126,8 @@ export default class ExampleRendererExtension extends LensRendererExtension { ### App Preferences -This extension can register custom app preferences. It is responsible for storing a state for custom preferences. +This extension can register custom app preferences. +It is responsible for storing a state for custom preferences. ```typescript import React from "react" @@ -145,7 +151,8 @@ export default class ExampleRendererExtension extends LensRendererExtension { ### Cluster Pages -This extension can register custom cluster pages. These pages are visible in a cluster menu when a cluster is opened. +This extension can register custom cluster pages. +These pages are visible in a cluster menu when a cluster is opened. ```typescript import React from "react" @@ -178,7 +185,8 @@ export default class ExampleExtension extends LensRendererExtension { ### Cluster Features -This extension can register installable features for a cluster. These features are visible in the "Cluster Settings" page. +This extension can register installable features for a cluster. +These features are visible in the "Cluster Settings" page. ```typescript import React from "react" diff --git a/docs/extensions/capabilities/styling.md b/docs/extensions/capabilities/styling.md index 236e8be120..cf80fd5530 100644 --- a/docs/extensions/capabilities/styling.md +++ b/docs/extensions/capabilities/styling.md @@ -4,7 +4,8 @@ Lens provides a set of global styles and UI components that can be used by any e ## Layout -For layout tasks, Lens uses the [flex.box](https://www.npmjs.com/package/flex.box) library which provides helpful class names to specify some of the [flexbox](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox) properties. For example, consider the following HTML and its associated CSS properties: +For layout tasks, Lens uses the [flex.box](https://www.npmjs.com/package/flex.box) library which provides helpful class names to specify some of the [flexbox](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox) properties. +For example, consider the following HTML and its associated CSS properties: ```html
@@ -22,7 +23,8 @@ However, you are free to use any styling technique or framework you like, includ ### Layout Variables -There is a set of CSS variables available for for basic layout needs. They are located inside `:root` and are defined in [app.scss](https://github.com/lensapp/lens/blob/master/src/renderer/components/app.scss): +There is a set of CSS variables available for for basic layout needs. +They are located inside `:root` and are defined in [app.scss](https://github.com/lensapp/lens/blob/master/src/renderer/components/app.scss): ```css --unit: 8px; @@ -31,7 +33,8 @@ There is a set of CSS variables available for for basic layout needs. They are l --border-radius: 3px; ``` -These variables are intended to set consistent margins and paddings across components. For example: +These variables are intended to set consistent margins and paddings across components. +For example: ```css .status { @@ -46,14 +49,16 @@ Lens uses two built-in themes defined in [the themes directory](https://github.c ### Theme Variables -When Lens is loaded, it transforms the selected theme's `json` file into a list of [CSS Custom Properties (CSS Variables)](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties). This list then gets injected into the `:root` element so that any of the down-level components can use them. +When Lens is loaded, it transforms the selected theme's `json` file into a list of [CSS Custom Properties (CSS Variables)](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties). +This list then gets injected into the `:root` element so that any of the down-level components can use them.  When the user changes the theme, the above process is repeated, and new CSS variables appear, replacing the previous ones. If you want to preserve Lens's native look and feel, with respect to the lightness or darkness of your extension, you can use the provided variables and built-in Lens components such as `Button`, `Select`, `Table`, and so on. -There is a set of CSS variables available for extensions to use for theming. They are all located inside `:root` and are defined in [app.scss](https://github.com/lensapp/lens/blob/master/src/renderer/components/app.scss): +There is a set of CSS variables available for extensions to use for theming. +They are all located inside `:root` and are defined in [app.scss](https://github.com/lensapp/lens/blob/master/src/renderer/components/app.scss): ```css --font-main: 'Roboto', 'Helvetica', 'Arial', sans-serif; @@ -88,7 +93,8 @@ as well as in [the theme modules](https://github.com/lensapp/lens/tree/master/sr ... ``` -These variables can be used in the following form: `var(--magenta)`. For example: +These variables can be used in the following form: `var(--magenta)`. +For example: ```css .status { @@ -97,11 +103,12 @@ These variables can be used in the following form: `var(--magenta)`. For example } ``` -A complete list of themable colors can be found in the [Color Reference](../color-reference). +A complete list of theme colors can be found in the [Color Reference](../color-reference). ### Theme Switching -When the light theme is active, the `` element gets a "theme-light" class, or: ``. If the class isn't there, the theme defaults to dark. The active theme can be changed in the **Preferences** page: +When the light theme is active, the `` element gets a "theme-light" class, or: ``. +If the class isn't there, the theme defaults to dark. The active theme can be changed in the **Preferences** page:  There is a way of detect active theme and its changes in JS. [MobX observer function/decorator](https://github.com/mobxjs/mobx-react#observercomponent) can be used for this purpose. diff --git a/docs/extensions/get-started/anatomy.md b/docs/extensions/get-started/anatomy.md index 5b0b94ec59..f445e421bf 100644 --- a/docs/extensions/get-started/anatomy.md +++ b/docs/extensions/get-started/anatomy.md @@ -1,6 +1,7 @@ # Extension Anatomy -In the [previous section](your-first-extension.md) you learned how to create your first extension. In this section you will learn how this extension works under the hood. +In the [previous section](your-first-extension.md) you learned how to create your first extension. +In this section you will learn how this extension works under the hood. The Hello World sample extension does three things: @@ -26,13 +27,19 @@ Let's take a closer look at our Hello World sample's source code and see how the ├── webpack.config.js // Webpack configuration ``` -The extension directory contains the extension's entry files and a few configuration files. Three files: `package.json`, `main.ts` and `renderer.tsx` are essential to understanding the Hello World sample extension. We'll look at those first. +The extension directory contains the extension's entry files and a few configuration files. +Three files: `package.json`, `main.ts` and `renderer.tsx` are essential to understanding the Hello World sample extension. +We'll look at those first. ### Extension Manifest -Each Lens extension must have a `package.json` file. It contains a mix of Node.js fields, including scripts and dependencies, and Lens-specific fields such as `publisher` and `contributes`. Some of the most-important fields include: +Each Lens extension must have a `package.json` file. +It contains a mix of Node.js fields, including scripts and dependencies, and Lens-specific fields such as `publisher` and `contributes`. +Some of the most-important fields include: -- `name` and `publisher`: Lens uses `@
- exampleId.set("secret")}>Show secret button
- {exampleId.get() === "secret" && (
-