diff --git a/README.md b/README.md index 8fadf2cde..4484e583c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@
-# Olares: An Open-Source Personal Cloud to
Reclaim Your Data +# beOS Pro: A Self-Hosted Server Platform You Control [![Mission](https://img.shields.io/badge/Mission-Let%20people%20own%20their%20data%20again-purple)](#)
[![Last Commit](https://img.shields.io/github/last-commit/beclab/Olares)](https://github.com/beclab/olares/commits/main) @@ -8,7 +8,7 @@ [![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) +[![License](https://img.shields.io/badge/License-AGPL--3.0-blue)](./LICENSE) beclab%2FOlares | Trendshift @@ -21,31 +21,28 @@

- Website · - Documentation · - Download LarePass · - Olares Apps · - Olares Space + Overview · + Docs Source · + Applications · + CLI · + Daemon

>*The modern internet built on public clouds is increasingly threatening your personal data privacy. As reliance on services like ChatGPT, Midjourney, and Facebook grows, so does the risk to your digital autonomy. Your data lives on their servers, subject to their terms, tracking, and potential censorship.* > >*It's time for a change.* -![Personal Cloud](https://app.cdn.olares.com/github/olares/public-cloud-to-personal-cloud.jpg) -We believe you have a fundamental right to control your digital life. The most effective way to uphold this right is by hosting your data locally, on your own hardware. +beOS Pro is a local-first server platform for running your own applications, storage, AI workloads, and internal services on hardware you control. -Olares is an **open-source personal cloud operating system** designed to empower you to own and manage your digital assets locally. Instead of relying on public cloud services, you can deploy powerful open-source alternatives locally on Olares, such as Ollama for hosting LLMs, ComfyUI for image generation, and Perplexica for private, AI-driven search and reasoning. Imagine the power of the cloud, but with you in complete command. +This fork is being refactored to remove mandatory dependency on vendor-managed activation, DNS, CDN, and remote control-plane services. The goal is straightforward: install on bare metal or on top of an existing Linux server, finish setup locally, and operate it without connecting to any external beOS-operated infrastructure unless you explicitly configure optional providers. > 🌟 *Star us to receive instant notifications about new releases and updates.* ## Architecture -Just as Public clouds offer IaaS, PaaS, and SaaS layers, Olares provides open-source alternatives to each of these layers. +beOS Pro is structured as a host bootstrap layer, a Kubernetes orchestration layer, and a containerized platform/application layer. - ![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/developer/concepts/system-architecture.html). +For the current architecture source, start with `docs/developer/concepts/system-architecture.md`. > 🔍 **How is Olares different from traditional NAS?** > diff --git a/build/base-package/install.sh b/build/base-package/install.sh index 2dd629105..2e05dcf03 100644 --- a/build/base-package/install.sh +++ b/build/base-package/install.sh @@ -66,14 +66,14 @@ if ! command_exists tar; then exit 1 fi -export BASE_DIR="$HOME/.olares" +export BASE_DIR="${BEOS_BASE_DIR:-$HOME/.beos-pro}" if [ ! -d $BASE_DIR ]; then mkdir -p $BASE_DIR fi -cdn_url=${OLARES_SYSTEM_CDN_SERVICE} +cdn_url=${BEOS_SYSTEM_CDN_SERVICE} if [ -z ${cdn_url} ]; then - cdn_url="https://cdn.olares.com" + cdn_url=${OLARES_SYSTEM_CDN_SERVICE} fi RELEASE_ID="#__RELEASE_ID__" @@ -87,52 +87,64 @@ if [[ x"$os_type" == x"Darwin" ]]; then CLI_FILE="olares-cli-v${VERSION}_darwin_${ARCH}${RELEASE_ID_SUFFIX}.tar.gz" fi +if [[ "$LOCAL_RELEASE" != "1" && -z "${cdn_url}" ]]; then + echo "error: no beOS Pro package mirror configured. Set BEOS_SYSTEM_CDN_SERVICE (or OLARES_SYSTEM_CDN_SERVICE for compatibility), or use LOCAL_RELEASE=1." + exit 1 +fi + if [[ "$LOCAL_RELEASE" == "1" ]]; then - if ! command_exists olares-cli ; then - echo "error: LOCAL_RELEASE specified but olares-cli not found" + if command_exists beos-cli ; then + INSTALL_OLARES_CLI=$(which beos-cli) + elif command_exists olares-cli ; then + INSTALL_OLARES_CLI=$(which olares-cli) + else + echo "error: LOCAL_RELEASE specified but neither beos-cli nor olares-cli was found" exit 1 fi - INSTALL_OLARES_CLI=$(which olares-cli) else expected_vendor="main" if [[ "$(basename "$REPO_PATH")" == "olares-one" ]]; then expected_vendor="OlaresOne" fi - if command_exists olares-cli && [[ "$(olares-cli -v | awk '{print $3}')" == "$VERSION" ]] && [[ "$(olares-cli --vendor)" == "$expected_vendor" ]]; then + if command_exists beos-cli && [[ "$(beos-cli -v | awk '{print $3}')" == "$VERSION" ]] && [[ "$(beos-cli --vendor)" == "$expected_vendor" ]]; then + INSTALL_OLARES_CLI=$(which beos-cli) + echo "beos-cli already installed and is the expected version" + echo "" + elif command_exists olares-cli && [[ "$(olares-cli -v | awk '{print $3}')" == "$VERSION" ]] && [[ "$(olares-cli --vendor)" == "$expected_vendor" ]]; then INSTALL_OLARES_CLI=$(which olares-cli) - echo "olares-cli already installed and is the expected version" + echo "compatible legacy olares-cli already installed and is the expected version" echo "" else if [[ ! -f ${CLI_FILE} ]]; then CLI_URL="${cdn_url}${REPO_PATH}${CLI_FILE}" - echo "downloading Olares installer from ${CLI_URL} ..." + echo "downloading beOS Pro installer from ${CLI_URL} ..." echo "" curl -Lo ${CLI_FILE} ${CLI_URL} if [[ $? -ne 0 ]]; then - echo "error: failed to download Olares installer" + echo "error: failed to download beOS Pro installer" exit 1 else - echo "Olares installer ${VERSION} download complete!" + echo "beOS Pro installer ${VERSION} download complete!" echo "" fi fi - INSTALL_OLARES_CLI="/usr/local/bin/olares-cli" + INSTALL_OLARES_CLI="/usr/local/bin/beos-cli" echo "unpacking Olares installer to $INSTALL_OLARES_CLI..." echo "" tar -zxf ${CLI_FILE} olares-cli && chmod +x olares-cli if [[ x"$os_type" == x"Darwin" ]]; then - if [ ! -f "/usr/local/Cellar/olares" ]; then + if [ ! -f "/usr/local/Cellar/beos" ]; then current_user=$(whoami) - $sh_c "sudo mkdir -p /usr/local/Cellar/olares && sudo chown ${current_user}:staff /usr/local/Cellar/olares" + $sh_c "sudo mkdir -p /usr/local/Cellar/beos && sudo chown ${current_user}:staff /usr/local/Cellar/beos" fi - $sh_c "mv olares-cli /usr/local/Cellar/olares/olares-cli && \ - sudo rm -rf /usr/local/bin/olares-cli && \ - sudo ln -s /usr/local/Cellar/olares/olares-cli $INSTALL_OLARES_CLI" + $sh_c "mv olares-cli /usr/local/Cellar/beos/beos-cli && \ + sudo rm -rf /usr/local/bin/beos-cli && \ + sudo ln -s /usr/local/Cellar/beos/beos-cli $INSTALL_OLARES_CLI" else - $sh_c "mv olares-cli $INSTALL_OLARES_CLI" + $sh_c "mv olares-cli $INSTALL_OLARES_CLI" fi if [[ $? -ne 0 ]]; then @@ -214,7 +226,7 @@ else fi -echo "installing Olares..." +echo "installing beOS Pro..." echo "" $sh_c "$INSTALL_OLARES_CLI install" diff --git a/build/base-package/joincluster.sh b/build/base-package/joincluster.sh index db7131eea..60224f213 100755 --- a/build/base-package/joincluster.sh +++ b/build/base-package/joincluster.sh @@ -162,14 +162,19 @@ if [[ "x${VERSION}" == "x" || "x${VERSION:3}" == "xVERSION__" ]]; then exit 1 fi -BASE_DIR="$HOME/.olares" +BASE_DIR="${BEOS_BASE_DIR:-$HOME/.beos-pro}" if [ ! -d $BASE_DIR ]; then mkdir -p $BASE_DIR fi -cdn_url=${OLARES_SYSTEM_CDN_SERVICE} +cdn_url=${BEOS_SYSTEM_CDN_SERVICE} if [[ -z "${cdn_url}" ]]; then - cdn_url="https://cdn.olares.com" + cdn_url=${OLARES_SYSTEM_CDN_SERVICE} +fi + +if [[ -z "${cdn_url}" ]]; then + echo "error: no beOS Pro package mirror configured. Set BEOS_SYSTEM_CDN_SERVICE (or OLARES_SYSTEM_CDN_SERVICE for compatibility)." + exit 1 fi set_master_host_ssh_options @@ -185,27 +190,31 @@ expected_vendor="main" if [[ "$(basename "$REPO_PATH")" == "olares-one" ]]; then expected_vendor="OlaresOne" fi -if command_exists olares-cli && [[ "$(olares-cli -v | awk '{print $3}')" == "$VERSION" ]] && [[ "$(olares-cli --vendor)" == "$expected_vendor" ]]; then +if command_exists beos-cli && [[ "$(beos-cli -v | awk '{print $3}')" == "$VERSION" ]] && [[ "$(beos-cli --vendor)" == "$expected_vendor" ]]; then + INSTALL_OLARES_CLI=$(which beos-cli) + echo "beos-cli already installed and is the expected version" + echo "" +elif command_exists olares-cli && [[ "$(olares-cli -v | awk '{print $3}')" == "$VERSION" ]] && [[ "$(olares-cli --vendor)" == "$expected_vendor" ]]; then INSTALL_OLARES_CLI=$(which olares-cli) - echo "olares-cli already installed and is the expected version" + echo "compatible legacy olares-cli already installed and is the expected version" echo "" else if [[ ! -f ${CLI_FILE} ]]; then CLI_URL="${cdn_url}${REPO_PATH}${CLI_FILE}" - echo "downloading Olares installer from ${CLI_URL} ..." + echo "downloading beOS Pro installer from ${CLI_URL} ..." echo "" curl -Lo ${CLI_FILE} ${CLI_URL} if [[ $? -ne 0 ]]; then - echo "error: failed to download Olares installer" + echo "error: failed to download beOS Pro installer" exit 1 else - echo "Olares installer ${VERSION} download complete!" + echo "beOS Pro installer ${VERSION} download complete!" echo "" fi fi - INSTALL_OLARES_CLI="/usr/local/bin/olares-cli" + INSTALL_OLARES_CLI="/usr/local/bin/beos-cli" echo "unpacking Olares installer to $INSTALL_OLARES_CLI..." echo "" tar -zxf ${CLI_FILE} olares-cli && chmod +x olares-cli @@ -230,7 +239,7 @@ CDN="--cdn-service ${cdn_url}" if [[ -f $BASE_DIR/.prepared ]]; then echo "file $BASE_DIR/.prepared detected, skip preparing phase" echo "" - echo "please make sure the prepared Olares version is the same as the master, or there might be compatibility issues" + echo "please make sure the prepared beOS Pro version is the same as the master, or there might be compatibility issues" echo "" else echo "running system prechecks ..." diff --git a/build/system-env.yaml b/build/system-env.yaml index 2c08c07b6..8d6bae3c9 100644 --- a/build/system-env.yaml +++ b/build/system-env.yaml @@ -11,16 +11,16 @@ systemEnvs: # TERMINUS_CERT_SERVICE_API, # TERMINUS_DNS_SERVICE_API - envName: OLARES_SYSTEM_REMOTE_SERVICE - default: "https://api.olares.com" + default: "" type: url editable: true - required: true + required: false # the legacy DOWNLOAD_CDN_URL - envName: OLARES_SYSTEM_CDN_SERVICE - default: "https://cdn.olares.com" + default: "" type: url editable: true - required: true + required: false # docker hub mirror endpoint for docker.io registry - envName: OLARES_SYSTEM_DOCKERHUB_SERVICE type: url diff --git a/cli/cmd/ctl/root.go b/cli/cmd/ctl/root.go index dec41ceca..883b93335 100755 --- a/cli/cmd/ctl/root.go +++ b/cli/cmd/ctl/root.go @@ -22,8 +22,8 @@ func NewDefaultCommand() *cobra.Command { config.Init() }) cmds := &cobra.Command{ - Use: "olares-cli", - Short: "Olares Installer", + Use: "beos-cli", + Short: "beOS Pro Installer", CompletionOptions: cobra.CompletionOptions{DisableDefaultCmd: true}, Version: version.VERSION, PersistentPreRun: func(cmd *cobra.Command, args []string) { @@ -40,7 +40,7 @@ func NewDefaultCommand() *cobra.Command { return }, } - cmds.Flags().BoolVar(&showVendor, "vendor", false, "show the vendor type of olares-cli") + cmds.Flags().BoolVar(&showVendor, "vendor", false, "show the vendor type of beos-cli") cmds.AddCommand(osinfo.NewCmdInfo()) cmds.AddCommand(os.NewOSCommands()...) diff --git a/cli/pkg/core/common/common.go b/cli/pkg/core/common/common.go index 1add77c44..be370795d 100755 --- a/cli/pkg/core/common/common.go +++ b/cli/pkg/core/common/common.go @@ -38,8 +38,8 @@ const ( DeployDir = "deploy" OlaresDir = "olares" - DefaultBaseDir = ".olares" - DefaultDomainName = "olares.com" + DefaultBaseDir = ".beos-pro" + DefaultDomainName = "beos.local" ManifestImage = "images.mf" ManifestImageNode = "images.node.mf" @@ -92,8 +92,8 @@ const ( ) const ( - DefaultOlaresCDNService = "https://cdn.olares.com" - DefaultBashUrl = "olares.sh" + DefaultOlaresCDNService = "" + DefaultBashUrl = "beos.sh" ) const ( diff --git a/framework/bfl/pkg/apis/iam/v1alpha1/operator/user_operator.go b/framework/bfl/pkg/apis/iam/v1alpha1/operator/user_operator.go index 08003661f..6c95df02a 100644 --- a/framework/bfl/pkg/apis/iam/v1alpha1/operator/user_operator.go +++ b/framework/bfl/pkg/apis/iam/v1alpha1/operator/user_operator.go @@ -291,11 +291,11 @@ func (o *UserOperator) GetDenyAllPolicy(user *iamV1alpha2.User) string { func (o *UserOperator) GetDomain() (string, error) { terminus, err := o.terminusClient.Get(o.ctx, "terminus", metav1.GetOptions{}) if err != nil { - return "", err + return constants.DefaultLocalDomain(), nil } if name, ok := terminus.Spec.Settings[users.SettingsDomainNameKey]; !ok { - return "", errors.New("olares domain name not found") + return constants.DefaultLocalDomain(), nil } else { return name, nil } diff --git a/framework/bfl/pkg/apis/settings/v1alpha1/handler.go b/framework/bfl/pkg/apis/settings/v1alpha1/handler.go index d7efd4ba1..e814d414f 100644 --- a/framework/bfl/pkg/apis/settings/v1alpha1/handler.go +++ b/framework/bfl/pkg/apis/settings/v1alpha1/handler.go @@ -126,16 +126,15 @@ func (h *Handler) handleBindingUserZone(req *restful.Request, resp *restful.Resp } if v, ok := user.Annotations[constants.UserTerminusWizardStatus]; ok { - if v != string(constants.WaitActivateVault) { + if constants.HasRemoteService() && v != string(constants.WaitActivateVault) { response.HandleError(resp, errors.Errorf("user '%s' wizard status err, %s", user.Name, v)) return } } domain, err := op.GetDomain() - if err != nil { - response.HandleError(resp, errors.Errorf("user '%s' get olares domain error, %v", user.Name, err)) - return + if err != nil || domain == "" { + domain = constants.DefaultLocalDomain() } userPatches := []func(*iamV1alpha2.User){ @@ -189,8 +188,24 @@ func (h *Handler) handleActivate(req *restful.Request, resp *restful.Response) { terminusName = userOp.GetTerminusName(user) if terminusName == "" { - response.HandleError(resp, errors.New("activate system: no olares name, please ensure olares name is bound first")) - return + domain, domainErr := userOp.GetDomain() + if domainErr != nil || domain == "" { + domain = constants.DefaultLocalDomain() + } + terminusName = string(constants.NewTerminusName(user.Name, domain)) + if err = userOp.UpdateUser(user, []func(*iamV1alpha2.User){ + func(u *iamV1alpha2.User) { + if u.Annotations == nil { + u.Annotations = map[string]string{} + } + u.Annotations[constants.UserAnnotationTerminusNameKey] = terminusName + }, + }); err != nil { + err = fmt.Errorf("activate system: failed to assign local beOS domain: %v", err) + klog.Error(err) + response.HandleError(resp, err) + return + } } if userOp.GetUserAnnotation(user, constants.UserAnnotationZoneKey) != "" || userOp.GetUserAnnotation(user, constants.UserTerminusWizardStatus) == string(constants.NetworkActivating) { // already activated, or already in the process of activating, return success idempotently @@ -254,6 +269,8 @@ func (h *Handler) handleActivate(req *restful.Request, resp *restful.Response) { reverseProxyConf.EnableFRP = true reverseProxyConf.FRPServer = payload.FRP.Host reverseProxyConf.FRPAuthMethod = FRPAuthMethodJWS + } else if !constants.HasRemoteService() { + reverseProxyConf.ExternalNetworkOff = true } } else { ownerUser, ownerErr := userOp.GetOwnerUser() @@ -283,6 +300,29 @@ func (h *Handler) handleActivate(req *restful.Request, resp *restful.Response) { return } + if !constants.HasRemoteService() { + zone := constants.TerminusName(terminusName).UserZone() + if err = userOp.UpdateUser(user, []func(*iamV1alpha2.User){ + func(u *iamV1alpha2.User) { + if u.Annotations == nil { + u.Annotations = map[string]string{} + } + u.Annotations[constants.UserAnnotationZoneKey] = zone + u.Annotations[constants.UserAnnotationIsEphemeral] = "false" + u.Annotations[constants.UserTerminusWizardStatus] = string(constants.WaitResetPassword) + u.Annotations[constants.UserTerminusWizardError] = "" + }, + }); err != nil { + err = fmt.Errorf("activate system: failed to finalize local beOS setup: %v", err) + klog.Error(err) + response.HandleError(resp, err) + return + } + + response.SuccessNoData(resp) + return + } + // all settings persisted, mark the status as activating // to trigger the activation watcher if err = userOp.UpdateUser(user, []func(*iamV1alpha2.User){ diff --git a/framework/bfl/pkg/constants/constants.go b/framework/bfl/pkg/constants/constants.go index a3dd49f2a..224499225 100644 --- a/framework/bfl/pkg/constants/constants.go +++ b/framework/bfl/pkg/constants/constants.go @@ -3,6 +3,7 @@ package constants import ( "fmt" "net/url" + "os" "strings" ) @@ -75,7 +76,7 @@ var ( ) var ( - OlaresRemoteService = "https://api.olares.com" + OlaresRemoteService = "" APIPrefixCertService string @@ -105,11 +106,15 @@ var ( ) const ( + EnvBeOSSystemRemoteService = "BEOS_SYSTEM_REMOTE_SERVICE" + EnvBeOSDefaultDomain = "BEOS_DEFAULT_DOMAIN" EnvOlaresSystemRemoteService = "OLARES_SYSTEM_REMOTE_SERVICE" UserAuthorizationTokenKey = "X-Authorization" HeaderBflUserKey = "X-BFL-USER" ) +const DefaultLocalDomainName = "beos.local" + var ( AnnotationGroup = "bytetrade.io" @@ -312,6 +317,31 @@ const ( ) func ReloadEnvDependantVars() error { + remoteService := strings.TrimSpace(OlaresRemoteService) + if remoteService == "" { + if envRemote := strings.TrimSpace(os.Getenv(EnvBeOSSystemRemoteService)); envRemote != "" { + remoteService = envRemote + } else if envRemote := strings.TrimSpace(os.Getenv(EnvOlaresSystemRemoteService)); envRemote != "" { + remoteService = envRemote + } + } + OlaresRemoteService = remoteService + + if remoteService == "" { + APIPrefixCertService = "" + APIPrefixDNSOPService = "" + APIFormatCertGenerateRequest = "" + APIFormatCertGenerateStatus = "" + APIFormatCertDownload = "" + APIDNSAddRecord = "" + APIFormatDNSDeleteRecord = "" + APIDNSAddCustomDomain = "" + APIDNSCheckCustomDomainCname = "" + APIDNSSetCloudFlareTunnel = "" + APIMyExternalIP = "" + return nil + } + APIPrefixCertService, err := url.JoinPath(OlaresRemoteService, "/cert") if err != nil { return err @@ -345,6 +375,17 @@ func ReloadEnvDependantVars() error { return nil } +func HasRemoteService() bool { + return strings.TrimSpace(OlaresRemoteService) != "" +} + +func DefaultLocalDomain() string { + if domain := strings.TrimSpace(os.Getenv(EnvBeOSDefaultDomain)); domain != "" { + return domain + } + return DefaultLocalDomainName +} + func init() { ReloadEnvDependantVars() } diff --git a/framework/bfl/pkg/watchers/network_activation/network_activation.go b/framework/bfl/pkg/watchers/network_activation/network_activation.go index 9b8aeacab..a0fe02290 100644 --- a/framework/bfl/pkg/watchers/network_activation/network_activation.go +++ b/framework/bfl/pkg/watchers/network_activation/network_activation.go @@ -93,6 +93,10 @@ func (s *Subscriber) Do(ctx context.Context, obj interface{}, _ watchers.Action) return s.markFailed(ctx, current, "no terminus name found") } + if !constants.HasRemoteService() { + return s.markSuccess(ctx, current, constants.TerminusName(terminusName).UserZone()) + } + if err := s.ensureL4ProxyDeployment(ctx); err != nil { return err } diff --git a/framework/osnode-init/pkg/constants/constants.go b/framework/osnode-init/pkg/constants/constants.go index a854c1e15..32a536a64 100644 --- a/framework/osnode-init/pkg/constants/constants.go +++ b/framework/osnode-init/pkg/constants/constants.go @@ -1,3 +1,3 @@ package constants -var OlaresRemoteService = "https://api.olares.com" +var OlaresRemoteService = ""