diff --git a/README.md b/README.md index 32f2fa3..9718ac5 100644 --- a/README.md +++ b/README.md @@ -54,9 +54,9 @@ The following list contains all the options and their default values.: | `k3d.defaults.numAgents` | 0 | default number of agent nodes for new K3D clusters. | | `k3d.defaults.serverArgs` | "" | default K3S server arguments for new K3D clusters. | | `k3d.images` | {} | images used for creating new K3D cluster nodes | -| `k3d.images.proposals.registry`| `https://registry.hub.docker.com` | registry used for looking for images for the cluster (defaults to the Docker Hub). | -| `k3d.images.proposals.repo` | `rancher/k3s` | image repository used for proposing different images, including the namespace (ie, `rancher/k3s`) | -| `k3d.images.proposals.tagRegex` | "" | filter proposed images with a _regex_ (ie, `.*v1\\.19.*` for filtering all the images with _1.19_). | +| `k3d.images.proposalsRegistry`| `https://registry.hub.docker.com` | registry used for looking for images for the cluster (defaults to the Docker Hub). | +| `k3d.images.proposalsRepo` | `rancher/k3s` | image repository used for proposing different images, including the namespace (ie, `rancher/k3s`) | +| `k3d.images.proposalsTagRegex` | "" | filter proposed images with a _regex_ (ie, `.*v1\\.19.*` for filtering all the images with _1.19_). | Example configuration: diff --git a/package.json b/package.json index 7503cbd..75dbba2 100644 --- a/package.json +++ b/package.json @@ -120,36 +120,30 @@ "type": "object", "description": "Settings for images used for creating new K3D cluster nodes", "properties": { - "k3d.images.proposals": { - "type": "object", - "description": "Proposed images, after querying the registry", - "properties": { - "k3d.images.proposals.registry": { - "type": "string", - "default": "https://registry.hub.docker.com", - "format": "uri", - "examples": [ - "https://registry.hub.docker.com" - ], - "description": "Registry used for looking for images for the cluster (defaults to the Docker Hub)." - }, - "k3d.images.proposals.repo": { - "type": "string", - "default": "rancher/k3s", - "examples": [ - "rancher/k3s" - ], - "markdownDescription": "Image repository used for proposing different images, including the namespace (ie, `rancher/k3s`)." - }, - "k3d.images.proposals.tagRegex": { - "type": "string", - "default": "", - "examples": [ - ".*1\\.19.*" - ], - "markdownDescription": "Filter images by a _regex_ (ie, `.*v1\\.19.*` for filtering all the images with _1.19_)." - } - } + "k3d.images.proposalsRegistry": { + "type": "string", + "default": "https://registry.hub.docker.com", + "format": "uri", + "examples": [ + "https://registry.hub.docker.com" + ], + "description": "Registry used for looking for images for the cluster (defaults to the Docker Hub)." + }, + "k3d.images.proposalsRepo": { + "type": "string", + "default": "rancher/k3s", + "examples": [ + "rancher/k3s" + ], + "markdownDescription": "Image repository used for proposing different images, including the namespace (ie, `rancher/k3s`)." + }, + "k3d.images.proposalsTagRegex": { + "type": "string", + "default": "", + "examples": [ + ".*1\\.19.*" + ], + "markdownDescription": "Filter images by a _regex_ (ie, `.*v1\\.19.*` for filtering all the images with _1.19_)." } } }, @@ -168,7 +162,7 @@ "Only consider **stable** releases", "Consider any k3d release (including `alpha` and `beta` releases)" ], - "default": "stable", + "default": "all", "description": "Versions of k3d that will be considered when downloading the binary from the list of GitHub releases." }, "k3d.updateKubeconfig": { diff --git a/src/commands/createClusterForm.ts b/src/commands/createClusterForm.ts index 2a785d6..77b8651 100644 --- a/src/commands/createClusterForm.ts +++ b/src/commands/createClusterForm.ts @@ -198,9 +198,12 @@ export async function getCreateClusterForm(defaults: ClusterCreateSettings): Pro res += imagesNames.map((s) => ``).join("\n"); res += ``; + const imageRepo = config.getK3DConfigImages("proposalsRepo", DEFAULT_IMAGE_REPO); + const imageRegistry = config.getK3DConfigImages("proposalsRegistry", DEFAULT_IMAGE_REGISTRY); + datalistParam = `list="images"`; datalistExplain = ` -
  • ... or accept one of proposals in the dropdown menu (obtained for "${getImageRepo()}" from ${getImageRegistry()}).
  • `; +
  • ... or accept one of proposals in the dropdown menu (obtained for "${imageRepo}" from ${imageRegistry}).
  • `; } } @@ -374,29 +377,11 @@ export function createClusterSettingsFromForm(s: any): ClusterCreateSettings { // images proposals ///////////////////////////////////////////////////////////////////////////////////////////////////// -function getImageRepo(): string { - const imageRepoConfig = config.getK3DConfigImagesProposals("repo"); - return imageRepoConfig ? imageRepoConfig : DEFAULT_IMAGE_REPO; -} - -function getImageRegistry(): string { - const imageRegistryConfig = config.getK3DConfigImagesProposals("registry"); - return imageRegistryConfig ? imageRegistryConfig : DEFAULT_IMAGE_REGISTRY; -} - // getProposedImages obtains a list of proposed images by querying the registry about tags // for a given image name. async function getProposedImages(): Promise> { - const imageRepo = getImageRepo(); - if (imageRepo === undefined || imageRepo.length === 0) { - return { succeeded: true, result: [] }; - } - - const imageRegistry = getImageRegistry(); - if (imageRegistry.length === 0) { - // return an empty result when no registry is provided - return { succeeded: true, result: [] }; - } + const imageRepo: string = config.getK3DConfigImages("proposalsRepo", DEFAULT_IMAGE_REPO); + const imageRegistry = config.getK3DConfigImages("proposalsRegistry", DEFAULT_IMAGE_REGISTRY); const components = imageRepo.split('/').slice(0, 2); if (components.length < 2) { @@ -406,7 +391,7 @@ async function getProposedImages(): Promise> { const imageNamespace = components[0]; const imageName = components[1]; - const imageTagFilterConfig = config.getK3DConfigImagesProposals("tagRegex"); + const imageTagFilterConfig = config.getK3DConfigImages("proposalsTagRegex", ""); const imageTagFilterRegex = imageTagFilterConfig ? new RegExp(imageTagFilterConfig, 'g') : undefined; const dockerInfo = await docker.getDockerInfo(config.getK3DDockerHost()); diff --git a/src/installer/installer.ts b/src/installer/installer.ts index dede5f5..5c9acee 100644 --- a/src/installer/installer.ts +++ b/src/installer/installer.ts @@ -20,6 +20,9 @@ const updateChannelAllUpdateURL = 'https://api.github.com/repos/rancher/k3d/rele // URL for the latest, stable release of k3d const updateChannelStableUpdateURL = `${updateChannelAllUpdateURL}/latest`; +// the base URL for downloading the executable +const updateExeURLBase = "https://github.com/rancher/k3d/releases/download"; + export enum EnsureMode { Alert, Silent, @@ -29,10 +32,7 @@ export function getOrInstallK3D(mode: EnsureMode): Errorable { const configuredBin: string | undefined = config.getK3DConfigPathFor('k3d'); if (configuredBin) { if (fs.existsSync(configuredBin)) { - return { - succeeded: true, - result: configuredBin - }; + return { succeeded: true, result: configuredBin }; } if (mode === EnsureMode.Alert) { @@ -44,19 +44,13 @@ export function getOrInstallK3D(mode: EnsureMode): Errorable { }); } - return { - succeeded: false, - error: [`${configuredBin} does not exist!`] - }; + 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 - }; + return { succeeded: true, result: k3dFullPath }; } logChannel.appendLine(`[installer] k3d binary not found`); @@ -71,22 +65,21 @@ export function getOrInstallK3D(mode: EnsureMode): Errorable { } logChannel.appendLine(`[installer] k3d not found and we did not try to install it`); - return { - succeeded: false, - error: [`k3d not found.`] - }; + 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> { const tool = 'k3d'; - const binFile = (shell.isUnix()) ? 'k3d' : 'k3d.exe'; + + // calculate the remove URL for the executable we want to download const binFileExtension = (shell.isUnix()) ? '' : '.exe'; const platform = shell.platform(); const os = platformUrlString(platform); + const remoteExe = `k3d-${os}-amd64${binFileExtension}`; - const version = await getStableK3DVersion(); + const version = await getLatestK3DVersionAvailable(); if (failed(version)) { return { succeeded: false, @@ -94,18 +87,22 @@ export async function installK3D(): Promise> { }; } + // final URL where the executable is located + const k3dExeURL = `${updateExeURLBase}/${version.result.trim()}/${remoteExe}`; + + // calculate the local destination for the executable + const localBinFile = (shell.isUnix()) ? 'k3d' : 'k3d.exe'; 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); + const downloadFile = path.join(installFolder, localBinFile); - logChannel.appendLine(`[installer] downloading ${k3dUrl} to ${downloadFile}`); - const downloadResult = await download.to(k3dUrl, downloadFile); + logChannel.appendLine(`[installer] downloading ${k3dExeURL} to ${downloadFile}`); + const downloadResult = await download.to(k3dExeURL, downloadFile); if (failed(downloadResult)) { return { succeeded: false, - error: [`Failed to download kubectl: ${downloadResult.error[0]}`] + error: [`Failed to download kubectl from ${k3dExeURL}: ${downloadResult.error[0]}`] }; } @@ -125,8 +122,8 @@ export async function installK3D(): Promise> { }; } -// getStableK3DVersion gets the latest version of K3D from GitHub -async function getStableK3DVersion(): Promise> { +// getLatestK3DVersionAvailable gets the latest version of K3D from GitHub +async function getLatestK3DVersionAvailable(): Promise> { const updateChannel = config.getK3DConfigUpdateChannel(); const updateChannelURL = updateChannel === config.UpdateChannel.All ? updateChannelAllUpdateURL : updateChannelStableUpdateURL; @@ -134,7 +131,7 @@ async function getStableK3DVersion(): Promise> { if (failed(downloadResult)) { return { succeeded: false, - error: [`Failed to find k3d stable version: ${downloadResult.error[0]}`] + error: [`Failed to find k3d version from ${updateChannelURL}: ${downloadResult.error[0]}`] }; } @@ -143,8 +140,5 @@ async function getStableK3DVersion(): Promise> { const v = versionObj['tag_name']; logChannel.appendLine(`[installer] found latest version ${v} from GitHub relases`); - return { - succeeded: true, - result: v - }; + return { succeeded: true, result: v }; } \ No newline at end of file diff --git a/src/utils/config.ts b/src/utils/config.ts index 0408100..0fa8ef2 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -39,10 +39,6 @@ export const VS_KUBE_K3D_CREATE_DEFAULS_CFG_KEY = export const VS_KUBE_K3D_IMAGES_CFG_KEY = `${VS_KUBE_K3D_CFG_KEY}.images`; -// setting: images proposals configuration -export const VS_KUBE_K3D_IMAGES_PROPOSALS_CFG_KEY = - `${VS_KUBE_K3D_IMAGES_CFG_KEY}.proposals`; - // setting: DOCKER_HOST export const VS_KUBE_K3D_DOCKERHOST_CFG_KEY = `${VS_KUBE_K3D_CFG_KEY}.dockerHost`; @@ -100,16 +96,13 @@ export function getK3DConfigCreateDefaults(key: string): T | undefined { return config.get(`${VS_KUBE_K3D_CREATE_DEFAULS_CFG_KEY}.${key}`); } -// getK3DConfigImages returns the image configuration. -export function getK3DConfigImages(key: string): string | undefined { - const config = vscode.workspace.getConfiguration(VS_KUBE_K3D_IMAGES_CFG_KEY); - return config.get(`${VS_KUBE_K3D_IMAGES_CFG_KEY}.${key}`); -} - // getK3DConfigImagesProposals returns the image proposals configuration. -export function getK3DConfigImagesProposals(key: string): string | undefined { - const config = vscode.workspace.getConfiguration(VS_KUBE_K3D_IMAGES_PROPOSALS_CFG_KEY); - return config.get(`${VS_KUBE_K3D_IMAGES_PROPOSALS_CFG_KEY}.${key}`); +export function getK3DConfigImages(key: string, fallback: string): string { + const baseKey = `${VS_KUBE_K3D_IMAGES_CFG_KEY}.${key}`; + const configKey = enclosingKey(baseKey); + const config = vscode.workspace.getConfiguration(configKey)[baseKey]; + return config ? config : fallback; + // return config.get(`${VS_KUBE_K3D_IMAGES_CFG_KEY}.${key}`, fallback); } export enum UpdateChannel {