-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Installer for the latest stable version of k3d
Signed-off-by: Alvaro Saurin <[email protected]>
- Loading branch information
Showing
14 changed files
with
2,540 additions
and
1,820 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Change Log | ||
|
||
## 0.0.2 | ||
|
||
- Installer | ||
|
||
## 0.0.1 | ||
|
||
- Basic cluster listing | ||
- Create cluster |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,36 @@ | ||
# k3d extension for Visual Studio Code | ||
# Kubernetes [k3d](https://github.com/rancher/k3d) extension for Visual Studio Code | ||
|
||
This extension displays your `k3d` local cluster in the Kubernetes extension's Cloud Explorer. | ||
You can use this to create and delete clusters, and to merge them into your kubeconfig. | ||
## Overview | ||
|
||
**This is an early stage preview. It's not feature complete! Feature requests welcome via the issues page. | ||
(And let us know about bugs too!)** | ||
This extension displays your [k3d](https://github.com/rancher/k3d) local clusters | ||
in the Kubernetes extension's Cloud Explorer. You can use this to create and | ||
delete clusters, and to merge them into your `kubeconfig`. | ||
|
||
**This is an early stage preview. It's not feature complete! Feature requests | ||
welcome via the issues page. (And let us know about bugs too!)** | ||
|
||
This project is heavily based on the [KinD plugin for VSCode](https://github.com/deislabs/kind-vscode). | ||
|
||
# Prerequisites | ||
## Settings | ||
|
||
Example: | ||
|
||
You must have a recent `k3d` binary on your system path. You can download the binaries for your | ||
operating system from https://github.com/rancher/k3d/releases. In particular, `k3d` must support | ||
JSON output. | ||
```JSON | ||
"vs-kubernetes-k3d": { | ||
"vs-kubernetes-k3d.k3d-path.linux": "/home/user/bin/k3d" | ||
} | ||
``` | ||
|
||
You can set the path to your k3d executble with the `k3d.path` setting. | ||
* `vs-kubernetes-k3d.k3d-path`: this extension will download a recent version | ||
of `k3d` automatically, but you can use your own binary by seting this | ||
parameter. | ||
|
||
# Development | ||
## Development | ||
|
||
The easiest way to start coding on the extension is by following these steps: | ||
|
||
* `git clone https://github.com/inercia/vscode-k3d.git` | ||
* `code vscode-k3d` | ||
* `npm install` in the terminal, then `F5` to run it in a new window. | ||
|
||
You can see the debug output in `View > Output` and choosing the `k3d` view. | ||
* `npm install` in the terminal, then `F5` to start a new VSCode window | ||
with the extension installed. You can add breakpoints and so on, and you | ||
can see the debug output in `View > Output` and choosing the `k3d` view. |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import * as path from 'path'; | ||
import * as stream from 'stream'; | ||
import * as tmp from 'tmp'; | ||
|
||
import { succeeded, Errorable } from '../utils/errorable'; | ||
|
||
type DownloadFunc = | ||
(url: string, destination?: string, options?: any) | ||
=> Promise<Buffer> & stream.Duplex; // Stream has additional events - see https://www.npmjs.com/package/download | ||
|
||
let download: DownloadFunc | undefined; | ||
|
||
function ensureDownloadFunc() { | ||
if (!download) { | ||
// Fix download module corrupting HOME environment variable on Windows | ||
// See https://github.com/Azure/vscode-kubernetes-tools/pull/302#issuecomment-404678781 | ||
// and https://github.com/kevva/npm-conf/issues/13 | ||
const home = process.env['HOME']; | ||
download = require('download'); | ||
if (home) { | ||
process.env['HOME'] = home; | ||
} | ||
} | ||
} | ||
|
||
export async function toTempFile(sourceUrl: string): Promise<Errorable<string>> { | ||
const tempFileObj = tmp.fileSync({ prefix: "vsk-k3d-autoinstall-" }); | ||
const downloadResult = await to(sourceUrl, tempFileObj.name); | ||
if (succeeded(downloadResult)) { | ||
return { succeeded: true, result: tempFileObj.name }; | ||
} | ||
return { succeeded: false, error: downloadResult.error }; | ||
} | ||
|
||
export async function to(sourceUrl: string, destinationFile: string): Promise<Errorable<null>> { | ||
ensureDownloadFunc(); | ||
try { | ||
await download!(sourceUrl, path.dirname(destinationFile), { filename: path.basename(destinationFile) }); // safe because we ensured it | ||
return { succeeded: true, result: null }; | ||
} catch (e) { | ||
return { succeeded: false, error: [e.message] }; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import * as vscode from 'vscode'; | ||
import { Platform, platform } from "../utils/shell"; | ||
import * as path from 'path'; | ||
import * as shell from '../utils/shell'; | ||
import { VS_KUBE_K3D_EXTENSION_CONFIG_KEY } from "../utils/config"; | ||
|
||
function osKeyString(os: Platform): string | null { | ||
switch (os) { | ||
case Platform.Windows: return 'windows'; | ||
case Platform.MacOS: return 'mac'; | ||
case Platform.Linux: return 'linux'; | ||
default: return null; | ||
} | ||
} | ||
|
||
export function platformUrlString(platform: Platform, supported?: Platform[]): string | null { | ||
if (supported && supported.indexOf(platform) < 0) { | ||
return null; | ||
} | ||
switch (platform) { | ||
case Platform.Windows: return 'windows'; | ||
case Platform.MacOS: return 'darwin'; | ||
case Platform.Linux: return 'linux'; | ||
default: return null; | ||
} | ||
} | ||
|
||
export function formatBin(tool: string, platform: Platform): string | null { | ||
const platformString = platformUrlString(platform); | ||
if (!platformString) { | ||
return null; | ||
} | ||
|
||
const toolPath = `${platformString}-amd64/${tool}`; | ||
if (platform === Platform.Windows) { | ||
return toolPath + '.exe'; | ||
} | ||
return toolPath; | ||
} | ||
|
||
// Functions for working with tool paths | ||
|
||
export function getConfigK3DToolPath(tool: string): string | undefined { | ||
const baseKey = getK3DToolPathBaseKey(tool); | ||
return getK3DPathSetting(baseKey); | ||
} | ||
|
||
function getK3DToolPathBaseKey(tool: string): string { | ||
return `${VS_KUBE_K3D_EXTENSION_CONFIG_KEY}.${tool}-path`; | ||
} | ||
|
||
function getK3DPathSetting(baseKey: string): string | undefined { | ||
const os = platform(); | ||
const osOverridePath = vscode.workspace.getConfiguration(VS_KUBE_K3D_EXTENSION_CONFIG_KEY)[osOverrideKey(os, baseKey)]; | ||
return osOverridePath || vscode.workspace.getConfiguration(VS_KUBE_K3D_EXTENSION_CONFIG_KEY)[baseKey]; | ||
} | ||
|
||
function osOverrideKey(os: Platform, baseKey: string): string { | ||
const osKey = osKeyString(os); | ||
return osKey ? `${baseKey}.${osKey}` : baseKey; // The 'else' clause should never happen so don't worry that this would result in double-checking a missing base key | ||
} | ||
|
||
export function getInstallFolder(tool: string): string { | ||
return path.join(shell.home(), `.vs-kubernetes/tools/${tool}`); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
'use strict'; | ||
|
||
import * as vscode from 'vscode'; | ||
import * as download from './downloads'; | ||
import * as fs from 'fs'; | ||
import * as path from 'path'; | ||
import mkdirp = require('mkdirp'); | ||
import * as shell from '../utils/shell'; | ||
import { logChannel } from '../utils/log'; | ||
import { Errorable, failed } from '../utils/errorable'; | ||
import { addPathToConfig, toolPathOSKey } from '../utils/config'; | ||
import { platformUrlString, getConfigK3DToolPath, getInstallFolder } from './installationlayout'; | ||
|
||
export enum EnsureMode { | ||
Alert, | ||
Silent, | ||
} | ||
|
||
export function getOrInstallK3D(mode: EnsureMode): Errorable<string> { | ||
const configuredBin: string | undefined = getConfigK3DToolPath('k3d'); | ||
if (configuredBin) { | ||
if (fs.existsSync(configuredBin)) { | ||
return { | ||
succeeded: true, | ||
result: configuredBin | ||
}; | ||
} | ||
|
||
if (mode === EnsureMode.Alert) { | ||
vscode.window.showErrorMessage(`${configuredBin} binary (specified in config file) does not exist!`, | ||
"Install k3d").then((str) => { | ||
if (str === "Install k3d") { | ||
return installK3D(); | ||
} | ||
}); | ||
} | ||
|
||
return { | ||
succeeded: false, | ||
error: [`${configuredBin} does not exist!`] | ||
}; | ||
} | ||
|
||
const k3dFullPath = shell.which("k3d"); | ||
if (k3dFullPath) { | ||
logChannel.appendLine(`[installer] already found at ${k3dFullPath}`); | ||
return { | ||
succeeded: true, | ||
result: k3dFullPath | ||
}; | ||
} | ||
|
||
logChannel.appendLine(`[installer] k3d binary not found`); | ||
|
||
if (mode === EnsureMode.Alert) { | ||
vscode.window.showErrorMessage(`Could not find k3d binary.`, | ||
"Install k3d").then((str) => { | ||
if (str === "Install k3d") { | ||
return installK3D(); | ||
} | ||
}); | ||
} | ||
|
||
logChannel.appendLine(`[installer] k3d not found and we did not try to install it`); | ||
return { | ||
succeeded: false, | ||
error: [`k3d not found.`] | ||
}; | ||
} | ||
|
||
// installK3D installs K3D in a tools directory, updating the config | ||
// for pointing to this file | ||
export async function installK3D(): Promise<Errorable<string>> { | ||
const tool = 'k3d'; | ||
const binFile = (shell.isUnix()) ? 'k3d' : 'k3d.exe'; | ||
const binFileExtension = (shell.isUnix()) ? '' : '.exe'; | ||
const platform = shell.platform(); | ||
const os = platformUrlString(platform); | ||
|
||
const version = await getStableK3DVersion(); | ||
if (failed(version)) { | ||
return { | ||
succeeded: false, | ||
error: version.error | ||
}; | ||
} | ||
|
||
const installFolder = getInstallFolder(tool); | ||
mkdirp.sync(installFolder); | ||
|
||
const k3dUrl = `https://github.com/rancher/k3d/releases/download/${version.result.trim()}/k3d-${os}-amd64${binFileExtension}`; | ||
const downloadFile = path.join(installFolder, binFile); | ||
|
||
logChannel.appendLine(`[installer] downloading ${k3dUrl} to ${downloadFile}`); | ||
const downloadResult = await download.to(k3dUrl, downloadFile); | ||
if (failed(downloadResult)) { | ||
return { | ||
succeeded: false, | ||
error: [`Failed to download kubectl: ${downloadResult.error[0]}`] | ||
}; | ||
} | ||
|
||
if (shell.isUnix()) { | ||
fs.chmodSync(downloadFile, '0777'); | ||
} | ||
|
||
// update the config for pointing to this file | ||
await addPathToConfig(toolPathOSKey(platform, tool), downloadFile); | ||
|
||
logChannel.appendLine(`[installer] k3d installed successfully`); | ||
|
||
// refresh the views | ||
vscode.commands.executeCommand("extension.vsKubernetesRefreshExplorer"); | ||
vscode.commands.executeCommand("extension.vsKubernetesRefreshCloudExplorer"); | ||
|
||
return { | ||
succeeded: true, | ||
result: downloadFile | ||
}; | ||
} | ||
|
||
// getStableK3DVersion gets the latest version of K3D from GitHub | ||
async function getStableK3DVersion(): Promise<Errorable<string>> { | ||
const downloadResult = await download.toTempFile('https://api.github.com/repos/rancher/k3d/releases/latest'); | ||
if (failed(downloadResult)) { | ||
return { | ||
succeeded: false, | ||
error: [`Failed to find k3d stable version: ${downloadResult.error[0]}`] | ||
}; | ||
} | ||
|
||
const versionObj = JSON.parse(fs.readFileSync(downloadResult.result, 'utf-8')); | ||
fs.unlinkSync(downloadResult.result); | ||
|
||
const v = versionObj['tag_name']; | ||
logChannel.appendLine(`[installer] found latest version ${v} from GitHub relases`); | ||
return { | ||
succeeded: true, | ||
result: v | ||
}; | ||
} |
Oops, something went wrong.