mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
hardware acceleration and support for NVIDIA cards on nonfree images (#3089)
* add nvidia packages
* add nvidia deps to nonfree
* gpu_acceleration flag & nvidia hacking
* fix gpu_config & /tmp/lxc.log
* implement hardware acceleration more dynamically
* refactor OpenUI
* use mknod
* registry updates for multi-hardware-requirements
* pluralize
* handle new registry types
* remove log
* migrations and driver fixes
* wip
* misc patches
* handle nvidia-container differently
* chore: comments (#3093)
* chore: comments
* revert some sizing
---------
Co-authored-by: Matt Hill <mattnine@protonmail.com>
* Revert "handle nvidia-container differently"
This reverts commit d708ae53df.
* fix debian containers
* cleanup
* feat: add empty array placeholder in forms (#3095)
* fixes from testing, client side device filtering for better fingerprinting resistance
* fix mac builds
---------
Co-authored-by: Sam Sartor <me@samsartor.com>
Co-authored-by: Matt Hill <mattnine@protonmail.com>
Co-authored-by: Alex Inkin <alexander@inkin.ru>
This commit is contained in:
@@ -24,7 +24,7 @@ import { MarketplaceItemComponent } from './item.component'
|
||||
icon=""
|
||||
/>
|
||||
<!-- release date -->
|
||||
@if (pkg().s9pk?.publishedAt; as published) {
|
||||
@if (pkg().s9pks[0]?.[1]?.publishedAt; as published) {
|
||||
<marketplace-item
|
||||
[style.pointer-events]="'none'"
|
||||
[data]="(published | date: 'medium')!"
|
||||
|
||||
@@ -72,8 +72,8 @@ export class FilterPackagesPipe implements PipeTransform {
|
||||
.filter(p => category === 'all' || p.categories.includes(category!))
|
||||
.sort((a, b) => {
|
||||
return (
|
||||
new Date(b.s9pk.publishedAt).valueOf() -
|
||||
new Date(a.s9pk.publishedAt).valueOf()
|
||||
new Date(b.s9pks[0]?.[1].publishedAt!).valueOf() -
|
||||
new Date(a.s9pks[0]?.[1].publishedAt!).valueOf()
|
||||
)
|
||||
})
|
||||
.map(a => ({ ...a }))
|
||||
|
||||
@@ -32,10 +32,7 @@ export type StoreData = {
|
||||
packages: MarketplacePkg[]
|
||||
}
|
||||
|
||||
export type MarketplacePkgBase = OptionalProperty<
|
||||
T.PackageVersionInfo,
|
||||
's9pk'
|
||||
> & {
|
||||
export type MarketplacePkgBase = T.PackageVersionInfo & {
|
||||
id: T.PackageId
|
||||
version: string
|
||||
flavor: string | null
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core'
|
||||
import { toSignal } from '@angular/core/rxjs-interop'
|
||||
import { ActivatedRoute } from '@angular/router'
|
||||
import { TuiDialogContext, TuiLoader, TuiNotification } from '@taiga-ui/core'
|
||||
import { TuiLoader, TuiNotification } from '@taiga-ui/core'
|
||||
import { NgDompurifyPipe } from '@taiga-ui/dompurify'
|
||||
import { injectContext, PolymorpheusComponent } from '@taiga-ui/polymorpheus'
|
||||
import { catchError, ignoreElements, Observable, of } from 'rxjs'
|
||||
import { catchError, ignoreElements, Observable, of, share } from 'rxjs'
|
||||
import { SafeLinksDirective } from '../directives/safe-links.directive'
|
||||
import { MarkdownPipe } from '../pipes/markdown.pipe'
|
||||
import { getErrorMessage } from '../services/error.service'
|
||||
@@ -34,7 +33,10 @@ import { getErrorMessage } from '../services/error.service'
|
||||
],
|
||||
})
|
||||
export class MarkdownComponent {
|
||||
protected readonly data = injectContext<{ data: Observable<string> }>().data
|
||||
private readonly data = injectContext<{
|
||||
data: Observable<string>
|
||||
}>().data.pipe(share())
|
||||
|
||||
protected readonly content = toSignal<string>(this.data)
|
||||
protected readonly error = toSignal(
|
||||
this.data.pipe(
|
||||
|
||||
@@ -5,11 +5,14 @@ import {
|
||||
InjectionToken,
|
||||
input,
|
||||
} from '@angular/core'
|
||||
import { TuiHintDirective } from '@taiga-ui/core'
|
||||
import { i18nPipe } from '../i18n/i18n.pipe'
|
||||
|
||||
export const VERSION = new InjectionToken<string>('VERSION')
|
||||
|
||||
@Directive({
|
||||
selector: '[docsLink]',
|
||||
hostDirectives: [TuiHintDirective],
|
||||
host: {
|
||||
target: '_blank',
|
||||
rel: 'noreferrer',
|
||||
@@ -20,12 +23,18 @@ export class DocsLinkDirective {
|
||||
private readonly version = inject(VERSION)
|
||||
|
||||
readonly path = input.required<string>()
|
||||
|
||||
readonly fragment = input<string>('')
|
||||
|
||||
protected readonly url = computed(() => {
|
||||
const path = this.path()
|
||||
const relative = path.startsWith('/') ? path : `/${path}`
|
||||
|
||||
return `https://docs.start9.com${relative}?os=${this.version}${this.fragment()}`
|
||||
})
|
||||
|
||||
constructor() {
|
||||
inject(TuiHintDirective).content.set(
|
||||
inject(i18nPipe).transform('Documentation'),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -596,4 +596,5 @@ export default {
|
||||
626: 'Hochladen',
|
||||
627: 'UI öffnen',
|
||||
628: 'In Zwischenablage kopiert',
|
||||
629: 'Die Liste ist leer',
|
||||
} satisfies i18n
|
||||
|
||||
@@ -595,4 +595,5 @@ export const ENGLISH = {
|
||||
'Upload': 626, // as in, upload a file
|
||||
'Open UI': 627, // as in, upload a file
|
||||
'Copied to clipboard': 628,
|
||||
} as const
|
||||
'The list is empty': 629,
|
||||
} as Record<any, any>
|
||||
|
||||
@@ -596,4 +596,5 @@ export default {
|
||||
626: 'Subir',
|
||||
627: 'Abrir UI',
|
||||
628: 'Copiado al portapapeles',
|
||||
629: 'La lista está vacía',
|
||||
} satisfies i18n
|
||||
|
||||
@@ -596,4 +596,5 @@ export default {
|
||||
626: 'Téléverser',
|
||||
627: 'Ouvrir UI',
|
||||
628: 'Copié dans le presse-papiers',
|
||||
629: 'La liste est vide',
|
||||
} satisfies i18n
|
||||
|
||||
@@ -596,4 +596,5 @@ export default {
|
||||
626: 'Prześlij',
|
||||
627: 'Otwórz UI',
|
||||
628: 'Skopiowano do schowka',
|
||||
629: 'Lista jest pusta',
|
||||
} satisfies i18n
|
||||
|
||||
@@ -20,6 +20,7 @@ import { tuiObfuscateOptionsProvider } from '@taiga-ui/cdk'
|
||||
import {
|
||||
TUI_DATE_FORMAT,
|
||||
TUI_DIALOGS_CLOSE,
|
||||
TUI_MEDIA,
|
||||
tuiAlertOptionsProvider,
|
||||
tuiButtonOptionsProvider,
|
||||
tuiDropdownOptionsProvider,
|
||||
@@ -140,4 +141,12 @@ export const APP_PROVIDERS = [
|
||||
none: identity,
|
||||
},
|
||||
}),
|
||||
{
|
||||
provide: TUI_MEDIA,
|
||||
useValue: {
|
||||
mobile: 1000,
|
||||
desktopSmall: 1280,
|
||||
desktopLarge: Infinity,
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
@@ -80,7 +80,7 @@ export interface FormContext<T> {
|
||||
margin: 1rem -1px -1rem;
|
||||
gap: 1rem;
|
||||
background: var(--tui-background-elevation-1);
|
||||
border-top: 1px solid var(--tui-background-base-alt);
|
||||
box-shadow: inset 0 1px var(--tui-background-neutral-1);
|
||||
}
|
||||
`,
|
||||
imports: [
|
||||
|
||||
@@ -87,6 +87,8 @@ import { FormObjectComponent } from './object.component'
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
} @empty {
|
||||
<div class="placeholder">{{ 'The list is empty' | i18n }}</div>
|
||||
}
|
||||
`,
|
||||
styles: `
|
||||
@@ -99,8 +101,8 @@ import { FormObjectComponent } from './object.component'
|
||||
|
||||
.label {
|
||||
display: flex;
|
||||
font-size: 1.25rem;
|
||||
font-weight: bold;
|
||||
align-items: center;
|
||||
font: var(--tui-font-heading-6);
|
||||
}
|
||||
|
||||
.add {
|
||||
@@ -157,6 +159,17 @@ import { FormObjectComponent } from './object.component'
|
||||
animation-name: tuiFade, tuiCollapse;
|
||||
}
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: var(--tui-height-m);
|
||||
color: var(--tui-text-tertiary);
|
||||
border-radius: var(--tui-radius-m);
|
||||
border: 1px dashed var(--tui-background-neutral-1);
|
||||
margin: 0.5rem 0 0;
|
||||
}
|
||||
`,
|
||||
hostDirectives: [ControlDirective],
|
||||
imports: [
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { Component, computed } from '@angular/core'
|
||||
import { FormsModule } from '@angular/forms'
|
||||
import { invert } from '@start9labs/shared'
|
||||
import { IST } from '@start9labs/start-sdk'
|
||||
import { tuiPure } from '@taiga-ui/cdk'
|
||||
import { TuiIcon, TuiTextfield } from '@taiga-ui/core'
|
||||
import { TuiChevron, TuiMultiSelect, TuiTooltip } from '@taiga-ui/kit'
|
||||
import { Control } from './control'
|
||||
import { HintPipe } from '../pipes/hint.pipe'
|
||||
import { Control } from './control'
|
||||
|
||||
@Component({
|
||||
selector: 'form-multiselect',
|
||||
@@ -21,7 +20,8 @@ import { HintPipe } from '../pipes/hint.pipe'
|
||||
[disabled]="disabled"
|
||||
[readOnly]="readOnly"
|
||||
[items]="items"
|
||||
[(ngModel)]="selected"
|
||||
[ngModel]="selected()"
|
||||
(ngModelChange)="onSelected($event)"
|
||||
(blur)="control.onTouched()"
|
||||
></select>
|
||||
@if (spec | hint; as hint) {
|
||||
@@ -58,30 +58,26 @@ export class FormMultiselectComponent extends Control<
|
||||
|
||||
private readonly isExceedingLimit = (item: string) =>
|
||||
!!this.spec.maxLength &&
|
||||
this.selected.length >= this.spec.maxLength &&
|
||||
!this.selected.includes(item)
|
||||
this.selected().length >= this.spec.maxLength &&
|
||||
!this.selected().includes(item)
|
||||
|
||||
readonly disabledItemHandler = (item: string): boolean =>
|
||||
this.isDisabled(item) || this.isExceedingLimit(item)
|
||||
|
||||
readonly items = Object.values(this.spec.values)
|
||||
readonly selected = computed(
|
||||
() =>
|
||||
this.control.value().map((key: string) => this.spec.values[key] || '') ||
|
||||
[],
|
||||
)
|
||||
|
||||
get disabled(): boolean {
|
||||
return typeof this.spec.disabled === 'string'
|
||||
}
|
||||
|
||||
get selected(): string[] {
|
||||
return this.memoize(this.value)
|
||||
}
|
||||
|
||||
set selected(value: string[]) {
|
||||
onSelected(value: string[]) {
|
||||
this.value = Object.entries(this.spec.values)
|
||||
.filter(([_, v]) => value.includes(v))
|
||||
.map(([k]) => k)
|
||||
}
|
||||
|
||||
@tuiPure
|
||||
private memoize(value: null | readonly string[]): string[] {
|
||||
return value?.map(key => this.spec.values[key] || '') || []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,11 +111,11 @@ import { ConfigService } from 'src/app/services/config.service'
|
||||
&-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(1, minmax(0, 1fr));
|
||||
gap: 4rem 3rem;
|
||||
gap: 3.5rem 2.5rem;
|
||||
padding: 1.5rem;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
padding: 2rem;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
@media (min-width: 1024px) {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
} from '@start9labs/shared'
|
||||
import { TuiCell } from '@taiga-ui/layout'
|
||||
import { PatchDB } from 'patch-db-client'
|
||||
import { from, map } from 'rxjs'
|
||||
import { defer, map } from 'rxjs'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { DataModel } from 'src/app/services/patch-db/data-model'
|
||||
import { getManifest } from 'src/app/utils/get-package-data'
|
||||
@@ -54,14 +54,13 @@ import {
|
||||
})
|
||||
export default class ServiceAboutRoute {
|
||||
private readonly pkgId = getPkgId()
|
||||
private readonly api = inject(ApiService)
|
||||
private readonly copyService = inject(CopyService)
|
||||
private readonly markdown = inject(DialogService).openComponent(MARKDOWN, {
|
||||
label: 'License',
|
||||
size: 'l',
|
||||
data: from(
|
||||
inject(ApiService).getStatic(
|
||||
`/s9pk/installed/${this.pkgId}.s9pk/LICENSE.md`,
|
||||
),
|
||||
data: defer(() =>
|
||||
this.api.getStatic([`/s9pk/installed/${this.pkgId}.s9pk/LICENSE.md`], {}),
|
||||
),
|
||||
})
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ async function parseS9pk(file: File): Promise<MarketplacePkgSideload> {
|
||||
sourceVersion: s9pk.manifest.canMigrateFrom,
|
||||
flavor: ExtendedVersion.parse(s9pk.manifest.version).flavor,
|
||||
fullLicense: await s9pk.license(),
|
||||
s9pks: [],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ import UpdatesComponent from './updates.component'
|
||||
</div>
|
||||
</td>
|
||||
<td class="desktop">{{ item().gitHash }}</td>
|
||||
<td class="desktop">{{ item().s9pk.publishedAt | date }}</td>
|
||||
<td class="desktop">{{ item().s9pks[0]?.[1]?.publishedAt | date }}</td>
|
||||
<td>
|
||||
<button
|
||||
tuiIconButton
|
||||
@@ -114,7 +114,9 @@ import UpdatesComponent from './updates.component'
|
||||
</p>
|
||||
<p tuiTitle class="mobile">
|
||||
<b>{{ 'Published' | i18n }}</b>
|
||||
<span tuiSubtitle>{{ item().s9pk.publishedAt | date }}</span>
|
||||
<span tuiSubtitle>
|
||||
{{ item().s9pks[0]?.[1]?.publishedAt | date }}
|
||||
</span>
|
||||
</p>
|
||||
<p tuiTitle>
|
||||
<span>
|
||||
|
||||
@@ -40,7 +40,9 @@ export namespace Mock {
|
||||
squashfs: {
|
||||
aarch64: {
|
||||
publishedAt: '2025-03-21T23:55:29.583006392Z',
|
||||
url: 'https://alpha-registry-x.start9.com/startos/v0.3.6-alpha.17/startos-0.3.6-alpha.17-b8ff331~dev_aarch64.squashfs',
|
||||
urls: [
|
||||
'https://alpha-registry-x.start9.com/startos/v0.3.6-alpha.17/startos-0.3.6-alpha.17-b8ff331~dev_aarch64.squashfs',
|
||||
],
|
||||
commitment: {
|
||||
hash: 'OUnANnZePtf7rSbj38JESl+iJAV0z0aiZ4opCiwpGbo=',
|
||||
size: 1331900416,
|
||||
@@ -52,7 +54,9 @@ export namespace Mock {
|
||||
},
|
||||
'aarch64-nonfree': {
|
||||
publishedAt: '2025-03-21T23:56:38.299572946Z',
|
||||
url: 'https://alpha-registry-x.start9.com/startos/v0.3.6-alpha.17/startos-0.3.6-alpha.17-b8ff331~dev_aarch64-nonfree.squashfs',
|
||||
urls: [
|
||||
'https://alpha-registry-x.start9.com/startos/v0.3.6-alpha.17/startos-0.3.6-alpha.17-b8ff331~dev_aarch64-nonfree.squashfs',
|
||||
],
|
||||
commitment: {
|
||||
hash: '6k+0RcyRQV+5A+h06OqpHxd4IT6IlFkfdy9dfHIP90c=',
|
||||
size: 1641500672,
|
||||
@@ -64,7 +68,9 @@ export namespace Mock {
|
||||
},
|
||||
raspberrypi: {
|
||||
publishedAt: '2025-03-22T00:08:17.083064390Z',
|
||||
url: 'https://alpha-registry-x.start9.com/startos/v0.3.6-alpha.17/startos-0.3.6-alpha.17-b8ff331~dev_raspberrypi.squashfs',
|
||||
urls: [
|
||||
'https://alpha-registry-x.start9.com/startos/v0.3.6-alpha.17/startos-0.3.6-alpha.17-b8ff331~dev_raspberrypi.squashfs',
|
||||
],
|
||||
commitment: {
|
||||
hash: 'K+XuTZxo1KVsKjNSV8PPOMruCvAEZwerF9mbpFl53Gk=',
|
||||
size: 1544417280,
|
||||
@@ -76,7 +82,9 @@ export namespace Mock {
|
||||
},
|
||||
x86_64: {
|
||||
publishedAt: '2025-03-22T00:05:57.684319247Z',
|
||||
url: 'https://alpha-registry-x.start9.com/startos/v0.3.6-alpha.17/startos-0.3.6-alpha.17-b8ff331~dev_x86_64.squashfs',
|
||||
urls: [
|
||||
'https://alpha-registry-x.start9.com/startos/v0.3.6-alpha.17/startos-0.3.6-alpha.17-b8ff331~dev_x86_64.squashfs',
|
||||
],
|
||||
commitment: {
|
||||
hash: '3UVkx3TQMBPlSU1OnV48Om9vjjA3s+Nk6dX3auYGpBo=',
|
||||
size: 1424007168,
|
||||
@@ -88,7 +96,9 @@ export namespace Mock {
|
||||
},
|
||||
'x86_64-nonfree': {
|
||||
publishedAt: '2025-03-22T00:07:11.893777122Z',
|
||||
url: 'https://alpha-registry-x.start9.com/startos/v0.3.6-alpha.17/startos-0.3.6-alpha.17-b8ff331~dev_x86_64-nonfree.squashfs',
|
||||
urls: [
|
||||
'https://alpha-registry-x.start9.com/startos/v0.3.6-alpha.17/startos-0.3.6-alpha.17-b8ff331~dev_x86_64-nonfree.squashfs',
|
||||
],
|
||||
commitment: {
|
||||
hash: 'IS1gJ56n/HlQqFbl1upMOAtLxyxB0cY0H89Ha+9h1lE=',
|
||||
size: 1743425536,
|
||||
@@ -110,7 +120,9 @@ export namespace Mock {
|
||||
squashfs: {
|
||||
aarch64: {
|
||||
publishedAt: '2025-04-21T20:58:48.140749883Z',
|
||||
url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.14/startos-0.4.0-alpha.14-33ae46f~dev_aarch64.squashfs',
|
||||
urls: [
|
||||
'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.14/startos-0.4.0-alpha.14-33ae46f~dev_aarch64.squashfs',
|
||||
],
|
||||
commitment: {
|
||||
hash: '4elBFVkd/r8hNadKmKtLIs42CoPltMvKe2z3LRqkphk=',
|
||||
size: 1343500288,
|
||||
@@ -122,7 +134,9 @@ export namespace Mock {
|
||||
},
|
||||
'aarch64-nonfree': {
|
||||
publishedAt: '2025-04-21T21:07:00.249285116Z',
|
||||
url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.14/startos-0.4.0-alpha.14-33ae46f~dev_aarch64-nonfree.squashfs',
|
||||
urls: [
|
||||
'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.14/startos-0.4.0-alpha.14-33ae46f~dev_aarch64-nonfree.squashfs',
|
||||
],
|
||||
commitment: {
|
||||
hash: 'MrCEi4jxbmPS7zAiGk/JSKlMsiuKqQy6RbYOxlGHOIQ=',
|
||||
size: 1653075968,
|
||||
@@ -134,7 +148,9 @@ export namespace Mock {
|
||||
},
|
||||
raspberrypi: {
|
||||
publishedAt: '2025-04-21T21:16:12.933319237Z',
|
||||
url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.14/startos-0.4.0-alpha.14-33ae46f~dev_raspberrypi.squashfs',
|
||||
urls: [
|
||||
'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.14/startos-0.4.0-alpha.14-33ae46f~dev_raspberrypi.squashfs',
|
||||
],
|
||||
commitment: {
|
||||
hash: '/XTVQRCqY3RK544PgitlKu7UplXjkmzWoXUh2E4HCw0=',
|
||||
size: 1490731008,
|
||||
@@ -146,7 +162,9 @@ export namespace Mock {
|
||||
},
|
||||
x86_64: {
|
||||
publishedAt: '2025-04-21T21:14:20.246908903Z',
|
||||
url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.14/startos-0.4.0-alpha.14-33ae46f~dev_x86_64.squashfs',
|
||||
urls: [
|
||||
'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.14/startos-0.4.0-alpha.14-33ae46f~dev_x86_64.squashfs',
|
||||
],
|
||||
commitment: {
|
||||
hash: '/6romKTVQGSaOU7FqSZdw0kFyd7P+NBSYNwM3q7Fe44=',
|
||||
size: 1411657728,
|
||||
@@ -158,7 +176,9 @@ export namespace Mock {
|
||||
},
|
||||
'x86_64-nonfree': {
|
||||
publishedAt: '2025-04-21T21:15:17.955265284Z',
|
||||
url: 'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.14/startos-0.4.0-alpha.14-33ae46f~dev_x86_64-nonfree.squashfs',
|
||||
urls: [
|
||||
'https://alpha-registry-x.start9.com/startos/v0.4.0-alpha.14/startos-0.4.0-alpha.14-33ae46f~dev_x86_64-nonfree.squashfs',
|
||||
],
|
||||
commitment: {
|
||||
hash: 'HCRq9sr/0t85pMdrEgNBeM4x11zVKHszGnD1GDyZbSE=',
|
||||
size: 1731035136,
|
||||
@@ -234,6 +254,7 @@ export namespace Mock {
|
||||
source: 'packed',
|
||||
arch: ['x86_64', 'aarch64'],
|
||||
emulateMissingAs: 'aarch64',
|
||||
nvidiaContainer: false,
|
||||
},
|
||||
},
|
||||
volumes: ['main'],
|
||||
@@ -242,6 +263,7 @@ export namespace Mock {
|
||||
arch: null,
|
||||
ram: null,
|
||||
},
|
||||
hardwareAcceleration: false,
|
||||
}
|
||||
|
||||
export const MockManifestLnd: T.Manifest = {
|
||||
@@ -292,6 +314,7 @@ export namespace Mock {
|
||||
source: 'packed',
|
||||
arch: ['x86_64', 'aarch64'],
|
||||
emulateMissingAs: 'aarch64',
|
||||
nvidiaContainer: false,
|
||||
},
|
||||
},
|
||||
volumes: ['main'],
|
||||
@@ -300,6 +323,7 @@ export namespace Mock {
|
||||
arch: null,
|
||||
ram: null,
|
||||
},
|
||||
hardwareAcceleration: false,
|
||||
}
|
||||
|
||||
export const MockManifestBitcoinProxy: T.Manifest = {
|
||||
@@ -343,6 +367,7 @@ export namespace Mock {
|
||||
source: 'packed',
|
||||
arch: ['x86_64', 'aarch64'],
|
||||
emulateMissingAs: 'aarch64',
|
||||
nvidiaContainer: false,
|
||||
},
|
||||
},
|
||||
volumes: ['main'],
|
||||
@@ -351,6 +376,7 @@ export namespace Mock {
|
||||
arch: null,
|
||||
ram: null,
|
||||
},
|
||||
hardwareAcceleration: false,
|
||||
}
|
||||
|
||||
export const BitcoinDep: T.DependencyMetadata = {
|
||||
@@ -376,7 +402,6 @@ export namespace Mock {
|
||||
'26.1.0:0.1.0': {
|
||||
title: 'Bitcoin Core',
|
||||
description: mockDescription,
|
||||
hardwareRequirements: { arch: null, device: [], ram: null },
|
||||
license: 'mit',
|
||||
wrapperRepo: 'https://github.com/start9labs/bitcoind-startos',
|
||||
upstreamRepo: 'https://github.com/bitcoin/bitcoin',
|
||||
@@ -398,12 +423,20 @@ export namespace Mock {
|
||||
stop: 'test',
|
||||
restore: 'test',
|
||||
},
|
||||
s9pk: {
|
||||
url: 'https://github.com/Start9Labs/bitcoind-startos/releases/download/v26.1.0/bitcoind.s9pk',
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
s9pks: [
|
||||
[
|
||||
{ arch: null, device: [], ram: null },
|
||||
{
|
||||
urls: [
|
||||
'https://github.com/Start9Labs/bitcoind-startos/releases/download/v26.1.0/bitcoind.s9pk',
|
||||
],
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
],
|
||||
],
|
||||
hardwareAcceleration: false,
|
||||
},
|
||||
'#knots:26.1.20240325:0': {
|
||||
title: 'Bitcoin Knots',
|
||||
@@ -411,7 +444,6 @@ export namespace Mock {
|
||||
short: 'An alternate fully verifying implementation of Bitcoin',
|
||||
long: 'Bitcoin Knots is a combined Bitcoin node and wallet. Not only is it easy to use, but it also ensures bitcoins you receive are both real bitcoins and really yours.',
|
||||
},
|
||||
hardwareRequirements: { arch: null, device: [], ram: null },
|
||||
license: 'mit',
|
||||
wrapperRepo: 'https://github.com/start9labs/bitcoinknots-startos',
|
||||
upstreamRepo: 'https://github.com/bitcoinknots/bitcoin',
|
||||
@@ -433,12 +465,20 @@ export namespace Mock {
|
||||
stop: 'test',
|
||||
restore: 'test',
|
||||
},
|
||||
s9pk: {
|
||||
url: 'https://github.com/Start9Labs/bitcoinknots-startos/releases/download/v26.1.20240513/bitcoind.s9pk',
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
s9pks: [
|
||||
[
|
||||
{ arch: null, device: [], ram: null },
|
||||
{
|
||||
urls: [
|
||||
'https://github.com/Start9Labs/bitcoinknots-startos/releases/download/v26.1.20240513/bitcoind.s9pk',
|
||||
],
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
],
|
||||
],
|
||||
hardwareAcceleration: false,
|
||||
},
|
||||
},
|
||||
categories: ['bitcoin', 'featured'],
|
||||
@@ -456,7 +496,6 @@ export namespace Mock {
|
||||
'26.1.0:0.1.0': {
|
||||
title: 'Bitcoin Core',
|
||||
description: mockDescription,
|
||||
hardwareRequirements: { arch: null, device: [], ram: null },
|
||||
license: 'mit',
|
||||
wrapperRepo: 'https://github.com/start9labs/bitcoind-startos',
|
||||
upstreamRepo: 'https://github.com/bitcoin/bitcoin',
|
||||
@@ -478,12 +517,20 @@ export namespace Mock {
|
||||
stop: 'test',
|
||||
restore: 'test',
|
||||
},
|
||||
s9pk: {
|
||||
url: 'https://github.com/Start9Labs/bitcoind-startos/releases/download/v26.1.0/bitcoind.s9pk',
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
s9pks: [
|
||||
[
|
||||
{ arch: null, device: [], ram: null },
|
||||
{
|
||||
urls: [
|
||||
'https://github.com/Start9Labs/bitcoind-startos/releases/download/v26.1.0/bitcoind.s9pk',
|
||||
],
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
],
|
||||
],
|
||||
hardwareAcceleration: false,
|
||||
},
|
||||
'#knots:26.1.20240325:0': {
|
||||
title: 'Bitcoin Knots',
|
||||
@@ -491,7 +538,6 @@ export namespace Mock {
|
||||
short: 'An alternate fully verifying implementation of Bitcoin',
|
||||
long: 'Bitcoin Knots is a combined Bitcoin node and wallet. Not only is it easy to use, but it also ensures bitcoins you receive are both real bitcoins and really yours.',
|
||||
},
|
||||
hardwareRequirements: { arch: null, device: [], ram: null },
|
||||
license: 'mit',
|
||||
wrapperRepo: 'https://github.com/start9labs/bitcoinknots-startos',
|
||||
upstreamRepo: 'https://github.com/bitcoinknots/bitcoin',
|
||||
@@ -513,12 +559,20 @@ export namespace Mock {
|
||||
stop: 'test',
|
||||
restore: 'test',
|
||||
},
|
||||
s9pk: {
|
||||
url: 'https://github.com/Start9Labs/bitcoinknots-startos/releases/download/v26.1.20240513/bitcoind.s9pk',
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
s9pks: [
|
||||
[
|
||||
{ arch: null, device: [], ram: null },
|
||||
{
|
||||
urls: [
|
||||
'https://github.com/Start9Labs/bitcoinknots-startos/releases/download/v26.1.20240513/bitcoind.s9pk',
|
||||
],
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
],
|
||||
],
|
||||
hardwareAcceleration: false,
|
||||
},
|
||||
},
|
||||
categories: ['bitcoin', 'featured'],
|
||||
@@ -538,7 +592,6 @@ export namespace Mock {
|
||||
'0.17.5:0': {
|
||||
title: 'LND',
|
||||
description: mockDescription,
|
||||
hardwareRequirements: { arch: null, device: [], ram: null },
|
||||
license: 'mit',
|
||||
wrapperRepo: 'https://github.com/start9labs/lnd-startos',
|
||||
upstreamRepo: 'https://github.com/lightningnetwork/lnd',
|
||||
@@ -563,12 +616,20 @@ export namespace Mock {
|
||||
stop: 'test',
|
||||
restore: 'test',
|
||||
},
|
||||
s9pk: {
|
||||
url: 'https://github.com/Start9Labs/lnd-startos/releases/download/v0.17.5/lnd.s9pk',
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
s9pks: [
|
||||
[
|
||||
{ arch: null, device: [], ram: null },
|
||||
{
|
||||
urls: [
|
||||
'https://github.com/Start9Labs/lnd-startos/releases/download/v0.17.5/lnd.s9pk',
|
||||
],
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
],
|
||||
],
|
||||
hardwareAcceleration: false,
|
||||
},
|
||||
},
|
||||
categories: ['lightning'],
|
||||
@@ -586,7 +647,6 @@ export namespace Mock {
|
||||
'0.17.4-beta:1.0-alpha': {
|
||||
title: 'LND',
|
||||
description: mockDescription,
|
||||
hardwareRequirements: { arch: null, device: [], ram: null },
|
||||
license: 'mit',
|
||||
wrapperRepo: 'https://github.com/start9labs/lnd-startos',
|
||||
upstreamRepo: 'https://github.com/lightningnetwork/lnd',
|
||||
@@ -611,12 +671,20 @@ export namespace Mock {
|
||||
stop: 'test',
|
||||
restore: 'test',
|
||||
},
|
||||
s9pk: {
|
||||
url: 'https://github.com/Start9Labs/lnd-startos/releases/download/v0.17.4/lnd.s9pk',
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
s9pks: [
|
||||
[
|
||||
{ arch: null, device: [], ram: null },
|
||||
{
|
||||
urls: [
|
||||
'https://github.com/Start9Labs/lnd-startos/releases/download/v0.17.4/lnd.s9pk',
|
||||
],
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
],
|
||||
],
|
||||
hardwareAcceleration: false,
|
||||
},
|
||||
},
|
||||
categories: ['lightning'],
|
||||
@@ -638,7 +706,6 @@ export namespace Mock {
|
||||
'27.0.0:1.0.0': {
|
||||
title: 'Bitcoin Core',
|
||||
description: mockDescription,
|
||||
hardwareRequirements: { arch: null, device: [], ram: null },
|
||||
license: 'mit',
|
||||
wrapperRepo: 'https://github.com/start9labs/bitcoind-startos',
|
||||
upstreamRepo: 'https://github.com/bitcoin/bitcoin',
|
||||
@@ -660,12 +727,20 @@ export namespace Mock {
|
||||
stop: 'test',
|
||||
restore: 'test',
|
||||
},
|
||||
s9pk: {
|
||||
url: 'https://github.com/Start9Labs/bitcoind-startos/releases/download/v27.0.0/bitcoind.s9pk',
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
s9pks: [
|
||||
[
|
||||
{ arch: null, device: [], ram: null },
|
||||
{
|
||||
urls: [
|
||||
'https://github.com/Start9Labs/bitcoind-startos/releases/download/v27.0.0/bitcoind.s9pk',
|
||||
],
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
],
|
||||
],
|
||||
hardwareAcceleration: false,
|
||||
},
|
||||
'#knots:27.1.0:0': {
|
||||
title: 'Bitcoin Knots',
|
||||
@@ -673,7 +748,6 @@ export namespace Mock {
|
||||
short: 'An alternate fully verifying implementation of Bitcoin',
|
||||
long: 'Bitcoin Knots is a combined Bitcoin node and wallet. Not only is it easy to use, but it also ensures bitcoins you receive are both real bitcoins and really yours.',
|
||||
},
|
||||
hardwareRequirements: { arch: null, device: [], ram: null },
|
||||
license: 'mit',
|
||||
wrapperRepo: 'https://github.com/start9labs/bitcoinknots-startos',
|
||||
upstreamRepo: 'https://github.com/bitcoinknots/bitcoin',
|
||||
@@ -695,12 +769,20 @@ export namespace Mock {
|
||||
stop: 'test',
|
||||
restore: 'test',
|
||||
},
|
||||
s9pk: {
|
||||
url: 'https://github.com/Start9Labs/bitcoinknots-startos/releases/download/v26.1.20240513/bitcoind.s9pk',
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
s9pks: [
|
||||
[
|
||||
{ arch: null, device: [], ram: null },
|
||||
{
|
||||
urls: [
|
||||
'https://github.com/Start9Labs/bitcoinknots-startos/releases/download/v26.1.20240513/bitcoind.s9pk',
|
||||
],
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
],
|
||||
],
|
||||
hardwareAcceleration: false,
|
||||
},
|
||||
},
|
||||
categories: ['bitcoin', 'featured'],
|
||||
@@ -718,7 +800,6 @@ export namespace Mock {
|
||||
'0.18.0:0.0.1': {
|
||||
title: 'LND',
|
||||
description: mockDescription,
|
||||
hardwareRequirements: { arch: null, device: [], ram: null },
|
||||
license: 'mit',
|
||||
wrapperRepo: 'https://github.com/start9labs/lnd-startos',
|
||||
upstreamRepo: 'https://github.com/lightningnetwork/lnd',
|
||||
@@ -743,12 +824,20 @@ export namespace Mock {
|
||||
stop: 'test',
|
||||
restore: 'test',
|
||||
},
|
||||
s9pk: {
|
||||
url: 'https://github.com/Start9Labs/lnd-startos/releases/download/v0.18.0.1/lnd.s9pk',
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
s9pks: [
|
||||
[
|
||||
{ arch: null, device: [], ram: null },
|
||||
{
|
||||
urls: [
|
||||
'https://github.com/Start9Labs/lnd-startos/releases/download/v0.18.0.1/lnd.s9pk',
|
||||
],
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
],
|
||||
],
|
||||
hardwareAcceleration: false,
|
||||
},
|
||||
},
|
||||
categories: ['lightning'],
|
||||
@@ -766,7 +855,6 @@ export namespace Mock {
|
||||
'0.3.2.7:0': {
|
||||
title: 'Bitcoin Proxy',
|
||||
description: mockDescription,
|
||||
hardwareRequirements: { arch: null, device: [], ram: null },
|
||||
license: 'mit',
|
||||
wrapperRepo: 'https://github.com/Start9Labs/btc-rpc-proxy-wrappers',
|
||||
upstreamRepo: 'https://github.com/Kixunil/btc-rpc-proxy',
|
||||
@@ -790,12 +878,20 @@ export namespace Mock {
|
||||
stop: 'test',
|
||||
restore: 'test',
|
||||
},
|
||||
s9pk: {
|
||||
url: 'https://github.com/Start9Labs/btc-rpc-proxy-startos/releases/download/v0.3.2.7/btc-rpc-proxy.s9pk',
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
s9pks: [
|
||||
[
|
||||
{ arch: null, device: [], ram: null },
|
||||
{
|
||||
urls: [
|
||||
'https://github.com/Start9Labs/btc-rpc-proxy-startos/releases/download/v0.3.2.7/btc-rpc-proxy.s9pk',
|
||||
],
|
||||
commitment: mockMerkleArchiveCommitment,
|
||||
signatures: {},
|
||||
publishedAt: Date.now().toString(),
|
||||
},
|
||||
],
|
||||
],
|
||||
hardwareAcceleration: false,
|
||||
},
|
||||
},
|
||||
categories: ['bitcoin'],
|
||||
|
||||
@@ -10,13 +10,11 @@ export abstract class ApiService {
|
||||
abstract uploadFile(guid: string, body: Blob): Promise<void>
|
||||
|
||||
// for getting static files: ex license
|
||||
abstract getStaticProxy(
|
||||
pkg: MarketplacePkg,
|
||||
path: 'LICENSE.md',
|
||||
abstract getStatic(
|
||||
urls: string[],
|
||||
params: Record<string, string | number>,
|
||||
): Promise<string>
|
||||
|
||||
abstract getStatic(url: string): Promise<string>
|
||||
|
||||
// websocket
|
||||
|
||||
abstract openWebsocket$<T>(
|
||||
|
||||
@@ -45,29 +45,22 @@ export class LiveApiService extends ApiService {
|
||||
|
||||
// for getting static files: ex: license
|
||||
|
||||
async getStaticProxy(
|
||||
pkg: MarketplacePkg,
|
||||
path: 'LICENSE.md',
|
||||
async getStatic(
|
||||
urls: string[],
|
||||
params: Record<string, string | number>,
|
||||
): Promise<string> {
|
||||
const encodedUrl = encodeURIComponent(pkg.s9pk.url)
|
||||
|
||||
return this.httpRequest({
|
||||
method: 'GET',
|
||||
url: `/s9pk/proxy/${encodedUrl}/${path}`,
|
||||
params: {
|
||||
rootSighash: pkg.s9pk.commitment.rootSighash,
|
||||
rootMaxsize: pkg.s9pk.commitment.rootMaxsize,
|
||||
},
|
||||
responseType: 'text',
|
||||
})
|
||||
}
|
||||
|
||||
async getStatic(url: string): Promise<string> {
|
||||
return this.httpRequest({
|
||||
method: 'GET',
|
||||
url,
|
||||
responseType: 'text',
|
||||
})
|
||||
for (let url in urls) {
|
||||
try {
|
||||
const res = await this.httpRequest<string>({
|
||||
method: 'GET',
|
||||
url,
|
||||
params,
|
||||
responseType: 'text',
|
||||
})
|
||||
return res
|
||||
} catch (e) {}
|
||||
}
|
||||
throw new Error('Could not fetch static file')
|
||||
}
|
||||
|
||||
// websocket
|
||||
|
||||
@@ -75,19 +75,14 @@ export class MockApiService extends ApiService {
|
||||
await pauseFor(2000)
|
||||
}
|
||||
|
||||
async getStaticProxy(
|
||||
pkg: MarketplacePkg,
|
||||
path: 'LICENSE.md',
|
||||
async getStatic(
|
||||
urls: string[],
|
||||
params: Record<string, string | number>,
|
||||
): Promise<string> {
|
||||
await pauseFor(2000)
|
||||
return markdown
|
||||
}
|
||||
|
||||
async getStatic(url: string): Promise<string> {
|
||||
await pauseFor(2000)
|
||||
return markdown
|
||||
}
|
||||
|
||||
// websocket
|
||||
|
||||
openWebsocket$<T>(
|
||||
|
||||
@@ -142,7 +142,23 @@ export class MarketplaceService {
|
||||
}
|
||||
|
||||
fetchStatic$(pkg: MarketplacePkg): Observable<string> {
|
||||
return from(this.api.getStaticProxy(pkg, 'LICENSE.md'))
|
||||
const registryAsset = pkg.s9pks[0]?.[1]
|
||||
|
||||
if (!registryAsset) {
|
||||
throw new Error('No s9pk')
|
||||
}
|
||||
|
||||
const urls =
|
||||
registryAsset.urls.map(
|
||||
u => `/s9pk/proxy/${encodeURIComponent(u)}/LICENSE.md`,
|
||||
) || []
|
||||
|
||||
return from(
|
||||
this.api.getStatic(urls, {
|
||||
rootSighash: registryAsset.commitment.rootSighash,
|
||||
rootMaxsize: registryAsset.commitment.rootMaxsize,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
private fetchRegistry$(url: string): Observable<StoreDataWithUrl | null> {
|
||||
|
||||
Reference in New Issue
Block a user