Compare commits

...

13 Commits

Author SHA1 Message Date
eball
f16ec6b0c6 fix(cli): remove error logging for GB10 chip check 2026-03-05 11:26:15 +08:00
aby913
7404674a20 fix(bfl): remove set custom domain on cloudflare (#2624)
* fix(bfl): remove set custom domain on cloudflare (#2619)

* fix(bfl): remove set custom domain on cloudflare
2026-03-05 11:04:15 +08:00
Power-One-2025
f116970ad0 docs: add manual restart instructions and refine discord channel config (#2617)
* add note and faq for manual restart

* update channel configuration for accuracy

* change for consistency
2026-03-05 10:29:42 +08:00
wiy
b6e866ce75 feat(olares-app): update version to v1.9.12 (#2623) 2026-03-04 23:51:04 +08:00
dkeven
39bd546ac8 fix(manifest): add password reset path for cli in auth provider (#2622) 2026-03-04 23:50:19 +08:00
eball
5820b5612e fix(daemon): increase retry count for USB device detection (#2620) 2026-03-04 23:49:37 +08:00
Teng
ef78e21933 docs: update Olares Manifest to 0.11.0 (#2527)
* update Olares Manifest to 0.11.0

* fix typo

* Update manifest.md

* Update manifest.md

* Update manifest.md

* Apply suggestions from code review

Co-authored-by: Meow33 <supermonkey03@163.com>

* Apply suggestions from code review

* Apply suggestions from code review

* Apply suggestions from code review

Co-authored-by: Meow33 <supermonkey03@163.com>

---------

Co-authored-by: Meow33 <supermonkey03@163.com>
2026-03-04 19:11:16 +08:00
eball
8ce8b6c976 feat(cli): add time synchronization check using chronyc (#2616)
* feat(cli): add time synchronization check using chronyc

* feat(cli): update time synchronization check to validate stratum value
2026-03-04 14:43:42 +08:00
dkeven
cbab40a597 feat(bfl): use unified remote api env to query external ip (#2614)
* feat(bfl): use unified remote api env to query external ip (#2611)

* chore(bfl): update bfl image version to v0.4.41
2026-03-04 00:19:03 +08:00
dkeven
14691ea3ec feat(daemon): use unified remote api env to query external ip (#2613) 2026-03-04 00:18:25 +08:00
Power-One-2025
98f123fbf1 docs: add persona setup for OpenClaw tutorial (#2605)
* Add: Personalize OpenClaw

* simplify a message

* refinements for accuracy

* remove redundant text

* tag the step with Optional

* address comments

* adjust image size

* adjust image size
2026-03-03 21:43:07 +08:00
Jeremiah Lee
8f5023ce17 docs: fix broken shields images and architecture link in README (#2608)
- shields.io is case sensitive for the repo name (capital O Olares), resulting in "invalid" text rendering in badge
- architecture URL in docs moved without redirect
2026-03-03 20:39:48 +08:00
Yajing
4467bc61df docs: restructure factory reset and reinstall docs for Olares One (#2607)
* restructure factory reset and reinstall docs

* address comment
2026-03-03 20:35:52 +08:00
30 changed files with 603 additions and 449 deletions

View File

@@ -3,10 +3,10 @@
# Olares: An Open-Source Personal Cloud to </br>Reclaim Your Data<!-- omit in toc -->
[![Mission](https://img.shields.io/badge/Mission-Let%20people%20own%20their%20data%20again-purple)](#)<br/>
[![Last Commit](https://img.shields.io/github/last-commit/beclab/olares)](https://github.com/beclab/olares/commits/main)
[![Last Commit](https://img.shields.io/github/last-commit/beclab/Olares)](https://github.com/beclab/olares/commits/main)
![Build Status](https://github.com/beclab/olares/actions/workflows/release-daily.yaml/badge.svg)
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/beclab/olares)](https://github.com/beclab/olares/releases)
[![GitHub Repo stars](https://img.shields.io/github/stars/beclab/olares?style=social)](https://github.com/beclab/olares/stargazers)
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/beclab/Olares)](https://github.com/beclab/olares/releases)
[![GitHub Repo stars](https://img.shields.io/github/stars/beclab/Olares?style=social)](https://github.com/beclab/Olares/stargazers)
[![Discord](https://img.shields.io/badge/Discord-7289DA?logo=discord&logoColor=white)](https://discord.gg/olares)
[![License](https://img.shields.io/badge/License-AGPL--3.0-blue)](https://github.com/beclab/olares/blob/main/LICENSE)
@@ -45,7 +45,7 @@ Just as Public clouds offer IaaS, PaaS, and SaaS layers, Olares provides open-so
![Tech Stacks](https://app.cdn.olares.com/github/olares/olares-architecture.jpg)
For detailed description of each component, refer to [Olares architecture](https://docs.olares.com/manual/concepts/system-architecture.html).
For detailed description of each component, refer to [Olares architecture](https://docs.olares.com/developer/concepts/system-architecture.html).
> 🔍 **How is Olares different from traditional NAS?**
>

View File

@@ -317,7 +317,7 @@ spec:
chown -R 1000:1000 /uploadstemp && \
chown -R 1000:1000 /appdata
- name: olares-app-init
image: beclab/system-frontend:v1.9.9
image: beclab/system-frontend:v1.9.12
imagePullPolicy: IfNotPresent
command:
- /bin/sh

View File

@@ -159,6 +159,7 @@ const (
CommandUpdatePciids = "update-pciids"
CommandNmcli = "nmcli"
CommandZRAMCtl = "zramctl"
CommandChronyc = "chronyc"
CacheCommandKubectlPath = "kubectl_bin_path"
CacheCommandMinikubePath = "minikube_bin_path"

View File

@@ -512,7 +512,6 @@ func getCpu() *CpuInfo {
if err == nil && strings.TrimSpace(string(output)) != "" {
isGB10Chip = true
} else {
fmt.Printf("Error checking GB10 chip: %v\n", err)
gb10env := os.Getenv(common.ENV_GB10_CHIP)
if gb10env == "1" || strings.EqualFold(gb10env, "true") {
isGB10Chip = true

View File

@@ -116,8 +116,14 @@ func (m *CheckPreparedModule) Init() {
Action: &CheckPrepared{Force: m.Force},
}
checkTimeSync := &task.LocalTask{
Name: "CheckTimeSynced",
Action: &WaitTimeSyncTask{},
}
m.Tasks = []task.Interface{
checkPrepared,
checkTimeSync,
}
}

View File

@@ -1033,3 +1033,37 @@ func (a *SaveMasterHostConfig) Execute(runtime connector.Runtime) error {
}
return os.WriteFile(filepath.Join(runtime.GetBaseDir(), common.MasterHostConfigFile), content, 0644)
}
type WaitTimeSyncTask struct {
common.KubeAction
}
func (t *WaitTimeSyncTask) Execute(runtime connector.Runtime) error {
if chronyc, err := util.GetCommand(common.CommandChronyc); err == nil && chronyc != "" {
ticker := time.NewTicker(2 * time.Second)
timeout := time.NewTimer(5 * time.Minute)
defer ticker.Stop()
defer timeout.Stop()
for {
select {
case <-ticker.C:
// output format:
// 68839BAF,104.131.155.175,3,1772592384.619310832,-0.001840593,0.001674238,0.001874871,-5.194,-0.001,0.112,0.162520304,0.010412607,1035.0,Normal
if res, err := runtime.GetRunner().Cmd(fmt.Sprintf("%s -c tracking", chronyc), false, true); err != nil {
logger.Errorf("failed to execute chronyc tracking: %v", err)
return err
} else {
resToken := strings.Split(res, ",")
// if the stratum of the server is 10 which means the local reference (hardware RTC) is active.
if strings.ToLower(resToken[2]) != "10" { // Stratum
logger.Infof("time synchronization is normal")
return nil
}
}
case <-timeout.C:
return fmt.Errorf("timeout waiting for time synchronization")
}
}
}
return nil
}

View File

@@ -27,7 +27,7 @@ func WithSerial(ctx context.Context, serial string) context.Context {
}
func (w *usbWatcher) Watch(ctx context.Context) {
retry := 1
retry := 3
devs, err := utils.DetectdUsbDevices(ctx)
for {
if err != nil {

View File

@@ -43,11 +43,12 @@ type state struct {
Disk string `json:"disk"`
// network info
WikiConnected bool `json:"wifiConnected"`
WifiSSID *string `json:"wifiSSID,omitempty"`
WiredConnected bool `json:"wiredConnected"`
HostIP string `json:"hostIp"`
ExternalIP string `json:"externalIp"`
WikiConnected bool `json:"wifiConnected"`
WifiSSID *string `json:"wifiSSID,omitempty"`
WiredConnected bool `json:"wiredConnected"`
HostIP string `json:"hostIp"`
ExternalIP string `json:"externalIp"`
ExternalIPProbeTime time.Time `json:"-"`
// installing / uninstalling / upgrading state
InstallingState ProcessingState `json:"installingState"`
@@ -130,7 +131,8 @@ func CheckCurrentStatus(ctx context.Context) error {
klog.Info("current state: ", CurrentState.TerminusState)
}()
utils.ForceMountHdd(ctx)
// Deprecated, only for Olares Zero
// utils.ForceMountHdd(ctx)
// set default value
if CurrentState.TerminusVersion == nil {
@@ -255,7 +257,10 @@ func CheckCurrentStatus(ctx context.Context) error {
}
CurrentState.HostIP = hostIp
CurrentState.ExternalIP = nets.GetMyExternalIPAddr()
if time.Since(CurrentState.ExternalIPProbeTime) > 1*time.Minute {
CurrentState.ExternalIP = nets.GetMyExternalIPAddr()
CurrentState.ExternalIPProbeTime = time.Now()
}
// get olares state

View File

@@ -181,6 +181,7 @@ var (
// {"installing k8s and kubesphere", "3%", 3},
// {"Generating \"ca\" certificate and key", "3%", 3},
// {"PatchKsCoreStatus success", "6%", 6},
{"time synchronization is normal", "3%", 3},
{"k8s and kubesphere installation is complete", "10%", 10},
{"Installing account ...", "15%", 15},
{"Installing settings ...", "20%", 20},

View File

@@ -4,14 +4,17 @@ import (
"crypto/tls"
"encoding/json"
"errors"
"io/ioutil"
"io"
"net"
"net/http"
"net/netip"
"net/url"
"os"
"strings"
"time"
"github.com/beclab/Olares/daemon/pkg/commands"
"github.com/gofiber/fiber/v2/log"
"github.com/libp2p/go-netroute"
pkg_errors "github.com/pkg/errors"
"github.com/txn2/txeh"
@@ -267,15 +270,7 @@ func GetHostIpFromHostsFile(domain string) (string, error) {
return ip, nil
}
// GetMyExternalIPAddr get my network outgoing ip address
func GetMyExternalIPAddr() string {
sites := map[string]string{
"httpbin": "https://httpbin.org/ip",
"ifconfigme": "https://ifconfig.me/all.json",
"externalip": "https://myexternalip.com/json",
"joinolares": "https://myip.joinolares.cn/ip",
}
type httpBin struct {
Origin string `json:"origin"`
}
@@ -295,80 +290,80 @@ func GetMyExternalIPAddr() string {
IP string `json:"ip"`
}
var unmarshalFuncs = map[string]func(v []byte) string{
"httpbin": func(v []byte) string {
var hb httpBin
if err := json.Unmarshal(v, &hb); err == nil && hb.Origin != "" {
return hb.Origin
}
return ""
},
"ifconfigme": func(v []byte) string {
var ifMe ifconfigMe
if err := json.Unmarshal(v, &ifMe); err == nil && ifMe.IPAddr != "" {
return ifMe.IPAddr
}
return ""
},
"externalip": func(v []byte) string {
var extip externalIP
if err := json.Unmarshal(v, &extip); err == nil && extip.IP != "" {
return extip.IP
}
return ""
},
"joinolares": func(v []byte) string {
return strings.TrimSpace(string(v))
},
type siteConfig struct {
url string
unmarshalFunc func(v []byte) string
}
ch := make(chan any, len(sites))
for site := range sites {
go func(name string) {
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
c := http.Client{Timeout: 5 * time.Second}
resp, err := c.Get(sites[name])
if err != nil {
ch <- err
return
}
defer resp.Body.Close()
respBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
ch <- err
return
}
ip := unmarshalFuncs[name](respBytes)
//println(name, site, ip)
ch <- ip
}(site)
externalIPServiceURL, err := url.JoinPath(commands.OLARES_REMOTE_SERVICE, "/myip/ip")
if err != nil {
klog.Error("failed to parse external IP service URL, ", err)
return ""
}
tr := time.NewTimer(time.Duration(5*len(sites)+3) * time.Second)
LOOP:
for i := 0; i < len(sites); i++ {
select {
case r, ok := <-ch:
if !ok {
continue
}
switch v := r.(type) {
case string:
ip := net.ParseIP(v)
if ip != nil && ip.To4() != nil && !ip.IsLoopback() && !ip.IsMulticast() {
return v
sites := []siteConfig{
{
url: externalIPServiceURL,
unmarshalFunc: func(v []byte) string {
return strings.TrimSpace(string(v))
},
},
{
url: "https://httpbin.org/ip",
unmarshalFunc: func(v []byte) string {
var hb httpBin
if err := json.Unmarshal(v, &hb); err == nil && hb.Origin != "" {
return hb.Origin
}
case error:
klog.Warningf("got an error, %v", v)
}
case <-tr.C:
tr.Stop()
klog.Warning("timed out")
break LOOP
return ""
},
},
{
url: "https://ifconfig.me/all.json",
unmarshalFunc: func(v []byte) string {
var ifMe ifconfigMe
if err := json.Unmarshal(v, &ifMe); err == nil && ifMe.IPAddr != "" {
return ifMe.IPAddr
}
return ""
},
},
{
url: "https://myexternalip.com/json",
unmarshalFunc: func(v []byte) string {
var extip externalIP
if err := json.Unmarshal(v, &extip); err == nil && extip.IP != "" {
return extip.IP
}
return ""
},
},
}
client := http.Client{
Timeout: 3 * time.Second,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
for _, site := range sites {
resp, err := client.Get(site.url)
if err != nil {
log.Warnf("failed to get external ip from %s, %v", site.url, err)
continue
}
respBytes, readErr := io.ReadAll(resp.Body)
resp.Body.Close()
if readErr != nil {
log.Warnf("failed to read response from %s, %v", site.url, readErr)
continue
}
ipStr := site.unmarshalFunc(respBytes)
ip := net.ParseIP(ipStr)
if ip != nil && ip.To4() != nil && !ip.IsLoopback() && !ip.IsMulticast() {
return ipStr
}
}

View File

@@ -216,23 +216,23 @@ export const oneSidebar: DefaultTheme.Sidebar = {
link: "/one/update",
},
{
text: "Back up & restore",
text: "Back up & restore data",
link: "/one/backup-resotre",
},
{
text: "Factory reset",
text: "Restore Olares One",
collapsed: true,
items: [
{
text: "Using LarePass",
text: "Factory reset",
link: "/one/factory-reset",
},
{
text: "In BIOS",
text: "Restore BIOS defaults",
link: "/one/factory-reset-in-bios",
},
{
text: "Using bootable USB",
text: "Reinstall Olares OS",
link: "/one/create-drive",
},
],

View File

@@ -216,23 +216,23 @@ export const oneSidebar: DefaultTheme.Sidebar = {
link: "/zh/one/update",
},
{
text: "Back up & restore",
text: "Back up & restore data",
link: "/zh/one/backup-resotre",
},
{
text: "Factory reset",
text: "Restore Olares One",
collapsed: true,
items: [
{
text: "Using LarePass",
text: "Factory reset",
link: "/zh/one/factory-reset",
},
{
text: "In BIOS",
text: "Restore BIOS defaults",
link: "/zh/one/factory-reset-in-bios",
},
{
text: "Using bootable USB",
text: "Reinstall Olares OS",
link: "/zh/one/create-drive",
},
],

View File

@@ -7,7 +7,15 @@ outline: [2, 3]
Every **Olares Application Chart** should include an `OlaresManifest.yaml` file in the root directory. `OlaresManifest.yaml` provides all the essential information about an Olares App. Both the **Olares Market protocol** and the Olares depend on this information to distribute and install applications.
:::info NOTE
Latest Olares Manifest version: `0.10.0`
Latest Olares Manifest version: `0.11.0`
- Removed deprecated fields of sysData
- Updated the example of shared app
- Added the apiVersion
- Added the sharedEntrance section
:::
:::details Changelog
`0.10.0`
- Modified the `categories` field
- Added the `provider` field in the Permission section
- Added the Provider section, to allow apps to expose specific service interfaces within the cluster
@@ -15,8 +23,7 @@ Latest Olares Manifest version: `0.10.0`
- Removed some deprecated fields from the Option section
- Added the `allowMultipleInstall` field, allowing the app to be installed as multiple independent instances
- Added the Envs section, to define environment variables required by the application
:::
:::details Changelog
`0.9.0`
- Added a `conflict` field in `options` to declare incompatible applications
- Removed `analytics` field in `options`
@@ -82,7 +89,7 @@ spec:
website: https://link.to.your.website
sourceCode: https://link.to.sourceCode
submitter: Submitter's Name
language:
locale:
- en
doc: https://link.to.documents
supportArch:
@@ -130,6 +137,13 @@ olaresManifest.version: 1.1.0
olaresManifest.version: '2.2'
olaresManifest.version: "3.0.122"
```
## apiVersion
- Type: `string`
- Optional
- Accepted Value: `v1`,`v2`
- Default: `v1`
For shared applications, use version `v2`, which supports multiple subcharts in a single OAC. For other applications, use `v1`.
## Metadata
@@ -152,7 +166,7 @@ metadata:
### name
- Type: `string`
- Accepted Value: `[a-z][a-z0-9]?`
- Accepted Value: `^[a-z][a-z0-9]{0,29}$`
Apps namespace in Olares, lowercase alphanumeric characters only. It can be up to 30 characters, and needs to be consistent with `FolderName` and `name` field in `Chart.yaml`.
@@ -160,7 +174,7 @@ Apps namespace in Olares, lowercase alphanumeric characters only. It can be u
- Type: `string`
The title of your app title shown in the Olares Market. Must be within `30` characters.
The title of your app shown in the Olares Market. Must be within `30` characters.
### description
@@ -189,8 +203,7 @@ The **Chart Version** of the application. It should be incremented each time the
Used to display your app on different category page in Olares Market.
Accepted Value for OS 1.11:
`Blockchain`, `Utilities`, `Social Network`, `Entertainment`, `Productivity`
- `Blockchain`, `Utilities`, `Social Network`, `Entertainment`, `Productivity`
Accepted Value for OS 1.12:
- `Creativity`
@@ -201,14 +214,13 @@ Accepted Value for OS 1.12:
- `Utilities_v112` (displayed as Utilities)
- `AI`
:::info NOTE
Olares Market categories were updated in OS 1.12.0. To ensure your app is compatible with both versions 1.11 and 1.12, include category values for both versions in your configuration.
:::
## Entrances
The number of entrances through which to access the app. You must specify at least 1 access method, with a maximum of 10 allowed.
The entrances (up to 10) that users can use to access the app. At least 1 is required.
:::info Example
```yaml
@@ -322,6 +334,24 @@ To ensure a seamless user experience, you can enable this option by setting it t
```
:::
## sharedEntrances
A shared entrance is an internal address provided by a shared application for other applications within the cluster to access. The field configuration for shared entrances is basically the same as for regular entrances. A typical shared entrance configuration is shown below.
:::info Example
```yaml
sharedEntrances:
- name: ollamav2
host: sharedentrances-ollama
port: 0
title: Ollama API
icon: https://app.cdn.olares.com/appstore/ollama/icon.png
invisible: true
authLevel: internal
```
:::
## Ports
Specify exposed ports
@@ -338,15 +368,50 @@ ports:
```
:::
### exposePort
- Type: `int`
- Optional
- Accepted Value: `0-65535`, except reserved ports `22`, `80`, `81`, `443`, `444`, `2379`, `18088`.
Olares will expose the ports you specify for an application, which are accessible via the application domain name in the local network, for example: `84864c1f.your_olares_id.olares.com:46879`. For each port you expose, Olares configures both TCP and UDP with the same port number.
When the `addToTailscaleAcl` field is set to `true`, the system will automatically assign a random port and add it to the Tailscale ACLs.
:::info NOTE
The exposed ports can only be accessed on the local network or through a VPN.
:::
### protocol
- Type: `string`
- Optional
- Accepted Value: `udp`, `tcp`
The protocol used for the exposed port. If specified, Olares exposes only the specified protocol. If omitted, Olares exposes both UDP and TCP by default.
### addToTailscaleAcl
- Type: `boolean`
- Optional
- Default: `false`
When the `addToTailscaleAcl` field is set to `true`, the system will automatically assign a random port and add it to the Tailscale ACLs.
## Tailscale
- Type: `map`
- Optional
Allow applications to add Access Control Lists (ACL) in Tailscale to open specified ports.
:::info Example
```yaml
tailscale:
acls:
- proto: tcp
dst:
- "*:46879"
- proto: "" # Optional. If not specified, all supported protocols will be allowed.
dst:
- "*:4557"
```
:::
## Permission
:::info Example
@@ -380,51 +445,6 @@ Whether the app requires read and write permission to the `Data` folder. If `.Va
Whether the app requires read and write permission to user's `Home` folder. List all directories that the application needs to access under the user's `Home`. All `userData` directory configured in the deployment YAML, must be included here.
### sysData
- Type: `list<map>`
- Optional
Declare the list of APIs that this app needs to access.
:::info NOTE
This configuration has been deprecated since version 1.12.0.
:::
:::info Example
```yaml
sysData:
- group: service.bfl
dataType: app
version: v1
ops:
- InstallDevApp
- dataType: legacy_prowlarr
appName: prowlarr
port: 9696
group: api.prowlarr
version: v2
ops:
- All
```
:::
All system API [providers](../advanced/provider.md) are list below:
| Group | version | dataType | ops |
| ----------- | ----------- | ----------- | ----------- |
| service.appstore | v1 | app | InstallDevApp, UninstallDevApp
| message-dispatcher.system-server | v1 | event | Create, List
| service.desktop | v1 | ai_message | AIMessage
| service.did | v1 | did | ResolveByDID, ResolveByName, Verify
| api.intent | v1 | legacy_api | POST
| service.intent | v1 | intent | RegisterIntentFilter, UnregisterIntentFilter, SendIntent, QueryIntent, ListDefaultChoice, CreateDefaultChoice, RemoveDefaultChoice, ReplaceDefaultChoice
| service.message | v1 | message | GetContactLogs, GetMessages, Message
| service.notification | v1 | message | Create
| service.notification | v1 | token | Create
| service.search | v1 | search | Input, Delete, InputRSS, DeleteRSS, QueryRSS, QuestionAI
| secret.infisical | v1 | secret | CreateSecret, RetrieveSecret
| secret.vault | v1 | key | List, Info, Sign
### provider
- Type: `list<map>`
@@ -461,25 +481,6 @@ provider:
```
:::
## Tailscale
- Type: `map`
- Optional
Allow applications to add Access Control Lists (ACL) in Tailscale to open specified ports.
:::info Example
```yaml
tailscale:
acls:
- proto: tcp
dst:
- "*:46879"
- proto: "" # Optional. If not specified, all supported protocols will be allowed.
dst:
- "*:4557"
```
:::
## Spec
Additional information about the application, primarily used for display in the Olares Market.
@@ -607,7 +608,7 @@ When set to `true`, Olares forces the application to run under user ID `1000` (a
- Type: `map`
- Optional
The Olares provides highly available middleware services. Developers do not need to install middleware repeatedly. Just simply add required middleware here, You can then directly use the corresponding middleware information in the application's deployment YAML file.
Olares provides highly available middleware services. Developers do not need to install middleware repeatedly. Add the required middleware here, then use the corresponding middleware values in the application's deployment YAML file.
Use the `scripts` field to specify scripts that should be executed after the database is created. Additionally, use the `extension` field to add the corresponding extension in the database.
@@ -803,10 +804,10 @@ Use the middleware information in deployment YAML
## Options
Configure system-related options here.
Configure Olares OS related options here.
### policies
- Type: `map`
- Type: `list<map>`
- Optional
Define detailed access control for subdomains of the app.
@@ -823,38 +824,35 @@ options:
```
:::
### clusterScoped
### appScope
- Type: `map`
- Optional
Whether this app is installed for all users in an Olares cluster.
Specifies whether the app should be installed for all users in the Olares cluster. For shared apps, set `clusterScoped` to `true` and provide the current app's name in the `appRef` field.
:::info Example For Server
:::info Example of ollamav2
```yaml
metadata:
name: gitlab
name: ollamav2
options:
appScope:
{{- if and .Values.admin .Values.bfl.username (eq .Values.admin .Values.bfl.username) }} # Only the administrator installs the shared service
clusterScoped: true
appRef:
- gitlabclienta #app name of clients
- gitlabclientb
```
:::
:::info Example For Client
```yaml
metadata:
name: gitlabclienta
options:
- ollamav2 # the name of current app specified in metadata.name
{{- else }}
clusterScoped: false
{{- end }}
dependencies:
- name: olares
version: ">=0.3.6-0"
version: '>=1.12.3-0'
type: system
- name: gitlab #app name of server
version: ">=0.0.1"
{{- if and .Values.admin .Values.bfl.username (eq .Values.admin .Values.bfl.username) }}
{{- else }}
type: application
mandatory: true
version: '>=1.0.1'
mandatory: true # Other users install the client, depend on the shared service installed by the admin
{{- end }}
```
:::
@@ -880,6 +878,24 @@ options:
```
:::
### conflicts
- Type: `list<map>`
- Optional
List other applications that conflict with this app here. Conflicting apps must be uninstalled before this app can be installed.
:::info Example
```yaml
options:
conflicts:
- name: comfyui
type: application
- name: comfyuiclient
type: application
```
:::
### mobileSupported
- Type: `boolean`
- Default: `false`
@@ -927,9 +943,8 @@ apiTimeout: 0
:::
### allowedOutboundPorts
- Type: `map`
- Type: `list<int>`
- Optional
The specified ports will be opened to allow external access via non-HTTP protocols, such as SMTP.
@@ -1027,4 +1042,4 @@ provider:
paths: ["/api*"] # API paths to expose; cannot consist of * only
verbs: ["*"] # Supported: post, get, put, delete, patch; "*" allows all methods
```
:::
:::

View File

@@ -1,15 +1,15 @@
---
outline: [2, 3]
description: Reinstall Olares OS on Olares One using a bootable USB to restore the device to factory state.
description: Reinstall Olares OS on Olares One using a bootable USB drive to restore the device to a clean initial state.
head:
- - meta
- name: keywords
content: Olares One, reinstall, factory reset, bootable USB, installation USB
content: Olares One, reinstall, Olares OS, bootable USB, installation USB
---
# Reset to factory settings using installation USB <Badge type="tip" text="15 min"/>
# Reinstall Olares OS using bootable USB <Badge type="tip" text="15 min"/>
Resetting to factory settings returns your Olares One to the initial setup state. You can reinstall Olares OS using the bootable USB drive included with Olares One.
Reinstalling Olares OS returns your Olares One to a clean initial state. You can do this using the bootable USB drive included with Olares One.
:::warning Data loss
This will permanently delete all accounts, settings, and data on the device. This action cannot be undone.
@@ -18,6 +18,9 @@ This will permanently delete all accounts, settings, and data on the device. Thi
## Prerequisites
**Hardware**<br>
- The bootable USB drive that came with Olares One.
:::tip Don't have the USB drive?
Download the [Olares One ISO](https://cdn.olares.com/one/v1.12.4-amd64.iso), which is device-specific and different from the standard Olares ISO, and flash it to a USB drive (8 GB or larger) using a tool such as [Balena Etcher](https://etcher.balena.io/).
:::
- A monitor and keyboard connected to Olares One.
## Step 1: Boot from the USB drive

View File

@@ -1,14 +1,14 @@
---
outline: [2, 3]
description: Learn how to restore your Olares One to factory settings in BIOS.
description: Learn how to restore BIOS defaults on Olares One to return the device to its initial setup state.
head:
- - meta
- name: keywords
content: Factory reset, Olares One, BIOS
content: Olares One, BIOS defaults, restore, BIOS setup
---
# Reset to factory settings in BIOS <Badge type="tip" text="10 min" />
# Restore BIOS defaults <Badge type="tip" text="10 min" />
Resetting to factory settings returns your Olares One to its initial setup state. If you have a monitor and keyboard connected, you can perform this reset directly in BIOS instead of using LarePass.
Restoring BIOS defaults resets the firmware configuration and returns your Olares One to its initial setup state. If you have a monitor and keyboard connected, you can perform this directly in BIOS.
:::warning Data loss
This will permanently delete all accounts, settings, and data on the device. This action cannot be undone.

View File

@@ -1,12 +1,12 @@
---
outline: [2, 3]
description: Learn how to restore your Olares One to factory settings using LarePass.
description: Learn how to factory reset your Olares One using LarePass.
head:
- - meta
- name: keywords
content: Factory reset, Olares One
content: factory reset, Olares One, LarePass
---
# Reset to factory settings using LarePass <Badge type="tip" text="10 min" />
# Factory reset via LarePass <Badge type="tip" text="10 min" />
If you have already activated Olares One and want to return it to the factory state, you can perform a reset in LarePass.

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

View File

@@ -1,6 +1,6 @@
---
outline: [2, 3]
description: Learn how to install, configure, and integrate OpenClaw with Discord.
description: Learn how to install, configure, personalize, and integrate OpenClaw with Discord.
head:
- - meta
- name: keywords
@@ -15,11 +15,10 @@ It acts as an "always-on" operator that can execute real tasks, such as searchin
## Learning objectives
By the end of this tutorial, you are be able to:
- Install and initialize the OpenClaw environment.
- Pair and connect the OpenClaw CLI and the Control UI.
- Configure OpenClaw to use the local AI model Ollama.
- Personalize OpenClaw to establish its identity and behavior.
- Integrate OpenClaw with Discord.
- Enable the web search capability using Brave Search.
- Manage skills and plug-ins.
@@ -132,18 +131,18 @@ Run a quick setup for the agent in the OpenClaw CLI.
- **Default Session Key**: Enter `agent:main:main`.
7. Click **Connect**.
The connection error `disconnected[1008]:pairing required` occurs. This is expected and means the device connection is waiting for approval.
The connection error `pairing required` occurs. This is expected and means the device connection is waiting for approval.
8. Return to the OpenClaw CLI window and enter the following command:
```bash
openclaw devices approve --latest
```
9. When the terminal displays the approval message, return to the Control UI and refresh it.
9. When the terminal displays the approval message, return to the Control UI.
![Pair sucess](/images/manual/use-cases/new-pair-success.png#bordered)
Now the **STATUS** in the **Snapshot** panel should be **Connected**.
Now the **STATUS** in the **Snapshot** panel should be **OK**.
![Health OK](/images/manual/use-cases/openclaw-connected.png#bordered)
![Health OK](/images/manual/use-cases/openclaw-connected1.png#bordered)
:::tip For advanced users
If you prefer to fully customize your initial setup, you can run the `openclaw onboard` command instead to launch the interactive configuration wizard.
@@ -163,7 +162,7 @@ Connect the Control UI to the OpenClaw CLI to use the graphical dashboard.
- **Default Session Key**: Enter `agent:main:main`.
3. Click **Connect**.
The connection error `disconnected[1008]:pairing required` occurs. This is expected and means the device connection is waiting for approval.
The connection error `pairing required` occurs. This is expected and means the device connection is waiting for approval.
4. Return to the OpenClaw CLI window and enter the following command:
```bash
openclaw devices list
@@ -181,9 +180,9 @@ Connect the Control UI to the OpenClaw CLI to use the graphical dashboard.
```bash
openclaw devices approve {RequestID}
```
7. When the terminal displays the approval message, return to the Control UI. Now the **STATUS** in the **Snapshot** panel should be **Connected**.
7. When the terminal displays the approval message, return to the Control UI. Now the **STATUS** in the **Snapshot** panel should be **OK**.
![Health OK](/images/manual/use-cases/openclaw-connected.png#bordered)
![Health OK](/images/manual/use-cases/openclaw-connected1.png#bordered)
## Configure local AI model
@@ -207,6 +206,75 @@ Connect the Control UI to the OpenClaw CLI to use the graphical dashboard.
```
4. Click **Save** in the upper-right corner. The system validates the config and restarts automatically to apply the changes.
::: tip Manual restart
If you need to restart OpenClaw manually, do not use the OpenClaw CLI. Use one of the following methods:
- **Restart the app from Settings or Market**:
- Open **Settings**, go to **Applications** > **OpenClaw**, click **Stop**, and then click **Resume**.
- Open **Market**, go to **My Olares**, find **OpenClaw**, click <i class="material-symbols-outlined">keyboard_arrow_down</i> next to the operation button, select **Stop**, and then select **Resume**.
- **Restart the container**: Open **Control Hub**, click `clawdbot` under **Deployments**, and then click **Restart**.
:::
## (Optional) Personalize OpenClaw
To make your OpenClaw bot more personalized, it is highly recommended to complete the persona setup process.
This process establishes the agent's identity, behavioral boundaries, and long-term memory through persona files. These files keep your agent's behavior consistent across all platforms and channels.
1. In the Control UI, select **Chat** from the left sidebar.
2. Ensure <i class="material-symbols-outlined">neurology</i> at the upper-right corner is enabled. This allows you to watch the agent think and edit persona files in real time.
3. Enter and send the following message to start:
```text
Wake up please!
```
The agent responds and starts interviewing you. You can establish rules, personality traits, and preferences. For example,
```text
- Call me Bella. I like simple language without technical jargons and
concise bulleted answers.
- You are John, a witty assistant who uses emojis.
- Never access my calendar without asking first, and never execute any
financial operations.
```
4. As you chat with the agent, look for the **Edit** messages. These indicate the agent is successfully writing your preferences to its core persona files, such as `IDENTITY.md`, `USER.md`, and `SOUL.md`.
![Persona files editing by OpenClaw](/images/manual/use-cases/openclaw-persona-recording.png#bordered){width=90%}
:::tip
If you do not see the intermediate persona file operations, refresh the page by clicking <i class="material-symbols-outlined">refresh</i> at the upper-right corner or by pressing F5.
:::
5. Continue the conversation until the agent gathers enough information. Then, it automatically deletes the temporary `BOOTSTRAP.md` file to finish the personalization process.
![Finish hatch agent](/images/manual/use-cases/openclaw-hatch-finish.png#bordered){width=90%}
6. (Optional) If the agent fails to update the persona files or delete `BOOTSTRAP.md`, explicitly instruct it to do so in the chat.
If the issue persists, resolve it using one of the following methods:
- **Increase the context window**: Select **Config** from the left sidebar, switch to the **Raw** tab, find the `models` section, and then increase the `contextWindow` value to at least 64K (200K is recommended).
:::tip
Note that a larger context window consumes more VRAM, so choose a value that your hardware can support.
:::
- **Change the model**: Switch to a model with better tool-calling and instructionfollowing capabilities.
7. Verify your agent's persona files are updated:
a. Open Files from the Launchpad.
b. Go to **Application** > **Data** > **clawdbot** > **config** > **workspace**.
c. Check the modified time of the `.md` files to identify which ones were recently updated, such as `USER.md` and `IDENTITY.md`.
![Persona files generated by OpenClaw](/images/manual/use-cases/openclaw-persona-files.png#bordered){width=90%}
d. (Optional) Double-click a file to verify that it contains your newly established rules such as name, language style, and restrictions.
:::tip Modify persona settings
To change these settings in the future, use one of the following methods:
- Ask the agent in the chat to update its rules.
- Download the `.md` files from this folder, edit them in a text editor, and re-upload them to overwrite the old ones.
:::
## Integrate with Discord
To chat with your agent remotely, connect it to a Discord bot.
@@ -251,14 +319,16 @@ To chat with your agent remotely, connect it to a Discord bot.
### Step 3: Configure channel
Configure the Discord channel in Control UI.
Connect OpenClaw to your Discord bot by adding its configuration in the Control UI.
:::info About channel configuration
This tutorial provides the basic setup to get your bot running in Discord quickly. For more detailed configurations, see the official [OpenClaw documentation](https://docs.openclaw.ai/channels).
:::
1. Return to the **Control UI** > **Config** > **Raw** tab.
2. Find the `channels` section:
2. Add the following `channels` section to the configuration file.
a. Update with your Discord bot token.
b. Enable Discord DM (Direct Messages) and set the Discord DM Policy to **Pairing**.
This configuration enables Discord Direct Messages (DMs) and sets the DM policy to pairing for security.
```json
"channels": {
@@ -276,8 +346,9 @@ Configure the Discord channel in Control UI.
![Discord channel added](/images/manual/use-cases/channels.png#bordered)
3. Click **Save**.
4. From the left sidebar, select **Channels**. On the Discord card, **Probe ok** indicates successful connection.
3. Replace `{YOUR_BOT_TOKEN}` with your Discord bot token.
4. Click **Save**.
5. From the left sidebar, select **Channels**. On the Discord card, **Probe ok** indicates successful connection.
![Probe OK](/images/manual/use-cases/probe-ok.png#bordered)
@@ -345,7 +416,7 @@ OpenClaw officially recommends Brave Search. It uses an independent web index op
## Manage skills and plugins
OpenClaw can be extended using skills and plugins
OpenClaw can be extended using skills and plugins:
- Skills add new capabilities to the AI. For example, managing Model Context Protocol servers.
- Plugins extend the system to support additional channels or community features. For example, adding iMessage via BlueBubbles.
@@ -442,7 +513,35 @@ To manage skills and plugins, install ClawHub. It is the package manager for Ope
![Toggle on plugin](/images/manual/use-cases/toggle-plugin.png#bordered)
6. Click **Save** in the upper-right corner. The system validates the config and restarts automatically to apply the changes.
6. Click **Save** in the upper-right corner. The system validates the config and restarts automatically to apply the changes.
::: tip Manual restart
If you need to restart OpenClaw manually, do not use the OpenClaw CLI. Use one of the following methods:
- **Restart the app from Settings or Market**:
- Open **Settings**, go to **Applications** > **OpenClaw**, click **Stop**, and then click **Resume**.
- Open **Market**, go to **My Olares**, find **OpenClaw**, click <i class="material-symbols-outlined">keyboard_arrow_down</i> next to the operation button, select **Stop**, and then select **Resume**.
- **Restart the container**: Open **Control Hub**, click `clawdbot` under **Deployments**, and then click **Restart**.
:::
## FAQ
### Cannot restart OpenClaw in CLI
If you attempt to manually start, stop, or restart OpenClaw using commands like `openclaw gateway` or `openclaw gateway stop` in the OpenClaw CLI, you receive the following error messages:
- `Gateway failed to start: gateway already running (pid 1); lock timeout after 5000ms`
- `Gateway service check failed: Error: systemctl --user unavailable: spawn systemctl ENOENT`
#### Cause
OpenClaw is deployed as a containerized app in Olares, where the gateway runs as the primary container process `pid 1` and is always active. This environment does not use standard Linux system and service management tools such as `systemd` and `systemctl`, so these commands do not work.
#### Solution
Do not use the OpenClaw CLI to manage the gateway service. Instead, restart OpenClaw using one of the following methods:
- **Restart OpenClaw from Settings or Market**:
- Open **Settings**, go to **Applications** > **OpenClaw**, click **Stop**, and then click then **Resume**.
- Open **Market**, go to **My Olares**, find **OpenClaw**, click <i class="material-symbols-outlined">keyboard_arrow_down</i> next to the operation button, select **Stop**, and then select **Resume**.
- **Restart the container**: Open **Control Hub**, click `clawdbot` under **Deployments**, and then click **Restart**.
## Resources

View File

@@ -7,7 +7,15 @@ outline: [2, 3]
每一个 Olares 应用的 Chart 根目录下都必须有一个名为 `OlaresManifest.yaml` 的文件。`OlaresManifest.yaml` 描述了一个 Olares 应用的所有基本信息。Olares 应用市场协议和 Olares 系统依赖这些关键信息来正确分发和安装应用。
:::info 提示
最新的 Olares 系统使用的 Manifest 版本为: `0.10.0`
最新的 Olares 系统使用的 Manifest 版本为: `0.11.0`
- 移除 已不支持的sysData 配置项
- 修改 共享应用的案例
- 增加 apiVersion 字段说明
- 增加 共享入口的配置说明
:::
:::details Changelog
`0.10.0`
- 修改 `categories` 分类
- 增加 Permission 部分中 `provider` 权限的申请
- 增加 Provider 部分,用于让应用对集群内暴露指定服务接口
@@ -15,8 +23,7 @@ outline: [2, 3]
- 移除 Option 部分已不支持的一些配置项
- 增加 `allowMultipleInstall` 配置,允许应用克隆出多个独立的实例
- 增加 Envs 部分,支持应用声明需要的环境变量
:::
:::details Changelog
`0.9.0`
-`options` 中增加 `conflict` 字段, 用于声明不兼容的应用
- 移除 `options``analytics` 配置项
@@ -82,7 +89,7 @@ spec:
website: https://link.to.your.website
sourceCode: https://link.to.sourceCode
submitter: Submitter's Name
language:
locale:
- en
doc: https://link.to.documents
supportArch:
@@ -131,6 +138,14 @@ olaresManifest.version: '2.2'
olaresManifest.version: "3.0.122"
```
## apiVersion
- 类型:`string`
- 可选
- 有效值:`v1`,`v2`
- 默认值:`v1`
共享应用需使用 `v2` 版本,支持一个 OAC 中包含多个子图表。其他应用请使用`v1`
## Metadata
应用的基本信息,用于在 Olares 系统和应用市场中展示应用。
@@ -152,7 +167,7 @@ metadata:
### name
- 类型:`string`
- Accepted Value: `[a-z][a-z0-9]?`
- 有效值:`^[a-z][a-z0-9]{0,29}$`
Olares 中的应用的命名空间,仅限小写字母数字字符。最多 30 个字符,需要与 `Chart.yaml` 中的 `FolderName``name` 字段保持一致。
@@ -200,8 +215,6 @@ OS 1.12 有效值:
- `Utilities_v112`:实用工具
- `AI`AI
:::info 提示
Olares OS 1.12.0 版本对应用商店的应用分类进行了调整,因此如果应用需要同时兼容 1.11 和 1.12 版本,请同时填写两个版本所需的分类。
:::
@@ -322,6 +335,23 @@ entrances:
```
:::
## sharedEntrances
共享入口是共享应用为集群内其他应用调用提供的接口地址。共享入口的字段配置和常规入口基本一致,一个典型的共享入口配置如下
:::info 示例
```yaml
sharedEntrances:
- name: ollamav2
host: sharedentrances-ollama
port: 0
title: Ollama API
icon: https://app.cdn.olares.com/appstore/ollama/icon.png
invisible: true
authLevel: internal
```
:::
## Ports
定义暴露的端口
@@ -338,14 +368,48 @@ ports:
```
:::
### exposePort
- 类型: `int`
- 可选
- 有效值: `0-65535`,保留端口 `22`, `80`, `81`, `443`, `444`, `2379`, `18088` 除外
Olares 会为你的应用暴露指定的端口,这些端口可通过应用域名在本地网络下访问,如`84864c1f.your_olares_id.olares.com:46879`。对于每个公开的端口Olares 会自动配置相同端口号的 TCP 和 UDP。
当将 `addToTailscaleAcl` 字段设置为 `true` 时,系统会为该端口分配一个随机端口,并自动将其加入到 Tailscale 的 ACL 中。
:::info 提示
暴露的端口只能通过本地网络或 Olares 专用网络访问。
:::
### protocol
- 类型: `string`
- 可选
- 有效值: `udp``tcp`
暴露端口使用的协议 如果不填默认同时开通udp和tcp。
### addToTailscaleAcl
- 类型: `boolean`
- 可选
- 默认值:`false`
当将 addToTailscaleAcl 字段设置为 true 时,系统会为该端口分配一个随机端口,并自动将其加入到 Tailscale 的 ACL 中。
## Tailscale
- 类型:`map`
- 可选
允许应用在 Tailscale 的ACL(Access Control Lists)中开放指定端口。
:::info 示例
```yaml
tailscale:
acls:
- proto: tcp
dst:
- "*:46879"
- proto: "" # 可选, 如果未指定,则允许使用所有支持的协议
dst:
- "*:4557"
```
:::
## Permission
@@ -380,51 +444,6 @@ permission:
应用是否需要对用户的 `Home` 文件夹进行读写权限。列出应用需要访问的用户 `Home` 下的所有目录。部署 YAML 中配置的所有 `userData` 目录都必须包含在此处。
### sysData
- 类型:`list<map>`
- 可选
声明该应用程序需要访问的 API 列表。
:::info 提示
从 1.12.0 版本开始,该权限配置已经被废弃。
:::
:::info 示例
```yaml
sysData:
- group: service.bfl
dataType: app
version: v1
ops:
- InstallDevApp
- dataType: legacy_prowlarr
appName: prowlarr
port: 9696
group: api.prowlarr
version: v2
ops:
- All
```
:::
所有系统 API [providers](../advanced/provider.md) 如下:
| Group | version | dataType | ops |
| ----------- | ----------- | ----------- | ----------- |
| service.appstore | v1 | app | InstallDevApp, UninstallDevApp
| message-disptahcer.system-server | v1 | event | Create, List
| service.desktop | v1 | ai_message | AIMessage
| service.did | v1 | did | ResolveByDID, ResolveByName, Verify
| api.intent | v1 | legacy_api | POST
| service.intent | v1 | intent | RegisterIntentFilter, UnregisterIntentFilter, SendIntent, QueryIntent, ListDefaultChoice, CreateDefaultChoice, RemoveDefaultChoice, ReplaceDefaultChoice
| service.message | v1 | message | GetContactLogs, GetMessages, Message
| service.notification | v1 | message | Create
| service.notification | v1 | token | Create
| service.search | v1 | search | Input, Delete, InputRSS, DeleteRSS, QueryRSS, QuestionAI
| secret.infisical | v1 | secret | CreateSecret, RetrieveSecret
| secret.vault | v1 | key | List, Info, Sign
### provider
- 类型:`list<map>`
@@ -432,7 +451,11 @@ permission:
用于声明本应用需访问的其他应用接口。被访问的应用需在其 `provider` 部分声明对外开放的 `providerName`,详见下方 Provider 章节。
此处 `appName` 应填写目标应用的 `name``providerName` 填写目标应用 `provider` 配置中的 `name` 字段。`podSelectors` 字段用于指定本应用中哪些 pod 需要访问目标应用。如果未声明此字段,则默认为本应用的所有 pod 注入 `outbound envoy sidecar`
配置访问的方式如下
1.`appName` 字段填写目标应用的 `name` 字段。
2.`providerName` 字段填写目标应用 `provider` 配置中的 `name` 字段。
你可以使用 `podSelectors` 字段来指定本应用中哪些 pod 需要访问目标应用。如果未声明此字段,则默认为本应用的所有 pod 注入 `outbound envoy sidecar`
:::info 调用应用示例
```yaml
@@ -458,25 +481,6 @@ provider:
:::
## Tailscale
- 类型:`map`
- 可选
允许应用在 Tailscale 的ACL(Access Control Lists)中开放指定端口。
:::info 示例
```yaml
tailscale:
acls:
- proto: tcp
dst:
- "*:46879"
- proto: "" # 可选, 如果未指定,则允许使用所有支持的协议
dst:
- "*:4557"
```
:::
## Spec
记录额外的应用信息,主要用于应用商店的展示。
@@ -796,10 +800,10 @@ middleware:
## Options
此部分配置系统相关的选项。
此部分用于配置与Olares系统相关的选项。
### policies
- 类型:`map`
- 类型:`list<map>`
- 可选
定义应用子域的详细访问控制。
@@ -816,40 +820,40 @@ options:
```
:::
### clusterScoped
### appScope
- 类型:`map`
- 可选
是否为 Olares 集群中的所有用户安装此应用程序。
是否为 Olares 集群中的所有用户安装此应用程序。对用共享应用,需要设置 `clusterScoped``true`, 同时在 `appRef` 字段填入应用名称
:::info 服务端示例
:::info 应用ollamav2示例
```yaml
metadata:
name: gitlab
name: ollamav2
options:
appScope:
{{- if and .Values.admin .Values.bfl.username (eq .Values.admin .Values.bfl.username) }} # 仅管理员安装共享服务
clusterScoped: true
appRef:
- gitlabclienta # 客户端的应用名称
- gitlabclientb
- ollamav2 # 此应用在 metadata.name 中声明的名字
{{- else }}
clusterScoped: false
{{- end }}
dependencies:
- name: olares
version: '>=1.12.3-0'
type: system
{{- if and .Values.admin .Values.bfl.username (eq .Values.admin .Values.bfl.username) }}
{{- else }}
- name: ollamav2
type: application
version: '>=1.0.1'
mandatory: true # 其他用户安装客户端,依赖管理员安装的共享服务
{{- end }}
```
:::
:::info 客户端示例
```yaml
metadata:
name: gitlabclienta
options:
dependencies:
- name: olares
version: ">=0.3.6-0"
type: system
- name: gitlab # 服务器端的应用名称
version: ">=0.0.1"
type: application
mandatory: true
```
:::
### dependencies
- 类型:`list<map>`
@@ -872,6 +876,24 @@ options:
```
:::
### conflicts
- 类型:`list<map>`
- 可选
请在此处声明与该应用冲突的其他应用。必须卸载冲突应用后才能安装此应用。
:::info 示例
```yaml
options:
conflicts:
- name: comfyui
type: application
- name: comfyuiclient
type: application
```
:::
### mobileSupported
- 类型: `boolean`
- 默认值: `false`
@@ -919,7 +941,7 @@ apiTimeout: 0
:::
### allowedOutboundPorts
- 类型: `map`
- 类型: `list<int>`
- 可选
要求开通以下端口进行非 HTTP 协议的对外访问,例如 SMTP 服务等。

View File

@@ -1,15 +1,15 @@
---
outline: [2, 3]
description: Reinstall Olares OS on Olares One using a bootable USB to restore the device to factory state.
description: Reinstall Olares OS on Olares One using a bootable USB drive to restore the device to a clean initial state.
head:
- - meta
- name: keywords
content: Olares One, reinstall, factory reset, bootable USB, installation USB
content: Olares One, reinstall, Olares OS, bootable USB, installation USB
---
# Reset to factory settings using installation USB <Badge type="tip" text="15 min"/>
# Reinstall Olares OS using bootable USB <Badge type="tip" text="15 min"/>
Resetting to factory settings returns your Olares One to the initial setup state. You can reinstall Olares OS using the bootable USB drive included with Olares One.
Reinstalling Olares OS returns your Olares One to a clean initial state. You can do this using the bootable USB drive included with Olares One.
:::warning Data loss
This will permanently delete all accounts, settings, and data on the device. This action cannot be undone.
@@ -18,6 +18,9 @@ This will permanently delete all accounts, settings, and data on the device. Thi
## Prerequisites
**Hardware**<br>
- The bootable USB drive that came with Olares One.
:::tip Don't have the USB drive?
Download the [Olares One ISO](https://cdn.olares.com/one/v1.12.4-amd64.iso), which is device-specific and different from the standard Olares ISO, and flash it to a USB drive (8 GB or larger) using a tool such as [Balena Etcher](https://etcher.balena.io/).
:::
- A monitor and keyboard connected to Olares One.
## Step 1: Boot from the USB drive

View File

@@ -1,14 +1,14 @@
---
outline: [2, 3]
description: Learn how to restore your Olares One to factory settings in BIOS.
description: Learn how to restore BIOS defaults on Olares One to return the device to its initial setup state.
head:
- - meta
- name: keywords
content: Factory reset, Olares One, BIOS
content: Olares One, BIOS defaults, restore, BIOS setup
---
# Reset to factory settings in BIOS <Badge type="tip" text="10 min" />
# Restore BIOS defaults <Badge type="tip" text="10 min" />
Resetting to factory settings returns your Olares One to its initial setup state. If you have a monitor and keyboard connected, you can perform this reset directly in BIOS instead of using LarePass.
Restoring BIOS defaults resets the firmware configuration and returns your Olares One to its initial setup state. If you have a monitor and keyboard connected, you can perform this directly in BIOS.
:::warning Data loss
This will permanently delete all accounts, settings, and data on the device. This action cannot be undone.

View File

@@ -1,12 +1,12 @@
---
outline: [2, 3]
description: Learn how to restore your Olares One to factory settings using LarePass.
description: Learn how to factory reset your Olares One using LarePass.
head:
- - meta
- name: keywords
content: Factory reset, Olares One
content: factory reset, Olares One, LarePass
---
# Reset to factory settings using LarePass <Badge type="tip" text="10 min" />
# Factory reset via LarePass <Badge type="tip" text="10 min" />
If you have already activated Olares One and want to return it to the factory state, you can perform a reset in LarePass.

View File

@@ -26,6 +26,7 @@ metadata:
rules:
- nonResourceURLs:
- "/api/reset/*"
- "/cli/api/reset/*"
verbs: ["*"]
---

View File

@@ -266,7 +266,7 @@ spec:
containers:
- name: api
image: beclab/bfl:v0.4.40
image: beclab/bfl:v0.4.42
imagePullPolicy: IfNotPresent
securityContext:
runAsUser: 1000

View File

@@ -178,8 +178,8 @@ func (h *Handler) setupAppCustomDomain(req *restful.Request, resp *restful.Respo
var settings app_service.ApplicationsSettings
appServiceClient := app_service.NewAppServiceClient()
var terminusName, zone string
terminusName, zone, err = h.getUserInfo()
var zone string
_, zone, err = h.getUserInfo()
if err != nil {
response.HandleError(resp, err)
return
@@ -223,8 +223,6 @@ func (h *Handler) setupAppCustomDomain(req *restful.Request, resp *restful.Respo
return
}
cm := certmanager.NewCertManager(constants.TerminusName(terminusName))
var operate = h.getCustomDomainOperation(reqCustomDomain, existsAppCustomDomain)
log.Infof("setAppCustomDomain: app: %s-%s, reqDomain: %s, existsDomain: %s, operate: %d, req: %s",
appName, entranceName, reqCustomDomain, existsAppCustomDomain, operate, utils.ToJSON(customDomain))
@@ -260,12 +258,6 @@ func (h *Handler) setupAppCustomDomain(req *restful.Request, resp *restful.Respo
customDomain = entranceCustomDomainMap
}
case constants.CustomDomainDelete, constants.CustomDomainUpdate:
_, err := cm.DeleteCustomDomainOnCloudflare(existsAppCustomDomain)
if err != nil {
log.Errorf("setAppCustomDomain: app: %s-%s, delete custom domain error %v", appName, entranceName, err)
response.HandleError(resp, err)
return
}
fallthrough
case constants.CustomDomainAdd:
formatSettings(customDomain, zone, "", "")

View File

@@ -97,6 +97,8 @@ var (
APIDNSSetCloudFlareTunnel string
APIMyExternalIP string
NameSSLConfigMapName = "zone-ssl-config"
nameParamters = "name=%s"
@@ -319,6 +321,11 @@ func ReloadEnvDependantVars() error {
return err
}
APIMyExternalIP, err = url.JoinPath(OlaresRemoteService, "/myip/ip")
if err != nil {
return err
}
APIFormatCertGenerateRequest = APIPrefixCertService + "/generate?" + nameParamters
APIFormatCertGenerateStatus = APIPrefixCertService + "/status?" + nameParamters

View File

@@ -3,14 +3,14 @@ package utils
import (
"crypto/tls"
"encoding/json"
"io/ioutil"
"io"
"net"
"net/http"
"strings"
"sync"
"time"
"bytetrade.io/web3os/bfl/internal/log"
"bytetrade.io/web3os/bfl/pkg/constants"
)
const (
@@ -40,13 +40,6 @@ func RemoteIp(req *http.Request) string {
// GetMyExternalIPAddr get my network outgoing ip address
func GetMyExternalIPAddr() string {
sites := map[string]string{
"httpbin": "https://httpbin.org/ip",
"ifconfigme": "https://ifconfig.me/all.json",
"externalip": "https://myexternalip.com/json",
"joinolares": "https://myip.joinolares.cn/ip",
}
type httpBin struct {
Origin string `json:"origin"`
}
@@ -66,96 +59,74 @@ func GetMyExternalIPAddr() string {
IP string `json:"ip"`
}
var unmarshalFuncs = map[string]func(v []byte) string{
"httpbin": func(v []byte) string {
var hb httpBin
if err := json.Unmarshal(v, &hb); err == nil && hb.Origin != "" {
return hb.Origin
}
return ""
},
"ifconfigme": func(v []byte) string {
var ifMe ifconfigMe
if err := json.Unmarshal(v, &ifMe); err == nil && ifMe.IPAddr != "" {
return ifMe.IPAddr
}
return ""
},
"externalip": func(v []byte) string {
var extip externalIP
if err := json.Unmarshal(v, &extip); err == nil && extip.IP != "" {
return extip.IP
}
return ""
},
"joinolares": func(v []byte) string {
return strings.TrimSpace(string(v))
},
type siteConfig struct {
url string
unmarshalFunc func(v []byte) string
}
var mu sync.Mutex
ch := make(chan any, len(sites))
chSyncOp := func(f func()) {
mu.Lock()
defer mu.Unlock()
if ch != nil {
f()
}
}
for site := range sites {
go func(name string) {
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
c := http.Client{Timeout: 5 * time.Second}
resp, err := c.Get(sites[name])
if err != nil {
chSyncOp(func() { ch <- err })
return
}
defer resp.Body.Close()
respBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
chSyncOp(func() { ch <- err })
return
}
ip := unmarshalFuncs[name](respBytes)
//println(name, site, ip)
chSyncOp(func() { ch <- ip })
}(site)
}
tr := time.NewTimer(time.Duration(5*len(sites)+3) * time.Second)
defer func() {
tr.Stop()
chSyncOp(func() {
close(ch)
ch = nil
})
}()
LOOP:
for i := 0; i < len(sites); i++ {
select {
case r, ok := <-ch:
if !ok {
continue
}
switch v := r.(type) {
case string:
ip := net.ParseIP(v)
if ip != nil && ip.To4() != nil && !ip.IsLoopback() && !ip.IsMulticast() {
return v
sites := []siteConfig{
{
url: constants.APIMyExternalIP,
unmarshalFunc: func(v []byte) string {
return strings.TrimSpace(string(v))
},
},
{
url: "https://httpbin.org/ip",
unmarshalFunc: func(v []byte) string {
var hb httpBin
if err := json.Unmarshal(v, &hb); err == nil && hb.Origin != "" {
return hb.Origin
}
case error:
log.Warnf("got an error, %v", v)
}
case <-tr.C:
tr.Stop()
log.Warnf("timed out")
break LOOP
return ""
},
},
{
url: "https://ifconfig.me/all.json",
unmarshalFunc: func(v []byte) string {
var ifMe ifconfigMe
if err := json.Unmarshal(v, &ifMe); err == nil && ifMe.IPAddr != "" {
return ifMe.IPAddr
}
return ""
},
},
{
url: "https://myexternalip.com/json",
unmarshalFunc: func(v []byte) string {
var extip externalIP
if err := json.Unmarshal(v, &extip); err == nil && extip.IP != "" {
return extip.IP
}
return ""
},
},
}
client := http.Client{
Timeout: 3 * time.Second,
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
for _, site := range sites {
resp, err := client.Get(site.url)
if err != nil {
log.Warnf("failed to get external ip from %s, %v", site.url, err)
continue
}
respBytes, readErr := io.ReadAll(resp.Body)
resp.Body.Close()
if readErr != nil {
log.Warnf("failed to read response from %s, %v", site.url, readErr)
continue
}
ipStr := site.unmarshalFunc(respBytes)
ip := net.ParseIP(ipStr)
if ip != nil && ip.To4() != nil && !ip.IsLoopback() && !ip.IsMulticast() {
return ipStr
}
}