Compare commits

..

10 Commits

Author SHA1 Message Date
AJ ONeal
6859ab4c2b feat: add sshd / sshd-service-install 2024-09-13 08:32:31 +00:00
AJ ONeal
f216ab69b4 WIP: sshd 2024-09-13 08:32:30 +00:00
Finley Thomalla
941453677e feat(koji): update releases and readme
Repository has been transferred to https://github.com/cococonscious/koji
2024-09-13 08:22:36 +00:00
AJ ONeal
556697ad67 ref: make ./builds-cacher.js one-off testable; add ./classify-one.js 2024-09-11 23:29:22 +00:00
AJ ONeal
595a0b8ef9 fix(linux-gnu): update build-classifier@v1.0.0: respect explicit 'gnu' 2024-09-11 17:18:17 -06:00
AJ ONeal
66ba82181c ref(example): update to use async/await 2024-09-11 20:22:17 +00:00
Nikolay Nikolaev
9d1cde0ced feat: add cilium
Signed-off-by: Nikolay Nikolaev <nicknickolaev@gmail.com>
2024-09-11 20:20:04 +00:00
AJ ONeal
566b5c047f fix(classifier): log rather than throw on failed classification 2024-08-20 15:51:02 -06:00
AJ ONeal
c71126fcd8 fix: init ~/.config/envman/ during init phase (before pre-install) 2024-07-24 12:23:34 -06:00
AJ ONeal
3263196360 fix(github-like): correct Authorization header 2024-06-05 19:41:24 +00:00
20 changed files with 701 additions and 385 deletions

View File

@@ -40,7 +40,7 @@ GitHubish.getAllReleases = async function ({
let userpass = `${username}:${token}`;
let basicAuth = btoa(userpass);
Object.assign(opts.headers, {
Authentication: `Basic ${basicAuth}`,
Authorization: `Basic ${basicAuth}`,
});
}

View File

@@ -23,7 +23,7 @@ install:
```text
~/.config/envman/PATH.env
~/.local/bin/foo
~/.local/opt/foo
~/.local/opt/foo/
```
## Cheat Sheet

View File

@@ -12,17 +12,19 @@ var repo = 'ripgrep';
/** **/
/******************************************************************************/
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
return all;
});
module.exports = async function (request) {
let all = await github(request, owner, repo);
return all;
};
if (module === require.main) {
module.exports(require('@root/request')).then(function (all) {
all = require('../_webi/normalize.js')(all);
(async function () {
let request = require('@root/request');
let normalize = require('../_webi/normalize.js');
let all = await module.exports(request);
all = normalize(all);
// just select the first 5 for demonstration
all.releases = all.releases.slice(0, 5);
console.info(JSON.stringify(all, null, 2));
});
})();
}

View File

@@ -189,9 +189,10 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
}
let bc = {};
bc.usedTerms = {};
bc.orphanTerms = Object.assign({}, ALL_TERMS);
bc.ALL_TERMS = ALL_TERMS;
bc.orphanTerms = Object.assign({}, bc.ALL_TERMS);
bc.unknownTerms = {};
bc.usedTerms = {};
bc.formats = [];
bc._triplets = {};
bc._targetsByBuildIdCache = {};
@@ -381,7 +382,14 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
if (!projInfo) {
projInfo = await getLatestBuilds(Releases, installersDir, cacheDir, name);
}
transformAndUpdate(name, projInfo, meta, tsDate);
let latestProjInfo = await BuildsCacher.transformAndUpdate(
name,
projInfo,
meta,
tsDate,
bc,
);
bc._caches[name] = latestProjInfo;
process.nextTick(async function () {
let now = date.valueOf();
@@ -393,103 +401,19 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
}
projInfo = await getLatestBuilds(Releases, installersDir, cacheDir, name);
transformAndUpdate(name, projInfo, meta, date);
let latestProjInfo = BuildsCacher.transformAndUpdate(
name,
projInfo,
meta,
date,
bc,
);
bc._caches[name] = latestProjInfo;
});
return projInfo;
};
function transformAndUpdate(name, projInfo, meta, date) {
meta.packages = [];
let updated = date.valueOf();
Object.assign(projInfo, { name, updated }, meta);
for (let build of projInfo.releases) {
let buildTarget = bc.classify(projInfo, build);
if (!buildTarget) {
// ignore known, non-package extensions
continue;
}
if (buildTarget.error) {
let err = buildTarget.error;
let code = err.code || '';
console.error(`[ERROR]: ${code} ${projInfo.name}: ${build.name}`);
console.error(`>>> ${err.message} <<<`);
console.error(projInfo);
console.error(build);
console.error(`^^^ ${err.message} ^^^`);
console.error(err.stack);
continue;
}
if (!build.name) {
build.name = build.download.replace(/.*\//, '');
}
build.target = buildTarget;
meta.packages.push(build);
}
updateReleasesByTriplet(meta);
updateAndSortVersions(projInfo, meta);
Object.assign(projInfo, { name, updated }, meta);
bc._caches[name] = projInfo;
}
function updateReleasesByTriplet(meta) {
for (let build of meta.packages) {
let target = build.target;
let triplet = `${target.os}-${target.arch}-${target.libc}`;
if (!meta.releasesByTriplet[triplet]) {
meta.releasesByTriplet[triplet] = {};
}
let buildsByRelease = meta.releasesByTriplet[triplet];
if (!buildsByRelease[build.version]) {
buildsByRelease[build.version] = [];
}
let packages = buildsByRelease[build.version];
packages.push(build);
}
}
// TODO
// - tag channels
function updateAndSortVersions(projInfo, meta) {
for (let build of projInfo.packages) {
let hasVersion = meta.versions.includes(build.version);
if (!hasVersion) {
build.lexver = Lexver.parseVersion(build.version);
meta.lexversMap[build.lexver] = build.version;
}
}
meta.lexvers = Object.keys(meta.lexversMap);
meta.lexvers.sort();
meta.lexvers.reverse();
meta.versions = [];
for (let lexver of meta.lexvers) {
let version = meta.lexversMap[lexver];
meta.versions.push(version);
}
projInfo.packages.sort(function (a, b) {
if (a.lexver > b.lexver) {
return -1;
}
if (a.lexver < b.lexver) {
return 1;
}
return 0;
});
}
// Makes sure that packages are updated once an hour, on average
bc._staleNames = [];
bc._freshenTimeout = null;
@@ -525,134 +449,6 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
bc._freshenTimeout.unref();
};
bc.classify = function (projInfo, build) {
/* jshint maxcomplexity: 25 */
let maybeInstallable = Triplet.maybeInstallable(projInfo, build);
if (!maybeInstallable) {
return null;
}
if (LEGACY_OS_MAP[build.os]) {
build.os = LEGACY_OS_MAP[build.os];
}
if (LEGACY_ARCH_MAP[build.arch]) {
build.arch = LEGACY_ARCH_MAP[build.arch];
}
// because some packages are shimmed to match a single download against
let preTarget = Object.assign({ os: '', arch: '', libc: '' }, build);
let targetId = `${preTarget.os}:${preTarget.arch}:${preTarget.libc}`;
let buildId = `${projInfo.name}:${targetId}@${build.download}`;
let target = bc._targetsByBuildIdCache[buildId];
if (target) {
Object.assign(build, { target: target, triplet: target.triplet });
return target;
}
let pattern = Triplet.toPattern(projInfo, build);
if (!pattern) {
let err = new Error(`no pattern generated for ${projInfo.name}`);
err.code = 'E_BUILD_NO_PATTERN';
target = { error: err };
bc._targetsByBuildIdCache[buildId] = target;
return target;
}
let rawTerms = pattern.split(/[_\{\}\/\.\-]+/g);
for (let term of rawTerms) {
delete bc.orphanTerms[term];
bc.usedTerms[term] = true;
}
// {NAME}/{NAME}-{VER}-Windows-x86_64_v2-musl.exe =>
// {NAME}.windows.x86_64v2.musl.exe
let terms = Triplet.patternToTerms(pattern);
if (!terms.length) {
let err = new Error(`'${terms}' was trimmed to ''`);
target = { error: err };
bc._targetsByBuildIdCache[buildId] = target;
return target;
}
for (let term of terms) {
if (!term) {
continue;
}
if (ALL_TERMS[term]) {
delete bc.orphanTerms[term];
bc.usedTerms[term] = true;
continue;
}
bc.unknownTerms[term] = true;
}
// {NAME}.windows.x86_64v2.musl.exe
// windows-x86_64_v2-musl
target = { triplet: '' };
void Triplet.termsToTarget(target, projInfo, build, terms);
target.triplet = `${target.arch}-${target.vendor}-${target.os}-${target.libc}`;
{
// TODO I don't love this hidden behavior
// perhaps classify should just happen when the package is loaded
// (and the sanity error should be removed, or thrown after the loop is complete)
let hasTriplet = projInfo.triplets.includes(target.triplet);
if (!hasTriplet) {
projInfo.triplets.push(target.triplet);
}
let hasOs = projInfo.oses.includes(target.os);
if (!hasOs) {
projInfo.oses.push(target.os);
}
let hasArch = projInfo.arches.includes(target.arch);
if (!hasArch) {
projInfo.arches.push(target.arch);
}
let hasLibc = projInfo.libcs.includes(target.libc);
if (!hasLibc) {
projInfo.libcs.push(target.libc);
}
if (!build.ext) {
build.ext = Triplet.buildToPackageType(build);
}
if (build.ext) {
if (!build.ext.startsWith('.')) {
build.ext = `.${build.ext}`;
}
}
let hasExt = projInfo.formats.includes(build.ext);
if (!hasExt) {
projInfo.formats.push(build.ext);
}
let hasGlobalExt = bc.formats.includes(build.ext);
if (!hasGlobalExt) {
bc.formats.push(build.ext);
}
}
bc._triplets[target.triplet] = true;
bc._targetsByBuildIdCache[buildId] = target;
let triple = [target.arch, target.vendor, target.os, target.libc];
for (let term of triple) {
if (!ALL_TERMS[term]) {
throw new Error(
`[SANITY FAIL] '${projInfo.name}' '${target.triplet}' generated unknown term '${term}'`,
);
}
delete bc.orphanTerms[term];
bc.usedTerms[term] = true;
}
return target;
};
/**
* Given a list of acceptable formats, get the sorted list of of formats.
* Actually used (as per node _webi/lint-builds.js):
@@ -967,3 +763,233 @@ BuildsCacher.create = function ({ ALL_TERMS, installers, caches }) {
return bc;
};
BuildsCacher._classify = function (bc, projInfo, build) {
/* jshint maxcomplexity: 25 */
let maybeInstallable = Triplet.maybeInstallable(projInfo, build);
if (!maybeInstallable) {
return null;
}
if (LEGACY_OS_MAP[build.os]) {
build.os = LEGACY_OS_MAP[build.os];
}
if (LEGACY_ARCH_MAP[build.arch]) {
build.arch = LEGACY_ARCH_MAP[build.arch];
}
// because some packages are shimmed to match a single download against
let preTarget = Object.assign({ os: '', arch: '', libc: '' }, build);
let targetId = `${preTarget.os}:${preTarget.arch}:${preTarget.libc}`;
let buildId = `${projInfo.name}:${targetId}@${build.download}`;
//console.log(`dbg: buildId`, buildId);
let target = bc._targetsByBuildIdCache[buildId];
if (target) {
Object.assign(build, { target: target, triplet: target.triplet });
return target;
}
let pattern = Triplet.toPattern(projInfo, build);
//console.log(`dbg: pattern`, pattern);
if (!pattern) {
let err = new Error(`no pattern generated for ${projInfo.name}`);
err.code = 'E_BUILD_NO_PATTERN';
target = { error: err };
bc._targetsByBuildIdCache[buildId] = target;
return target;
}
let rawTerms = pattern.split(/[_\{\}\/\.\-]+/g);
//console.log(`dbg: rawTerms`, rawTerms);
for (let term of rawTerms) {
delete bc.orphanTerms[term];
bc.usedTerms[term] = true;
}
// {NAME}/{NAME}-{VER}-Windows-x86_64_v2-musl.exe =>
// {NAME}.windows.x86_64v2.musl.exe
let terms = Triplet.patternToTerms(pattern);
//console.log(`dbg: terms`, terms);
if (!terms.length) {
let err = new Error(`'${terms}' was trimmed to ''`);
target = { error: err };
bc._targetsByBuildIdCache[buildId] = target;
return target;
}
for (let term of terms) {
if (!term) {
continue;
}
if (bc.ALL_TERMS[term]) {
delete bc.orphanTerms[term];
bc.usedTerms[term] = true;
continue;
}
bc.unknownTerms[term] = true;
}
// {NAME}.windows.x86_64v2.musl.exe
// windows-x86_64_v2-musl
target = { triplet: '' };
try {
void Triplet.termsToTarget(target, projInfo, build, terms);
} catch (e) {
console.error(`PACKAGE FORMAT CHANGE for '${projInfo.name}':`);
console.error(e.message);
console.error(build);
return null;
}
target.triplet = `${target.arch}-${target.vendor}-${target.os}-${target.libc}`;
{
// TODO I don't love this hidden behavior
// perhaps classify should just happen when the package is loaded
// (and the sanity error should be removed, or thrown after the loop is complete)
let hasTriplet = projInfo.triplets.includes(target.triplet);
if (!hasTriplet) {
projInfo.triplets.push(target.triplet);
}
let hasOs = projInfo.oses.includes(target.os);
if (!hasOs) {
projInfo.oses.push(target.os);
}
let hasArch = projInfo.arches.includes(target.arch);
if (!hasArch) {
projInfo.arches.push(target.arch);
}
let hasLibc = projInfo.libcs.includes(target.libc);
if (!hasLibc) {
projInfo.libcs.push(target.libc);
}
if (!build.ext) {
build.ext = Triplet.buildToPackageType(build);
}
if (build.ext) {
if (!build.ext.startsWith('.')) {
build.ext = `.${build.ext}`;
}
}
let hasExt = projInfo.formats.includes(build.ext);
if (!hasExt) {
projInfo.formats.push(build.ext);
}
let hasGlobalExt = bc.formats.includes(build.ext);
if (!hasGlobalExt) {
bc.formats.push(build.ext);
}
}
bc._triplets[target.triplet] = true;
bc._targetsByBuildIdCache[buildId] = target;
let triple = [target.arch, target.vendor, target.os, target.libc];
for (let term of triple) {
if (!bc.ALL_TERMS[term]) {
throw new Error(
`[SANITY FAIL] '${projInfo.name}' '${target.triplet}' generated unknown term '${term}'`,
);
}
delete bc.orphanTerms[term];
bc.usedTerms[term] = true;
}
return target;
};
BuildsCacher.transformAndUpdate = function (name, projInfo, meta, date, bc) {
meta.packages = [];
let updated = date.valueOf();
Object.assign(projInfo, { name, updated }, meta);
for (let build of projInfo.releases) {
let buildTarget = BuildsCacher._classify(bc, projInfo, build);
if (!buildTarget) {
// ignore known, non-package extensions
continue;
}
if (buildTarget.error) {
let err = buildTarget.error;
let code = err.code || '';
console.error(`[ERROR]: ${code} ${projInfo.name}: ${build.name}`);
console.error(`>>> ${err.message} <<<`);
console.error(projInfo);
console.error(build);
console.error(`^^^ ${err.message} ^^^`);
console.error(err.stack);
continue;
}
if (!build.name) {
build.name = build.download.replace(/.*\//, '');
}
build.target = buildTarget;
meta.packages.push(build);
}
BuildsCacher.updateReleasesByTriplet(meta);
BuildsCacher.updateAndSortVersions(projInfo, meta);
Object.assign(projInfo, { name, updated }, meta);
return projInfo;
};
// TODO
// - tag channels
BuildsCacher.updateAndSortVersions = function (projInfo, meta) {
for (let build of projInfo.packages) {
let hasVersion = meta.versions.includes(build.version);
if (!hasVersion) {
build.lexver = Lexver.parseVersion(build.version);
meta.lexversMap[build.lexver] = build.version;
}
}
meta.lexvers = Object.keys(meta.lexversMap);
meta.lexvers.sort();
meta.lexvers.reverse();
meta.versions = [];
for (let lexver of meta.lexvers) {
let version = meta.lexversMap[lexver];
meta.versions.push(version);
}
projInfo.packages.sort(function (a, b) {
if (a.lexver > b.lexver) {
return -1;
}
if (a.lexver < b.lexver) {
return 1;
}
return 0;
});
};
BuildsCacher.updateReleasesByTriplet = function (meta) {
for (let build of meta.packages) {
let target = build.target;
let triplet = `${target.os}-${target.arch}-${target.libc}`;
if (!meta.releasesByTriplet[triplet]) {
meta.releasesByTriplet[triplet] = {};
}
let buildsByRelease = meta.releasesByTriplet[triplet];
if (!buildsByRelease[build.version]) {
buildsByRelease[build.version] = [];
}
let packages = buildsByRelease[build.version];
packages.push(build);
}
};

92
_webi/classify-one.js Normal file
View File

@@ -0,0 +1,92 @@
'use strict';
let Path = require('node:path');
// let Builds = require('./builds.js');
let BuildsCacher = require('./builds-cacher.js');
let Triplet = require('./build-classifier/triplet.js');
let request = require('@root/request');
async function main() {
let projName = process.argv[2];
if (!projName) {
console.error(``);
console.error(`USAGE`);
console.error(``);
console.error(` classify-one <project-name>`);
console.error(``);
console.error(`EXAMPLE`);
console.error(``);
console.error(` classify-one caddy`);
console.error(``);
return;
}
let tsDate = new Date(0);
let meta = {
// version info
versions: [],
lexvers: [],
lexversMap: {},
// culled release assets
packages: [],
releasesByTriplet: {},
// target info
triplets: [],
oses: [],
arches: [],
libcs: [],
formats: [],
// TODO channels: [],
};
let installersDir = Path.join(__dirname, '..');
let Releases = require(`${installersDir}/${projName}/releases.js`);
if (!Releases.latest) {
Releases.latest = Releases;
}
let projInfo = await Releases.latest(request);
// let packages = await Builds.getPackage({ name: projName });
// console.log(packages);
let bc = {};
bc.ALL_TERMS = Triplet.TERMS_PRIMARY_MAP;
bc.orphanTerms = Object.assign({}, bc.ALL_TERMS);
bc.unknownTerms = {};
bc.usedTerms = {};
bc.formats = [];
bc._targetsByBuildIdCache = {};
bc._triplets = {};
let transformed = BuildsCacher.transformAndUpdate(
projName,
projInfo,
meta,
tsDate,
bc,
);
console.log(`[DEBUG] transformed`);
let sample = transformed.packages.slice(0, 20);
console.log('packages:', sample, ':packages');
console.log(
'releasesByTriplet:',
transformed.releasesByTriplet['linux-x86_64-none'][transformed.versions[0]],
':releasesByTriplet',
);
console.log('versions:', transformed.versions, ':versions');
console.log('triplets:', transformed.triplets, ':triplets');
console.log('oses:', transformed.oses, ':oses');
console.log('arches:', transformed.arches, ':arches');
console.log('libcs:', transformed.libcs, ':libcs');
console.log('formats:', transformed.formats, ':formats');
console.log(Object.keys(transformed));
}
main().catch(function (err) {
console.error('Error:');
console.error(err);
});

View File

@@ -235,8 +235,6 @@ __bootstrap_webi() {
webi_path_add() {
my_path="${1}"
fn_envman_init
# \v was chosen as it is extremely unlikely for a filename
# \1 could be an even better choice, but needs more testing.
# (currently tested working on: linux & mac)
@@ -399,7 +397,6 @@ __bootstrap_webi() {
export _webi_tmp="${_webi_tmp:-"$HOME/.local/opt/webi-tmp.d"}"
mkdir -p "${WEBI_PKG_PATH}"
mkdir -p "$HOME/.local/bin"
mkdir -p "$HOME/.local/opt"
if test -e ~/.local/bin; then
@@ -408,6 +405,7 @@ __bootstrap_webi() {
echo " Creating$(t_path ' ~/.local/bin')"
mkdir -p "$HOME/.local/bin"
fi
fn_envman_init
##
##

47
cilium/README.md Normal file
View File

@@ -0,0 +1,47 @@
---
title: cilium
homepage: https://github.com/cilium/cilium-cli
tagline: |
cilium: manage & troubleshoot Kubernetes clusters running Cilium
---
To update or switch versions, run `webi cilium@stable` (or `@v2`, `@beta`,etc).
### Files
These are the files / directories that are created and/or modified with this
install:
```text
~/.config/envman/PATH.env
~/.local/bin/cilium
~/.local/opt/cilium/
```
## Cheat Sheet
> Cilium is an open source, cloud native solution for providing, securing, and
> observing network connectivity between workloads, fueled by the revolutionary
> Kernel technology eBPF.
Quick Start User Guide:
<https://docs.cilium.io/en/stable/gettingstarted/k8s-install-default/#k8s-install-quick>
To install the default version of the Cilium image:
```sh
cilium install
```
To upgrade to a specific version of the Cilium image:
```sh
cilium upgrade --version v1.15.3
```
To check the status of the current Cilium deployment:
```sh
cilium status
```

45
cilium/install.ps1 Normal file
View File

@@ -0,0 +1,45 @@
#!/usr/bin/env pwsh
##################
# Install cilium #
##################
$pkg_cmd_name = "cilium"
$pkg_dst_cmd = "$Env:USERPROFILE\.local\bin\cilium.exe"
$pkg_dst = "$pkg_dst_cmd"
$pkg_src_cmd = "$Env:USERPROFILE\.local\opt\cilium-v$Env:WEBI_VERSION\bin\cilium.exe"
$pkg_src_bin = "$Env:USERPROFILE\.local\opt\cilium-v$Env:WEBI_VERSION\bin"
$pkg_src_dir = "$Env:USERPROFILE\.local\opt\cilium-v$Env:WEBI_VERSION"
$pkg_src = "$pkg_src_cmd"
New-Item "$Env:USERPROFILE\Downloads\webi" -ItemType Directory -Force | Out-Null
$pkg_download = "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE"
IF (!(Test-Path -Path "$Env:USERPROFILE\Downloads\webi\$Env:WEBI_PKG_FILE")) {
Write-Output "Downloading cilium from $Env:WEBI_PKG_URL to $pkg_download"
& curl.exe -A "$Env:WEBI_UA" -fsSL "$Env:WEBI_PKG_URL" -o "$pkg_download.part"
& Move-Item "$pkg_download.part" "$pkg_download"
}
IF (!(Test-Path -Path "$pkg_src_cmd")) {
Write-Output "Installing cilium"
Push-Location .local\tmp
Remove-Item -Path ".\cilium-v*" -Recurse -ErrorAction Ignore
Remove-Item -Path ".\cilium.exe" -Recurse -ErrorAction Ignore
Write-Output "Unpacking $pkg_download"
& tar xf "$pkg_download"
Write-Output "Install Location: $pkg_src_cmd"
New-Item "$pkg_src_bin" -ItemType Directory -Force
Move-Item -Path ".\cilium-*\cilium.exe" -Destination "$pkg_src_bin"
Pop-Location
}
Write-Output "Copying into '$pkg_dst_cmd' from '$pkg_src_cmd'"
Remove-Item -Path "$pkg_dst_cmd" -Recurse -ErrorAction Ignore
Copy-Item -Path "$pkg_src" -Destination "$pkg_dst" -Recurse

39
cilium/install.sh Normal file
View File

@@ -0,0 +1,39 @@
#!/bin/sh
__init_cilium() {
set -e
set -u
##################
# Install cilium #
##################
pkg_cmd_name="cilium"
pkg_dst_cmd="$HOME/.local/bin/cilium"
pkg_dst="$pkg_dst_cmd"
pkg_src_cmd="$HOME/.local/opt/cilium-v$WEBI_VERSION/bin/cilium"
pkg_src_dir="$HOME/.local/opt/cilium-v$WEBI_VERSION"
pkg_src="$pkg_src_cmd"
WEBI_SINGLE=true
# pkg_install must be defined by every package
pkg_install() {
# ~/.local/opt/cilium-v0.16.16/bin
mkdir -p "$(dirname "${pkg_src_cmd}")"
# mv ./hugo ~/.local/opt/cilium-v0.16.16/bin/
mv ./cilium "${pkg_src_cmd}"
}
pkg_get_current_version() {
cilium version 2> /dev/null |
head -n 1 |
cut -d ' ' -f 2
}
}
__init_cilium

22
cilium/releases.js Normal file
View File

@@ -0,0 +1,22 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'cilium';
var repo = 'cilium-cli';
module.exports = async function (request) {
let all = await github(request, owner, repo);
return all;
};
if (module === require.main) {
(async function () {
let request = require('@root/request');
let normalize = require('../_webi/normalize.js');
let all = await module.exports(request);
all = normalize(all);
// just select the first 5 for demonstration
all.releases = all.releases.slice(0, 5);
console.info(JSON.stringify(all, null, 2));
})();
}

View File

@@ -1,45 +0,0 @@
'use strict';
var path = require('path');
var github = require('../_common/github.js');
var owner = 'eugeneware';
var repo = 'ffmpeg-static';
module.exports = function (request) {
return github(request, owner, repo).then(function (all) {
all.releases = all.releases
.filter(function (rel) {
let isFfmpeg = rel.name.includes('ffmpeg');
if (!isFfmpeg) {
return;
}
// remove README and LICENSE
return !['.README', '.LICENSE'].includes(path.extname(rel.name));
})
.map(function (rel) {
rel.version = rel.version.replace(/^b/, '');
if (/win32/.test(rel.name)) {
rel.os = 'windows';
rel.ext = 'exe';
}
if (/ia32/.test(rel.name)) {
rel.arch = '386';
} else if (/x64/.test(rel.name)) {
rel.arch = 'amd64';
}
return rel;
});
return all;
});
};
if (module === require.main) {
module.exports(require('@root/request')).then(function (all) {
all = require('../_webi/normalize.js')(all);
console.info(JSON.stringify(all));
});
}

View File

@@ -3,51 +3,17 @@ set -e
set -u
if command -v fish > /dev/null; then
if ! test -r ~/.config/fish/config.fish; then
if [ ! -e ~/.config/fish/config.fish ]; then
mkdir -p ~/.config/fish
touch ~/.config/fish/config.fish
chmod 0600 ~/.config/fish/config.fish
fi
else
if command -v sudo > /dev/null; then
my_answer='n'
if command -v apt > /dev/null; then
echo ""
echo "ERROR"
echo " No Webi installer for fish on Linux yet."
echo ""
echo "SOLUTION"
echo " Would you like to install with apt?"
echo " sudo apt install -y fish"
echo ""
printf "Install with sudo and apt [Y/n]? "
elif command -v apk > /dev/null; then
echo ""
echo "ERROR"
echo " No Webi installer for fish on Alpine yet."
echo ""
echo "SOLUTION"
echo " Would you like to install with apk?"
echo " sudo apk add --no-cache fish"
echo ""
printf "Install with sudo and apk [Y/n]? "
elif test "Darwin" != "$(uname -s)"; then
echo "No fish installer for Linux yet."
exit 1
fi
fi
read -r my_answer < /dev/tty
if test -z "${my_answer}" ||
test "${my_answer}" = "Y" ||
test "${my_answer}" = "y"; then
sudo apt install -y fish
else
exit 1
fi
elif test "Darwin" != "$(uname -s)"; then
echo "No fish installer for Linux yet."
exit 1
fi
if [ "Darwin" != "$(uname -s)" ]; then
echo "No fish installer for Linux yet. Try this instead:"
echo " sudo apt install -y fish"
exit 1
fi
################
@@ -71,10 +37,6 @@ pkg_src="$pkg_src_cmd"
# pkg_install must be defined by every package
_macos_post_install() {
if test "Darwin" != "$(uname -s)"; then
return 0
fi
if ! [ -e "$HOME/.local/bin/fish" ]; then
return 0
fi
@@ -109,10 +71,8 @@ _macos_post_install() {
killall cfprefsd
}
if test "Darwin" = "$(uname -s)"; then
# always try to reset the default shells
_macos_post_install
fi
# always try to reset the default shells
_macos_post_install
pkg_install() {
mv fish.app/Contents/Resources/base/usr/local "$HOME/.local/opt/fish-v${WEBI_VERSION}"
@@ -124,10 +84,7 @@ pkg_post_install() {
webi_post_install
# try again to update default shells, now that all files should exist
if test "Darwin" = "$(uname -s)"; then
# always try to reset the default shells
_macos_post_install
fi
_macos_post_install
if [ ! -e ~/.config/fish/config.fish ]; then
mkdir -p ~/.config/fish

View File

@@ -14,57 +14,11 @@ __init_git() {
echo >&2 " for example, try: xcode-select --install"
# sudo xcodebuild -license accept
else
fn_prompt_sudo_install git
echo >&2 "Error: to install 'git' on Linux use the built-in package manager."
echo >&2 " for example, try: sudo apt install -y git"
fi
exit 1
}
fn_prompt_sudo_install() {
a_pkg="${1}"
if command -v sudo > /dev/null; then
my_answer='n'
cmd_pkg_add=''
if command -v apt > /dev/null; then
echo ""
echo "ERROR"
echo " No Webi installer for ${a_pkg} on Linux yet."
echo ""
echo "SOLUTION"
echo " Would you like to install with apt?"
echo " sudo apt install -y ${a_pkg}"
echo ""
printf "Install with sudo and apt [Y/n]? "
cmd_pkg_add='sudo apt install -y'
elif command -v apk > /dev/null; then
echo ""
echo "ERROR"
echo " No Webi installer for ${a_pkg} on Alpine yet."
echo ""
echo "SOLUTION"
echo " Would you like to install with apk?"
echo " sudo apk add --no-cache ${a_pkg}"
echo ""
printf "Install with sudo and apk [Y/n]? "
cmd_pkg_add='sudo apk add --no-cache'
elif test "Darwin" != "$(uname -s)"; then
echo "No ${a_pkg} installer for Linux yet."
exit 1
fi
read -r my_answer < /dev/tty
if test -z "${my_answer}" ||
test "${my_answer}" = "Y" ||
test "${my_answer}" = "y"; then
$cmd_pkg_add "${a_pkg}"
else
exit 1
fi
elif test "Darwin" != "$(uname -s)"; then
echo "No ${a_pkg} installer for Linux yet."
exit 1
fi
}
__init_git

View File

@@ -1,6 +1,6 @@
---
title: koji
homepage: https://github.com/its-danny/koji
homepage: https://github.com/cococonscious/koji
tagline: |
🦊 An interactive CLI for creating conventional commits.
---
@@ -13,7 +13,7 @@ To update or switch versions, run `webi koji@stable` (or `@v2`, `@beta`, etc).
> `koji` is an interactive CLI for creating [conventional commits][cc].
![](https://github.com/its-danny/koji/raw/main/meta/demo.gif)
![](https://github.com/cococonscious/koji/raw/main/meta/demo.gif)
[cc]: https://conventionalcommits.org/en/v1.0.0/
@@ -105,4 +105,4 @@ description = "A new feature"
```
The default emoji can be seen in
[koji-default.toml](https://github.com/its-danny/koji/blob/main/meta/config/koji-default.toml).
[default.toml](https://github.com/cococonscious/koji/blob/main/meta/config/default.toml).

View File

@@ -1,7 +1,7 @@
'use strict';
var github = require('../_common/github.js');
var owner = 'its-danny';
var owner = 'cococonscious';
var repo = 'koji';
module.exports = function (request) {

30
sshd/README.md Normal file
View File

@@ -0,0 +1,30 @@
---
title: OpenSSH (for Windows)
homepage: https://webinstall.dev/sshd
tagline: |
OpenSSH: Window's built-in SSH implementation for remote login
---
To update (replacing the current version) run `webi sudo`.
## Cheat Sheet
> Does the tedious work of installing, registering, and starting Windows' built-in OpenSSH Server (`sshd`)
As this requires Administrator permissions, you must run the command yourself:
```sh
sshd-service-install
```
### Files
These are the files / directories that are created and/or modified with this
install:
```text
~/.local/bin/sudo.bat
~/.local/bin/sshd-service-install.bat
```

52
sshd/install.ps1 Normal file
View File

@@ -0,0 +1,52 @@
#!/usr/bin/env pwsh
$ErrorActionPreference = 'stop'
function Repair-MissingCommand {
Param(
[string]$Name,
[string]$Package,
[string]$Command
)
Write-Host " Checking for $Name ..."
$HasCommand = Get-Command -Name $Command -ErrorAction Silent
IF ($HasCommand) {
Return
}
& $HOME\.local\bin\webi-pwsh.ps1 $Package
$null = Sync-EnvPath
}
function Install-WebiHostedScript () {
Param(
[string]$Package,
[string]$ScriptName
)
$PwshName = "_${ScriptName}.ps1"
$PwshUrl = "${Env:WEBI_HOST}/packages/${Package}/${ScriptName}.ps1"
$PwshPath = "$HOME\.local\bin\${PwshName}"
$OldPath = "$HOME\.local\bin\${ScriptName}.ps1"
$BatPath = "$HOME\.local\bin\${ScriptName}.bat"
$PwshExec = "powershell -ExecutionPolicy Bypass"
$Bat = "@echo off`r`n$PwshExec %USERPROFILE%\.local\bin\${PwshName} %*"
Invoke-DownloadUrl -Force -URL $PwshUrl -Path $PwshPath
Set-Content -Path $BatPath -Value $Bat
Write-Host " Created alias ${BatPath}"
Write-Host " to run ${PwshPath}"
# fix for old installs
Remove-Item -Path $OldPath -Force -ErrorAction Ignore
}
Repair-MissingCommand -Name "sudo (RunAs alias)" -Package "sudo" -Command "sudo"
Install-WebiHostedScript -Package "sshd" -ScriptName "sshd-service-install"
Write-Output ""
Write-Output "${TTask}Copy, paste, and run${TReset} the following to install sshd as a system service"
Write-Output " ${TCmd}sshd-service-install${TReset}"
Write-Output ""

35
sshd/install.sh Normal file
View File

@@ -0,0 +1,35 @@
__install_sshd() {
my_os="$(uname -s)"
if test "Darwin" = "${my_os}"; then
echo >&2 ""
echo >&2 "Copy, paste, and run the following to enable the built-in sshd:"
echo >&2 " sudo systemsetup -f -setremotelogin on"
echo >&2 " sudo systemsetup -getremotelogin"
echo >&2 ""
exit 1
fi
echo >&2 "Install and enable sshd using your system package manager:"
my_cmd=""
if test command -v sudo > /dev/null; then
my_cmd="sudo "
fi
if test command -v apt > /dev/null; then
echo " ${my_cmd}apt install -y openssh-server"
echo " ${my_cmd}systemctl enable ssh"
echo " ${my_cmd}systemctl start ssh"
elif test command -v yum > /dev/null; then
echo " ${my_cmd}yum -y install openssh-server"
echo " ${my_cmd}systemctl enable ssh"
echo " ${my_cmd}systemctl start ssh"
elif test command -v apk > /dev/null; then
echo " ${my_cmd}apk add --no-cache openssh"
echo " ${my_cmd}service sshd added to runlevel default"
echo " ${my_cmd}service sshd start"
else
echo " (unknown package manager / init daemon)"
fi
exit 1
}

View File

@@ -0,0 +1,62 @@
#!/usr/bin/env pwsh
$Esc = [char]27
$Warn = "${Esc}[1m[33m"
$ResetAll = "${Esc}[0m"
# See
# - <https://gist.github.com/HacDan/026fa8d7d4130fbbc2409d84c2d04143#load-public-keys>
# - <https://techcommunity.microsoft.com/t5/itops-talk-blog/installing-and-configuring-openssh-on-windows-server-2019/ba-p/309540>
# - <https://learn.microsoft.com/windows-server/administration/openssh/openssh_install_firstuse>
function InstallOpenSSHServer {
$OpenSSHServer = Get-WindowsCapability -Online | `
Where-Object -Property Name -Like "OpenSSH.Server*"
IF (-Not ($OpenSSHServer.State -eq "Installed")) {
Add-WindowsCapability -Online -Name $sshd.Name
}
$Sshd = Get-Service -Name "sshd"
IF (-Not ($Sshd.Status -eq "Running")) {
Start-Service "sshd"
}
IF (-Not ($Sshd.StartupType -eq "Automatic")) {
Set-Service -Name "sshd" -StartupType "Automatic"
}
$SshAgent = Get-Service -Name "ssh-agent"
IF (-Not ($SshAgent.Status -eq "Running")) {
Start-Service "ssh-agent"
}
IF (-Not ($SshAgent.StartupType -eq "Automatic")) {
Set-Service -Name "ssh-agent" -StartupType "Automatic"
}
Install-Module -Force OpenSSHUtils -Scope AllUsers
}
function SelfElevate {
Write-Host "${Warn}Installing 'sshd' requires Admin privileges${ResetAll}"
Write-Host "Install will continue automatically in 5 seconds..."
Sleep 5.0
# Self-elevate the script if required
$CurUser = New-Object Security.Principal.WindowsPrincipal(
[Security.Principal.WindowsIdentity]::GetCurrent()
)
$IsAdmin = $CurUser.IsInRole(
[Security.Principal.WindowsBuiltInRole]::Administrator
)
if ($IsAdmin) {
Return 0
}
$CurLoc = Get-Location
$CommandLine = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments
Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine
Set-Location $CurLoc
Exit 0
}
SelfElevate
InstallOpenSSHServer