Compare commits
11 Commits
module-app
...
cli/fix/di
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
751e69d20b | ||
|
|
1a200ed17c | ||
|
|
48fdaa5481 | ||
|
|
570fe070c9 | ||
|
|
6b18bbd94d | ||
|
|
c6836f9859 | ||
|
|
288869d91d | ||
|
|
8ea8a0857e | ||
|
|
87674cc5d9 | ||
|
|
11f556e9af | ||
|
|
d2d3195fea |
@@ -317,7 +317,7 @@ spec:
|
||||
chown -R 1000:1000 /uploadstemp && \
|
||||
chown -R 1000:1000 /appdata
|
||||
- name: olares-app-init
|
||||
image: beclab/system-frontend:v1.6.32
|
||||
image: beclab/system-frontend:v1.6.36
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- /bin/sh
|
||||
|
||||
@@ -195,13 +195,13 @@ func (g *GenerateK3sService) Execute(runtime connector.Runtime) error {
|
||||
defaultKubeletArs := map[string]string{
|
||||
"kube-reserved": "cpu=200m,memory=250Mi,ephemeral-storage=1Gi",
|
||||
"system-reserved": "cpu=200m,memory=250Mi,ephemeral-storage=1Gi",
|
||||
"eviction-hard": "memory.available<5%,nodefs.available<10%,imagefs.available<10%",
|
||||
"eviction-hard": "memory.available<5%,nodefs.available<5%,imagefs.available<5%",
|
||||
"config": "/etc/rancher/k3s/kubelet.config",
|
||||
"containerd": container.DefaultContainerdCRISocket,
|
||||
"cgroup-driver": "systemd",
|
||||
"runtime-request-timeout": "5m",
|
||||
"image-gc-high-threshold": "91",
|
||||
"image-gc-low-threshold": "90",
|
||||
"image-gc-high-threshold": "96",
|
||||
"image-gc-low-threshold": "95",
|
||||
"housekeeping_interval": "5s",
|
||||
}
|
||||
defaultKubeProxyArgs := map[string]string{
|
||||
|
||||
@@ -296,8 +296,10 @@ func GetKubeletConfiguration(runtime connector.Runtime, kubeConf *common.KubeCon
|
||||
"memory": "250Mi",
|
||||
},
|
||||
"evictionHard": map[string]string{
|
||||
"memory.available": "5%",
|
||||
"pid.available": "10%",
|
||||
"memory.available": "5%",
|
||||
"pid.available": "10%",
|
||||
"nodefs.available": "5%",
|
||||
"imagefs.available": "5%",
|
||||
},
|
||||
"evictionSoft": map[string]string{
|
||||
"memory.available": "10%",
|
||||
@@ -309,8 +311,8 @@ func GetKubeletConfiguration(runtime connector.Runtime, kubeConf *common.KubeCon
|
||||
"evictionPressureTransitionPeriod": "30s",
|
||||
"featureGates": FeatureGatesDefaultConfiguration,
|
||||
"runtimeRequestTimeout": "5m",
|
||||
"imageGCHighThresholdPercent": 91,
|
||||
"imageGCLowThresholdPercent": 90,
|
||||
"imageGCHighThresholdPercent": 96,
|
||||
"imageGCLowThresholdPercent": 95,
|
||||
}
|
||||
|
||||
if securityEnhancement {
|
||||
|
||||
@@ -19,7 +19,6 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
DIDGateURL = "https://did-gate-v3.bttcdn.com/1.0/name/"
|
||||
DIDGateTimeout = 10 * time.Second
|
||||
DIDCachePath = "/var/lib/olares"
|
||||
)
|
||||
@@ -90,7 +89,7 @@ type CheckJWSResult struct {
|
||||
}
|
||||
|
||||
// resolveDID resolves a DID either from cache or from the DID gate
|
||||
func ResolveOlaresName(olares_id string) (*didcore.ResolutionResult, error) {
|
||||
func ResolveOlaresName(gateUrl, olares_id string) (*didcore.ResolutionResult, error) {
|
||||
name := strings.Replace(olares_id, "@", ".", -1)
|
||||
// Try to get from cache first
|
||||
cached, err := getDB().Get([]byte(name), nil)
|
||||
@@ -105,7 +104,7 @@ func ResolveOlaresName(olares_id string) (*didcore.ResolutionResult, error) {
|
||||
client := &http.Client{
|
||||
Timeout: DIDGateTimeout,
|
||||
}
|
||||
resp, err := client.Get(DIDGateURL + name)
|
||||
resp, err := client.Get(gateUrl + name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch DID from gate: %w", err)
|
||||
}
|
||||
@@ -135,7 +134,7 @@ func ResolveOlaresName(olares_id string) (*didcore.ResolutionResult, error) {
|
||||
}
|
||||
|
||||
// CheckJWS verifies a JWS and returns the terminus name, body and kid
|
||||
func CheckJWS(jws string, duration int64) (*CheckJWSResult, error) {
|
||||
func CheckJWS(gateUrl, jws string, duration int64) (*CheckJWSResult, error) {
|
||||
var kid string
|
||||
var name string
|
||||
var timestamp int64
|
||||
@@ -198,7 +197,7 @@ func CheckJWS(jws string, duration int64) (*CheckJWSResult, error) {
|
||||
}
|
||||
|
||||
// Resolve DID
|
||||
resolutionResult, err := ResolveOlaresName(name)
|
||||
resolutionResult, err := ResolveOlaresName(gateUrl, name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to resolve DID: %w", err)
|
||||
}
|
||||
|
||||
@@ -20,6 +20,12 @@ func NewUsbWatcher() *usbWatcher {
|
||||
return w
|
||||
}
|
||||
|
||||
var UsbSerialKey = struct{}{}
|
||||
|
||||
func WithSerial(ctx context.Context, serial string) context.Context {
|
||||
return context.WithValue(ctx, UsbSerialKey, serial)
|
||||
}
|
||||
|
||||
func (w *usbWatcher) Watch(ctx context.Context) {
|
||||
retry := 1
|
||||
devs, err := utils.DetectdUsbDevices(ctx)
|
||||
@@ -55,6 +61,16 @@ func (w *usbWatcher) Watch(ctx context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
serial := ctx.Value(UsbSerialKey).(string)
|
||||
if serial != "" {
|
||||
klog.Info("mount usb device with serial, ", serial)
|
||||
devs = utils.FilterArray(devs, utils.FilterBySerial(serial))
|
||||
if len(devs) == 0 {
|
||||
klog.Info("no usb device found with serial, ", serial)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
mountedPath, err := utils.MountUsbDevice(ctx, commands.MOUNT_BASE_DIR, devs)
|
||||
if err != nil {
|
||||
klog.Error("mount usb error, ", err)
|
||||
@@ -80,13 +96,13 @@ func (w *umountWatcher) Watch(ctx context.Context) {
|
||||
}
|
||||
|
||||
func NewUsbMonitor(ctx context.Context) error {
|
||||
return utils.MonitorUsbDevice(ctx, func(action string) error {
|
||||
return utils.MonitorUsbDevice(ctx, func(action, serial string) error {
|
||||
switch action {
|
||||
case "add":
|
||||
delay := time.NewTimer(2 * time.Second)
|
||||
go func() {
|
||||
<-delay.C
|
||||
NewUsbWatcher().Watch(ctx)
|
||||
NewUsbWatcher().Watch(WithSerial(ctx, serial))
|
||||
}()
|
||||
case "remove":
|
||||
NewUmountWatcher().Watch(ctx)
|
||||
|
||||
@@ -119,7 +119,7 @@ func DetectdHddDevices(ctx context.Context) (usbDevs []storageDevice, err error)
|
||||
return detectdStorageDevices(ctx, "ata")
|
||||
}
|
||||
|
||||
func MonitorUsbDevice(ctx context.Context, cb func(action string) error) error {
|
||||
func MonitorUsbDevice(ctx context.Context, cb func(action, serial string) error) error {
|
||||
filter := &usbmon.ActionFilter{Action: usbmon.ActionAll}
|
||||
devs, err := usbmon.ListenFiltered(ctx, filter)
|
||||
if err != nil {
|
||||
@@ -137,8 +137,8 @@ func MonitorUsbDevice(ctx context.Context, cb func(action string) error) error {
|
||||
fmt.Println("Path: " + dev.Path())
|
||||
fmt.Println("Vendor: " + dev.Vendor())
|
||||
|
||||
if cb != nil {
|
||||
err = cb(dev.Action())
|
||||
if cb != nil && dev.Serial() != "" {
|
||||
err = cb(dev.Action(), dev.Serial())
|
||||
if err != nil {
|
||||
klog.Error("usb action callback error, ", err, ", ", dev.Action())
|
||||
}
|
||||
@@ -197,6 +197,12 @@ func MountedHddPath(ctx context.Context) ([]string, error) {
|
||||
return getMountedPath(hdds)
|
||||
}
|
||||
|
||||
func FilterBySerial(serial string) func(dev storageDevice) bool {
|
||||
return func(dev storageDevice) bool {
|
||||
return dev.IDSerial == serial || dev.IDSerialShort == serial
|
||||
}
|
||||
}
|
||||
|
||||
func MountUsbDevice(ctx context.Context, mountBaseDir string, dev []storageDevice) (mountedPath []string, err error) {
|
||||
mounter := mountutils.New("")
|
||||
mountedList, err := mounter.List()
|
||||
|
||||
@@ -19,7 +19,7 @@ func DetectdHddDevices(ctx context.Context) (usbDevs []storageDevice, err error)
|
||||
return
|
||||
}
|
||||
|
||||
func MonitorUsbDevice(ctx context.Context, cb func(action string) error) error {
|
||||
func MonitorUsbDevice(ctx context.Context, cb func(action, id string) error) error {
|
||||
klog.Warning("not implement")
|
||||
return nil
|
||||
}
|
||||
@@ -72,3 +72,9 @@ func MountedPath(ctx context.Context) ([]mountedPath, error) {
|
||||
klog.Warning("not implement")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func FilterBySerial(serial string) func(dev storageDevice) bool {
|
||||
return func(dev storageDevice) bool {
|
||||
return dev.IDSerial == serial || dev.IDSerialShort == serial
|
||||
}
|
||||
}
|
||||
|
||||
11
daemon/pkg/utils/utils.go
Normal file
11
daemon/pkg/utils/utils.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package utils
|
||||
|
||||
func FilterArray[T any](items []T, fn func(T) bool) []T {
|
||||
var filtered []T
|
||||
for _, item := range items {
|
||||
if fn(item) {
|
||||
filtered = append(filtered, item)
|
||||
}
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
@@ -6,7 +6,7 @@ const side = {
|
||||
text: "What is Olares",
|
||||
link: "/manual/overview",
|
||||
items: [
|
||||
{ text: "Compare Olares and NAS", link: "/manual/olares-vs-nas" },
|
||||
// { text: "Compare Olares and NAS", link: "/manual/olares-vs-nas" },
|
||||
{ text: "Help and support", link: "/manual/help/request-technical-support"}
|
||||
// collapsed: true,
|
||||
// items: [
|
||||
@@ -468,10 +468,10 @@ const side = {
|
||||
text: "Steam",
|
||||
link: "/use-cases/stream-game",
|
||||
},
|
||||
{
|
||||
text: "Redroid",
|
||||
link: "/use-cases/host-cloud-android",
|
||||
},
|
||||
// {
|
||||
// text: "Redroid",
|
||||
// link: "/use-cases/host-cloud-android",
|
||||
// },
|
||||
{
|
||||
text: "Windows",
|
||||
link: "/use-cases/windows",
|
||||
|
||||
@@ -8,7 +8,7 @@ const side = {
|
||||
items: [
|
||||
// { text: "应用场景", link: "/zh/manual/why-olares" },
|
||||
//{ text: "功能对比", link: "/zh/manual/feature-overview" },
|
||||
{ text: "比较 Olares 和 NAS", link: "/zh/manual/olares-vs-nas" },
|
||||
// { text: "比较 Olares 和 NAS", link: "/zh/manual/olares-vs-nas" },
|
||||
{text: "帮助与支持", link: "/zh/manual/help/request-technical-support",}
|
||||
// collapsed: true,
|
||||
// items: [
|
||||
@@ -425,7 +425,7 @@ const side = {
|
||||
],
|
||||
"/zh/use-cases/": [
|
||||
{
|
||||
text: "Tutorials & use cases",
|
||||
text: "应用示例",
|
||||
link: "/zh/use-cases/",
|
||||
items: [
|
||||
{
|
||||
@@ -471,10 +471,10 @@ const side = {
|
||||
text: "Steam",
|
||||
link: "/zh/use-cases/stream-game",
|
||||
},
|
||||
{
|
||||
text: "Redroid",
|
||||
link: "/zh/use-cases/host-cloud-android",
|
||||
},
|
||||
// {
|
||||
// text: "Redroid",
|
||||
// link: "/zh/use-cases/host-cloud-android",
|
||||
// },
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -16,7 +16,6 @@ From running AI models to building seamless workflows across your self-hosted se
|
||||
{ title: 'Ollama', link: './ollama.html', tags: ['AI']},
|
||||
{ title: 'Jellyfin', link: './stream-media.html', tags: ['Entertainment']},
|
||||
{ title: 'Steam', link: './stream-game.html', tags: ['Entertainment']},
|
||||
{ title: 'Redroid', link: './host-cloud-android.html', tags: ['Virtual Machine']},
|
||||
{ title: 'Windows', link: './windows.html', tags: ['Virtual Machine']},
|
||||
{ title: 'DeerFlow', link: './host-cloud-android.html', tags: ['AI']},
|
||||
{ title: 'ACE-Step', link: './ace-step.html', tags: ['AI']},
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
description: 了解 Olares 在 AI 流程、创意工具和自托管应用中的实际用例,充分释放 Olares 的潜力。
|
||||
---
|
||||
|
||||
# 使用场景与教程
|
||||
# 应用示例
|
||||
|
||||
本节聚焦于**真实场景**,帮助你充分挖掘 Olares 的强大功能。 从运行 AI 模型到在自托管服务间构建无缝工作流,这些动手教程将指导你完成具体任务,并利用已安装的应用实现完整、实用的解决方案。
|
||||
本节聚焦于真实场景,帮助你充分挖掘 Olares 的强大功能。 从运行 AI 模型到在自托管服务间构建无缝工作流,这些动手教程将指导你完成具体任务,并利用已安装的应用实现完整、实用的解决方案。
|
||||
|
||||
<FilterableList :items="[
|
||||
{ title: 'Stable Diffusion', link: './stable-diffusion.html', tags: ['AI'] },
|
||||
@@ -15,5 +15,4 @@ description: 了解 Olares 在 AI 流程、创意工具和自托管应用中的
|
||||
{ title: 'Ollama', link: './ollama.html', tags: ['AI'] },
|
||||
{ title: 'Jellyfin', link: './stream-media.html', tags: ['娱乐'] },
|
||||
{ title: 'Steam', link: './stream-game.html', tags: ['娱乐'] },
|
||||
{ title: 'Redroid', link: './host-cloud-android.html', tags: ['虚拟机'] },
|
||||
]" />
|
||||
|
||||
@@ -170,7 +170,7 @@ spec:
|
||||
priorityClassName: "system-cluster-critical"
|
||||
containers:
|
||||
- name: app-service
|
||||
image: beclab/app-service:0.4.70
|
||||
image: beclab/app-service:0.4.72
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
runAsUser: 0
|
||||
|
||||
@@ -2,7 +2,6 @@ package appinstaller
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
appv1alpha1 "github.com/beclab/Olares/framework/app-service/api/app.bytetrade.io/v1alpha1"
|
||||
@@ -12,7 +11,6 @@ import (
|
||||
"github.com/beclab/Olares/framework/app-service/pkg/helm"
|
||||
"github.com/beclab/Olares/framework/app-service/pkg/users/userspace"
|
||||
apputils "github.com/beclab/Olares/framework/app-service/pkg/utils/app"
|
||||
helmrelease "helm.sh/helm/v3/pkg/release"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
@@ -23,15 +21,7 @@ import (
|
||||
|
||||
// Upgrade do a upgrade operation for release.
|
||||
func (h *HelmOps) Upgrade() error {
|
||||
status, err := h.status()
|
||||
if err != nil {
|
||||
klog.Errorf("get release status failed %v", err)
|
||||
return err
|
||||
}
|
||||
if status.Info.Status == helmrelease.StatusDeployed {
|
||||
return h.upgrade()
|
||||
}
|
||||
return fmt.Errorf("cannot upgrade release %s/%s, current state is %s", h.app.Namespace, h.app.AppName, status.Info.Status)
|
||||
return h.upgrade()
|
||||
}
|
||||
|
||||
func (h *HelmOps) upgrade() error {
|
||||
|
||||
@@ -87,7 +87,8 @@ func UpgradeCharts(ctx context.Context, actionConfig *action.Configuration, sett
|
||||
client.Namespace = namespace
|
||||
client.Timeout = 300 * time.Second
|
||||
client.Recreate = false
|
||||
client.Atomic = true
|
||||
// Do not use Atomic, this could cause helm wait all resource ready.
|
||||
//client.Atomic = true
|
||||
if reuseValue {
|
||||
client.ReuseValues = true
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ spec:
|
||||
memory: 300Mi
|
||||
|
||||
- name: download-server
|
||||
image: "beclab/download-server:v0.1.16"
|
||||
image: "beclab/download-server:v0.1.17"
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
runAsUser: 0
|
||||
|
||||
@@ -210,7 +210,7 @@ spec:
|
||||
command:
|
||||
- /samba_share
|
||||
- name: files
|
||||
image: beclab/files-server:v0.2.142
|
||||
image: beclab/files-server:v0.2.144
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: true
|
||||
|
||||
@@ -140,7 +140,7 @@ spec:
|
||||
name: check-chart-repo
|
||||
containers:
|
||||
- name: appstore-backend
|
||||
image: beclab/market-backend:v0.6.13
|
||||
image: beclab/market-backend:v0.6.15
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 81
|
||||
|
||||
@@ -248,7 +248,7 @@ spec:
|
||||
|
||||
containers:
|
||||
- name: seafile-server
|
||||
image: beclab/pg_seafile_server:v0.0.16
|
||||
image: beclab/pg_seafile_server:v0.0.17
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 8082
|
||||
|
||||
@@ -251,6 +251,8 @@ data:
|
||||
not startswith(image, "ghcr.io/coder/coder:v2.19.0")
|
||||
not startswith(image, "apecloud/")
|
||||
not startswith(image, "kldtks/")
|
||||
not startswith(image, "alpine:")
|
||||
not startswith(image, "mariadb:")
|
||||
}
|
||||
|
||||
is_root_user(ctx) if {
|
||||
|
||||
Reference in New Issue
Block a user