Compare commits
61 Commits
cli/feat/s
...
module-bfl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a61c37dea1 | ||
|
|
ac03f2a13d | ||
|
|
f6eb6574d6 | ||
|
|
9113e14b7a | ||
|
|
fc62d8280a | ||
|
|
cfb74ce1d2 | ||
|
|
5639d4844b | ||
|
|
f74fcec59e | ||
|
|
ddbb13533d | ||
|
|
b65a3e3514 | ||
|
|
1f110184bd | ||
|
|
90eed09f10 | ||
|
|
44ccf86032 | ||
|
|
67425162c2 | ||
|
|
8a786c7c5a | ||
|
|
c026e82615 | ||
|
|
e29c7f264e | ||
|
|
c98c855099 | ||
|
|
4ae552f33f | ||
|
|
f2aad6d9f6 | ||
|
|
02bc4fafd5 | ||
|
|
b8d6e2f3cc | ||
|
|
763c80c5fa | ||
|
|
3091e40ff0 | ||
|
|
8d34cc995d | ||
|
|
a19e81a4a0 | ||
|
|
ee3f2a7df2 | ||
|
|
73ea65b004 | ||
|
|
4ef2e7124a | ||
|
|
ef46f91ec7 | ||
|
|
0f5a346d86 | ||
|
|
caa799e902 | ||
|
|
2be5f6d108 | ||
|
|
05f3c8ffdc | ||
|
|
c0e242b05c | ||
|
|
7929e420b1 | ||
|
|
66de213f43 | ||
|
|
2166cec66f | ||
|
|
1a0f9727c4 | ||
|
|
810253fe94 | ||
|
|
23429a6193 | ||
|
|
49e40f316f | ||
|
|
1e7b655826 | ||
|
|
adea16ce7e | ||
|
|
c2222859a5 | ||
|
|
e7dde2ff51 | ||
|
|
d06c1e8a99 | ||
|
|
131faacce0 | ||
|
|
8133704761 | ||
|
|
09e61aecad | ||
|
|
bc5fd5fd82 | ||
|
|
1367355661 | ||
|
|
30195f1513 | ||
|
|
88b140ccc2 | ||
|
|
39947f464c | ||
|
|
7440e85c2e | ||
|
|
d71747928c | ||
|
|
b20d5c0876 | ||
|
|
c4fc3198bb | ||
|
|
260b6154f3 | ||
|
|
ecfcd0d1d8 |
@@ -54,6 +54,7 @@ rules:
|
||||
- "/system/configuration/encoding"
|
||||
- "/api/search/get_directory/"
|
||||
- "/api/search/sync_search/"
|
||||
- "/api/share/smb_share_user/"
|
||||
verbs: ["*"]
|
||||
|
||||
---
|
||||
|
||||
@@ -317,7 +317,7 @@ spec:
|
||||
chown -R 1000:1000 /uploadstemp && \
|
||||
chown -R 1000:1000 /appdata
|
||||
- name: olares-app-init
|
||||
image: beclab/system-frontend:v1.7.1
|
||||
image: beclab/system-frontend:v1.8.3
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- /bin/sh
|
||||
@@ -439,7 +439,7 @@ spec:
|
||||
- name: NATS_SUBJECT_VAULT
|
||||
value: os.vault.{{ .Values.bfl.username}}
|
||||
- name: user-service
|
||||
image: beclab/user-service:v0.0.81
|
||||
image: beclab/user-service:v0.0.83
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
|
||||
@@ -12,4 +12,5 @@ rules:
|
||||
- "/task/*"
|
||||
- "/search/*"
|
||||
- "/monitorsetting/*"
|
||||
- "/file/*"
|
||||
verbs: ["*"]
|
||||
@@ -66,13 +66,7 @@ if ! command_exists tar; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ x"$KUBE_TYPE" == x"" ]]; then
|
||||
echo "the KUBE_TYPE env var is not set, defaulting to \"k3s\""
|
||||
echo ""
|
||||
export KUBE_TYPE="k3s"
|
||||
fi
|
||||
|
||||
BASE_DIR="$HOME/.olares"
|
||||
export BASE_DIR="$HOME/.olares"
|
||||
if [ ! -d $BASE_DIR ]; then
|
||||
mkdir -p $BASE_DIR
|
||||
fi
|
||||
@@ -148,10 +142,6 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
PARAMS="--version $VERSION --base-dir $BASE_DIR"
|
||||
KUBE_PARAM="--kube $KUBE_TYPE"
|
||||
CDN="--cdn-service ${cdn_url}"
|
||||
|
||||
if [[ -f $BASE_DIR/.prepared ]]; then
|
||||
echo "file $BASE_DIR/.prepared detected, skip preparing phase"
|
||||
echo ""
|
||||
@@ -162,7 +152,7 @@ else
|
||||
echo ""
|
||||
else
|
||||
echo "building local release ..."
|
||||
$sh_c "$INSTALL_OLARES_CLI release $PARAMS $CDN"
|
||||
$sh_c "$INSTALL_OLARES_CLI release"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "error: failed to build local release"
|
||||
exit 1
|
||||
@@ -171,16 +161,13 @@ else
|
||||
else
|
||||
echo "running system prechecks ..."
|
||||
echo ""
|
||||
$sh_c "$INSTALL_OLARES_CLI precheck $PARAMS"
|
||||
$sh_c "$INSTALL_OLARES_CLI precheck"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
echo "downloading installation wizard..."
|
||||
echo ""
|
||||
if [[ ! -z "$RELEASE_ID_SUFFIX" ]]; then
|
||||
DOWNLOAD_WIZARD_RELEASE_ID_PARAM="--release-id $RELEASE_ID"
|
||||
fi
|
||||
$sh_c "$INSTALL_OLARES_CLI download wizard $PARAMS $KUBE_PARAM $CDN $DOWNLOAD_WIZARD_RELEASE_ID_PARAM"
|
||||
$sh_c "$INSTALL_OLARES_CLI download wizard"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "error: failed to download installation wizard"
|
||||
exit 1
|
||||
@@ -189,7 +176,7 @@ else
|
||||
|
||||
echo "downloading installation packages..."
|
||||
echo ""
|
||||
$sh_c "$INSTALL_OLARES_CLI download component $PARAMS $KUBE_PARAM $CDN"
|
||||
$sh_c "$INSTALL_OLARES_CLI download component"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "error: failed to download installation packages"
|
||||
exit 1
|
||||
@@ -197,11 +184,7 @@ else
|
||||
|
||||
echo "preparing installation environment..."
|
||||
echo ""
|
||||
# env 'REGISTRY_MIRRORS' is a docker image cache mirrors, separated by commas
|
||||
if [ x"$REGISTRY_MIRRORS" != x"" ]; then
|
||||
extra="--registry-mirrors $REGISTRY_MIRRORS"
|
||||
fi
|
||||
$sh_c "$INSTALL_OLARES_CLI prepare $PARAMS $KUBE_PARAM $extra"
|
||||
$sh_c "$INSTALL_OLARES_CLI prepare"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "error: failed to prepare installation environment"
|
||||
exit 1
|
||||
@@ -218,38 +201,18 @@ if [ "$PREINSTALL" == "1" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "$JUICEFS" == "1" ]]; then
|
||||
echo "JuiceFS is enabled"
|
||||
fsflag="--with-juicefs=true"
|
||||
if [[ "$STORAGE" == "" ]]; then
|
||||
echo "installing MinIO ..."
|
||||
else
|
||||
echo "checking storage config ..."
|
||||
fi
|
||||
$sh_c "$INSTALL_OLARES_CLI install storage $PARAMS"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "configuring storage ..."
|
||||
$sh_c "$INSTALL_OLARES_CLI install storage"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "error: failed to configure storage"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -n "$SWAPPINESS" ]]; then
|
||||
swapflag="$swapflag --swappiness $SWAPPINESS"
|
||||
fi
|
||||
if [[ "$ENABLE_POD_SWAP" == "1" ]]; then
|
||||
swapflag="$swapflag --enable-pod-swap"
|
||||
fi
|
||||
if [[ "$ENABLE_ZRAM" == "1" ]]; then
|
||||
swapflag="$swapflag --enable-zram"
|
||||
fi
|
||||
if [[ -n "$ZRAM_SIZE" ]]; then
|
||||
swapflag="$swapflag --zram-size $ZRAM_SIZE"
|
||||
fi
|
||||
if [[ -n "$ZRAM_SWAP_PRIORITY" ]]; then
|
||||
swapflag="$swapflag --zram-swap-priority $ZRAM_SWAP_PRIORITY"
|
||||
fi
|
||||
|
||||
echo "installing Olares..."
|
||||
echo ""
|
||||
$sh_c "$INSTALL_OLARES_CLI install $PARAMS $KUBE_PARAM $fsflag $swapflag"
|
||||
$sh_c "$INSTALL_OLARES_CLI install"
|
||||
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "error: failed to install Olares"
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
type Addon struct {
|
||||
Name string `yaml:"name" json:"name,omitempty"`
|
||||
Namespace string `yaml:"namespace" json:"namespace,omitempty"`
|
||||
Sources Sources `yaml:"sources" json:"sources,omitempty"`
|
||||
Retries int `yaml:"retries" json:"retries,omitempty"`
|
||||
Delay int `yaml:"delay" json:"delay,omitempty"`
|
||||
}
|
||||
|
||||
type Sources struct {
|
||||
Chart Chart `yaml:"chart" json:"chart,omitempty"`
|
||||
Yaml Yaml `yaml:"yaml" json:"yaml,omitempty"`
|
||||
}
|
||||
|
||||
type Chart struct {
|
||||
Name string `yaml:"name" json:"name,omitempty"`
|
||||
Repo string `yaml:"repo" json:"repo,omitempty"`
|
||||
Path string `yaml:"path" json:"path,omitempty"`
|
||||
Version string `yaml:"version" json:"version,omitempty"`
|
||||
ValuesFile string `yaml:"valuesFile" json:"valuesFile,omitempty"`
|
||||
Values []string `yaml:"values" json:"values,omitempty"`
|
||||
}
|
||||
|
||||
type Yaml struct {
|
||||
Path []string `yaml:"path" json:"path,omitempty"`
|
||||
}
|
||||
@@ -1,403 +0,0 @@
|
||||
/*
|
||||
Copyright 2021.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/core/util"
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
|
||||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
|
||||
|
||||
// ClusterSpec defines the desired state of Cluster
|
||||
type ClusterSpec struct {
|
||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
|
||||
// Foo is an example field of Cluster. Edit Cluster_types.go to remove/update
|
||||
Hosts []HostCfg `yaml:"hosts" json:"hosts,omitempty"`
|
||||
RoleGroups RoleGroups `yaml:"roleGroups" json:"roleGroups,omitempty"`
|
||||
ControlPlaneEndpoint ControlPlaneEndpoint `yaml:"controlPlaneEndpoint" json:"controlPlaneEndpoint,omitempty"`
|
||||
Kubernetes Kubernetes `yaml:"kubernetes" json:"kubernetes,omitempty"`
|
||||
Network NetworkConfig `yaml:"network" json:"network,omitempty"`
|
||||
Registry RegistryConfig `yaml:"registry" json:"registry,omitempty"`
|
||||
Addons []Addon `yaml:"addons" json:"addons,omitempty"`
|
||||
KubeSphere KubeSphere `json:"kubesphere,omitempty"`
|
||||
}
|
||||
|
||||
// ClusterStatus defines the observed state of Cluster
|
||||
type ClusterStatus struct {
|
||||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
|
||||
JobInfo JobInfo `json:"jobInfo,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
NetworkPlugin string `json:"networkPlugin,omitempty"`
|
||||
NodesCount int `json:"nodesCount,omitempty"`
|
||||
EtcdCount int `json:"etcdCount,omitempty"`
|
||||
MasterCount int `json:"masterCount,omitempty"`
|
||||
WorkerCount int `json:"workerCount,omitempty"`
|
||||
Nodes []NodeStatus `json:"nodes,omitempty"`
|
||||
Conditions []Condition `json:"Conditions,omitempty"`
|
||||
}
|
||||
|
||||
// JobInfo defines the job information to be used to create a cluster or add a node.
|
||||
type JobInfo struct {
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Pods []PodInfo `json:"pods,omitempty"`
|
||||
}
|
||||
|
||||
// PodInfo defines the pod information to be used to create a cluster or add a node.
|
||||
type PodInfo struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Containers []ContainerInfo `json:"containers,omitempty"`
|
||||
}
|
||||
|
||||
// ContainerInfo defines the container information to be used to create a cluster or add a node.
|
||||
type ContainerInfo struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// NodeStatus defines the status information of the nodes in the cluster.
|
||||
type NodeStatus struct {
|
||||
InternalIP string `json:"internalIP,omitempty"`
|
||||
Hostname string `json:"hostname,omitempty"`
|
||||
Roles map[string]bool `json:"roles,omitempty"`
|
||||
}
|
||||
|
||||
// Condition defines the process information.
|
||||
type Condition struct {
|
||||
Step string `json:"step,omitempty"`
|
||||
StartTime metav1.Time `json:"startTime,omitempty"`
|
||||
EndTime metav1.Time `json:"endTime,omitempty"`
|
||||
Status bool `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
|
||||
// Cluster is the Schema for the clusters API
|
||||
// +kubebuilder:resource:path=clusters,scope=Cluster
|
||||
type Cluster struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ClusterSpec `json:"spec,omitempty"`
|
||||
Status ClusterStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// ClusterList contains a list of Cluster
|
||||
type ClusterList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Cluster `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Cluster{}, &ClusterList{})
|
||||
}
|
||||
|
||||
// HostCfg defines host information for cluster.
|
||||
type HostCfg struct {
|
||||
Name string `yaml:"name,omitempty" json:"name,omitempty"`
|
||||
Address string `yaml:"address,omitempty" json:"address,omitempty"`
|
||||
InternalAddress string `yaml:"internalAddress,omitempty" json:"internalAddress,omitempty"`
|
||||
Port int `yaml:"port,omitempty" json:"port,omitempty"`
|
||||
User string `yaml:"user,omitempty" json:"user,omitempty"`
|
||||
Password string `yaml:"password,omitempty" json:"password,omitempty"`
|
||||
PrivateKey string `yaml:"privateKey,omitempty" json:"privateKey,omitempty"`
|
||||
PrivateKeyPath string `yaml:"privateKeyPath,omitempty" json:"privateKeyPath,omitempty"`
|
||||
Arch string `yaml:"arch,omitempty" json:"arch,omitempty"`
|
||||
|
||||
Labels map[string]string `yaml:"labels,omitempty" json:"labels,omitempty"`
|
||||
ID string `yaml:"id,omitempty" json:"id,omitempty"`
|
||||
Index int `json:"-"`
|
||||
IsEtcd bool `json:"-"`
|
||||
IsMaster bool `json:"-"`
|
||||
IsWorker bool `json:"-"`
|
||||
|
||||
EtcdExist bool `json:"-"`
|
||||
EtcdName string `json:"-"`
|
||||
}
|
||||
|
||||
// RoleGroups defines the grouping of role for hosts (etcd / master / worker).
|
||||
type RoleGroups struct {
|
||||
Etcd []string `yaml:"etcd" json:"etcd,omitempty"`
|
||||
Master []string `yaml:"master" json:"master,omitempty"`
|
||||
Worker []string `yaml:"worker" json:"worker,omitempty"`
|
||||
}
|
||||
|
||||
// HostGroups defines the grouping of hosts for cluster (all / etcd / master / worker / k8s).
|
||||
type HostGroups struct {
|
||||
All []HostCfg
|
||||
Etcd []HostCfg
|
||||
Master []HostCfg
|
||||
Worker []HostCfg
|
||||
K8s []HostCfg
|
||||
}
|
||||
|
||||
// ControlPlaneEndpoint defines the control plane endpoint information for cluster.
|
||||
type ControlPlaneEndpoint struct {
|
||||
InternalLoadbalancer string `yaml:"internalLoadbalancer" json:"internalLoadbalancer,omitempty"`
|
||||
Domain string `yaml:"domain" json:"domain,omitempty"`
|
||||
Address string `yaml:"address" json:"address,omitempty"`
|
||||
Port int `yaml:"port" json:"port,omitempty"`
|
||||
}
|
||||
|
||||
// RegistryConfig defines the configuration information of the image's repository.
|
||||
type RegistryConfig struct {
|
||||
RegistryMirrors []string `yaml:"registryMirrors" json:"registryMirrors,omitempty"`
|
||||
InsecureRegistries []string `yaml:"insecureRegistries" json:"insecureRegistries,omitempty"`
|
||||
PrivateRegistry string `yaml:"privateRegistry" json:"privateRegistry,omitempty"`
|
||||
}
|
||||
|
||||
// KubeSphere defines the configuration information of the KubeSphere.
|
||||
type KubeSphere struct {
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
Configurations string `json:"configurations,omitempty"`
|
||||
}
|
||||
|
||||
// ExternalEtcd defines configuration information of external etcd.
|
||||
type ExternalEtcd struct {
|
||||
Endpoints []string
|
||||
CaFile string
|
||||
CertFile string
|
||||
KeyFile string
|
||||
}
|
||||
|
||||
// Copy is used to create a copy for Runtime.
|
||||
func (h *HostCfg) Copy() *HostCfg {
|
||||
host := *h
|
||||
return &host
|
||||
}
|
||||
|
||||
// GenerateCertSANs is used to generate cert sans for cluster.
|
||||
func (cfg *ClusterSpec) GenerateCertSANs() []string {
|
||||
clusterSvc := fmt.Sprintf("kubernetes.default.svc.%s", cfg.Kubernetes.ClusterName)
|
||||
defaultCertSANs := []string{"kubernetes", "kubernetes.default", "kubernetes.default.svc", clusterSvc, "localhost", "127.0.0.1"}
|
||||
extraCertSANs := []string{}
|
||||
|
||||
extraCertSANs = append(extraCertSANs, cfg.ControlPlaneEndpoint.Domain)
|
||||
extraCertSANs = append(extraCertSANs, cfg.ControlPlaneEndpoint.Address)
|
||||
|
||||
for _, host := range cfg.Hosts {
|
||||
extraCertSANs = append(extraCertSANs, host.Name)
|
||||
extraCertSANs = append(extraCertSANs, fmt.Sprintf("%s.%s", host.Name, cfg.Kubernetes.ClusterName))
|
||||
if host.Address != cfg.ControlPlaneEndpoint.Address {
|
||||
extraCertSANs = append(extraCertSANs, host.Address)
|
||||
}
|
||||
if host.InternalAddress != host.Address && host.InternalAddress != cfg.ControlPlaneEndpoint.Address {
|
||||
extraCertSANs = append(extraCertSANs, host.InternalAddress)
|
||||
}
|
||||
}
|
||||
|
||||
extraCertSANs = append(extraCertSANs, util.ParseIp(cfg.Network.KubeServiceCIDR)[0])
|
||||
|
||||
defaultCertSANs = append(defaultCertSANs, extraCertSANs...)
|
||||
|
||||
if cfg.Kubernetes.ApiserverCertExtraSans != nil {
|
||||
defaultCertSANs = append(defaultCertSANs, cfg.Kubernetes.ApiserverCertExtraSans...)
|
||||
}
|
||||
|
||||
return defaultCertSANs
|
||||
}
|
||||
|
||||
// GroupHosts is used to group hosts according to the configuration file.s
|
||||
func (cfg *ClusterSpec) GroupHosts() (*HostGroups, error) {
|
||||
clusterHostsGroups := HostGroups{}
|
||||
|
||||
hostList := map[string]string{}
|
||||
for _, host := range cfg.Hosts {
|
||||
hostList[host.Name] = host.Name
|
||||
}
|
||||
|
||||
etcdGroup, masterGroup, workerGroup, err := cfg.ParseRolesList(hostList)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for index, host := range cfg.Hosts {
|
||||
host.Index = index
|
||||
if len(etcdGroup) > 0 {
|
||||
for _, hostName := range etcdGroup {
|
||||
if host.Name == hostName {
|
||||
host.IsEtcd = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(masterGroup) > 0 {
|
||||
for _, hostName := range masterGroup {
|
||||
if host.Name == hostName {
|
||||
host.IsMaster = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(workerGroup) > 0 {
|
||||
for _, hostName := range workerGroup {
|
||||
if hostName != "" && host.Name == hostName {
|
||||
host.IsWorker = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if host.IsEtcd {
|
||||
clusterHostsGroups.Etcd = append(clusterHostsGroups.Etcd, host)
|
||||
}
|
||||
if host.IsMaster {
|
||||
clusterHostsGroups.Master = append(clusterHostsGroups.Master, host)
|
||||
}
|
||||
if host.IsWorker {
|
||||
clusterHostsGroups.Worker = append(clusterHostsGroups.Worker, host)
|
||||
}
|
||||
if host.IsMaster || host.IsWorker {
|
||||
clusterHostsGroups.K8s = append(clusterHostsGroups.K8s, host)
|
||||
}
|
||||
clusterHostsGroups.All = append(clusterHostsGroups.All, host)
|
||||
}
|
||||
|
||||
//Check that the parameters under roleGroups are incorrect
|
||||
if len(masterGroup) == 0 {
|
||||
logger.Fatal(errors.New("The number of master cannot be 0"))
|
||||
}
|
||||
if len(etcdGroup) == 0 {
|
||||
logger.Fatal(errors.New("The number of etcd cannot be 0"))
|
||||
}
|
||||
|
||||
if len(masterGroup) != len(clusterHostsGroups.Master) {
|
||||
return nil, errors.New("Incorrect nodeName under roleGroups/master in the configuration file")
|
||||
}
|
||||
if len(etcdGroup) != len(clusterHostsGroups.Etcd) {
|
||||
return nil, errors.New("Incorrect nodeName under roleGroups/etcd in the configuration file")
|
||||
}
|
||||
if len(workerGroup) != len(clusterHostsGroups.Worker) {
|
||||
return nil, errors.New("Incorrect nodeName under roleGroups/work in the configuration file")
|
||||
}
|
||||
|
||||
return &clusterHostsGroups, nil
|
||||
}
|
||||
|
||||
// ClusterIP is used to get the kube-apiserver service address inside the cluster.
|
||||
func (cfg *ClusterSpec) ClusterIP() string {
|
||||
return util.ParseIp(cfg.Network.KubeServiceCIDR)[0]
|
||||
}
|
||||
|
||||
// CorednsClusterIP is used to get the coredns service address inside the cluster.
|
||||
func (cfg *ClusterSpec) CorednsClusterIP() string {
|
||||
return util.ParseIp(cfg.Network.KubeServiceCIDR)[2]
|
||||
}
|
||||
|
||||
// ClusterDNS is used to get the dns server address inside the cluster.
|
||||
func (cfg *ClusterSpec) ClusterDNS() string {
|
||||
if cfg.Kubernetes.EnableNodelocaldns() {
|
||||
return "169.254.25.10"
|
||||
}
|
||||
return cfg.CorednsClusterIP()
|
||||
}
|
||||
|
||||
// ParseRolesList is used to parse the host grouping list.
|
||||
func (cfg *ClusterSpec) ParseRolesList(hostList map[string]string) ([]string, []string, []string, error) {
|
||||
etcdGroupList := []string{}
|
||||
masterGroupList := []string{}
|
||||
workerGroupList := []string{}
|
||||
|
||||
for _, host := range cfg.RoleGroups.Etcd {
|
||||
if strings.Contains(host, "[") && strings.Contains(host, "]") && strings.Contains(host, ":") {
|
||||
etcdGroupList = append(etcdGroupList, getHostsRange(host, hostList, "etcd")...)
|
||||
} else {
|
||||
if err := hostVerify(hostList, host, "etcd"); err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
etcdGroupList = append(etcdGroupList, host)
|
||||
}
|
||||
}
|
||||
|
||||
for _, host := range cfg.RoleGroups.Master {
|
||||
if strings.Contains(host, "[") && strings.Contains(host, "]") && strings.Contains(host, ":") {
|
||||
masterGroupList = append(masterGroupList, getHostsRange(host, hostList, "master")...)
|
||||
} else {
|
||||
if err := hostVerify(hostList, host, "master"); err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
masterGroupList = append(masterGroupList, host)
|
||||
}
|
||||
}
|
||||
|
||||
for _, host := range cfg.RoleGroups.Worker {
|
||||
if strings.Contains(host, "[") && strings.Contains(host, "]") && strings.Contains(host, ":") {
|
||||
workerGroupList = append(workerGroupList, getHostsRange(host, hostList, "worker")...)
|
||||
} else {
|
||||
if err := hostVerify(hostList, host, "worker"); err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
workerGroupList = append(workerGroupList, host)
|
||||
}
|
||||
}
|
||||
return etcdGroupList, masterGroupList, workerGroupList, nil
|
||||
}
|
||||
|
||||
func getHostsRange(rangeStr string, hostList map[string]string, group string) []string {
|
||||
hostRangeList := []string{}
|
||||
r := regexp.MustCompile(`\[(\d+)\:(\d+)\]`)
|
||||
nameSuffix := r.FindStringSubmatch(rangeStr)
|
||||
namePrefix := strings.Split(rangeStr, nameSuffix[0])[0]
|
||||
nameSuffixStart, _ := strconv.Atoi(nameSuffix[1])
|
||||
nameSuffixEnd, _ := strconv.Atoi(nameSuffix[2])
|
||||
for i := nameSuffixStart; i <= nameSuffixEnd; i++ {
|
||||
if err := hostVerify(hostList, fmt.Sprintf("%s%d", namePrefix, i), group); err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
hostRangeList = append(hostRangeList, fmt.Sprintf("%s%d", namePrefix, i))
|
||||
}
|
||||
return hostRangeList
|
||||
}
|
||||
|
||||
func hostVerify(hostList map[string]string, hostName string, group string) error {
|
||||
if _, ok := hostList[hostName]; !ok {
|
||||
return fmt.Errorf("[%s] is in [%s] group, but not in hosts list", hostName, group)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
Haproxy = "haproxy"
|
||||
)
|
||||
|
||||
func (c ControlPlaneEndpoint) IsInternalLBEnabled() bool {
|
||||
if c.InternalLoadbalancer == Haproxy {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -1,276 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/core/util"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultPreDir = "kubekey"
|
||||
DefaultTmpDir = "/tmp/kubekey"
|
||||
DefaultSSHPort = 22
|
||||
DefaultLBPort = 6443
|
||||
DefaultLBDomain = "lb.kubesphere.local"
|
||||
DefaultNetworkPlugin = "calico"
|
||||
DefaultPodsCIDR = "10.233.64.0/18"
|
||||
DefaultServiceCIDR = "10.233.0.0/18"
|
||||
DefaultKubeImageNamespace = "kubesphere"
|
||||
DefaultClusterName = "cluster.local"
|
||||
DefaultArch = "amd64"
|
||||
DefaultEtcdVersion = "v3.4.13"
|
||||
DefaultEtcdPort = "2379"
|
||||
DefaultDockerVersion = "20.10.8"
|
||||
DefaultCrictlVersion = "v1.22.0"
|
||||
DefaultKubeVersion = "v1.21.5"
|
||||
DefaultCalicoVersion = "v3.20.0"
|
||||
DefaultFlannelVersion = "v0.12.0"
|
||||
DefaultCniVersion = "v0.9.1"
|
||||
DefaultCiliumVersion = "v1.8.3"
|
||||
DefaultKubeovnVersion = "v1.5.0"
|
||||
DefaultHelmVersion = "v3.6.3"
|
||||
DefaultMaxPods = 200
|
||||
DefaultNodeCidrMaskSize = 24
|
||||
DefaultIPIPMode = "Always"
|
||||
DefaultVXLANMode = "Never"
|
||||
DefaultVethMTU = 1440
|
||||
DefaultBackendMode = "vxlan"
|
||||
DefaultProxyMode = "ipvs"
|
||||
DefaultCrioEndpoint = "unix:///var/run/crio/crio.sock"
|
||||
DefaultContainerdEndpoint = "unix:///run/containerd/containerd.sock"
|
||||
DefaultIsulaEndpoint = "unix:///var/run/isulad.sock"
|
||||
Etcd = "etcd"
|
||||
Master = "master"
|
||||
Worker = "worker"
|
||||
K8s = "k8s"
|
||||
DefaultEtcdBackupDir = "/var/backups/kube_etcd"
|
||||
DefaultEtcdBackupPeriod = 30
|
||||
DefaultKeepBackNumber = 5
|
||||
DefaultEtcdBackupScriptDir = "/usr/local/bin/kube-scripts"
|
||||
DefaultJoinCIDR = "100.64.0.0/16"
|
||||
DefaultNetworkType = "geneve"
|
||||
DefaultVlanID = "100"
|
||||
DefaultOvnLabel = "node-role.kubernetes.io/control-plane"
|
||||
DefaultDPDKVersion = "19.11"
|
||||
DefaultDNSAddress = "114.114.114.114"
|
||||
|
||||
Docker = "docker"
|
||||
Containerd = "containerd"
|
||||
Crio = "crio"
|
||||
Isula = "isula"
|
||||
)
|
||||
|
||||
func (cfg *ClusterSpec) SetDefaultClusterSpec(incluster bool) (*ClusterSpec, *HostGroups, error) {
|
||||
clusterCfg := ClusterSpec{}
|
||||
|
||||
clusterCfg.Hosts = SetDefaultHostsCfg(cfg)
|
||||
clusterCfg.RoleGroups = cfg.RoleGroups
|
||||
hostGroups, err := clusterCfg.GroupHosts()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
clusterCfg.ControlPlaneEndpoint = SetDefaultLBCfg(cfg, hostGroups.Master, incluster)
|
||||
clusterCfg.Network = SetDefaultNetworkCfg(cfg)
|
||||
clusterCfg.Kubernetes = SetDefaultClusterCfg(cfg)
|
||||
clusterCfg.Registry = cfg.Registry
|
||||
clusterCfg.Addons = cfg.Addons
|
||||
clusterCfg.KubeSphere = cfg.KubeSphere
|
||||
|
||||
if cfg.Kubernetes.ClusterName == "" {
|
||||
clusterCfg.Kubernetes.ClusterName = DefaultClusterName
|
||||
}
|
||||
if cfg.Kubernetes.Version == "" {
|
||||
clusterCfg.Kubernetes.Version = DefaultKubeVersion
|
||||
}
|
||||
if cfg.Kubernetes.MaxPods == 0 {
|
||||
clusterCfg.Kubernetes.MaxPods = DefaultMaxPods
|
||||
}
|
||||
if cfg.Kubernetes.NodeCidrMaskSize == 0 {
|
||||
clusterCfg.Kubernetes.NodeCidrMaskSize = DefaultNodeCidrMaskSize
|
||||
}
|
||||
if cfg.Kubernetes.ProxyMode == "" {
|
||||
clusterCfg.Kubernetes.ProxyMode = DefaultProxyMode
|
||||
}
|
||||
return &clusterCfg, hostGroups, nil
|
||||
}
|
||||
|
||||
func SetDefaultHostsCfg(cfg *ClusterSpec) []HostCfg {
|
||||
var hostscfg []HostCfg
|
||||
if len(cfg.Hosts) == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, host := range cfg.Hosts {
|
||||
if len(host.Address) == 0 && len(host.InternalAddress) > 0 {
|
||||
host.Address = host.InternalAddress
|
||||
}
|
||||
if len(host.InternalAddress) == 0 && len(host.Address) > 0 {
|
||||
host.InternalAddress = host.Address
|
||||
}
|
||||
if host.User == "" {
|
||||
host.User = "root"
|
||||
}
|
||||
if host.Port == 0 {
|
||||
host.Port = DefaultSSHPort
|
||||
}
|
||||
if host.PrivateKey == "" {
|
||||
if host.Password == "" && host.PrivateKeyPath == "" {
|
||||
host.PrivateKeyPath = "~/.ssh/id_rsa"
|
||||
}
|
||||
if host.PrivateKeyPath != "" && strings.HasPrefix(strings.TrimSpace(host.PrivateKeyPath), "~/") {
|
||||
homeDir, _ := util.Home()
|
||||
host.PrivateKeyPath = strings.Replace(host.PrivateKeyPath, "~/", fmt.Sprintf("%s/", homeDir), 1)
|
||||
}
|
||||
}
|
||||
|
||||
if host.Arch == "" {
|
||||
host.Arch = DefaultArch
|
||||
}
|
||||
hostscfg = append(hostscfg, host)
|
||||
}
|
||||
return hostscfg
|
||||
}
|
||||
|
||||
func SetDefaultLBCfg(cfg *ClusterSpec, masterGroup []HostCfg, incluster bool) ControlPlaneEndpoint {
|
||||
if !incluster {
|
||||
//The detection is not an HA environment, and the address at LB does not need input
|
||||
if len(masterGroup) == 1 && cfg.ControlPlaneEndpoint.Address != "" {
|
||||
fmt.Println("When the environment is not HA, the LB address does not need to be entered, so delete the corresponding value.")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
//Check whether LB should be configured
|
||||
if len(masterGroup) >= 3 && !cfg.ControlPlaneEndpoint.IsInternalLBEnabled() && cfg.ControlPlaneEndpoint.Address == "" {
|
||||
fmt.Println("When the environment has at least three masters, You must set the value of the LB address or enable the internal loadbalancer.")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// Check whether LB address and the internal LB are both enabled
|
||||
if cfg.ControlPlaneEndpoint.IsInternalLBEnabled() && cfg.ControlPlaneEndpoint.Address != "" {
|
||||
fmt.Println("You cannot set up the internal load balancer and the LB address at the same time.")
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
if cfg.ControlPlaneEndpoint.Address == "" || cfg.ControlPlaneEndpoint.Address == "127.0.0.1" {
|
||||
cfg.ControlPlaneEndpoint.Address = masterGroup[0].InternalAddress
|
||||
}
|
||||
if cfg.ControlPlaneEndpoint.Domain == "" {
|
||||
cfg.ControlPlaneEndpoint.Domain = DefaultLBDomain
|
||||
}
|
||||
if cfg.ControlPlaneEndpoint.Port == 0 {
|
||||
cfg.ControlPlaneEndpoint.Port = DefaultLBPort
|
||||
}
|
||||
defaultLbCfg := cfg.ControlPlaneEndpoint
|
||||
return defaultLbCfg
|
||||
}
|
||||
|
||||
func SetDefaultNetworkCfg(cfg *ClusterSpec) NetworkConfig {
|
||||
if cfg.Network.Plugin == "" {
|
||||
cfg.Network.Plugin = DefaultNetworkPlugin
|
||||
}
|
||||
if cfg.Network.KubePodsCIDR == "" {
|
||||
cfg.Network.KubePodsCIDR = DefaultPodsCIDR
|
||||
}
|
||||
if cfg.Network.KubeServiceCIDR == "" {
|
||||
cfg.Network.KubeServiceCIDR = DefaultServiceCIDR
|
||||
}
|
||||
if cfg.Network.Calico.IPIPMode == "" {
|
||||
cfg.Network.Calico.IPIPMode = DefaultIPIPMode
|
||||
}
|
||||
if cfg.Network.Calico.VXLANMode == "" {
|
||||
cfg.Network.Calico.VXLANMode = DefaultVXLANMode
|
||||
}
|
||||
if cfg.Network.Calico.VethMTU == 0 {
|
||||
cfg.Network.Calico.VethMTU = DefaultVethMTU
|
||||
}
|
||||
if cfg.Network.Flannel.BackendMode == "" {
|
||||
cfg.Network.Flannel.BackendMode = DefaultBackendMode
|
||||
}
|
||||
// kube-ovn default config
|
||||
if cfg.Network.Kubeovn.JoinCIDR == "" {
|
||||
cfg.Network.Kubeovn.JoinCIDR = DefaultJoinCIDR
|
||||
}
|
||||
if cfg.Network.Kubeovn.Label == "" {
|
||||
cfg.Network.Kubeovn.Label = DefaultOvnLabel
|
||||
}
|
||||
if cfg.Network.Kubeovn.VlanID == "" {
|
||||
cfg.Network.Kubeovn.VlanID = DefaultVlanID
|
||||
}
|
||||
if cfg.Network.Kubeovn.NetworkType == "" {
|
||||
cfg.Network.Kubeovn.NetworkType = DefaultNetworkType
|
||||
}
|
||||
if cfg.Network.Kubeovn.PingerExternalAddress == "" {
|
||||
cfg.Network.Kubeovn.PingerExternalAddress = DefaultDNSAddress
|
||||
}
|
||||
if cfg.Network.Kubeovn.DpdkVersion == "" {
|
||||
cfg.Network.Kubeovn.DpdkVersion = DefaultDPDKVersion
|
||||
}
|
||||
defaultNetworkCfg := cfg.Network
|
||||
|
||||
return defaultNetworkCfg
|
||||
}
|
||||
|
||||
func SetDefaultClusterCfg(cfg *ClusterSpec) Kubernetes {
|
||||
if cfg.Kubernetes.Version == "" {
|
||||
cfg.Kubernetes.Version = DefaultKubeVersion
|
||||
} else {
|
||||
s := strings.Split(cfg.Kubernetes.Version, "-")
|
||||
if len(s) > 1 {
|
||||
cfg.Kubernetes.Version = s[0]
|
||||
cfg.Kubernetes.Type = s[1]
|
||||
}
|
||||
}
|
||||
if cfg.Kubernetes.ClusterName == "" {
|
||||
cfg.Kubernetes.ClusterName = DefaultClusterName
|
||||
}
|
||||
if cfg.Kubernetes.EtcdBackupDir == "" {
|
||||
cfg.Kubernetes.EtcdBackupDir = DefaultEtcdBackupDir
|
||||
}
|
||||
if cfg.Kubernetes.EtcdBackupPeriod == 0 {
|
||||
cfg.Kubernetes.EtcdBackupPeriod = DefaultEtcdBackupPeriod
|
||||
}
|
||||
if cfg.Kubernetes.KeepBackupNumber == 0 {
|
||||
cfg.Kubernetes.KeepBackupNumber = DefaultKeepBackNumber
|
||||
}
|
||||
if cfg.Kubernetes.EtcdBackupScriptDir == "" {
|
||||
cfg.Kubernetes.EtcdBackupScriptDir = DefaultEtcdBackupScriptDir
|
||||
}
|
||||
if cfg.Kubernetes.ContainerManager == "" {
|
||||
cfg.Kubernetes.ContainerManager = Docker
|
||||
}
|
||||
if cfg.Kubernetes.ContainerRuntimeEndpoint == "" {
|
||||
switch cfg.Kubernetes.ContainerManager {
|
||||
case Docker:
|
||||
cfg.Kubernetes.ContainerRuntimeEndpoint = ""
|
||||
case Crio:
|
||||
cfg.Kubernetes.ContainerRuntimeEndpoint = DefaultCrioEndpoint
|
||||
case Containerd:
|
||||
cfg.Kubernetes.ContainerRuntimeEndpoint = DefaultContainerdEndpoint
|
||||
case Isula:
|
||||
cfg.Kubernetes.ContainerRuntimeEndpoint = DefaultIsulaEndpoint
|
||||
default:
|
||||
cfg.Kubernetes.ContainerRuntimeEndpoint = ""
|
||||
}
|
||||
}
|
||||
defaultClusterCfg := cfg.Kubernetes
|
||||
|
||||
return defaultClusterCfg
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
Copyright 2021.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package v1alpha1 contains API Schema definitions for the kubekey v1alpha1 API group
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=kubekey.kubesphere.io
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
)
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = GroupVersion
|
||||
|
||||
var (
|
||||
// GroupVersion is group version used to register these objects
|
||||
GroupVersion = schema.GroupVersion{Group: "kubekey.kubesphere.io", Version: "v1alpha1"}
|
||||
|
||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
|
||||
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
|
||||
|
||||
// AddToScheme adds the types in this group-version to the given scheme.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return GroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import "k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
type Kubernetes struct {
|
||||
Type string `yaml:"type" json:"type,omitempty"`
|
||||
Version string `yaml:"version" json:"version,omitempty"`
|
||||
ClusterName string `yaml:"clusterName" json:"clusterName,omitempty"`
|
||||
MasqueradeAll bool `yaml:"masqueradeAll" json:"masqueradeAll,omitempty"`
|
||||
MaxPods int `yaml:"maxPods" json:"maxPods,omitempty"`
|
||||
NodeCidrMaskSize int `yaml:"nodeCidrMaskSize" json:"nodeCidrMaskSize,omitempty"`
|
||||
ApiserverCertExtraSans []string `yaml:"apiserverCertExtraSans" json:"apiserverCertExtraSans,omitempty"`
|
||||
ProxyMode string `yaml:"proxyMode" json:"proxyMode,omitempty"`
|
||||
// +optional
|
||||
Nodelocaldns *bool `yaml:"nodelocaldns" json:"nodelocaldns,omitempty"`
|
||||
EtcdBackupDir string `yaml:"etcdBackupDir" json:"etcdBackupDir,omitempty"`
|
||||
EtcdBackupPeriod int `yaml:"etcdBackupPeriod" json:"etcdBackupPeriod,omitempty"`
|
||||
KeepBackupNumber int `yaml:"keepBackupNumber" json:"keepBackupNumber,omitempty"`
|
||||
EtcdBackupScriptDir string `yaml:"etcdBackupScript" json:"etcdBackupScript,omitempty"`
|
||||
ContainerManager string `yaml:"containerManager" json:"containerManager,omitempty"`
|
||||
ContainerRuntimeEndpoint string `yaml:"containerRuntimeEndpoint" json:"containerRuntimeEndpoint,omitempty"`
|
||||
ApiServerArgs []string `yaml:"apiserverArgs" json:"apiserverArgs,omitempty"`
|
||||
ControllerManagerArgs []string `yaml:"controllerManagerArgs" json:"controllerManagerArgs,omitempty"`
|
||||
SchedulerArgs []string `yaml:"schedulerArgs" json:"schedulerArgs,omitempty"`
|
||||
KubeletArgs []string `yaml:"kubeletArgs" json:"kubeletArgs,omitempty"`
|
||||
KubeProxyArgs []string `yaml:"kubeProxyArgs" json:"kubeProxyArgs,omitempty"`
|
||||
KubeletConfiguration runtime.RawExtension `yaml:"kubeletConfiguration" json:"kubeletConfiguration,omitempty"`
|
||||
KubeProxyConfiguration runtime.RawExtension `yaml:"kubeProxyConfiguration" json:"kubeProxyConfiguration,omitempty"`
|
||||
}
|
||||
|
||||
// EnableNodelocaldns is used to determine whether to deploy nodelocaldns.
|
||||
func (k *Kubernetes) EnableNodelocaldns() bool {
|
||||
if k.Nodelocaldns == nil {
|
||||
return true
|
||||
}
|
||||
return *k.Nodelocaldns
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
type NetworkConfig struct {
|
||||
Plugin string `yaml:"plugin" json:"plugin,omitempty"`
|
||||
KubePodsCIDR string `yaml:"kubePodsCIDR" json:"kubePodsCIDR,omitempty"`
|
||||
KubeServiceCIDR string `yaml:"kubeServiceCIDR" json:"kubeServiceCIDR,omitempty"`
|
||||
Calico CalicoCfg `yaml:"calico" json:"calico,omitempty"`
|
||||
Flannel FlannelCfg `yaml:"flannel" json:"flannel,omitempty"`
|
||||
Kubeovn KubeovnCfg `yaml:"kubeovn" json:"kubeovn,omitempty"`
|
||||
}
|
||||
|
||||
type CalicoCfg struct {
|
||||
IPIPMode string `yaml:"ipipMode" json:"ipipMode,omitempty"`
|
||||
VXLANMode string `yaml:"vxlanMode" json:"vxlanMode,omitempty"`
|
||||
VethMTU int `yaml:"vethMTU" json:"vethMTU,omitempty"`
|
||||
}
|
||||
|
||||
type FlannelCfg struct {
|
||||
BackendMode string `yaml:"backendMode" json:"backendMode,omitempty"`
|
||||
Directrouting bool `yaml:"directRouting" json:"directRouting,omitempty"`
|
||||
}
|
||||
|
||||
type KubeovnCfg struct {
|
||||
JoinCIDR string `yaml:"joinCIDR" json:"joinCIDR,omitempty"`
|
||||
NetworkType string `yaml:"networkType" json:"networkType,omitempty"`
|
||||
Label string `yaml:"label" json:"label,omitempty"`
|
||||
Iface string `yaml:"iface" json:"iface,omitempty"`
|
||||
VlanInterfaceName string `yaml:"vlanInterfaceName" json:"vlanInterfaceName,omitempty"`
|
||||
VlanID string `yaml:"vlanID" json:"vlanID,omitempty"`
|
||||
DpdkMode bool `yaml:"dpdkMode" json:"dpdkMode,omitempty"`
|
||||
EnableSSL bool `yaml:"enableSSL" json:"enableSSL,omitempty"`
|
||||
EnableMirror bool `yaml:"enableMirror" json:"enableMirror,omitempty"`
|
||||
HwOffload bool `yaml:"hwOffload" json:"hwOffload,omitempty"`
|
||||
DpdkVersion string `yaml:"dpdkVersion" json:"dpdkVersion,omitempty"`
|
||||
PingerExternalAddress string `yaml:"pingerExternalAddress" json:"pingerExternalAddress,omitempty"`
|
||||
PingerExternalDomain string `yaml:"pingerExternalDomain" json:"pingerExternalDomain,omitempty"`
|
||||
}
|
||||
@@ -1,611 +0,0 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by controller-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Addon) DeepCopyInto(out *Addon) {
|
||||
*out = *in
|
||||
in.Sources.DeepCopyInto(&out.Sources)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Addon.
|
||||
func (in *Addon) DeepCopy() *Addon {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Addon)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CalicoCfg) DeepCopyInto(out *CalicoCfg) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CalicoCfg.
|
||||
func (in *CalicoCfg) DeepCopy() *CalicoCfg {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CalicoCfg)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Chart) DeepCopyInto(out *Chart) {
|
||||
*out = *in
|
||||
if in.Values != nil {
|
||||
in, out := &in.Values, &out.Values
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Chart.
|
||||
func (in *Chart) DeepCopy() *Chart {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Chart)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Cluster) DeepCopyInto(out *Cluster) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster.
|
||||
func (in *Cluster) DeepCopy() *Cluster {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Cluster)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Cluster) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterList) DeepCopyInto(out *ClusterList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Cluster, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterList.
|
||||
func (in *ClusterList) DeepCopy() *ClusterList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ClusterList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
|
||||
*out = *in
|
||||
if in.Hosts != nil {
|
||||
in, out := &in.Hosts, &out.Hosts
|
||||
*out = make([]HostCfg, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
in.RoleGroups.DeepCopyInto(&out.RoleGroups)
|
||||
out.ControlPlaneEndpoint = in.ControlPlaneEndpoint
|
||||
in.Kubernetes.DeepCopyInto(&out.Kubernetes)
|
||||
out.Network = in.Network
|
||||
in.Registry.DeepCopyInto(&out.Registry)
|
||||
if in.Addons != nil {
|
||||
in, out := &in.Addons, &out.Addons
|
||||
*out = make([]Addon, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
out.KubeSphere = in.KubeSphere
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpec.
|
||||
func (in *ClusterSpec) DeepCopy() *ClusterSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterStatus) DeepCopyInto(out *ClusterStatus) {
|
||||
*out = *in
|
||||
in.JobInfo.DeepCopyInto(&out.JobInfo)
|
||||
if in.Nodes != nil {
|
||||
in, out := &in.Nodes, &out.Nodes
|
||||
*out = make([]NodeStatus, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterStatus.
|
||||
func (in *ClusterStatus) DeepCopy() *ClusterStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Condition) DeepCopyInto(out *Condition) {
|
||||
*out = *in
|
||||
in.StartTime.DeepCopyInto(&out.StartTime)
|
||||
in.EndTime.DeepCopyInto(&out.EndTime)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition.
|
||||
func (in *Condition) DeepCopy() *Condition {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Condition)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ContainerInfo) DeepCopyInto(out *ContainerInfo) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerInfo.
|
||||
func (in *ContainerInfo) DeepCopy() *ContainerInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ContainerInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ControlPlaneEndpoint) DeepCopyInto(out *ControlPlaneEndpoint) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneEndpoint.
|
||||
func (in *ControlPlaneEndpoint) DeepCopy() *ControlPlaneEndpoint {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ControlPlaneEndpoint)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExternalEtcd) DeepCopyInto(out *ExternalEtcd) {
|
||||
*out = *in
|
||||
if in.Endpoints != nil {
|
||||
in, out := &in.Endpoints, &out.Endpoints
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalEtcd.
|
||||
func (in *ExternalEtcd) DeepCopy() *ExternalEtcd {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExternalEtcd)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FlannelCfg) DeepCopyInto(out *FlannelCfg) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlannelCfg.
|
||||
func (in *FlannelCfg) DeepCopy() *FlannelCfg {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FlannelCfg)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HostCfg) DeepCopyInto(out *HostCfg) {
|
||||
*out = *in
|
||||
if in.Labels != nil {
|
||||
in, out := &in.Labels, &out.Labels
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostCfg.
|
||||
func (in *HostCfg) DeepCopy() *HostCfg {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HostCfg)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HostGroups) DeepCopyInto(out *HostGroups) {
|
||||
*out = *in
|
||||
if in.All != nil {
|
||||
in, out := &in.All, &out.All
|
||||
*out = make([]HostCfg, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Etcd != nil {
|
||||
in, out := &in.Etcd, &out.Etcd
|
||||
*out = make([]HostCfg, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Master != nil {
|
||||
in, out := &in.Master, &out.Master
|
||||
*out = make([]HostCfg, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Worker != nil {
|
||||
in, out := &in.Worker, &out.Worker
|
||||
*out = make([]HostCfg, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.K8s != nil {
|
||||
in, out := &in.K8s, &out.K8s
|
||||
*out = make([]HostCfg, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostGroups.
|
||||
func (in *HostGroups) DeepCopy() *HostGroups {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HostGroups)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *JobInfo) DeepCopyInto(out *JobInfo) {
|
||||
*out = *in
|
||||
if in.Pods != nil {
|
||||
in, out := &in.Pods, &out.Pods
|
||||
*out = make([]PodInfo, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JobInfo.
|
||||
func (in *JobInfo) DeepCopy() *JobInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(JobInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeSphere) DeepCopyInto(out *KubeSphere) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeSphere.
|
||||
func (in *KubeSphere) DeepCopy() *KubeSphere {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeSphere)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeovnCfg) DeepCopyInto(out *KubeovnCfg) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeovnCfg.
|
||||
func (in *KubeovnCfg) DeepCopy() *KubeovnCfg {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeovnCfg)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Kubernetes) DeepCopyInto(out *Kubernetes) {
|
||||
*out = *in
|
||||
if in.ApiserverCertExtraSans != nil {
|
||||
in, out := &in.ApiserverCertExtraSans, &out.ApiserverCertExtraSans
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Nodelocaldns != nil {
|
||||
in, out := &in.Nodelocaldns, &out.Nodelocaldns
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.ApiServerArgs != nil {
|
||||
in, out := &in.ApiServerArgs, &out.ApiServerArgs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.ControllerManagerArgs != nil {
|
||||
in, out := &in.ControllerManagerArgs, &out.ControllerManagerArgs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SchedulerArgs != nil {
|
||||
in, out := &in.SchedulerArgs, &out.SchedulerArgs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.KubeletArgs != nil {
|
||||
in, out := &in.KubeletArgs, &out.KubeletArgs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.KubeProxyArgs != nil {
|
||||
in, out := &in.KubeProxyArgs, &out.KubeProxyArgs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
in.KubeletConfiguration.DeepCopyInto(&out.KubeletConfiguration)
|
||||
in.KubeProxyConfiguration.DeepCopyInto(&out.KubeProxyConfiguration)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Kubernetes.
|
||||
func (in *Kubernetes) DeepCopy() *Kubernetes {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Kubernetes)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *NetworkConfig) DeepCopyInto(out *NetworkConfig) {
|
||||
*out = *in
|
||||
out.Calico = in.Calico
|
||||
out.Flannel = in.Flannel
|
||||
out.Kubeovn = in.Kubeovn
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkConfig.
|
||||
func (in *NetworkConfig) DeepCopy() *NetworkConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(NetworkConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *NodeStatus) DeepCopyInto(out *NodeStatus) {
|
||||
*out = *in
|
||||
if in.Roles != nil {
|
||||
in, out := &in.Roles, &out.Roles
|
||||
*out = make(map[string]bool, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeStatus.
|
||||
func (in *NodeStatus) DeepCopy() *NodeStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(NodeStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PodInfo) DeepCopyInto(out *PodInfo) {
|
||||
*out = *in
|
||||
if in.Containers != nil {
|
||||
in, out := &in.Containers, &out.Containers
|
||||
*out = make([]ContainerInfo, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodInfo.
|
||||
func (in *PodInfo) DeepCopy() *PodInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PodInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RegistryConfig) DeepCopyInto(out *RegistryConfig) {
|
||||
*out = *in
|
||||
if in.RegistryMirrors != nil {
|
||||
in, out := &in.RegistryMirrors, &out.RegistryMirrors
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.InsecureRegistries != nil {
|
||||
in, out := &in.InsecureRegistries, &out.InsecureRegistries
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegistryConfig.
|
||||
func (in *RegistryConfig) DeepCopy() *RegistryConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RegistryConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RoleGroups) DeepCopyInto(out *RoleGroups) {
|
||||
*out = *in
|
||||
if in.Etcd != nil {
|
||||
in, out := &in.Etcd, &out.Etcd
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Master != nil {
|
||||
in, out := &in.Master, &out.Master
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Worker != nil {
|
||||
in, out := &in.Worker, &out.Worker
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleGroups.
|
||||
func (in *RoleGroups) DeepCopy() *RoleGroups {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RoleGroups)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Sources) DeepCopyInto(out *Sources) {
|
||||
*out = *in
|
||||
in.Chart.DeepCopyInto(&out.Chart)
|
||||
in.Yaml.DeepCopyInto(&out.Yaml)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Sources.
|
||||
func (in *Sources) DeepCopy() *Sources {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Sources)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Yaml) DeepCopyInto(out *Yaml) {
|
||||
*out = *in
|
||||
if in.Path != nil {
|
||||
in, out := &in.Path, &out.Path
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Yaml.
|
||||
func (in *Yaml) DeepCopy() *Yaml {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Yaml)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
@@ -48,7 +48,6 @@ type ClusterSpec struct {
|
||||
Network NetworkConfig `yaml:"network" json:"network,omitempty"`
|
||||
Registry RegistryConfig `yaml:"registry" json:"registry,omitempty"`
|
||||
Addons []Addon `yaml:"addons" json:"addons,omitempty"`
|
||||
KubeSphere KubeSphere `json:"kubesphere,omitempty"`
|
||||
}
|
||||
|
||||
// ClusterStatus defines the observed state of Cluster
|
||||
@@ -134,10 +133,6 @@ type ClusterList struct {
|
||||
Items []Cluster `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Cluster{}, &ClusterList{})
|
||||
}
|
||||
|
||||
// HostCfg defines host information for cluster.
|
||||
type HostCfg struct {
|
||||
Name string `yaml:"name,omitempty" json:"name,omitempty"`
|
||||
@@ -187,13 +182,6 @@ type RegistryConfig struct {
|
||||
Auths runtime.RawExtension `yaml:"auths" json:"auths,omitempty"`
|
||||
}
|
||||
|
||||
// KubeSphere defines the configuration information of the KubeSphere.
|
||||
type KubeSphere struct {
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
Configurations string `json:"configurations,omitempty"`
|
||||
}
|
||||
|
||||
// GenerateCertSANs is used to generate cert sans for cluster.
|
||||
func (cfg *ClusterSpec) GenerateCertSANs() []string {
|
||||
clusterSvc := fmt.Sprintf("kubernetes.default.svc.%s", cfg.Kubernetes.DNSDomain)
|
||||
|
||||
@@ -133,7 +133,6 @@ func (cfg *ClusterSpec) SetDefaultClusterSpec(incluster bool, macos bool) (*Clus
|
||||
clusterCfg.Kubernetes = SetDefaultClusterCfg(cfg)
|
||||
clusterCfg.Registry = cfg.Registry
|
||||
clusterCfg.Addons = cfg.Addons
|
||||
clusterCfg.KubeSphere = cfg.KubeSphere
|
||||
|
||||
if cfg.Kubernetes.ClusterName == "" {
|
||||
clusterCfg.Kubernetes.ClusterName = DefaultClusterName
|
||||
|
||||
@@ -138,7 +138,3 @@ type ManifestList struct {
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Manifest `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Manifest{}, &ManifestList{})
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
83
cli/cmd/config/common_flags.go
Normal file
83
cli/cmd/config/common_flags.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
cc "github.com/beclab/Olares/cli/pkg/core/common"
|
||||
"github.com/beclab/Olares/cli/version"
|
||||
)
|
||||
|
||||
func AddStorageFlagsBy(flagSetter CommandFlagSetter) {
|
||||
// Storage backend type: managed-minio, s3, oss, cos, minio
|
||||
flagSetter.Add(common.FlagStorageType,
|
||||
"",
|
||||
"",
|
||||
"Set storage backend type: managed-minio, s3, oss, cos, minio",
|
||||
).WithAlias(common.FlagLegacyStorageType)
|
||||
|
||||
flagSetter.Add(common.FlagS3Bucket, "", "", "Object storage bucket name")
|
||||
flagSetter.Add(common.FlagBackupKeyPrefix, "", "", "Object storage key prefix for backups")
|
||||
flagSetter.Add(common.FlagAWSAccessKeyIDSetup, "", "", "Access key ID for object storage")
|
||||
flagSetter.Add(common.FlagAWSSecretAccessKeySetup, "", "", "Secret access key for object storage")
|
||||
flagSetter.Add(common.FlagAWSSessionTokenSetup, "", "", "Session token for temporary credentials")
|
||||
flagSetter.Add(common.FlagClusterID, "", "", "Cluster ID used as JuiceFS filesystem name in cloud environments")
|
||||
flagSetter.Add(common.FlagBackupSecret, "", "", "Backup sync secret for Terminus cloud")
|
||||
flagSetter.Add(common.FlagBackupClusterBucket, "", "", "Backup cluster bucket name")
|
||||
flagSetter.Add(common.FlagIsCloudVersion, "", "", "Set to true when running in Terminus cloud environment")
|
||||
}
|
||||
|
||||
func AddVersionFlagBy(flagSetter CommandFlagSetter) {
|
||||
flagSetter.Add(common.FlagVersion,
|
||||
"v",
|
||||
version.VERSION,
|
||||
"Set Olares version, e.g., 1.10.0, 1.10.0-20241109",
|
||||
)
|
||||
}
|
||||
|
||||
func AddBaseDirFlagBy(flagSetter CommandFlagSetter) {
|
||||
flagSetter.Add(common.FlagBaseDir,
|
||||
"b",
|
||||
"",
|
||||
"Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir,
|
||||
)
|
||||
}
|
||||
|
||||
func AddMiniKubeProfileFlagBy(flagSetter CommandFlagSetter) {
|
||||
flagSetter.Add(common.FlagMiniKubeProfile,
|
||||
"p",
|
||||
"",
|
||||
"Set Minikube profile name, only in MacOS platform, defaults to "+common.MinikubeDefaultProfile,
|
||||
).WithAlias(common.FlagLegacyMiniKubeProfile)
|
||||
}
|
||||
|
||||
func AddKubeTypeFlagBy(flagSetter CommandFlagSetter) {
|
||||
flagSetter.Add(common.FlagKubeType,
|
||||
"",
|
||||
common.K3s,
|
||||
"Set kube type, e.g., k3s or k8s",
|
||||
).WithAlias(common.FlagLegacyKubeType)
|
||||
}
|
||||
|
||||
func AddCDNServiceFlagBy(flagSetter CommandFlagSetter) {
|
||||
flagSetter.Add(common.FlagCDNService,
|
||||
"",
|
||||
cc.DefaultOlaresCDNService,
|
||||
"Set the CDN accelerated download address in the format https://cdn.olares.cn. If not set, the default download address will be used",
|
||||
).WithEnv(common.ENV_OLARES_CDN_SERVICE)
|
||||
}
|
||||
|
||||
func AddManifestFlagBy(flagSetter CommandFlagSetter) {
|
||||
flagSetter.Add(common.FlagManifest,
|
||||
"",
|
||||
"",
|
||||
"Set package manifest file, defaults to ${base-dir}/versions/v{version}/installation.manifest",
|
||||
)
|
||||
}
|
||||
|
||||
func AddMasterHostFlagsBy(flagSetter CommandFlagSetter) {
|
||||
flagSetter.Add(common.FlagMasterHost, "", "", "IP address of the master node")
|
||||
flagSetter.Add(common.FlagMasterNodeName, "", "", "Name of the master node")
|
||||
flagSetter.Add(common.FlagMasterSSHUser, "", "", "Username of the master node, defaults to root")
|
||||
flagSetter.Add(common.FlagMasterSSHPassword, "", "", "Password of the master node")
|
||||
flagSetter.Add(common.FlagMasterSSHPrivateKeyPath, "", "", "Path to the SSH key to access the master node, defaults to ~/.ssh/id_rsa")
|
||||
flagSetter.Add(common.FlagMasterSSHPort, "", 0, "SSH Port of the master node, defaults to 22")
|
||||
}
|
||||
110
cli/cmd/config/flag_setter.go
Normal file
110
cli/cmd/config/flag_setter.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
)
|
||||
|
||||
// Init initializes viper as the single source of truth:
|
||||
// 1) Load /etc/olares/release (dotenv) into the process env if present
|
||||
// 2) Enable viper to read environment variables
|
||||
// 3) Bind environment variables for all known keys we care about
|
||||
func Init() {
|
||||
godotenv.Load(common.OlaresReleaseFile)
|
||||
viper.SetEnvPrefix("OLARES")
|
||||
viper.SetEnvKeyReplacer(envKeyReplacer)
|
||||
viper.AutomaticEnv()
|
||||
}
|
||||
|
||||
var aliasToFlag = map[string]string{}
|
||||
var envToFlag = map[string]string{}
|
||||
var envKeyReplacer = strings.NewReplacer("-", "_")
|
||||
|
||||
type CommandFlagSetter interface {
|
||||
Add(flag string, short string, defValue any, description string) CommandFlagItem
|
||||
}
|
||||
|
||||
type CommandFlagItem interface {
|
||||
WithAlias(aliases ...string) CommandFlagItem
|
||||
WithEnv(envs ...string) CommandFlagItem
|
||||
}
|
||||
|
||||
func NewFlagSetterFor(cmd *cobra.Command) CommandFlagSetter {
|
||||
if cmd == nil {
|
||||
panic(fmt.Errorf("command is nil"))
|
||||
}
|
||||
cmd.Flags().SetNormalizeFunc(func(f *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||
if f, ok := aliasToFlag[name]; ok {
|
||||
return pflag.NormalizedName(f)
|
||||
}
|
||||
return pflag.NormalizedName(name)
|
||||
})
|
||||
return &commandFlagSetterImpl{
|
||||
command: cmd,
|
||||
}
|
||||
}
|
||||
|
||||
type commandFlagSetterImpl struct {
|
||||
command *cobra.Command
|
||||
}
|
||||
|
||||
type commandFlagItemImpl struct {
|
||||
command *cobra.Command
|
||||
flag string
|
||||
}
|
||||
|
||||
func (c *commandFlagSetterImpl) Add(flag string, short string, defValue any, description string) CommandFlagItem {
|
||||
switch reflect.TypeOf(defValue).Kind() {
|
||||
case reflect.Bool:
|
||||
c.command.Flags().BoolP(flag, short, defValue.(bool), description)
|
||||
case reflect.String:
|
||||
c.command.Flags().StringP(flag, short, defValue.(string), description)
|
||||
case reflect.Int:
|
||||
c.command.Flags().IntP(flag, short, defValue.(int), description)
|
||||
}
|
||||
viper.BindPFlag(flag, c.command.Flags().Lookup(flag))
|
||||
|
||||
// transitional support for legacy envs without prefix
|
||||
// it should be removed after all envs are migrated
|
||||
viper.BindEnv(flag, strings.ToUpper(envKeyReplacer.Replace(flag)))
|
||||
return &commandFlagItemImpl{
|
||||
flag: flag,
|
||||
command: c.command,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *commandFlagItemImpl) WithAlias(aliases ...string) CommandFlagItem {
|
||||
for _, a := range aliases {
|
||||
if f, ok := aliasToFlag[a]; ok {
|
||||
if f != c.flag {
|
||||
panic(fmt.Errorf("flag alias %s already exists for flag %s, please use a different alias", a, f))
|
||||
}
|
||||
continue
|
||||
}
|
||||
viper.BindEnv(c.flag, a)
|
||||
aliasToFlag[a] = c.flag
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *commandFlagItemImpl) WithEnv(envs ...string) CommandFlagItem {
|
||||
for _, e := range envs {
|
||||
if f, ok := envToFlag[e]; ok {
|
||||
if f != c.flag {
|
||||
panic(fmt.Errorf("env %s already exists for flag %s, please use a different env", e, f))
|
||||
}
|
||||
continue
|
||||
}
|
||||
viper.BindEnv(c.flag, e)
|
||||
envToFlag[e] = c.flag
|
||||
}
|
||||
return c
|
||||
}
|
||||
21
cli/cmd/ctl/amdgpu/install.go
Normal file
21
cli/cmd/ctl/amdgpu/install.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package amdgpu
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdAmdGpuInstall() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "install",
|
||||
Short: "Install AMD ROCm stack via amdgpu-install",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.AmdGpuInstall(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
16
cli/cmd/ctl/amdgpu/root.go
Normal file
16
cli/cmd/ctl/amdgpu/root.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package amdgpu
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
func NewCmdAmdGpu() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "amdgpu",
|
||||
Short: "Manage AMD GPU ROCm stack",
|
||||
}
|
||||
cmd.AddCommand(NewCmdAmdGpuInstall())
|
||||
cmd.AddCommand(NewCmdAmdGpuUninstall())
|
||||
cmd.AddCommand(NewCmdAmdGpuStatus())
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
21
cli/cmd/ctl/amdgpu/status.go
Normal file
21
cli/cmd/ctl/amdgpu/status.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package amdgpu
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdAmdGpuStatus() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "status",
|
||||
Short: "Show AMD GPU driver and ROCm status",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.AmdGpuStatus(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
21
cli/cmd/ctl/amdgpu/uninstall.go
Normal file
21
cli/cmd/ctl/amdgpu/uninstall.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package amdgpu
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdAmdGpuUninstall() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "uninstall",
|
||||
Short: "Uninstall AMD ROCm stack via amdgpu-install",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.AmdGpuUninstall(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
@@ -3,22 +3,23 @@ package gpu
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdInstallGpu() *cobra.Command {
|
||||
o := options.NewInstallGpuOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "install",
|
||||
Short: "Install GPU drivers for Olares",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.InstallGpuDrivers(o); err != nil {
|
||||
if err := pipelines.InstallGpuDrivers(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.AddFlags(cmd)
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -3,22 +3,25 @@ package node
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdAddNode() *cobra.Command {
|
||||
o := options.NewAddNodeOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "add",
|
||||
Short: "add worker node to the cluster",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.AddNodePipeline(o); err != nil {
|
||||
if err := pipelines.AddNodePipeline(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.AddFlags(cmd)
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddMasterHostFlagsBy(flagSetter)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -3,22 +3,24 @@ package node
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdMasterInfo() *cobra.Command {
|
||||
o := options.NewMasterInfoOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "masterinfo",
|
||||
Short: "get information about master node, and check whether current node can be added to the cluster",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.MasterInfoPipeline(o); err != nil {
|
||||
if err := pipelines.MasterInfoPipeline(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.AddFlags(cmd)
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddMasterHostFlagsBy(flagSetter)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
package options
|
||||
|
||||
import (
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
cc "github.com/beclab/Olares/cli/pkg/core/common"
|
||||
"github.com/beclab/Olares/cli/pkg/phase/cluster"
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
type CliTerminusUninstallOptions struct {
|
||||
Version string
|
||||
BaseDir string
|
||||
All bool
|
||||
Phase string
|
||||
Quiet bool
|
||||
}
|
||||
|
||||
func NewCliTerminusUninstallOptions() *CliTerminusUninstallOptions {
|
||||
return &CliTerminusUninstallOptions{}
|
||||
}
|
||||
|
||||
func (o *CliTerminusUninstallOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
cmd.Flags().BoolVar(&o.All, "all", false, "Uninstall Olares completely, including prepared dependencies")
|
||||
cmd.Flags().StringVar(&o.Phase, "phase", cluster.PhaseInstall.String(), "Uninstall from a specified phase and revert to the previous one. For example, using --phase install will remove the tasks performed in the 'install' phase, effectively returning the system to the 'prepare' state.")
|
||||
cmd.Flags().BoolVar(&o.Quiet, "quiet", false, "Quiet mode, default: false")
|
||||
}
|
||||
|
||||
type CliTerminusInstallOptions struct {
|
||||
Version string
|
||||
KubeType string
|
||||
WithJuiceFS bool
|
||||
MiniKubeProfile string
|
||||
BaseDir string
|
||||
EnableReverseProxy *bool
|
||||
common.SwapConfig
|
||||
}
|
||||
|
||||
func NewCliTerminusInstallOptions() *CliTerminusInstallOptions {
|
||||
return &CliTerminusInstallOptions{
|
||||
EnableReverseProxy: pointer.Bool(false),
|
||||
}
|
||||
}
|
||||
|
||||
func (o *CliTerminusInstallOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().BoolVar(o.EnableReverseProxy, "enable-reverse-proxy", false, "Enable reverse proxy, if not set, will be dynamically enabled if public IP is not detected, and disabled otherwise")
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVar(&o.KubeType, "kube", "k3s", "Set kube type, e.g., k3s or k8s")
|
||||
cmd.Flags().BoolVar(&o.WithJuiceFS, "with-juicefs", false, "Use JuiceFS as the rootfs for Olares workloads, rather than the local disk.")
|
||||
cmd.Flags().StringVarP(&o.MiniKubeProfile, "profile", "p", "", "Set Minikube profile name, only in MacOS platform, defaults to "+common.MinikubeDefaultProfile)
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
(&o.SwapConfig).AddFlags(cmd.Flags())
|
||||
}
|
||||
|
||||
type CliPrepareSystemOptions struct {
|
||||
Version string
|
||||
KubeType string
|
||||
RegistryMirrors string
|
||||
BaseDir string
|
||||
MinikubeProfile string
|
||||
}
|
||||
|
||||
func NewCliPrepareSystemOptions() *CliPrepareSystemOptions {
|
||||
return &CliPrepareSystemOptions{}
|
||||
}
|
||||
|
||||
func (o *CliPrepareSystemOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVar(&o.KubeType, "kube", "k3s", "Set kube type, e.g., k3s or k8s")
|
||||
cmd.Flags().StringVarP(&o.RegistryMirrors, "registry-mirrors", "r", "", "Docker Container registry mirrors, multiple mirrors are separated by commas")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
cmd.Flags().StringVarP(&o.MinikubeProfile, "profile", "p", "", "Set Minikube profile name, only in MacOS platform, defaults to "+common.MinikubeDefaultProfile)
|
||||
}
|
||||
|
||||
type ChangeIPOptions struct {
|
||||
Version string
|
||||
BaseDir string
|
||||
NewMasterHost string
|
||||
WSLDistribution string
|
||||
MinikubeProfile string
|
||||
}
|
||||
|
||||
func NewChangeIPOptions() *ChangeIPOptions {
|
||||
return &ChangeIPOptions{}
|
||||
}
|
||||
|
||||
func (o *ChangeIPOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
cmd.Flags().StringVar(&o.NewMasterHost, "new-master-host", "", "Update the master node's IP if it's changed, only in Linux worker node")
|
||||
cmd.Flags().StringVarP(&o.WSLDistribution, "distribution", "d", "", "Set WSL distribution name, only in Windows platform, defaults to "+common.WSLDefaultDistribution)
|
||||
cmd.Flags().StringVarP(&o.MinikubeProfile, "profile", "p", "", "Set Minikube profile name, only in MacOS platform, defaults to "+common.MinikubeDefaultProfile)
|
||||
}
|
||||
|
||||
type PreCheckOptions struct {
|
||||
Version string
|
||||
BaseDir string
|
||||
}
|
||||
|
||||
func NewPreCheckOptions() *PreCheckOptions {
|
||||
return &PreCheckOptions{}
|
||||
}
|
||||
|
||||
func (o *PreCheckOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
}
|
||||
|
||||
type InstallStorageOptions struct {
|
||||
Version string
|
||||
BaseDir string
|
||||
}
|
||||
|
||||
func NewInstallStorageOptions() *InstallStorageOptions {
|
||||
return &InstallStorageOptions{}
|
||||
}
|
||||
|
||||
func (o *InstallStorageOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
}
|
||||
|
||||
type AddNodeOptions struct {
|
||||
common.MasterHostConfig
|
||||
Version string
|
||||
BaseDir string
|
||||
}
|
||||
|
||||
func NewAddNodeOptions() *AddNodeOptions {
|
||||
return &AddNodeOptions{}
|
||||
}
|
||||
|
||||
func (o *AddNodeOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
(&o.MasterHostConfig).AddFlags(cmd.Flags())
|
||||
}
|
||||
|
||||
type MasterInfoOptions struct {
|
||||
BaseDir string
|
||||
common.MasterHostConfig
|
||||
}
|
||||
|
||||
func NewMasterInfoOptions() *MasterInfoOptions {
|
||||
return &MasterInfoOptions{}
|
||||
}
|
||||
|
||||
func (o *MasterInfoOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
(&o.MasterHostConfig).AddFlags(cmd.Flags())
|
||||
}
|
||||
|
||||
type UpgradeOptions struct {
|
||||
Version string
|
||||
BaseDir string
|
||||
}
|
||||
|
||||
func NewUpgradeOptions() *UpgradeOptions {
|
||||
return &UpgradeOptions{}
|
||||
}
|
||||
|
||||
func (o *UpgradeOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set target Olares version to upgrade to, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package options
|
||||
|
||||
import (
|
||||
cc "github.com/beclab/Olares/cli/pkg/core/common"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type CliDownloadWizardOptions struct {
|
||||
Version string
|
||||
KubeType string
|
||||
BaseDir string
|
||||
CDNService string
|
||||
ReleaseID string
|
||||
UrlOverride string
|
||||
}
|
||||
|
||||
func NewCliDownloadWizardOptions() *CliDownloadWizardOptions {
|
||||
return &CliDownloadWizardOptions{}
|
||||
}
|
||||
|
||||
func (o *CliDownloadWizardOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
cmd.Flags().StringVar(&o.KubeType, "kube", "k3s", "Set kube type, e.g., k3s or k8s")
|
||||
cmd.Flags().StringVar(&o.CDNService, "cdn-service", "", "Set the CDN accelerated download address in the format https://example.cdn.com. If not set, the default download address will be used")
|
||||
cmd.Flags().StringVar(&o.UrlOverride, "url-override", "", "Set another URL for wizard download explicitly")
|
||||
cmd.Flags().StringVar(&o.ReleaseID, "release-id", "", "Set the specific release id of the release version")
|
||||
}
|
||||
|
||||
type CliDownloadOptions struct {
|
||||
Version string
|
||||
KubeType string
|
||||
Manifest string
|
||||
BaseDir string
|
||||
CDNService string
|
||||
}
|
||||
|
||||
func NewCliDownloadOptions() *CliDownloadOptions {
|
||||
return &CliDownloadOptions{}
|
||||
}
|
||||
|
||||
func (o *CliDownloadOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir , defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
cmd.Flags().StringVar(&o.Manifest, "manifest", "", "Set package manifest file , defaults to {base-dir}/versions/v{version}/installation.manifest")
|
||||
cmd.Flags().StringVar(&o.KubeType, "kube", "k3s", "Set kube type, e.g., k3s or k8s")
|
||||
cmd.Flags().StringVar(&o.CDNService, "cdn-service", "", "Set the CDN accelerated download address in the format https://example.cdn.com. If not set, the default download address will be used")
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package options
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
cc "github.com/beclab/Olares/cli/pkg/core/common"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type GpuOptions struct {
|
||||
Version string
|
||||
BaseDir string
|
||||
}
|
||||
|
||||
func (o *GpuOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
}
|
||||
|
||||
type InstallGpuOptions struct {
|
||||
GpuOptions
|
||||
Cuda string
|
||||
}
|
||||
|
||||
func NewInstallGpuOptions() *InstallGpuOptions {
|
||||
return &InstallGpuOptions{}
|
||||
}
|
||||
|
||||
func (o *InstallGpuOptions) AddFlags(cmd *cobra.Command) {
|
||||
o.GpuOptions.AddFlags(cmd)
|
||||
cmd.Flags().StringVar(&o.Cuda, "cuda", "", fmt.Sprintf("The version of the CUDA driver, current supported versions are %s", common.CurrentVerifiedCudaVersion))
|
||||
}
|
||||
@@ -3,22 +3,36 @@ package os
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdChangeIP() *cobra.Command {
|
||||
o := options.NewChangeIPOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "change-ip",
|
||||
Short: "change The IP address of Olares OS",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.ChangeIPPipeline(o); err != nil {
|
||||
if err := pipelines.ChangeIPPipeline(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.AddFlags(cmd)
|
||||
|
||||
// todo: merge master host config with release info
|
||||
// be backward compatible with old version and olaresd
|
||||
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddMasterHostFlagsBy(flagSetter)
|
||||
flagSetter.Add(common.FlagWSLDistribution,
|
||||
"d",
|
||||
"",
|
||||
"Set WSL distribution name, only on Windows platform, defaults to "+common.WSLDefaultDistribution,
|
||||
).WithAlias(common.FlagLegacyWSLDistribution)
|
||||
config.AddMiniKubeProfileFlagBy(flagSetter)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@ package os
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -22,52 +23,61 @@ func NewCmdRootDownload() *cobra.Command {
|
||||
}
|
||||
|
||||
func NewCmdDownload() *cobra.Command {
|
||||
o := options.NewCliDownloadOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "component",
|
||||
Short: "Download the packages and components needed to install Olares",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
if err := pipelines.DownloadInstallationPackage(o); err != nil {
|
||||
if err := pipelines.DownloadInstallationPackage(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddCDNServiceFlagBy(flagSetter)
|
||||
config.AddManifestFlagBy(flagSetter)
|
||||
|
||||
o.AddFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCmdDownloadWizard() *cobra.Command {
|
||||
o := options.NewCliDownloadWizardOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "wizard",
|
||||
Short: "Download the Olares installation wizard",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
if err := pipelines.DownloadInstallationWizard(o); err != nil {
|
||||
if err := pipelines.DownloadInstallationWizard(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
|
||||
o.AddFlags(cmd)
|
||||
flagSetter.Add(common.FlagReleaseID, "", "", "Set the specific release id of the release version")
|
||||
flagSetter.Add(common.FlagURLOverride, "", "", "Set another URL for wizard download explicitly")
|
||||
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddCDNServiceFlagBy(flagSetter)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCmdCheckDownload() *cobra.Command {
|
||||
o := options.NewCliDownloadOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "check",
|
||||
Short: "Check Downloaded Olares Installation Package",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
if err := pipelines.CheckDownloadInstallationPackage(o); err != nil {
|
||||
if err := pipelines.CheckDownloadInstallationPackage(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
o.AddFlags(cmd)
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddManifestFlagBy(flagSetter)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -3,36 +3,81 @@ package os
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type InstallOsOptions struct {
|
||||
InstallOptions *options.CliTerminusInstallOptions
|
||||
}
|
||||
|
||||
func NewInstallOsOptions() *InstallOsOptions {
|
||||
return &InstallOsOptions{
|
||||
InstallOptions: options.NewCliTerminusInstallOptions(),
|
||||
}
|
||||
}
|
||||
|
||||
func NewCmdInstallOs() *cobra.Command {
|
||||
o := NewInstallOsOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "install",
|
||||
Short: "Install Olares",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if !cmd.Flags().Changed("enable-reverse-proxy") {
|
||||
o.InstallOptions.EnableReverseProxy = nil
|
||||
}
|
||||
if err := pipelines.CliInstallTerminusPipeline(o.InstallOptions); err != nil {
|
||||
if err := pipelines.CliInstallTerminusPipeline(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.InstallOptions.AddFlags(cmd)
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
flagSetter.Add(common.FlagOSUserName,
|
||||
"",
|
||||
"",
|
||||
"Set the username for the Olares instance, if not set, will be prompted for input",
|
||||
).WithEnv(common.EnvLegacyOSUserName)
|
||||
flagSetter.Add(common.FlagOSDomainName,
|
||||
"",
|
||||
"",
|
||||
"Set the domain name for the Olares instance, if not set, will be prompted for input",
|
||||
).WithEnv(common.EnvLegacyOSDomainName)
|
||||
flagSetter.Add(common.FlagOSPassword,
|
||||
"",
|
||||
"",
|
||||
"Set the inital password for the first user of the Olares instance, if not set, a randomly generated password will be used",
|
||||
)
|
||||
flagSetter.Add(common.FlagEnableReverseProxy,
|
||||
"",
|
||||
false,
|
||||
"Enable reverse proxy, if not set, will be dynamically enabled if public IP is not detected, and disabled otherwise",
|
||||
)
|
||||
flagSetter.Add(common.FlagEnableJuiceFS,
|
||||
"",
|
||||
false,
|
||||
"Use JuiceFS as the rootfs for Olares workloads, rather than the local disk.",
|
||||
).WithAlias(common.FlagLegacyEnableJuiceFS).WithEnv(common.EnvLegacyEnableJuiceFS)
|
||||
flagSetter.Add(common.FlagEnablePodSwap,
|
||||
"",
|
||||
false,
|
||||
"Enable pods on Kubernetes cluster to use swap, setting --enable-zram, --zram-size or --zram-swap-priority implicitly enables this option, regardless of the command line args, note that only pods of the BestEffort QOS group can use swap due to K8s design",
|
||||
)
|
||||
flagSetter.Add(common.FlagSwappiness,
|
||||
"",
|
||||
false,
|
||||
"Configure the Linux swappiness value, if not set, the current configuration is remained",
|
||||
)
|
||||
flagSetter.Add(common.FlagEnableZRAM,
|
||||
"",
|
||||
false,
|
||||
"Set up a ZRAM device to be used for swap, setting --zram-size or --zram-swap-priority implicitly enables this option, regardless of the command line args",
|
||||
)
|
||||
flagSetter.Add(common.FlagZRAMSize,
|
||||
"",
|
||||
"",
|
||||
"Set the size of the ZRAM device, takes a format of https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/quantity, defaults to half of the total RAM",
|
||||
)
|
||||
flagSetter.Add(common.FlagZRAMSwapPriority,
|
||||
"",
|
||||
false,
|
||||
"Set the swap priority of the ZRAM device, between -1 and 32767, defaults to 100",
|
||||
)
|
||||
|
||||
config.AddCDNServiceFlagBy(flagSetter)
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddStorageFlagsBy(flagSetter)
|
||||
config.AddKubeTypeFlagBy(flagSetter)
|
||||
config.AddMiniKubeProfileFlagBy(flagSetter)
|
||||
|
||||
cmd.AddCommand(NewCmdInstallStorage())
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package os
|
||||
import (
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
@@ -13,6 +14,9 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
@@ -20,6 +24,7 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/util"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// LogCollectOptions holds options for collecting logs
|
||||
@@ -276,7 +281,7 @@ func collectSystemdLogs(tw *tar.Writer, options *LogCollectOptions) error {
|
||||
}
|
||||
|
||||
func collectDmesgLogs(tw *tar.Writer, options *LogCollectOptions) error {
|
||||
cmd := exec.Command("dmesg")
|
||||
cmd := exec.Command("dmesg -T")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -399,6 +404,126 @@ func collectKubernetesLogs(tw *tar.Writer, options *LogCollectOptions) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := collectNginxLogsFromLabeledPods(tw); err != nil {
|
||||
if !options.IgnoreKubeErrors {
|
||||
return fmt.Errorf("failed to collect nginx logs from labeled pods: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func collectNginxLogsFromLabeledPods(tw *tar.Writer) error {
|
||||
if _, err := util.GetCommand("kubectl"); err != nil {
|
||||
fmt.Printf("warning: kubectl not found, skipping collecting nginx logs from labeled pods\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
cfg, err := ctrl.GetConfig()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get kubeconfig: %v", err)
|
||||
}
|
||||
clientset, err := kubernetes.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create kube client: %v", err)
|
||||
}
|
||||
|
||||
type selectorSpec struct {
|
||||
LabelSelector string
|
||||
ContainerName string
|
||||
}
|
||||
selectors := []selectorSpec{
|
||||
{LabelSelector: "app=l4-bfl-proxy", ContainerName: ""},
|
||||
{LabelSelector: "tier=bfl", ContainerName: "ingress"},
|
||||
}
|
||||
|
||||
type targetPod struct {
|
||||
Namespace string
|
||||
Name string
|
||||
ContainerName string
|
||||
}
|
||||
var targets []targetPod
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
for _, sel := range selectors {
|
||||
podList, err := clientset.CoreV1().Pods(corev1.NamespaceAll).List(ctx, metav1.ListOptions{LabelSelector: sel.LabelSelector})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list pods by label %q: %v", sel.LabelSelector, err)
|
||||
}
|
||||
for _, pod := range podList.Items {
|
||||
targets = append(targets, targetPod{
|
||||
Namespace: pod.Namespace,
|
||||
Name: pod.Name,
|
||||
ContainerName: sel.ContainerName,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if len(targets) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// simplest approach: use kubectl cp (it already implements copy via tar over exec)
|
||||
tempDir, err := os.MkdirTemp("", "olares-nginx-logs-*")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create temp directory for nginx logs: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
files := []string{"/var/log/nginx/access.log", "/var/log/nginx/error.log"}
|
||||
for _, target := range targets {
|
||||
for _, remotePath := range files {
|
||||
base := filepath.Base(remotePath)
|
||||
archivePath := filepath.Join("nginx", target.Namespace, target.Name, base)
|
||||
|
||||
dest := filepath.Join(tempDir, fmt.Sprintf("%s__%s__%s", target.Namespace, target.Name, base))
|
||||
|
||||
err := kubectlCopyFile(target.Namespace, target.Name, target.ContainerName, remotePath, dest)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to kubectl cp %s/%s:%s: %v", target.Namespace, target.Name, remotePath, err)
|
||||
}
|
||||
|
||||
fi, err := os.Stat(dest)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to stat copied nginx log %s: %v", dest, err)
|
||||
}
|
||||
|
||||
f, err := os.Open(dest)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open copied nginx log %s: %v", dest, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
header := &tar.Header{
|
||||
Name: archivePath,
|
||||
Mode: 0644,
|
||||
Size: fi.Size(),
|
||||
ModTime: time.Now(),
|
||||
}
|
||||
if err := tw.WriteHeader(header); err != nil {
|
||||
return fmt.Errorf("failed to write header for %s: %v", archivePath, err)
|
||||
}
|
||||
if _, err := io.CopyN(tw, f, header.Size); err != nil {
|
||||
return fmt.Errorf("failed to write data for %s: %v", archivePath, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func kubectlCopyFile(namespace, pod, container, remotePath, destPath string) error {
|
||||
args := []string{"-n", namespace, "cp"}
|
||||
if container != "" {
|
||||
args = append(args, "-c", container)
|
||||
}
|
||||
args = append(args, fmt.Sprintf("%s:%s", pod, remotePath), destPath)
|
||||
|
||||
cmd := exec.Command("kubectl", args...)
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("kubectl %s failed: %v, output: %s", strings.Join(args, " "), err, strings.TrimSpace(string(out)))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -485,13 +610,9 @@ func collectNetworkConfigs(tw *tar.Writer, options *LogCollectOptions) error {
|
||||
}
|
||||
|
||||
func getBaseDir() (string, error) {
|
||||
// quick path to get basedir from argument instance
|
||||
arg := &common.Argument{}
|
||||
if err := arg.LoadReleaseInfo(); err != nil {
|
||||
return "", fmt.Errorf("failed to load olares release info: %v", err)
|
||||
}
|
||||
if arg.BaseDir != "" {
|
||||
return arg.BaseDir, nil
|
||||
basedir := viper.GetString(common.FlagBaseDir)
|
||||
if basedir != "" {
|
||||
return basedir, nil
|
||||
}
|
||||
homeDir, err := util.Home()
|
||||
if err != nil {
|
||||
|
||||
@@ -3,22 +3,23 @@ package os
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdPrecheck() *cobra.Command {
|
||||
o := options.NewPreCheckOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "precheck",
|
||||
Short: "precheck the installation compatibility of the system",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.StartPreCheckPipeline(o); err != nil {
|
||||
if err := pipelines.StartPreCheckPipeline(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.AddFlags(cmd)
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -3,32 +3,34 @@ package os
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type PrepareSystemOptions struct {
|
||||
PrepareOptions *options.CliPrepareSystemOptions
|
||||
}
|
||||
|
||||
func NewPrepareSystemOptions() *PrepareSystemOptions {
|
||||
return &PrepareSystemOptions{
|
||||
PrepareOptions: options.NewCliPrepareSystemOptions(),
|
||||
}
|
||||
}
|
||||
|
||||
func NewCmdPrepare() *cobra.Command {
|
||||
o := NewPrepareSystemOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "prepare [component1 component2 ...]",
|
||||
Short: "Prepare install",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.PrepareSystemPipeline(o.PrepareOptions, args); err != nil {
|
||||
if err := pipelines.PrepareSystemPipeline(args); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.PrepareOptions.AddFlags(cmd)
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
|
||||
flagSetter.Add(common.FlagRegistryMirrors,
|
||||
"r",
|
||||
"",
|
||||
"Extra Docker Container registry mirrors, multiple mirrors are separated by commas",
|
||||
)
|
||||
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddStorageFlagsBy(flagSetter)
|
||||
config.AddKubeTypeFlagBy(flagSetter)
|
||||
config.AddMiniKubeProfileFlagBy(flagSetter)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -3,23 +3,26 @@ package os
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdInstallStorage() *cobra.Command {
|
||||
o := options.NewInstallStorageOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "storage",
|
||||
Short: "install a storage backend for the Olares shared filesystem, or in the case of external storage, validate the config",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.CliInstallStoragePipeline(o); err != nil {
|
||||
if err := pipelines.CliInstallStoragePipeline(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.AddFlags(cmd)
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddStorageFlagsBy(flagSetter)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -3,33 +3,37 @@ package os
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/phase/cluster"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type UninstallOsOptions struct {
|
||||
UninstallOptions *options.CliTerminusUninstallOptions
|
||||
}
|
||||
|
||||
func NewUninstallOsOptions() *UninstallOsOptions {
|
||||
return &UninstallOsOptions{
|
||||
UninstallOptions: options.NewCliTerminusUninstallOptions(),
|
||||
}
|
||||
}
|
||||
|
||||
func NewCmdUninstallOs() *cobra.Command {
|
||||
o := NewUninstallOsOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "uninstall",
|
||||
Short: "Uninstall Olares",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := pipelines.UninstallTerminusPipeline(o.UninstallOptions)
|
||||
err := pipelines.UninstallTerminusPipeline()
|
||||
if err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.UninstallOptions.AddFlags(cmd)
|
||||
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddStorageFlagsBy(flagSetter)
|
||||
|
||||
// these two flags' names are too general, and only used in cmd options, so we manually bind them to the viper
|
||||
// inside the pipeline creator, it still uses the flag vars to get the values
|
||||
cmd.Flags().Bool("all", false, "Uninstall Olares completely, including prepared dependencies")
|
||||
viper.BindPFlag(common.FlagUninstallAll, cmd.Flags().Lookup("all"))
|
||||
cmd.Flags().String("phase", cluster.PhaseInstall.String(), "Uninstall from a specified phase and revert to the previous one. For example, using --phase install will remove the tasks performed in the 'install' phase, effectively returning the system to the 'prepare' state.")
|
||||
viper.BindPFlag(common.FlagUninstallPhase, cmd.Flags().Lookup("phase"))
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -3,39 +3,33 @@ package os
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/phase"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/beclab/Olares/cli/pkg/upgrade"
|
||||
"github.com/beclab/Olares/cli/version"
|
||||
"github.com/spf13/cobra"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
type UpgradeOsOptions struct {
|
||||
UpgradeOptions *options.UpgradeOptions
|
||||
}
|
||||
|
||||
func NewUpgradeOsOptions() *UpgradeOsOptions {
|
||||
return &UpgradeOsOptions{
|
||||
UpgradeOptions: options.NewUpgradeOptions(),
|
||||
}
|
||||
}
|
||||
|
||||
func NewCmdUpgradeOs() *cobra.Command {
|
||||
o := NewUpgradeOsOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "upgrade",
|
||||
Short: "Upgrade Olares to a newer version",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.UpgradeOlaresPipeline(o.UpgradeOptions); err != nil {
|
||||
if err := pipelines.UpgradeOlaresPipeline(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.UpgradeOptions.AddFlags(cmd)
|
||||
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
|
||||
cmd.AddCommand(NewCmdCurrentVersionUpgradeSpec())
|
||||
cmd.AddCommand(NewCmdUpgradeViable())
|
||||
cmd.AddCommand(NewCmdUpgradePrecheck())
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package ctl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/amdgpu"
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/disk"
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/gpu"
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/node"
|
||||
@@ -13,6 +17,9 @@ import (
|
||||
|
||||
func NewDefaultCommand() *cobra.Command {
|
||||
var showVendor bool
|
||||
cobra.OnInitialize(func() {
|
||||
config.Init()
|
||||
})
|
||||
cmds := &cobra.Command{
|
||||
Use: "olares-cli",
|
||||
Short: "Olares Installer",
|
||||
@@ -20,7 +27,7 @@ func NewDefaultCommand() *cobra.Command {
|
||||
Version: version.VERSION,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if showVendor {
|
||||
println(version.VENDOR)
|
||||
fmt.Println(version.VENDOR)
|
||||
} else {
|
||||
cmd.Usage()
|
||||
}
|
||||
@@ -33,6 +40,7 @@ func NewDefaultCommand() *cobra.Command {
|
||||
cmds.AddCommand(os.NewOSCommands()...)
|
||||
cmds.AddCommand(node.NewNodeCommand())
|
||||
cmds.AddCommand(gpu.NewCmdGpu())
|
||||
cmds.AddCommand(amdgpu.NewCmdAmdGpu())
|
||||
cmds.AddCommand(user.NewUserCommand())
|
||||
cmds.AddCommand(disk.NewDiskCommand())
|
||||
|
||||
|
||||
14
cli/go.mod
14
cli/go.mod
@@ -24,8 +24,6 @@ require (
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/libp2p/go-netroute v0.2.2
|
||||
github.com/lithammer/dedent v1.1.0
|
||||
github.com/mitchellh/mapstructure v1.4.1
|
||||
github.com/modood/table v0.0.0-20220527013332-8d47e76dad33
|
||||
github.com/mr-tron/base58 v1.2.0
|
||||
github.com/multiformats/go-varint v0.0.7
|
||||
github.com/pelletier/go-toml v1.9.5
|
||||
@@ -37,7 +35,8 @@ require (
|
||||
github.com/shirou/gopsutil/v4 v4.25.7
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/spf13/pflag v1.0.7
|
||||
github.com/spf13/pflag v1.0.10
|
||||
github.com/spf13/viper v1.21.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/syndtr/goleveldb v1.0.0
|
||||
github.com/tyler-smith/go-bip39 v1.1.0
|
||||
@@ -114,6 +113,7 @@ require (
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.1 // indirect
|
||||
github.com/go-resty/resty/v2 v2.16.5 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/gobwas/glob v0.2.4-0.20181002190808-e7a84e9525fe // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
@@ -171,6 +171,7 @@ require (
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.2.1 // indirect
|
||||
github.com/opencontainers/selinux v1.13.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
@@ -181,11 +182,14 @@ require (
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rubenv/sql-migrate v1.8.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/smartystreets/goconvey v1.8.1 // indirect
|
||||
github.com/spf13/cast v1.9.2 // indirect
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||
github.com/spf13/afero v1.15.0 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/thoas/go-funk v0.9.3 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.15 // indirect
|
||||
github.com/tklauser/numcpus v0.10.0 // indirect
|
||||
|
||||
34
cli/go.sum
34
cli/go.sum
@@ -181,6 +181,8 @@ github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpv
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/gobwas/glob v0.2.4-0.20181002190808-e7a84e9525fe h1:zn8tqiUbec4wR94o7Qj3LZCAT6uGobhEgnDRg6isG5U=
|
||||
github.com/gobwas/glob v0.2.4-0.20181002190808-e7a84e9525fe/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
@@ -226,8 +228,6 @@ github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
|
||||
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
|
||||
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
|
||||
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
@@ -268,8 +268,6 @@ github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2E
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
@@ -316,8 +314,6 @@ github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa1
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
||||
@@ -342,8 +338,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/modood/table v0.0.0-20220527013332-8d47e76dad33 h1:T5IbS9C1G2zeHb6eBy6OfIvj5tfQB23kGFpewCJuGDg=
|
||||
github.com/modood/table v0.0.0-20220527013332-8d47e76dad33/go.mod h1:41qyXVI5QH9/ObyPj27CGCVau5v/njfc3Gjj7yzr0HQ=
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
||||
@@ -382,6 +376,8 @@ github.com/opencontainers/selinux v1.13.1 h1:A8nNeceYngH9Ow++M+VVEwJVpdFmrlxsN22
|
||||
github.com/opencontainers/selinux v1.13.1/go.mod h1:S10WXZ/osk2kWOYKy1x2f/eXF5ZHJoUs8UU/2caNRbg=
|
||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI=
|
||||
@@ -422,6 +418,8 @@ github.com/rubenv/sql-migrate v1.8.0 h1:dXnYiJk9k3wetp7GfQbKJcPHjVJL6YK19tKj8t2N
|
||||
github.com/rubenv/sql-migrate v1.8.0/go.mod h1:F2bGFBwCU+pnmbtNYDeKvSuvL6lBVtXDXUUv5t+u1qw=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA=
|
||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
|
||||
@@ -440,17 +438,19 @@ github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c h1:aqg5Vm5dwtvL+Yg
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c/go.mod h1:owqhoLW1qZoYLZzLnBw+QkPP9WZnjlSWihhxAJC1+/M=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY=
|
||||
github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec=
|
||||
github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
|
||||
github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60=
|
||||
github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE=
|
||||
github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
||||
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
|
||||
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
|
||||
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
@@ -466,6 +466,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/thoas/go-funk v0.9.3 h1:7+nAEx3kn5ZJcnDm2Bh23N2yOtweO14bi//dvRtgLpw=
|
||||
|
||||
133
cli/pkg/amdgpu/tasks.go
Normal file
133
cli/pkg/amdgpu/tasks.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package amdgpu
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
cc "github.com/beclab/Olares/cli/pkg/core/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/connector"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/core/task"
|
||||
"github.com/beclab/Olares/cli/pkg/utils"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// InstallAmdRocmModule installs AMD ROCm stack on supported Ubuntu if AMD GPU is present.
|
||||
type InstallAmdRocmModule struct {
|
||||
common.KubeModule
|
||||
}
|
||||
|
||||
func (m *InstallAmdRocmModule) Init() {
|
||||
m.Name = "InstallAMDGPU"
|
||||
|
||||
installAmd := &task.RemoteTask{
|
||||
Name: "InstallAmdRocm",
|
||||
Hosts: m.Runtime.GetHostsByRole(common.Master),
|
||||
Action: &InstallAmdRocm{
|
||||
// no manifest needed
|
||||
},
|
||||
Parallel: false,
|
||||
Retry: 1,
|
||||
}
|
||||
|
||||
m.Tasks = []task.Interface{
|
||||
installAmd,
|
||||
}
|
||||
}
|
||||
|
||||
// InstallAmdRocm installs ROCm using amdgpu-install on Ubuntu 22.04/24.04 for AMD GPUs.
|
||||
type InstallAmdRocm struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (t *InstallAmdRocm) Execute(runtime connector.Runtime) error {
|
||||
si := runtime.GetSystemInfo()
|
||||
if !si.IsLinux() || !si.IsUbuntu() || !(si.IsUbuntuVersionEqual(connector.Ubuntu2204) || si.IsUbuntuVersionEqual(connector.Ubuntu2404)) {
|
||||
return nil
|
||||
}
|
||||
|
||||
amdGPUExists, err := utils.HasAmdIGPU(runtime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// skip rocm install
|
||||
if !amdGPUExists {
|
||||
return nil
|
||||
}
|
||||
rocmV, _ := utils.RocmVersion()
|
||||
min := semver.MustParse("7.1.1")
|
||||
if rocmV != nil && rocmV.LessThan(min) {
|
||||
return fmt.Errorf("detected ROCm version %s, which is lower than required %s; please uninstall existing ROCm/AMDGPU components before installation with command: olares-cli amdgpu uninstall", rocmV.Original(), min.Original())
|
||||
}
|
||||
if rocmV != nil && rocmV.GreaterThan(min) {
|
||||
logger.Warnf("Warning: detected ROCm version %s great than maximum tested version %s")
|
||||
return nil
|
||||
}
|
||||
if rocmV != nil && rocmV.Equal(min) {
|
||||
logger.Infof("detected ROCm version %s, skip rocm install...", min.Original())
|
||||
return nil
|
||||
}
|
||||
|
||||
// ensure python3-setuptools and python3-wheel
|
||||
_, _ = runtime.GetRunner().SudoCmd("apt-get update", false, true)
|
||||
checkPkgs := "dpkg -s python3-setuptools python3-wheel >/dev/null 2>&1 || DEBIAN_FRONTEND=noninteractive apt-get install -y python3-setuptools python3-wheel"
|
||||
if _, err := runtime.GetRunner().SudoCmd(checkPkgs, false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to install python3-setuptools and python3-wheel")
|
||||
}
|
||||
// ensure amdgpu-install exists
|
||||
if _, err := exec.LookPath("amdgpu-install"); err != nil {
|
||||
var debURL string
|
||||
if si.IsUbuntuVersionEqual(connector.Ubuntu2404) {
|
||||
debURL = "https://repo.radeon.com/amdgpu-install/7.1.1/ubuntu/noble/amdgpu-install_7.1.1.70101-1_all.deb"
|
||||
} else {
|
||||
debURL = "https://repo.radeon.com/amdgpu-install/7.1.1/ubuntu/jammy/amdgpu-install_7.1.1.70101-1_all.deb"
|
||||
}
|
||||
tmpDeb := path.Join(runtime.GetBaseDir(), cc.PackageCacheDir, "gpu", "amdgpu-install_7.1.1.70101-1_all.deb")
|
||||
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("install -d -m 0755 %s", filepath.Dir(tmpDeb)), false, true); err != nil {
|
||||
return err
|
||||
}
|
||||
cmd := fmt.Sprintf("sh -c 'wget -O %s %s'", tmpDeb, debURL)
|
||||
if _, err := runtime.GetRunner().SudoCmd(cmd, false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to download amdgpu-install deb")
|
||||
}
|
||||
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("DEBIAN_FRONTEND=noninteractive apt-get install -y %s", tmpDeb), false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to install amdgpu-install deb")
|
||||
}
|
||||
}
|
||||
// run installer for rocm usecase
|
||||
if _, err := runtime.GetRunner().SudoCmd("amdgpu-install -y --usecase=rocm", false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to install AMD ROCm via amdgpu-install")
|
||||
}
|
||||
fmt.Println()
|
||||
logger.Warn("Warning: To enable ROCm, please reboot your machine after installation.")
|
||||
return nil
|
||||
}
|
||||
|
||||
type AmdgpuInstallAction struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (t *AmdgpuInstallAction) Execute(runtime connector.Runtime) error {
|
||||
if _, err := runtime.GetRunner().SudoCmd("amdgpu-install -y --usecase=rocm", false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to install AMD ROCm via amdgpu-install")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AmdgpuUninstallAction struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (t *AmdgpuUninstallAction) Execute(runtime connector.Runtime) error {
|
||||
if _, err := runtime.GetRunner().SudoCmd("amdgpu-install --uninstall -y", false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to uninstall AMD ROCm via amdgpu-install")
|
||||
}
|
||||
fmt.Println()
|
||||
logger.Warn("Warning: Please reboot your machine after uninstall to fully remove ROCm components.")
|
||||
return nil
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package confirm
|
||||
|
||||
import (
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/task"
|
||||
)
|
||||
|
||||
type InstallConfirmModule struct {
|
||||
common.KubeModule
|
||||
Skip bool
|
||||
}
|
||||
|
||||
func (i *InstallConfirmModule) IsSkip() bool {
|
||||
return i.Skip
|
||||
}
|
||||
|
||||
func (i *InstallConfirmModule) Init() {
|
||||
i.Name = "ConfirmModule"
|
||||
i.Desc = "Display confirmation form"
|
||||
|
||||
display := &task.LocalTask{
|
||||
Name: "ConfirmForm",
|
||||
Desc: "Display confirmation form",
|
||||
Action: new(InstallationConfirm),
|
||||
}
|
||||
|
||||
i.Tasks = []task.Interface{
|
||||
display,
|
||||
}
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package confirm
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/modood/table"
|
||||
"github.com/pkg/errors"
|
||||
versionutil "k8s.io/apimachinery/pkg/util/version"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/connector"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
)
|
||||
|
||||
// PreCheckResults defines the items to be checked.
|
||||
type PreCheckResults struct {
|
||||
Name string `table:"name"`
|
||||
Sudo string `table:"sudo"`
|
||||
Curl string `table:"curl"`
|
||||
Openssl string `table:"openssl"`
|
||||
Ebtables string `table:"ebtables"`
|
||||
Socat string `table:"socat"`
|
||||
Ipset string `table:"ipset"`
|
||||
Ipvsadm string `table:"ipvsadm"`
|
||||
Conntrack string `table:"conntrack"`
|
||||
Chronyd string `table:"chrony"`
|
||||
Docker string `table:"docker"`
|
||||
Containerd string `table:"containerd"`
|
||||
Nfs string `table:"nfs client"`
|
||||
Ceph string `table:"ceph client"`
|
||||
Glusterfs string `table:"glusterfs client"`
|
||||
Time string `table:"time"`
|
||||
}
|
||||
|
||||
type InstallationConfirm struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (i *InstallationConfirm) Execute(runtime connector.Runtime) error {
|
||||
var (
|
||||
results []PreCheckResults
|
||||
stopFlag bool
|
||||
)
|
||||
|
||||
pre := make([]map[string]string, 0, len(runtime.GetAllHosts()))
|
||||
for _, host := range runtime.GetAllHosts() {
|
||||
if v, ok := host.GetCache().Get(common.NodePreCheck); ok {
|
||||
pre = append(pre, v.(map[string]string))
|
||||
} else {
|
||||
return errors.New("get node check result failed by host cache")
|
||||
}
|
||||
}
|
||||
|
||||
for node := range pre {
|
||||
var result PreCheckResults
|
||||
_ = mapstructure.Decode(pre[node], &result)
|
||||
results = append(results, result)
|
||||
}
|
||||
table.OutputA(results)
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
|
||||
if i.KubeConf.Arg.Artifact == "" {
|
||||
for _, host := range results {
|
||||
if host.Sudo == "" {
|
||||
logger.Errorf("%s: sudo is required.", host.Name)
|
||||
stopFlag = true
|
||||
}
|
||||
|
||||
if host.Conntrack == "" {
|
||||
logger.Errorf("%s: conntrack is required.", host.Name)
|
||||
stopFlag = true
|
||||
}
|
||||
|
||||
if host.Socat == "" {
|
||||
logger.Errorf("%s: socat is required.", host.Name)
|
||||
stopFlag = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("")
|
||||
fmt.Println("This is a simple check of your environment.")
|
||||
fmt.Println("Before installation, ensure that your machines meet all requirements specified at")
|
||||
fmt.Println("https://github.com/kubesphere/kubekey#requirements-and-recommendations")
|
||||
fmt.Println("")
|
||||
|
||||
if k8sVersion, err := versionutil.ParseGeneric(i.KubeConf.Cluster.Kubernetes.Version); err == nil {
|
||||
if k8sVersion.AtLeast(versionutil.MustParseSemantic("v1.24.0")) && i.KubeConf.Cluster.Kubernetes.ContainerManager == common.Docker {
|
||||
fmt.Println("[Notice]")
|
||||
fmt.Println("Incorrect runtime. Please specify a container runtime other than Docker to install Kubernetes v1.24 or later.")
|
||||
fmt.Println("You can set \"spec.kubernetes.containerManager\" in the configuration file to \"containerd\" or add \"--container-manager containerd\" to the \"./kk create cluster\" command.")
|
||||
fmt.Println("For more information, see:")
|
||||
fmt.Println("https://github.com/kubesphere/kubekey/blob/master/docs/commands/kk-create-cluster.md")
|
||||
fmt.Println("https://kubernetes.io/docs/setup/production-environment/container-runtimes/#container-runtimes")
|
||||
fmt.Println("https://kubernetes.io/blog/2022/02/17/dockershim-faq/")
|
||||
fmt.Println("")
|
||||
stopFlag = true
|
||||
}
|
||||
}
|
||||
|
||||
if stopFlag {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
confirmOK := true // TODO: force skip
|
||||
for !confirmOK {
|
||||
fmt.Printf("Continue this installation? [yes/no]: ")
|
||||
input, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
input = strings.TrimSpace(strings.ToLower(input))
|
||||
|
||||
switch strings.ToLower(input) {
|
||||
case "yes", "y":
|
||||
confirmOK = true
|
||||
case "no", "n":
|
||||
os.Exit(0)
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -81,6 +81,7 @@ func (m *RunPrechecksModule) Init() {
|
||||
new(NvidiaCardArchChecker),
|
||||
new(NouveauChecker),
|
||||
new(CudaChecker),
|
||||
new(RocmChecker),
|
||||
}
|
||||
runPreChecks := &task.LocalTask{
|
||||
Name: "RunPrechecks",
|
||||
|
||||
@@ -372,6 +372,48 @@ func (c *CudaChecker) Check(runtime connector.Runtime) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RocmChecker checks AMD ROCm version for AMD GPU on Ubuntu 22.04/24.04 only.
|
||||
type RocmChecker struct{}
|
||||
|
||||
func (r *RocmChecker) Name() string {
|
||||
return "ROCm"
|
||||
}
|
||||
|
||||
func (r *RocmChecker) Check(runtime connector.Runtime) error {
|
||||
if !runtime.GetSystemInfo().IsLinux() {
|
||||
return nil
|
||||
}
|
||||
si := runtime.GetSystemInfo()
|
||||
if !si.IsUbuntu() || !(si.IsUbuntuVersionEqual(connector.Ubuntu2204) || si.IsUbuntuVersionEqual(connector.Ubuntu2404)) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// detect AMD GPU presence
|
||||
amdGPUExists, err := utils.HasAmdIGPU(runtime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// no AMD GPU found, no need to check rocm
|
||||
if !amdGPUExists {
|
||||
return nil
|
||||
}
|
||||
|
||||
curV, err := utils.RocmVersion()
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
min := semver.MustParse("7.1.1")
|
||||
if curV.LessThan(min) {
|
||||
return fmt.Errorf("detected ROCm version %s, which is lower than required %s; please uninstall existing ROCm/AMDGPU components before installation with command: olares-cli amdgpu uninstall", curV.Original(), min.Original())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// precheck - task
|
||||
|
||||
@@ -489,7 +531,7 @@ func (t *GetStorageKeyTask) Execute(runtime connector.Runtime) error {
|
||||
defer cancel()
|
||||
|
||||
if stdout, err := runtime.GetRunner().CmdContext(ctx, fmt.Sprintf("%s get terminus terminus -o jsonpath='{.metadata.annotations.bytetrade\\.io/s3-ak}'", kubectl), false, false); err != nil {
|
||||
storageAccessKey = os.Getenv(common.ENV_AWS_ACCESS_KEY_ID_SETUP)
|
||||
storageAccessKey = t.KubeConf.Arg.Storage.StorageAccessKey
|
||||
if storageAccessKey == "" {
|
||||
logger.Errorf("storage access key not found")
|
||||
}
|
||||
@@ -498,7 +540,7 @@ func (t *GetStorageKeyTask) Execute(runtime connector.Runtime) error {
|
||||
}
|
||||
|
||||
if stdout, err := runtime.GetRunner().CmdContext(ctx, fmt.Sprintf("%s get terminus terminus -o jsonpath='{.metadata.annotations.bytetrade\\.io/s3-sk}'", kubectl), false, false); err != nil {
|
||||
storageSecretKey = os.Getenv(common.ENV_AWS_SECRET_ACCESS_KEY_SETUP)
|
||||
storageSecretKey = t.KubeConf.Arg.Storage.StorageSecretKey
|
||||
if storageSecretKey == "" {
|
||||
logger.Errorf("storage secret key not found")
|
||||
}
|
||||
@@ -507,7 +549,7 @@ func (t *GetStorageKeyTask) Execute(runtime connector.Runtime) error {
|
||||
}
|
||||
|
||||
if stdout, err := runtime.GetRunner().CmdContext(ctx, fmt.Sprintf("%s get terminus terminus -o jsonpath='{.metadata.annotations.bytetrade\\.io/s3-sts}'", kubectl), false, false); err != nil {
|
||||
storageToken = os.Getenv(common.ENV_AWS_SESSION_TOKEN_SETUP)
|
||||
storageToken = t.KubeConf.Arg.Storage.StorageToken
|
||||
if storageToken == "" {
|
||||
logger.Errorf("storage token not found")
|
||||
}
|
||||
@@ -516,7 +558,7 @@ func (t *GetStorageKeyTask) Execute(runtime connector.Runtime) error {
|
||||
}
|
||||
|
||||
if stdout, err := runtime.GetRunner().CmdContext(ctx, fmt.Sprintf("%s get terminus terminus -o jsonpath='{.metadata.labels.bytetrade\\.io/cluster-id}'", kubectl), false, false); err != nil {
|
||||
storageClusterId = os.Getenv(common.ENV_CLUSTER_ID)
|
||||
storageClusterId = t.KubeConf.Arg.Storage.StorageClusterId
|
||||
if storageClusterId == "" {
|
||||
logger.Errorf("storage cluster id not found")
|
||||
}
|
||||
|
||||
@@ -23,31 +23,19 @@ import (
|
||||
const (
|
||||
DefaultK8sVersion = "v1.33.3"
|
||||
DefaultK3sVersion = "v1.33.3-k3s"
|
||||
DefaultKubernetesVersion = ""
|
||||
DefaultKubeSphereVersion = "v3.3.0"
|
||||
CurrentVerifiedCudaVersion = "13.1"
|
||||
)
|
||||
|
||||
const (
|
||||
K3s = "k3s"
|
||||
K8e = "k8e"
|
||||
Kubernetes = "kubernetes"
|
||||
K3s = "k3s"
|
||||
|
||||
LocalHost = "localhost"
|
||||
|
||||
AllInOne = "allInOne"
|
||||
File = "file"
|
||||
Operator = "operator"
|
||||
CommandLine = "commandLine"
|
||||
|
||||
Master = "master"
|
||||
Worker = "worker"
|
||||
ETCD = "etcd"
|
||||
K8s = "k8s"
|
||||
Registry = "registry"
|
||||
KubeKey = "kubekey"
|
||||
Harbor = "harbor"
|
||||
DockerCompose = "compose"
|
||||
Master = "master"
|
||||
Worker = "worker"
|
||||
ETCD = "etcd"
|
||||
K8s = "k8s"
|
||||
Registry = "registry"
|
||||
|
||||
KubeBinaries = "KubeBinaries"
|
||||
WslBinaries = "WslBinaries"
|
||||
@@ -58,23 +46,14 @@ const (
|
||||
BinDir = "/usr/local/bin"
|
||||
KubeConfigDir = "/etc/kubernetes"
|
||||
KubeAddonsDir = "/etc/kubernetes/addons"
|
||||
KubeEtcdCertDir = "/etc/kubernetes/etcd"
|
||||
KubeCertDir = "/etc/kubernetes/pki"
|
||||
KubeManifestDir = "/etc/kubernetes/manifests"
|
||||
KubeScriptDir = "/usr/local/bin/kube-scripts"
|
||||
KubeletFlexvolumesPluginsDir = "/usr/libexec/kubernetes/kubelet-plugins/volume/exec"
|
||||
K3sImageDir = "/var/lib/images"
|
||||
MinikubeDefaultProfile = "olares-0"
|
||||
MinikubeEtcdCertDir = "/var/lib/minikube/certs/etcd"
|
||||
WSLDefaultDistribution = "Ubuntu"
|
||||
RunLockDir = "/var/run/lock"
|
||||
|
||||
InstallerScriptsDir = "scripts"
|
||||
|
||||
ETCDCertDir = "/etc/ssl/etcd/ssl"
|
||||
RegistryCertDir = "/etc/ssl/registry/ssl"
|
||||
|
||||
HaproxyDir = "/etc/kubekey/haproxy"
|
||||
ETCDCertDir = "/etc/ssl/etcd/ssl"
|
||||
|
||||
IPv4Regexp = "[\\d]+\\.[\\d]+\\.[\\d]+\\.[\\d]+"
|
||||
IPv6Regexp = "[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){0,7}::[a-f0-9]{0,4}(:[a-f0-9]{1,4}){0,7}"
|
||||
@@ -85,7 +64,6 @@ const (
|
||||
Kubeovn = "kubeovn"
|
||||
|
||||
Docker = "docker"
|
||||
Crictl = "crictl"
|
||||
Containerd = "containerd"
|
||||
Crio = "crio"
|
||||
Isula = "isula"
|
||||
@@ -94,14 +72,8 @@ const (
|
||||
// global cache key
|
||||
// PreCheckModule
|
||||
NodePreCheck = "nodePreCheck"
|
||||
K8sVersion = "k8sVersion" // current k8s version
|
||||
MaxK8sVersion = "maxK8sVersion" // max k8s version of nodes
|
||||
KubeSphereVersion = "kubeSphereVersion" // current KubeSphere version
|
||||
ClusterNodeStatus = "clusterNodeStatus"
|
||||
ClusterNodeCRIRuntimes = "ClusterNodeCRIRuntimes"
|
||||
DesiredK8sVersion = "desiredK8sVersion"
|
||||
PlanK8sVersion = "planK8sVersion"
|
||||
NodeK8sVersion = "NodeK8sVersion"
|
||||
|
||||
// ETCDModule
|
||||
ETCDCluster = "etcdCluster"
|
||||
@@ -113,15 +85,6 @@ const (
|
||||
ClusterExist = "clusterExist"
|
||||
|
||||
MasterInfo = "masterInfo"
|
||||
|
||||
// CertsModule
|
||||
Certificate = "certificate"
|
||||
CaCertificate = "caCertificate"
|
||||
|
||||
// Artifact pipeline
|
||||
Artifact = "artifact"
|
||||
|
||||
SkipMasterNodePullImages = "skipMasterNodePullImages"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -147,16 +110,6 @@ const (
|
||||
Fedora = "fedora"
|
||||
RHEl = "rhel"
|
||||
Raspbian = "raspbian"
|
||||
PVE = "pve"
|
||||
WSL = "wsl"
|
||||
)
|
||||
|
||||
const (
|
||||
TRUE = "true"
|
||||
FALSE = "false"
|
||||
|
||||
YES = "yes"
|
||||
NO = "no"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -271,32 +224,82 @@ const (
|
||||
ENV_OLARES_VERSION = "OLARES_VERSION"
|
||||
ENV_TERMINUS_IS_CLOUD_VERSION = "TERMINUS_IS_CLOUD_VERSION"
|
||||
ENV_KUBE_TYPE = "KUBE_TYPE"
|
||||
ENV_REGISTRY_MIRRORS = "REGISTRY_MIRRORS"
|
||||
ENV_OLARES_CDN_SERVICE = "OLARES_SYSTEM_CDN_SERVICE"
|
||||
ENV_STORAGE = "STORAGE"
|
||||
ENV_S3_BUCKET = "S3_BUCKET"
|
||||
ENV_LOCAL_GPU_ENABLE = "LOCAL_GPU_ENABLE"
|
||||
ENV_AWS_ACCESS_KEY_ID_SETUP = "AWS_ACCESS_KEY_ID_SETUP"
|
||||
ENV_AWS_SECRET_ACCESS_KEY_SETUP = "AWS_SECRET_ACCESS_KEY_SETUP"
|
||||
ENV_AWS_SESSION_TOKEN_SETUP = "AWS_SESSION_TOKEN_SETUP"
|
||||
ENV_BACKUP_KEY_PREFIX = "BACKUP_KEY_PREFIX"
|
||||
ENV_BACKUP_SECRET = "BACKUP_SECRET"
|
||||
ENV_CLUSTER_ID = "CLUSTER_ID"
|
||||
ENV_BACKUP_CLUSTER_BUCKET = "BACKUP_CLUSTER_BUCKET"
|
||||
ENV_HOST_IP = "HOST_IP"
|
||||
ENV_PREINSTALL = "PREINSTALL"
|
||||
ENV_DISABLE_HOST_IP_PROMPT = "DISABLE_HOST_IP_PROMPT"
|
||||
ENV_AUTO_ADD_FIREWALL_RULES = "AUTO_ADD_FIREWALL_RULES"
|
||||
ENV_TERMINUS_OS_DOMAINNAME = "TERMINUS_OS_DOMAINNAME"
|
||||
ENV_DEFAULT_WSL_DISTRO_LOCATION = "DEFAULT_WSL_DISTRO_LOCATION" // If set to 1, the default WSL distro storage will be used.
|
||||
|
||||
ENV_CONTAINER = "container"
|
||||
ENV_CONTAINER_MODE = "CONTAINER_MODE" // running in docker container
|
||||
|
||||
OLARES_SYSTEM_ENV_FILENAME = "system-env.yaml"
|
||||
OLARES_USER_ENV_FILENAME = "user-env.yaml"
|
||||
)
|
||||
|
||||
const (
|
||||
FlagVersion = "version"
|
||||
FlagBaseDir = "base-dir"
|
||||
|
||||
FlagWSLDistribution = "wsl-distribution"
|
||||
FlagLegacyWSLDistribution = "distribution"
|
||||
|
||||
FlagMasterHost = "master-host"
|
||||
FlagMasterNodeName = "master-node-name"
|
||||
FlagMasterSSHUser = "master-ssh-user"
|
||||
FlagMasterSSHPassword = "master-ssh-password"
|
||||
FlagMasterSSHPrivateKeyPath = "master-ssh-private-key-path"
|
||||
FlagMasterSSHPort = "master-ssh-port"
|
||||
|
||||
FlagOSUserName = "os-username"
|
||||
EnvLegacyOSUserName = "TERMINUS_OS_USERNAME"
|
||||
|
||||
FlagOSDomainName = "os-domainname"
|
||||
EnvLegacyOSDomainName = "TERMINUS_OS_DOMAINNAME"
|
||||
|
||||
FlagOSPassword = "os-password"
|
||||
EnvLegacyEncryptedOSPassword = "TERMINUS_OS_PASSWORD"
|
||||
|
||||
FlagCDNService = "cdn-service"
|
||||
FlagManifest = "manifest"
|
||||
FlagURLOverride = "url-override"
|
||||
FlagReleaseID = "release-id"
|
||||
FlagKubeType = "kube-type"
|
||||
FlagLegacyKubeType = "kube"
|
||||
|
||||
FlagEnableJuiceFS = "enable-juicefs"
|
||||
FlagLegacyEnableJuiceFS = "with-juicefs"
|
||||
EnvLegacyEnableJuiceFS = "JUICEFS"
|
||||
|
||||
FlagMiniKubeProfile = "minikube-profile"
|
||||
FlagLegacyMiniKubeProfile = "profile"
|
||||
|
||||
FlagEnableReverseProxy = "enable-reverse-proxy"
|
||||
FlagEnablePodSwap = "enable-pod-swap"
|
||||
FlagSwappiness = "swappiness"
|
||||
FlagEnableZRAM = "enable-zram"
|
||||
FlagZRAMSize = "zram-size"
|
||||
FlagZRAMSwapPriority = "zram-swap-priority"
|
||||
FlagRegistryMirrors = "registry-mirrors"
|
||||
|
||||
FlagStorageType = "storage-type"
|
||||
FlagLegacyStorageType = "storage"
|
||||
|
||||
FlagS3Bucket = "s3-bucket"
|
||||
FlagBackupKeyPrefix = "backup-key-prefix"
|
||||
FlagAWSAccessKeyIDSetup = "aws-access-key-id-setup"
|
||||
FlagAWSSecretAccessKeySetup = "aws-secret-access-key-setup"
|
||||
FlagAWSSessionTokenSetup = "aws-session-token-setup"
|
||||
FlagClusterID = "cluster-id"
|
||||
FlagBackupSecret = "backup-secret"
|
||||
FlagBackupClusterBucket = "backup-cluster-bucket"
|
||||
FlagIsCloudVersion = "is-cloud-version"
|
||||
|
||||
FlagUninstallPhase = "uninstall-phase"
|
||||
FlagUninstallAll = "uninstall-all"
|
||||
)
|
||||
|
||||
func SetSystemEnv(key, value string) {
|
||||
os.Setenv(key, value)
|
||||
}
|
||||
|
||||
@@ -29,10 +29,8 @@ type KubeAction struct {
|
||||
func (k *KubeAction) AutoAssert(runtime connector.Runtime) {
|
||||
kubeRuntime := runtime.(*KubeRuntime)
|
||||
conf := &KubeConf{
|
||||
Cluster: kubeRuntime.Cluster,
|
||||
ClusterName: kubeRuntime.ClusterName,
|
||||
Kubeconfig: kubeRuntime.Kubeconfig,
|
||||
Arg: kubeRuntime.Arg,
|
||||
Cluster: kubeRuntime.Cluster,
|
||||
Arg: kubeRuntime.Arg,
|
||||
}
|
||||
|
||||
k.KubeConf = conf
|
||||
|
||||
@@ -22,11 +22,8 @@ import (
|
||||
)
|
||||
|
||||
type KubeConf struct {
|
||||
ClusterHosts []string
|
||||
ClusterName string
|
||||
Cluster *kubekeyapiv1alpha2.ClusterSpec
|
||||
Kubeconfig string
|
||||
Arg *Argument
|
||||
Cluster *kubekeyapiv1alpha2.ClusterSpec
|
||||
Arg *Argument
|
||||
}
|
||||
|
||||
type KubeModule struct {
|
||||
@@ -41,27 +38,8 @@ func (k *KubeModule) IsSkip() bool {
|
||||
func (k *KubeModule) AutoAssert() {
|
||||
kubeRuntime := k.Runtime.(*KubeRuntime)
|
||||
conf := &KubeConf{
|
||||
ClusterName: kubeRuntime.ClusterName,
|
||||
Cluster: kubeRuntime.Cluster,
|
||||
Kubeconfig: kubeRuntime.Kubeconfig,
|
||||
Arg: kubeRuntime.Arg,
|
||||
}
|
||||
|
||||
k.KubeConf = conf
|
||||
}
|
||||
|
||||
type KubeCustomModule struct {
|
||||
module.CustomModule
|
||||
KubeConf *KubeConf
|
||||
}
|
||||
|
||||
func (k *KubeCustomModule) AutoAssert() {
|
||||
kubeRuntime := k.Runtime.(*KubeRuntime)
|
||||
conf := &KubeConf{
|
||||
ClusterName: kubeRuntime.ClusterName,
|
||||
Cluster: kubeRuntime.Cluster,
|
||||
Kubeconfig: kubeRuntime.Kubeconfig,
|
||||
Arg: kubeRuntime.Arg,
|
||||
Cluster: kubeRuntime.Cluster,
|
||||
Arg: kubeRuntime.Arg,
|
||||
}
|
||||
|
||||
k.KubeConf = conf
|
||||
|
||||
@@ -29,9 +29,8 @@ type KubePrepare struct {
|
||||
func (k *KubePrepare) AutoAssert(runtime connector.Runtime) {
|
||||
kubeRuntime := runtime.(*KubeRuntime)
|
||||
conf := &KubeConf{
|
||||
Cluster: kubeRuntime.Cluster,
|
||||
Kubeconfig: kubeRuntime.Kubeconfig,
|
||||
Arg: kubeRuntime.Arg,
|
||||
Cluster: kubeRuntime.Cluster,
|
||||
Arg: kubeRuntime.Arg,
|
||||
}
|
||||
|
||||
k.KubeConf = conf
|
||||
|
||||
@@ -29,10 +29,8 @@ type KubeRollback struct {
|
||||
func (k *KubeRollback) AutoAssert(runtime connector.Runtime) {
|
||||
kubeRuntime := runtime.(*KubeRuntime)
|
||||
conf := &KubeConf{
|
||||
Cluster: kubeRuntime.Cluster,
|
||||
ClusterName: kubeRuntime.ClusterName,
|
||||
Kubeconfig: kubeRuntime.Kubeconfig,
|
||||
Arg: kubeRuntime.Arg,
|
||||
Cluster: kubeRuntime.Cluster,
|
||||
Arg: kubeRuntime.Arg,
|
||||
}
|
||||
|
||||
k.KubeConf = conf
|
||||
|
||||
@@ -28,7 +28,7 @@ import (
|
||||
"github.com/joho/godotenv"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
kubekeyapiv1alpha2 "github.com/beclab/Olares/cli/apis/kubekey/v1alpha2"
|
||||
"github.com/beclab/Olares/cli/pkg/core/common"
|
||||
@@ -40,43 +40,19 @@ import (
|
||||
|
||||
type KubeRuntime struct {
|
||||
connector.BaseRuntime
|
||||
ClusterName string
|
||||
Cluster *kubekeyapiv1alpha2.ClusterSpec
|
||||
Kubeconfig string
|
||||
Arg *Argument
|
||||
Cluster *kubekeyapiv1alpha2.ClusterSpec
|
||||
Arg *Argument
|
||||
}
|
||||
|
||||
type Argument struct {
|
||||
NodeName string `json:"node_name"`
|
||||
FilePath string `json:"file_path"`
|
||||
KubernetesVersion string `json:"kubernetes_version"`
|
||||
KsEnable bool `json:"ks_enable"`
|
||||
KsVersion string `json:"ks_version"`
|
||||
OlaresVersion string `json:"olares_version"`
|
||||
Debug bool `json:"debug"`
|
||||
IgnoreErr bool `json:"ignore_err"`
|
||||
SkipPullImages bool `json:"skip_pull_images"`
|
||||
SKipPushImages bool `json:"skip_push_images"`
|
||||
SecurityEnhancement bool `json:"security_enhancement"`
|
||||
DeployLocalStorage *bool `json:"deploy_local_storage"`
|
||||
// DownloadCommand func(path, url string) string
|
||||
SkipConfirmCheck bool `json:"skip_confirm_check"`
|
||||
InCluster bool `json:"in_cluster"`
|
||||
ContainerManager string `json:"container_manager"`
|
||||
FromCluster bool `json:"from_cluster"`
|
||||
KubeConfig string `json:"kube_config"`
|
||||
Artifact string `json:"artifact"`
|
||||
InstallPackages bool `json:"install_packages"`
|
||||
ImagesDir string `json:"images_dir"`
|
||||
Namespace string `json:"namespace"`
|
||||
DeleteCRI bool `json:"delete_cri"`
|
||||
Role string `json:"role"`
|
||||
Type string `json:"type"`
|
||||
Kubetype string `json:"kube_type"`
|
||||
SystemInfo connector.Systems
|
||||
InCluster bool `json:"in_cluster"`
|
||||
ContainerManager string `json:"container_manager"`
|
||||
Kubetype string `json:"kube_type"`
|
||||
SystemInfo connector.Systems
|
||||
|
||||
// Extra args
|
||||
ExtraAddon string `json:"extra_addon"` // addon yaml config
|
||||
RegistryMirrors string `json:"registry_mirrors"`
|
||||
OlaresCDNService string `json:"olares_cdn_service"`
|
||||
|
||||
@@ -86,10 +62,6 @@ type Argument struct {
|
||||
// master node ssh config
|
||||
*MasterHostConfig
|
||||
|
||||
LocalSSHPort int `json:"-"`
|
||||
|
||||
SkipMasterPullImages bool `json:"skip_master_pull_images"`
|
||||
|
||||
// User
|
||||
User *User `json:"user"`
|
||||
// if juicefs is opted off, the local storage is used directly
|
||||
@@ -102,8 +74,6 @@ type Argument struct {
|
||||
NetworkSettings *NetworkSettings `json:"network_settings"`
|
||||
GPU *GPU `json:"gpu"`
|
||||
|
||||
Request any `json:"-"`
|
||||
|
||||
IsCloudInstance bool `json:"is_cloud_instance"`
|
||||
MinikubeProfile string `json:"minikube_profile"`
|
||||
WSLDistribution string `json:"wsl_distribution"`
|
||||
@@ -114,8 +84,6 @@ type Argument struct {
|
||||
ConsoleLogTruncate bool `json:"console_log_truncate"`
|
||||
HostIP string `json:"host_ip"`
|
||||
|
||||
CudaVersion string `json:"cuda_version"`
|
||||
|
||||
IsOlaresInContainer bool `json:"is_olares_in_container"`
|
||||
}
|
||||
|
||||
@@ -127,14 +95,6 @@ type SwapConfig struct {
|
||||
ZRAMSwapPriority int `json:"zram_swap_priority"`
|
||||
}
|
||||
|
||||
func (cfg *SwapConfig) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.BoolVar(&cfg.EnablePodSwap, "enable-pod-swap", false, "Enable pods on Kubernetes cluster to use swap, setting --enable-zram, --zram-size or --zram-swap-priority implicitly enables this option, regardless of the command line args, note that only pods of the BestEffort QOS group can use swap due to K8s design")
|
||||
fs.IntVar(&cfg.Swappiness, "swappiness", 0, "Configure the Linux swappiness value, if not set, the current configuration is remained")
|
||||
fs.BoolVar(&cfg.EnableZRAM, "enable-zram", false, "Set up a ZRAM device to be used for swap, setting --zram-size or --zram-swap-priority implicitly enables this option, regardless of the command line args")
|
||||
fs.StringVar(&cfg.ZRAMSize, "zram-size", "", "Set the size of the ZRAM device, takes a format of https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/quantity, defaults to half of the total RAM")
|
||||
fs.IntVar(&cfg.ZRAMSwapPriority, "zram-swap-priority", 0, "Set the swap priority of the ZRAM device, between -1 and 32767, defaults to 100")
|
||||
}
|
||||
|
||||
func (cfg *SwapConfig) Validate() error {
|
||||
if cfg.ZRAMSize == "" {
|
||||
return nil
|
||||
@@ -164,21 +124,12 @@ type MasterHostConfig struct {
|
||||
MasterSSHPort int `json:"master_ssh_port"`
|
||||
}
|
||||
|
||||
func (cfg *MasterHostConfig) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.StringVar(&cfg.MasterHost, "master-host", "", "IP address of the master node")
|
||||
fs.StringVar(&cfg.MasterNodeName, "master-node-name", "", "Name of the master node")
|
||||
fs.StringVar(&cfg.MasterSSHUser, "master-ssh-user", "", "Username of the master node, defaults to root")
|
||||
fs.StringVar(&cfg.MasterSSHPassword, "master-ssh-password", "", "Password of the master node")
|
||||
fs.StringVar(&cfg.MasterSSHPrivateKeyPath, "master-ssh-private-key-path", "", "Path to the SSH key to access the master node, defaults to ~/.ssh/id_rsa")
|
||||
fs.IntVar(&cfg.MasterSSHPort, "master-ssh-port", 0, "SSH Port of the master node, defaults to 22")
|
||||
}
|
||||
|
||||
func (cfg *MasterHostConfig) Validate() error {
|
||||
if cfg.MasterHost == "" {
|
||||
return errors.New("--master-host is not provided")
|
||||
return errors.New("master host is not provided")
|
||||
}
|
||||
if cfg.MasterSSHUser != "" && cfg.MasterSSHUser != "root" && cfg.MasterSSHPassword == "" {
|
||||
return errors.New("--master-ssh-password must be provided for non-root user in order to execute sudo command")
|
||||
return errors.New("master ssh password must be provided for non-root user in order to execute sudo command")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -222,9 +173,9 @@ type Storage struct {
|
||||
StorageAccessKey string `json:"storage_access_key"`
|
||||
StorageSecretKey string `json:"storage_secret_key"`
|
||||
|
||||
StorageToken string `json:"storage_token"` // juicefs --> from env
|
||||
StorageClusterId string `json:"storage_cluster_id"` // use only on the Terminus cloud, juicefs --> from env
|
||||
StorageSyncSecret string `json:"storage_sync_secret"` // use only on the Terminus cloud --> from env
|
||||
StorageToken string `json:"storage_token"` // juicefs
|
||||
StorageClusterId string `json:"storage_cluster_id"` // use only on the Terminus cloud, juicefs
|
||||
StorageSyncSecret string `json:"storage_sync_secret"` // use only on the Terminus cloud
|
||||
BackupClusterBucket string `json:"backup_cluster_bucket"`
|
||||
}
|
||||
|
||||
@@ -235,58 +186,35 @@ type GPU struct {
|
||||
func NewArgument() *Argument {
|
||||
si := connector.GetSystemInfo()
|
||||
arg := &Argument{
|
||||
KsEnable: true,
|
||||
KsVersion: DefaultKubeSphereVersion,
|
||||
InstallPackages: false,
|
||||
SKipPushImages: false,
|
||||
ContainerManager: Containerd,
|
||||
SystemInfo: si,
|
||||
Storage: &Storage{
|
||||
StorageType: ManagedMinIO,
|
||||
},
|
||||
GPU: &GPU{
|
||||
Enable: !strings.EqualFold(os.Getenv(ENV_LOCAL_GPU_ENABLE), "0"), // default enable GPU, not set or 1 means enable
|
||||
GPU: &GPU{},
|
||||
User: &User{
|
||||
UserName: strings.TrimSpace(viper.GetString(FlagOSUserName)),
|
||||
DomainName: strings.TrimSpace(viper.GetString(FlagOSDomainName)),
|
||||
Password: strings.TrimSpace(viper.GetString(FlagOSPassword)),
|
||||
},
|
||||
User: &User{},
|
||||
NetworkSettings: &NetworkSettings{},
|
||||
RegistryMirrors: os.Getenv(ENV_REGISTRY_MIRRORS),
|
||||
OlaresCDNService: os.Getenv(ENV_OLARES_CDN_SERVICE),
|
||||
HostIP: os.Getenv(ENV_HOST_IP),
|
||||
RegistryMirrors: viper.GetString(FlagRegistryMirrors),
|
||||
OlaresCDNService: viper.GetString(FlagCDNService),
|
||||
HostIP: viper.GetString(ENV_HOST_IP),
|
||||
Environment: os.Environ(),
|
||||
MasterHostConfig: &MasterHostConfig{},
|
||||
SwapConfig: &SwapConfig{},
|
||||
}
|
||||
// default enable GPU unless explicitly set to "0"
|
||||
arg.GPU.Enable = !strings.EqualFold(os.Getenv(ENV_LOCAL_GPU_ENABLE), "0")
|
||||
arg.IsCloudInstance, _ = strconv.ParseBool(os.Getenv(ENV_TERMINUS_IS_CLOUD_VERSION))
|
||||
arg.IsOlaresInContainer = os.Getenv("CONTAINER_MODE") == "oic"
|
||||
arg.IsOlaresInContainer = os.Getenv(ENV_CONTAINER_MODE) == "oic"
|
||||
si.IsOIC = arg.IsOlaresInContainer
|
||||
|
||||
if err := arg.LoadReleaseInfo(); err != nil {
|
||||
fmt.Printf("error loading release info: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
arg.loadMasterHostConfig()
|
||||
return arg
|
||||
}
|
||||
|
||||
// LoadReleaseInfo loads base directory and version settings
|
||||
// from /etc/olares/release and environment variables,
|
||||
// with the latter takes precedence.
|
||||
// Note that the command line options --base-dir and --version
|
||||
// still have the highest priority and will override any values loaded here
|
||||
func (a *Argument) LoadReleaseInfo() error {
|
||||
// load envs from the release file
|
||||
// already existing envs are not overridden so
|
||||
err := godotenv.Load(OlaresReleaseFile)
|
||||
|
||||
// silently ignore the non-existence of a release file
|
||||
// otherwise, return the error
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
a.BaseDir = os.Getenv(ENV_OLARES_BASE_DIR)
|
||||
a.OlaresVersion = os.Getenv(ENV_OLARES_VERSION)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Argument) SaveReleaseInfo(withoutName bool) error {
|
||||
if a.BaseDir == "" {
|
||||
return errors.New("invalid: empty base directory")
|
||||
@@ -372,14 +300,6 @@ func (a *Argument) SetOlaresVersion(version string) {
|
||||
a.OlaresVersion = version
|
||||
}
|
||||
|
||||
func (a *Argument) SetRegistryMirrors(registryMirrors string) {
|
||||
a.RegistryMirrors = registryMirrors
|
||||
}
|
||||
|
||||
func (a *Argument) SetDeleteCRI(deleteCRI bool) {
|
||||
a.DeleteCRI = deleteCRI
|
||||
}
|
||||
|
||||
func (a *Argument) SetStorage(storage *Storage) {
|
||||
a.Storage = storage
|
||||
}
|
||||
@@ -411,11 +331,6 @@ func (a *Argument) SetKubeVersion(kubeType string) {
|
||||
a.Kubetype = kubeType
|
||||
}
|
||||
|
||||
func (a *Argument) SetKubernetesVersion(kubeType string, kubeVersion string) {
|
||||
a.KubernetesVersion = kubeVersion
|
||||
a.Kubetype = kubeType
|
||||
}
|
||||
|
||||
func (a *Argument) SetBaseDir(dir string) {
|
||||
if dir != "" {
|
||||
a.BaseDir = dir
|
||||
@@ -434,10 +349,36 @@ func (a *Argument) SetBaseDir(dir string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Argument) SetCudaVersion(cudaVersion string) {
|
||||
a.CudaVersion = CurrentVerifiedCudaVersion
|
||||
if cudaVersion != "" {
|
||||
a.CudaVersion = cudaVersion
|
||||
// loadMasterHostConfig loads master host configuration from master.conf file (if exists)
|
||||
// and then overrides with any values set via command line flags or environment variables.
|
||||
func (a *Argument) loadMasterHostConfig() {
|
||||
// First, try to load from master.conf file
|
||||
configPath := filepath.Join(a.BaseDir, MasterHostConfigFile)
|
||||
if content, err := os.ReadFile(configPath); err == nil {
|
||||
json.Unmarshal(content, a.MasterHostConfig)
|
||||
}
|
||||
// Then override with viper values (from flags or env)
|
||||
if v := viper.GetString(FlagMasterHost); v != "" {
|
||||
a.MasterHost = v
|
||||
}
|
||||
if v := viper.GetString(FlagMasterNodeName); v != "" {
|
||||
a.MasterNodeName = v
|
||||
}
|
||||
if v := viper.GetString(FlagMasterSSHUser); v != "" {
|
||||
a.MasterSSHUser = v
|
||||
}
|
||||
if v := viper.GetString(FlagMasterSSHPassword); v != "" {
|
||||
a.MasterSSHPassword = v
|
||||
}
|
||||
if v := viper.GetString(FlagMasterSSHPrivateKeyPath); v != "" {
|
||||
a.MasterSSHPrivateKeyPath = v
|
||||
}
|
||||
if v := viper.GetInt(FlagMasterSSHPort); v != 0 {
|
||||
a.MasterSSHPort = v
|
||||
}
|
||||
// Set a dummy name to bypass validity checks if master host is set but node name is not
|
||||
if a.MasterHost != "" && a.MasterNodeName == "" {
|
||||
a.MasterNodeName = "master"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,60 +408,15 @@ func (a *Argument) SetSwapConfig(config SwapConfig) {
|
||||
a.Swappiness = config.Swappiness
|
||||
}
|
||||
|
||||
func (a *Argument) SetMasterHostOverride(config MasterHostConfig) {
|
||||
if config.MasterHost != "" {
|
||||
a.MasterHost = config.MasterHost
|
||||
}
|
||||
if config.MasterNodeName != "" {
|
||||
a.MasterNodeName = config.MasterNodeName
|
||||
}
|
||||
|
||||
// set a dummy name to bypass validity checks
|
||||
// as it will be overridden later when the node name is fetched
|
||||
if a.MasterNodeName == "" {
|
||||
a.MasterNodeName = "master"
|
||||
}
|
||||
if config.MasterSSHPassword != "" {
|
||||
a.MasterSSHPassword = config.MasterSSHPassword
|
||||
}
|
||||
if config.MasterSSHUser != "" {
|
||||
a.MasterSSHUser = config.MasterSSHUser
|
||||
}
|
||||
if config.MasterSSHPort != 0 {
|
||||
a.MasterSSHPort = config.MasterSSHPort
|
||||
}
|
||||
if config.MasterSSHPrivateKeyPath != "" {
|
||||
a.MasterSSHPrivateKeyPath = config.MasterSSHPrivateKeyPath
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Argument) LoadMasterHostConfigIfAny() error {
|
||||
if a.BaseDir == "" {
|
||||
return errors.New("basedir unset")
|
||||
}
|
||||
content, err := os.ReadFile(filepath.Join(a.BaseDir, MasterHostConfigFile))
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal(content, a.MasterHostConfig)
|
||||
}
|
||||
|
||||
func NewKubeRuntime(flag string, arg Argument) (*KubeRuntime, error) {
|
||||
loader := NewLoader(flag, arg)
|
||||
func NewKubeRuntime(arg Argument) (*KubeRuntime, error) {
|
||||
loader := NewLoader(arg)
|
||||
cluster, err := loader.Load()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = loadExtraAddons(cluster, arg.ExtraAddon); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
base := connector.NewBaseRuntime(cluster.Name, connector.NewDialer(),
|
||||
arg.Debug, arg.IgnoreErr, arg.BaseDir, arg.OlaresVersion, arg.ConsoleLogFileName, arg.ConsoleLogTruncate, arg.SystemInfo)
|
||||
arg.BaseDir, arg.OlaresVersion, arg.ConsoleLogFileName, arg.ConsoleLogTruncate, arg.SystemInfo)
|
||||
|
||||
clusterSpec := &cluster.Spec
|
||||
defaultCluster, roleGroups := clusterSpec.SetDefaultClusterSpec(arg.InCluster, arg.SystemInfo.IsDarwin())
|
||||
@@ -530,9 +426,6 @@ func NewKubeRuntime(flag string, arg Argument) (*KubeRuntime, error) {
|
||||
if host.IsRole(Master) || host.IsRole(Worker) {
|
||||
host.SetRole(K8s)
|
||||
}
|
||||
if host.IsRole(Master) && arg.SkipMasterPullImages {
|
||||
host.GetCache().Set(SkipMasterNodePullImages, true)
|
||||
}
|
||||
if _, ok := hostSet[host.GetName()]; !ok {
|
||||
hostSet[host.GetName()] = struct{}{}
|
||||
base.AppendHost(host)
|
||||
@@ -546,12 +439,9 @@ func NewKubeRuntime(flag string, arg Argument) (*KubeRuntime, error) {
|
||||
args, _ := json.Marshal(arg)
|
||||
logger.Debugf("[runtime] arg: %s", string(args))
|
||||
|
||||
arg.KsEnable = defaultCluster.KubeSphere.Enabled
|
||||
arg.KsVersion = defaultCluster.KubeSphere.Version
|
||||
r := &KubeRuntime{
|
||||
Cluster: defaultCluster,
|
||||
ClusterName: cluster.Name,
|
||||
Arg: &arg,
|
||||
Cluster: defaultCluster,
|
||||
Arg: &arg,
|
||||
}
|
||||
r.BaseRuntime = base
|
||||
|
||||
|
||||
@@ -17,15 +17,9 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -33,10 +27,7 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/core/util"
|
||||
|
||||
kubekeyapiv1alpha2 "github.com/beclab/Olares/cli/apis/kubekey/v1alpha2"
|
||||
"github.com/beclab/Olares/cli/pkg/version/kubesphere"
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/yaml.v2"
|
||||
k8syaml "k8s.io/apimachinery/pkg/util/yaml"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -47,137 +38,19 @@ type Loader interface {
|
||||
Load() (*kubekeyapiv1alpha2.Cluster, error)
|
||||
}
|
||||
|
||||
type Options map[string]interface{}
|
||||
|
||||
func NewLoader(flag string, arg Argument) Loader {
|
||||
switch flag {
|
||||
case File:
|
||||
return NewFileLoader(arg)
|
||||
case Operator:
|
||||
return &ConfigMapLoader{}
|
||||
case AllInOne:
|
||||
return NewDefaultLoader(arg)
|
||||
case CommandLine:
|
||||
return NewCommandLineLoader(arg)
|
||||
default:
|
||||
return NewDefaultLoader(arg)
|
||||
}
|
||||
}
|
||||
|
||||
type CommandLineLoader struct {
|
||||
arg Argument
|
||||
hostname string
|
||||
kubernetesVersion string
|
||||
}
|
||||
|
||||
func NewCommandLineLoader(arg Argument) *CommandLineLoader {
|
||||
return &CommandLineLoader{
|
||||
arg: arg,
|
||||
kubernetesVersion: arg.KubernetesVersion,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CommandLineLoader) validate() error {
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Failed to get hostname: %v\n", err))
|
||||
}
|
||||
|
||||
c.hostname = hostname
|
||||
|
||||
// flags
|
||||
if c.arg.MasterNodeName == "" {
|
||||
return errors.New("No master nodeName provided, with flag '--master-node-name'")
|
||||
}
|
||||
if c.arg.MasterHost == "" {
|
||||
return errors.New("No master host provided, with flag '--master-host'")
|
||||
}
|
||||
if c.arg.MasterSSHUser == "" {
|
||||
return errors.New("No master ssh user provided, with flag '--master-ssh-user'")
|
||||
}
|
||||
if c.arg.KubernetesVersion == "" {
|
||||
return errors.New("No kubernetes version provided, with flag '--with-kubernetes'")
|
||||
}
|
||||
if c.arg.MasterSSHPassword == "" && c.arg.MasterSSHPrivateKeyPath == "" {
|
||||
return errors.New("No master ssh password and private key file, with flag '--master-ssh-password' or '--master-ssh-private-keyfile'")
|
||||
}
|
||||
|
||||
if err := localSSH(c.arg.SystemInfo.GetOsType()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CommandLineLoader) Load() (*kubekeyapiv1alpha2.Cluster, error) {
|
||||
u, err := currentUser(c.arg.SystemInfo.GetOsType())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := c.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cluster := &kubekeyapiv1alpha2.Cluster{}
|
||||
|
||||
// current node
|
||||
cluster.Spec.Hosts = append(cluster.Spec.Hosts, kubekeyapiv1alpha2.HostCfg{
|
||||
Name: c.hostname,
|
||||
Address: "",
|
||||
InternalAddress: "",
|
||||
Port: c.arg.LocalSSHPort,
|
||||
User: u.Name,
|
||||
PrivateKeyPath: fmt.Sprintf("%s/.ssh/id_rsa", u.HomeDir),
|
||||
Arch: "",
|
||||
})
|
||||
|
||||
cluster.Spec.RoleGroups = map[string][]string{
|
||||
Worker: {c.hostname},
|
||||
}
|
||||
|
||||
// master node
|
||||
masterHostCfg := kubekeyapiv1alpha2.HostCfg{
|
||||
Name: c.arg.MasterNodeName,
|
||||
Address: c.arg.MasterHost,
|
||||
InternalAddress: c.arg.MasterHost,
|
||||
Port: c.arg.MasterSSHPort,
|
||||
User: c.arg.MasterSSHUser,
|
||||
Arch: "",
|
||||
}
|
||||
if c.arg.MasterSSHPassword != "" {
|
||||
masterHostCfg.Password = c.arg.MasterSSHPassword
|
||||
}
|
||||
if c.arg.MasterSSHPrivateKeyPath != "" {
|
||||
masterHostCfg.Password = ""
|
||||
masterHostCfg.PrivateKeyPath = c.arg.MasterSSHPrivateKeyPath
|
||||
}
|
||||
|
||||
cluster.Spec.Hosts = append(cluster.Spec.Hosts, masterHostCfg)
|
||||
|
||||
cluster.Spec.RoleGroups[Master] = []string{c.arg.MasterNodeName}
|
||||
cluster.Spec.RoleGroups[ETCD] = []string{c.arg.MasterNodeName}
|
||||
|
||||
if err := defaultCommonClusterConfig(cluster, c.arg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cluster, nil
|
||||
func NewLoader(arg Argument) Loader {
|
||||
return NewDefaultLoader(arg)
|
||||
}
|
||||
|
||||
type DefaultLoader struct {
|
||||
arg Argument
|
||||
KubernetesVersion string
|
||||
KubeSphereVersion string
|
||||
KubeSphereEnable bool
|
||||
}
|
||||
|
||||
func NewDefaultLoader(arg Argument) *DefaultLoader {
|
||||
return &DefaultLoader{
|
||||
arg: arg,
|
||||
KubernetesVersion: arg.KubernetesVersion,
|
||||
KubeSphereVersion: arg.KsVersion,
|
||||
KubeSphereEnable: arg.KsEnable,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,16 +141,6 @@ func (d *DefaultLoader) Load() (*kubekeyapiv1alpha2.Cluster, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if d.KubeSphereEnable {
|
||||
ver := normalizedBuildVersion(d.KubeSphereVersion)
|
||||
if ver == "" {
|
||||
return nil, errors.New(fmt.Sprintf("Unsupported Kubesphere Version: %v\n", d.KubeSphereVersion))
|
||||
}
|
||||
if err := defaultKSConfig(&allInOne.Spec.KubeSphere, ver); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := defaultCommonClusterConfig(allInOne, d.arg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -289,147 +152,6 @@ func (d *DefaultLoader) Load() (*kubekeyapiv1alpha2.Cluster, error) {
|
||||
return allInOne, nil
|
||||
}
|
||||
|
||||
type FileLoader struct {
|
||||
arg Argument
|
||||
FilePath string
|
||||
KubernetesVersion string
|
||||
KubeSphereVersion string
|
||||
KubeSphereEnable bool
|
||||
}
|
||||
|
||||
func NewFileLoader(arg Argument) *FileLoader {
|
||||
return &FileLoader{
|
||||
arg: arg,
|
||||
FilePath: arg.FilePath,
|
||||
KubernetesVersion: arg.KubernetesVersion,
|
||||
KubeSphereVersion: arg.KsVersion,
|
||||
KubeSphereEnable: arg.KsEnable,
|
||||
}
|
||||
}
|
||||
|
||||
func (f FileLoader) Load() (*kubekeyapiv1alpha2.Cluster, error) {
|
||||
var objName string
|
||||
|
||||
clusterCfg := kubekeyapiv1alpha2.Cluster{}
|
||||
fp, err := filepath.Abs(f.FilePath)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to look up current directory")
|
||||
}
|
||||
// fixme: It will lead to nil pointer err
|
||||
//if len(f.KubernetesVersion) != 0 {
|
||||
// _ = exec.Command("/bin/sh", "-c", fmt.Sprintf("sed -i \"/version/s/\\:.*/\\: %s/g\" %s", f.KubernetesVersion, fp)).Run()
|
||||
//}
|
||||
file, err := os.Open(fp)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to open the given cluster configuration file")
|
||||
}
|
||||
defer file.Close()
|
||||
b1 := bufio.NewReader(file)
|
||||
for {
|
||||
result := make(map[string]interface{})
|
||||
content, err := k8syaml.NewYAMLReader(b1).Read()
|
||||
if len(content) == 0 {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to read the given cluster configuration file")
|
||||
}
|
||||
err = yaml.Unmarshal(content, &result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to unmarshal the given cluster configuration file")
|
||||
}
|
||||
|
||||
if result["kind"] == "Cluster" {
|
||||
contentToJson, err := k8syaml.ToJSON(content)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to convert configuration to json")
|
||||
}
|
||||
if err := json.Unmarshal(contentToJson, &clusterCfg); err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to unmarshal configuration")
|
||||
}
|
||||
metadata := result["metadata"].(map[interface{}]interface{})
|
||||
objName = metadata["name"].(string)
|
||||
}
|
||||
|
||||
if result["kind"] == "ConfigMap" || result["kind"] == "ClusterConfiguration" {
|
||||
metadata := result["metadata"].(map[interface{}]interface{})
|
||||
labels := metadata["labels"].(map[interface{}]interface{})
|
||||
clusterCfg.Spec.KubeSphere.Enabled = true
|
||||
|
||||
v, ok := labels["version"]
|
||||
if !ok {
|
||||
return nil, errors.New("Unknown version")
|
||||
}
|
||||
|
||||
version := v.(string)
|
||||
_, stable := kubesphere.StabledVersionSupport(version)
|
||||
_, latest := kubesphere.LatestRelease(version)
|
||||
_, dev := kubesphere.DevRelease(version)
|
||||
if stable || latest || dev {
|
||||
clusterCfg.Spec.KubeSphere.Configurations = "---\n" + string(content)
|
||||
clusterCfg.Spec.KubeSphere.Version = version
|
||||
} else {
|
||||
return nil, errors.New(fmt.Sprintf("Unsupported KubeSphere version: %s", version))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if f.KubeSphereEnable {
|
||||
ver := normalizedBuildVersion(f.KubeSphereVersion)
|
||||
if ver == "" {
|
||||
return nil, errors.New(fmt.Sprintf("Unsupported Kubesphere Version: %v\n", f.KubeSphereVersion))
|
||||
}
|
||||
if err := defaultKSConfig(&clusterCfg.Spec.KubeSphere, ver); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if ver := normalizedBuildVersion(f.KubernetesVersion); ver != "" {
|
||||
s := strings.Split(ver, "-")
|
||||
if len(s) > 1 {
|
||||
clusterCfg.Spec.Kubernetes.Version = s[0]
|
||||
clusterCfg.Spec.Kubernetes.Type = s[1]
|
||||
} else {
|
||||
clusterCfg.Spec.Kubernetes.Version = ver
|
||||
}
|
||||
}
|
||||
|
||||
if f.arg.ContainerManager != "" && f.arg.ContainerManager != Docker {
|
||||
clusterCfg.Spec.Kubernetes.ContainerManager = f.arg.ContainerManager
|
||||
}
|
||||
|
||||
clusterCfg.Spec.Kubernetes.Version = normalizedBuildVersion(clusterCfg.Spec.Kubernetes.Version)
|
||||
clusterCfg.Spec.KubeSphere.Version = normalizedBuildVersion(clusterCfg.Spec.KubeSphere.Version)
|
||||
clusterCfg.Name = objName
|
||||
return &clusterCfg, nil
|
||||
}
|
||||
|
||||
type ConfigMapLoader struct {
|
||||
}
|
||||
|
||||
func (c ConfigMapLoader) Load() (*kubekeyapiv1alpha2.Cluster, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func defaultKSConfig(ks *kubekeyapiv1alpha2.KubeSphere, version string) error {
|
||||
ks.Enabled = true
|
||||
version = strings.TrimSpace(version)
|
||||
ksInstaller, ok := kubesphere.StabledVersionSupport(version)
|
||||
if ok {
|
||||
ks.Version = ksInstaller.Version
|
||||
ks.Configurations = ksInstaller.CCToString()
|
||||
} else if latest, ok := kubesphere.LatestRelease(version); ok {
|
||||
ks.Version = version
|
||||
ks.Configurations = latest.CCToString()
|
||||
} else if dev, ok := kubesphere.DevRelease(version); ok {
|
||||
ks.Version = version
|
||||
ks.Configurations = dev.CCToString()
|
||||
} else {
|
||||
return errors.New(fmt.Sprintf("Unsupported KubeSphere version: %s", version))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// normalizedBuildVersion used to returns normalized build version (with "v" prefix if needed)
|
||||
// If input doesn't match known version pattern, returns empty string.
|
||||
func normalizedBuildVersion(version string) string {
|
||||
@@ -442,57 +164,6 @@ func normalizedBuildVersion(version string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type ExtraAddon struct {
|
||||
Addons []kubekeyapiv1alpha2.Addon `yaml:"Addons"`
|
||||
}
|
||||
|
||||
// load addon from argument
|
||||
func loadExtraAddons(cluster *kubekeyapiv1alpha2.Cluster, addonFile string) error {
|
||||
if addonFile == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
fp, err := filepath.Abs(addonFile)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("Failed to load addon in file: %s", addonFile))
|
||||
}
|
||||
|
||||
content, err := ioutil.ReadFile(fp)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Unable to open the given addon config file")
|
||||
}
|
||||
|
||||
if len(content) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var result ExtraAddon
|
||||
err = yaml.Unmarshal(content, &result)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Unable to read the given addon configuration file")
|
||||
}
|
||||
|
||||
if len(result.Addons) > 0 {
|
||||
cluster.Spec.Addons = append(cluster.Spec.Addons, result.Addons...)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func currentUser(osType string) (*user.User, error) {
|
||||
u, err := user.Current()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if osType != Darwin && osType != Windows {
|
||||
if u.Username != "root" {
|
||||
return nil, errors.New(fmt.Sprintf("Current user is %s. Please use root!", u.Username))
|
||||
}
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func installSUDOIfMissing() error {
|
||||
p, _ := util.GetCommand("sudo")
|
||||
if p != "" {
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/core/connector"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type LocalRuntime struct {
|
||||
connector.BaseRuntime
|
||||
}
|
||||
|
||||
func NewLocalRuntime(debug, ingoreErr bool) (LocalRuntime, error) {
|
||||
var localRuntime LocalRuntime
|
||||
u, err := user.Current()
|
||||
if err != nil {
|
||||
return localRuntime, err
|
||||
}
|
||||
if u.Username != "root" {
|
||||
return localRuntime, fmt.Errorf("current user is %s. Please use root", u.Username)
|
||||
}
|
||||
|
||||
if output, err := exec.Command("/bin/sh", "-c", "if [ ! -f \"$HOME/.ssh/id_rsa\" ]; then mkdir -p \"$HOME/.ssh\" && ssh-keygen -t rsa-sha2-512 -P \"\" -f $HOME/.ssh/id_rsa && ls $HOME/.ssh;fi;").CombinedOutput(); err != nil {
|
||||
return localRuntime, errors.New(fmt.Sprintf("Failed to generate public key: %v\n%s", err, string(output)))
|
||||
}
|
||||
if output, err := exec.Command("/bin/sh", "-c", "echo \"\n$(cat $HOME/.ssh/id_rsa.pub)\" >> $HOME/.ssh/authorized_keys && awk ' !x[$0]++{print > \"'$HOME'/.ssh/authorized_keys.tmp\"}' $HOME/.ssh/authorized_keys && mv $HOME/.ssh/authorized_keys.tmp $HOME/.ssh/authorized_keys").CombinedOutput(); err != nil {
|
||||
return localRuntime, errors.New(fmt.Sprintf("Failed to copy public key to authorized_keys: %v\n%s", err, string(output)))
|
||||
}
|
||||
|
||||
name, err := os.Hostname()
|
||||
if err != nil {
|
||||
return localRuntime, err
|
||||
}
|
||||
base := connector.NewBaseRuntime(name, connector.NewDialer(), debug, ingoreErr, "", "", "", false, nil)
|
||||
|
||||
host := connector.NewHost()
|
||||
host.Name = name
|
||||
host.Address = ""
|
||||
host.InternalAddress = ""
|
||||
host.Port = 22
|
||||
host.User = u.Username
|
||||
host.Password = ""
|
||||
host.PrivateKeyPath = fmt.Sprintf("%s/.ssh/id_rsa", u.HomeDir)
|
||||
host.Arch = ""
|
||||
host.SetRole(KubeKey)
|
||||
|
||||
base.AppendHost(host)
|
||||
base.AppendRoleMap(host)
|
||||
|
||||
local := LocalRuntime{base}
|
||||
return local, nil
|
||||
}
|
||||
@@ -51,7 +51,6 @@ type ModuleRuntime interface {
|
||||
GetBaseDir() string
|
||||
GetInstallerDir() string
|
||||
GetWorkDir() string
|
||||
GetIgnoreErr() bool
|
||||
GetAllHosts() []Host
|
||||
SetAllHosts([]Host)
|
||||
GetHostsByRole(role string) []Host
|
||||
|
||||
@@ -39,8 +39,6 @@ type BaseRuntime struct {
|
||||
baseDir string
|
||||
installerDir string
|
||||
workDir string
|
||||
verbose bool
|
||||
ignoreErr bool
|
||||
allHosts []Host
|
||||
roleHosts map[string][]Host
|
||||
deprecatedHosts map[string]string
|
||||
@@ -50,12 +48,10 @@ type BaseRuntime struct {
|
||||
k8sClient *kubernetes.Clientset
|
||||
}
|
||||
|
||||
func NewBaseRuntime(name string, connector Connector, verbose bool, ignoreErr bool, baseDir string, olaresVersion string, consoleLogFileName string, consoleLogTruncate bool, systemInfo Systems) BaseRuntime {
|
||||
func NewBaseRuntime(name string, connector Connector, baseDir string, olaresVersion string, consoleLogFileName string, consoleLogTruncate bool, systemInfo Systems) BaseRuntime {
|
||||
base := BaseRuntime{
|
||||
ObjName: name,
|
||||
connector: connector,
|
||||
verbose: verbose,
|
||||
ignoreErr: ignoreErr,
|
||||
allHosts: make([]Host, 0, 0),
|
||||
roleHosts: make(map[string][]Host),
|
||||
deprecatedHosts: make(map[string]string),
|
||||
@@ -169,10 +165,6 @@ func (b *BaseRuntime) GetWorkDir() string {
|
||||
return b.workDir
|
||||
}
|
||||
|
||||
func (b *BaseRuntime) GetIgnoreErr() bool {
|
||||
return b.ignoreErr
|
||||
}
|
||||
|
||||
func (b *BaseRuntime) GetAllHosts() []Host {
|
||||
hosts := make([]Host, 0, 0)
|
||||
for i := range b.allHosts {
|
||||
|
||||
@@ -51,10 +51,12 @@ func (d DebianVersion) String() string {
|
||||
}
|
||||
|
||||
const (
|
||||
Ubuntu20 UbuntuVersion = "20."
|
||||
Ubuntu22 UbuntuVersion = "22."
|
||||
Ubuntu24 UbuntuVersion = "24."
|
||||
Ubuntu25 UbuntuVersion = "25."
|
||||
Ubuntu20 UbuntuVersion = "20."
|
||||
Ubuntu22 UbuntuVersion = "22."
|
||||
Ubuntu24 UbuntuVersion = "24."
|
||||
Ubuntu25 UbuntuVersion = "25."
|
||||
Ubuntu2204 UbuntuVersion = "22.04"
|
||||
Ubuntu2404 UbuntuVersion = "24.04"
|
||||
|
||||
Debian9 DebianVersion = "9"
|
||||
Debian10 DebianVersion = "10"
|
||||
|
||||
@@ -59,20 +59,6 @@ func (b *BaseTaskModule) Run(result *ending.ModuleResult) {
|
||||
logger.Infof("[A] %s: %s %s (%s)", ac.Host.GetName(), t.GetName(), ac.Status.String(), util.ShortDur(elapsed))
|
||||
|
||||
result.AppendHostResult(ac)
|
||||
|
||||
if _, ok := t.(*task.RemoteTask); ok {
|
||||
if b.Runtime.GetIgnoreErr() {
|
||||
if len(b.Runtime.GetAllHosts()) > 0 {
|
||||
if ac.GetStatus() == ending.FAILED {
|
||||
res.Status = ending.SUCCESS
|
||||
b.Runtime.DeleteHost(ac.Host)
|
||||
}
|
||||
} else {
|
||||
result.ErrResult(errors.Wrapf(res.CombineErr(), "Module[%s] exec failed", b.Name))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if res.IsFailed() {
|
||||
|
||||
@@ -165,7 +165,7 @@ func (t *UpdateNvidiaContainerToolkitSource) Execute(runtime connector.Runtime)
|
||||
|
||||
// decide mirror based on OLARES_SYSTEM_CDN_SERVICE
|
||||
var mirrorHost string
|
||||
cdnService := os.Getenv(common.ENV_OLARES_CDN_SERVICE)
|
||||
cdnService := t.KubeConf.Arg.OlaresCDNService
|
||||
if cdnService != "" {
|
||||
cdnRaw := cdnService
|
||||
if !strings.HasPrefix(cdnRaw, "http") {
|
||||
|
||||
@@ -36,6 +36,7 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/k3s/templates"
|
||||
"github.com/beclab/Olares/cli/pkg/manifest"
|
||||
"github.com/beclab/Olares/cli/pkg/registry"
|
||||
"github.com/beclab/Olares/cli/pkg/storage"
|
||||
)
|
||||
|
||||
type InstallContainerModule struct {
|
||||
@@ -470,6 +471,18 @@ func (j *JoinNodesModule) Init() {
|
||||
Parallel: true,
|
||||
}
|
||||
|
||||
createSharedLibDirForWorker := &task.RemoteTask{
|
||||
Name: "CreateSharedLibDir(k3s)",
|
||||
Desc: "Create shared lib directory on worker",
|
||||
Hosts: j.Runtime.GetHostsByRole(common.Worker),
|
||||
Prepare: &prepare.PrepareCollection{
|
||||
&kubernetes.NodeInCluster{Not: true},
|
||||
new(common.OnlyWorker),
|
||||
},
|
||||
Action: new(storage.CreateSharedLibDir),
|
||||
Parallel: true,
|
||||
}
|
||||
|
||||
enableK3s := &task.RemoteTask{
|
||||
Name: "EnableK3sService",
|
||||
Desc: "Enable k3s service",
|
||||
@@ -536,6 +549,7 @@ func (j *JoinNodesModule) Init() {
|
||||
k3sService,
|
||||
k3sEnv,
|
||||
k3sRegistryConfig,
|
||||
createSharedLibDirForWorker,
|
||||
enableK3s,
|
||||
copyKubeConfigForMaster,
|
||||
syncKubeConfigToWorker,
|
||||
@@ -579,22 +593,3 @@ func (d *DeleteClusterModule) Init() {
|
||||
execScript,
|
||||
}
|
||||
}
|
||||
|
||||
type SaveKubeConfigModule struct {
|
||||
common.KubeModule
|
||||
}
|
||||
|
||||
func (s *SaveKubeConfigModule) Init() {
|
||||
s.Name = "SaveKubeConfigModule"
|
||||
s.Desc = "Save kube config file as a configmap"
|
||||
|
||||
save := &task.LocalTask{
|
||||
Name: "SaveKubeConfig(k3s)",
|
||||
Desc: "Save kube config as a configmap",
|
||||
Action: new(SaveKubeConfig),
|
||||
}
|
||||
|
||||
s.Tasks = []task.Interface{
|
||||
save,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
package k3s
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -41,11 +39,7 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/k3s/templates"
|
||||
"github.com/beclab/Olares/cli/pkg/utils"
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
versionutil "k8s.io/apimachinery/pkg/util/version"
|
||||
kube "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
)
|
||||
|
||||
type GetClusterStatus struct {
|
||||
@@ -397,53 +391,23 @@ type CopyK3sKubeConfig struct {
|
||||
}
|
||||
|
||||
func (c *CopyK3sKubeConfig) Execute(runtime connector.Runtime) error {
|
||||
createConfigDirCmd := "mkdir -p /root/.kube && mkdir -p $HOME/.kube"
|
||||
getKubeConfigCmd := "cp -f /etc/rancher/k3s/k3s.yaml /root/.kube/config"
|
||||
chmodKubeConfigCmd := "chmod 0600 /root/.kube/config"
|
||||
targetHome, targetUID, targetGID, err := utils.ResolveSudoUserHomeAndIDs(runtime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd := strings.Join([]string{createConfigDirCmd, getKubeConfigCmd, chmodKubeConfigCmd}, " && ")
|
||||
if _, err := runtime.GetRunner().SudoCmd(cmd, false, false); err != nil {
|
||||
cmds := []string{
|
||||
"mkdir -p /root/.kube",
|
||||
"cp -f /etc/rancher/k3s/k3s.yaml /root/.kube/config",
|
||||
"chmod 0600 /root/.kube/config",
|
||||
fmt.Sprintf("mkdir -p %s", filepath.Join(targetHome, ".kube")),
|
||||
fmt.Sprintf("cp -f /etc/rancher/k3s/k3s.yaml %s", filepath.Join(targetHome, ".kube", "config")),
|
||||
fmt.Sprintf("chmod 0600 %s", filepath.Join(targetHome, ".kube", "config")),
|
||||
fmt.Sprintf("chown -R %s:%s %s", targetUID, targetGID, filepath.Join(targetHome, ".kube")),
|
||||
}
|
||||
if _, err := runtime.GetRunner().SudoCmd(strings.Join(cmds, " && "), false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "copy k3s kube config failed")
|
||||
}
|
||||
|
||||
userMkdir := "mkdir -p $HOME/.kube"
|
||||
if _, err := runtime.GetRunner().Cmd(userMkdir, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "user mkdir $HOME/.kube failed")
|
||||
}
|
||||
|
||||
userCopyKubeConfig := "cp -f /etc/rancher/k3s/k3s.yaml $HOME/.kube/config"
|
||||
if _, err := runtime.GetRunner().SudoCmd(userCopyKubeConfig, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "user copy /etc/rancher/k3s/k3s.yaml to $HOME/.kube/config failed")
|
||||
}
|
||||
|
||||
if _, err := runtime.GetRunner().SudoCmd("chmod 0600 $HOME/.kube/config", false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chmod k3s $HOME/.kube/config 0600 failed")
|
||||
}
|
||||
|
||||
// userId, err := runtime.GetRunner().Cmd("echo $(id -u)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
// }
|
||||
|
||||
// userGroupId, err := runtime.GetRunner().Cmd("echo $(id -g)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
// }
|
||||
|
||||
userId, err := runtime.GetRunner().Cmd("echo $SUDO_UID", false, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
}
|
||||
|
||||
userGroupId, err := runtime.GetRunner().Cmd("echo $SUDO_GID", false, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
}
|
||||
|
||||
chownKubeConfig := fmt.Sprintf("chown -R %s:%s $HOME/.kube", userId, userGroupId)
|
||||
if _, err := runtime.GetRunner().SudoCmd(chownKubeConfig, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chown user kube config failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -493,59 +457,29 @@ func (s *SyncKubeConfigToWorker) Execute(runtime connector.Runtime) error {
|
||||
if v, ok := s.PipelineCache.Get(common.ClusterStatus); ok {
|
||||
cluster := v.(*K3sStatus)
|
||||
|
||||
createConfigDirCmd := "mkdir -p /root/.kube"
|
||||
if _, err := runtime.GetRunner().SudoCmd(createConfigDirCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "create .kube dir failed")
|
||||
}
|
||||
|
||||
oldServer := "server: https://127.0.0.1:6443"
|
||||
newServer := fmt.Sprintf("server: https://%s:%d",
|
||||
s.KubeConf.Cluster.ControlPlaneEndpoint.Domain,
|
||||
s.KubeConf.Cluster.ControlPlaneEndpoint.Port)
|
||||
newKubeConfig := strings.Replace(cluster.KubeConfig, oldServer, newServer, -1)
|
||||
|
||||
syncKubeConfigForRootCmd := fmt.Sprintf("echo '%s' > %s", newKubeConfig, "/root/.kube/config")
|
||||
if _, err := runtime.GetRunner().SudoCmd(syncKubeConfigForRootCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "sync kube config for root failed")
|
||||
}
|
||||
|
||||
if _, err := runtime.GetRunner().SudoCmd("chmod 0600 /root/.kube/config", false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chmod k3s $HOME/.kube/config failed")
|
||||
}
|
||||
|
||||
userConfigDirCmd := "mkdir -p $HOME/.kube"
|
||||
if _, err := runtime.GetRunner().Cmd(userConfigDirCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "user mkdir $HOME/.kube failed")
|
||||
}
|
||||
|
||||
syncKubeConfigForUserCmd := fmt.Sprintf("echo '%s' > %s", newKubeConfig, "$HOME/.kube/config")
|
||||
if _, err := runtime.GetRunner().Cmd(syncKubeConfigForUserCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "sync kube config for normal user failed")
|
||||
}
|
||||
|
||||
// userId, err := runtime.GetRunner().Cmd("echo $(id -u)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
// }
|
||||
|
||||
// userGroupId, err := runtime.GetRunner().Cmd("echo $(id -g)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
// }
|
||||
|
||||
userId, err := runtime.GetRunner().Cmd("echo $SUDO_UID", false, false)
|
||||
targetHome, targetUID, targetGID, err := utils.ResolveSudoUserHomeAndIDs(runtime)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
return err
|
||||
}
|
||||
targetKubeConfigPath := filepath.Join(targetHome, ".kube", "config")
|
||||
|
||||
userGroupId, err := runtime.GetRunner().Cmd("echo $SUDO_GID", false, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
cmds := []string{
|
||||
"mkdir -p /root/.kube",
|
||||
fmt.Sprintf("echo '%s' > %s", newKubeConfig, "/root/.kube/config"),
|
||||
"chmod 0600 /root/.kube/config",
|
||||
fmt.Sprintf("mkdir -p %s", filepath.Join(targetHome, ".kube")),
|
||||
fmt.Sprintf("echo '%s' > %s", newKubeConfig, targetKubeConfigPath),
|
||||
fmt.Sprintf("chmod 0600 %s", targetKubeConfigPath),
|
||||
fmt.Sprintf("chown -R %s:%s %s", targetUID, targetGID, filepath.Join(targetHome, ".kube")),
|
||||
}
|
||||
|
||||
chownKubeConfig := fmt.Sprintf("chown -R %s:%s -R $HOME/.kube", userId, userGroupId)
|
||||
if _, err := runtime.GetRunner().SudoCmd(chownKubeConfig, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chown user kube config failed")
|
||||
if _, err := runtime.GetRunner().SudoCmd(strings.Join(cmds, " && "), false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "sync kube config failed")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -575,65 +509,6 @@ func (e *ExecUninstallScript) Execute(runtime connector.Runtime) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type SaveKubeConfig struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (s *SaveKubeConfig) Execute(_ connector.Runtime) error {
|
||||
status, ok := s.PipelineCache.Get(common.ClusterStatus)
|
||||
if !ok {
|
||||
return errors.New("get kubernetes status failed by pipeline cache")
|
||||
}
|
||||
cluster := status.(*K3sStatus)
|
||||
|
||||
oldServer := fmt.Sprintf("https://%s:%d", s.KubeConf.Cluster.ControlPlaneEndpoint.Domain, s.KubeConf.Cluster.ControlPlaneEndpoint.Port)
|
||||
newServer := fmt.Sprintf("https://%s:%d", s.KubeConf.Cluster.ControlPlaneEndpoint.Address, s.KubeConf.Cluster.ControlPlaneEndpoint.Port)
|
||||
newKubeConfigStr := strings.Replace(cluster.KubeConfig, oldServer, newServer, -1)
|
||||
kubeConfigBase64 := base64.StdEncoding.EncodeToString([]byte(newKubeConfigStr))
|
||||
|
||||
config, err := clientcmd.NewClientConfigFromBytes([]byte(newKubeConfigStr))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
restConfig, err := config.ClientConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
clientsetForCluster, err := kube.NewForConfig(restConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespace := &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "kubekey-system",
|
||||
},
|
||||
}
|
||||
if _, err := clientsetForCluster.
|
||||
CoreV1().
|
||||
Namespaces().
|
||||
Create(context.TODO(), namespace, metav1.CreateOptions{}); err != nil {
|
||||
// return err
|
||||
}
|
||||
|
||||
cm := &corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: fmt.Sprintf("%s-kubeconfig", s.KubeConf.ClusterName),
|
||||
},
|
||||
Data: map[string]string{
|
||||
"kubeconfig": kubeConfigBase64,
|
||||
},
|
||||
}
|
||||
|
||||
if _, err := clientsetForCluster.
|
||||
CoreV1().
|
||||
ConfigMaps("kubekey-system").
|
||||
Create(context.TODO(), cm, metav1.CreateOptions{}); err != nil {
|
||||
// return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GenerateK3sRegistryConfig struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/core/prepare"
|
||||
"github.com/beclab/Olares/cli/pkg/core/task"
|
||||
"github.com/beclab/Olares/cli/pkg/manifest"
|
||||
"github.com/beclab/Olares/cli/pkg/storage"
|
||||
)
|
||||
|
||||
type StatusModule struct {
|
||||
@@ -243,6 +244,18 @@ func (j *JoinNodesModule) Init() {
|
||||
Retry: 5,
|
||||
}
|
||||
|
||||
createSharedLibDirForWorker := &task.RemoteTask{
|
||||
Name: "CreateSharedLibDir(k8s)",
|
||||
Desc: "Create shared lib directory on worker",
|
||||
Hosts: j.Runtime.GetHostsByRole(common.Worker),
|
||||
Prepare: &prepare.PrepareCollection{
|
||||
&NodeInCluster{Not: true},
|
||||
new(common.OnlyWorker),
|
||||
},
|
||||
Action: new(storage.CreateSharedLibDir),
|
||||
Parallel: true,
|
||||
}
|
||||
|
||||
joinWorkerNode := &task.RemoteTask{
|
||||
Name: "JoinWorkerNode(k8s)",
|
||||
Desc: "Join worker node",
|
||||
@@ -323,6 +336,7 @@ func (j *JoinNodesModule) Init() {
|
||||
j.Tasks = []task.Interface{
|
||||
generateKubeadmConfig,
|
||||
joinMasterNode,
|
||||
createSharedLibDirForWorker,
|
||||
joinWorkerNode,
|
||||
copyKubeConfig,
|
||||
removeMasterTaint,
|
||||
@@ -380,26 +394,6 @@ func (c *UmountKubeModule) Init() {
|
||||
}
|
||||
}
|
||||
|
||||
type SaveKubeConfigModule struct {
|
||||
common.KubeModule
|
||||
}
|
||||
|
||||
func (s *SaveKubeConfigModule) Init() {
|
||||
s.Name = "SaveKubeConfigModule"
|
||||
s.Desc = "Save kube config file as a configmap"
|
||||
|
||||
save := &task.LocalTask{
|
||||
Name: "SaveKubeConfig(k8s)",
|
||||
Desc: "Save kube config as a configmap",
|
||||
Action: new(SaveKubeConfig),
|
||||
Retry: 5,
|
||||
}
|
||||
|
||||
s.Tasks = []task.Interface{
|
||||
save,
|
||||
}
|
||||
}
|
||||
|
||||
type ConfigureKubernetesModule struct {
|
||||
common.KubeModule
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ package kubernetes
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -34,11 +33,6 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/manifest"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
kubeerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
kube "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
|
||||
kubekeyv1alpha2 "github.com/beclab/Olares/cli/apis/kubekey/v1alpha2"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
@@ -417,51 +411,23 @@ type CopyKubeConfigForControlPlane struct {
|
||||
}
|
||||
|
||||
func (c *CopyKubeConfigForControlPlane) Execute(runtime connector.Runtime) error {
|
||||
createConfigDirCmd := "mkdir -p /root/.kube"
|
||||
getKubeConfigCmd := "cp -f /etc/kubernetes/admin.conf /root/.kube/config"
|
||||
cmd := strings.Join([]string{createConfigDirCmd, getKubeConfigCmd}, " && ")
|
||||
if _, err := runtime.GetRunner().SudoCmd(cmd, false, false); err != nil {
|
||||
targetHome, targetUID, targetGID, err := utils.ResolveSudoUserHomeAndIDs(runtime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmds := []string{
|
||||
"mkdir -p /root/.kube",
|
||||
"cp -f /etc/kubernetes/admin.conf /root/.kube/config",
|
||||
"chmod 0600 /root/.kube/config",
|
||||
fmt.Sprintf("mkdir -p %s", filepath.Join(targetHome, ".kube")),
|
||||
fmt.Sprintf("cp -f /etc/kubernetes/admin.conf %s", filepath.Join(targetHome, ".kube", "config")),
|
||||
fmt.Sprintf("chmod 0600 %s", filepath.Join(targetHome, ".kube", "config")),
|
||||
fmt.Sprintf("chown -R %s:%s %s", targetUID, targetGID, filepath.Join(targetHome, ".kube")),
|
||||
}
|
||||
if _, err := runtime.GetRunner().SudoCmd(strings.Join(cmds, " && "), false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "copy kube config failed")
|
||||
}
|
||||
|
||||
userMkdir := "mkdir -p $HOME/.kube"
|
||||
if _, err := runtime.GetRunner().Cmd(userMkdir, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "user mkdir $HOME/.kube failed")
|
||||
}
|
||||
|
||||
userCopyKubeConfig := "cp -f /etc/kubernetes/admin.conf $HOME/.kube/config"
|
||||
if _, err := runtime.GetRunner().SudoCmd(userCopyKubeConfig, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "user copy /etc/kubernetes/admin.conf to $HOME/.kube/config failed")
|
||||
}
|
||||
|
||||
if _, err := runtime.GetRunner().SudoCmd("chmod 0600 $HOME/.kube/config", false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chmod $HOME/.kube/config failed")
|
||||
}
|
||||
|
||||
// userId, err := runtime.GetRunner().Cmd("echo $(id -u)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
// }
|
||||
|
||||
// userGroupId, err := runtime.GetRunner().Cmd("echo $(id -g)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
// }
|
||||
|
||||
userId, err := runtime.GetRunner().Cmd("echo $SUDO_UID", false, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
}
|
||||
|
||||
userGroupId, err := runtime.GetRunner().Cmd("echo $SUDO_GID", false, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
}
|
||||
|
||||
chownKubeConfig := fmt.Sprintf("chown -R %s:%s $HOME/.kube", userId, userGroupId)
|
||||
if _, err := runtime.GetRunner().SudoCmd(chownKubeConfig, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chown user kube config failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -521,53 +487,23 @@ func (s *SyncKubeConfigToWorker) Execute(runtime connector.Runtime) error {
|
||||
if v, ok := s.PipelineCache.Get(common.ClusterStatus); ok {
|
||||
cluster := v.(*KubernetesStatus)
|
||||
|
||||
createConfigDirCmd := "mkdir -p /root/.kube"
|
||||
if _, err := runtime.GetRunner().SudoCmd(createConfigDirCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "create .kube dir failed")
|
||||
}
|
||||
|
||||
syncKubeConfigForRootCmd := fmt.Sprintf("echo '%s' > %s", cluster.KubeConfig, "/root/.kube/config")
|
||||
if _, err := runtime.GetRunner().SudoCmd(syncKubeConfigForRootCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "sync kube config for root failed")
|
||||
}
|
||||
|
||||
if _, err := runtime.GetRunner().SudoCmd("chmod 0600 /root/.kube/config", false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chmod $HOME/.kube/config failed")
|
||||
}
|
||||
|
||||
userConfigDirCmd := "mkdir -p $HOME/.kube"
|
||||
if _, err := runtime.GetRunner().Cmd(userConfigDirCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "user mkdir $HOME/.kube failed")
|
||||
}
|
||||
|
||||
syncKubeConfigForUserCmd := fmt.Sprintf("echo '%s' > %s", cluster.KubeConfig, "$HOME/.kube/config")
|
||||
if _, err := runtime.GetRunner().Cmd(syncKubeConfigForUserCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "sync kube config for normal user failed")
|
||||
}
|
||||
|
||||
// userId, err := runtime.GetRunner().Cmd("echo $(id -u)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
// }
|
||||
|
||||
// userGroupId, err := runtime.GetRunner().Cmd("echo $(id -g)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
// }
|
||||
|
||||
userId, err := runtime.GetRunner().Cmd("echo $SUDO_UID", false, false)
|
||||
targetHome, targetUID, targetGID, err := utils.ResolveSudoUserHomeAndIDs(runtime)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
return err
|
||||
}
|
||||
targetKubeConfigPath := filepath.Join(targetHome, ".kube", "config")
|
||||
|
||||
userGroupId, err := runtime.GetRunner().Cmd("echo $SUDO_GID", false, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
cmds := []string{
|
||||
"mkdir -p /root/.kube",
|
||||
fmt.Sprintf("echo '%s' > %s", cluster.KubeConfig, "/root/.kube/config"),
|
||||
"chmod 0600 /root/.kube/config",
|
||||
fmt.Sprintf("mkdir -p %s", filepath.Join(targetHome, ".kube")),
|
||||
fmt.Sprintf("echo '%s' > %s", cluster.KubeConfig, targetKubeConfigPath),
|
||||
fmt.Sprintf("chmod 0600 %s", targetKubeConfigPath),
|
||||
fmt.Sprintf("chown -R %s:%s %s", targetUID, targetGID, filepath.Join(targetHome, ".kube")),
|
||||
}
|
||||
|
||||
chownKubeConfig := fmt.Sprintf("chown -R %s:%s -R $HOME/.kube", userId, userGroupId)
|
||||
if _, err := runtime.GetRunner().SudoCmd(chownKubeConfig, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chown user kube config failed")
|
||||
if _, err := runtime.GetRunner().SudoCmd(strings.Join(cmds, " && "), false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "sync kube config failed")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -660,91 +596,6 @@ func (k *KubectlDeleteCurrentWorkerNode) Execute(runtime connector.Runtime) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
type SaveKubeConfig struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (s *SaveKubeConfig) Execute(runtime connector.Runtime) error {
|
||||
status, ok := s.PipelineCache.Get(common.ClusterStatus)
|
||||
if !ok {
|
||||
return errors.New("get kubernetes status failed by pipeline cache")
|
||||
}
|
||||
cluster := status.(*KubernetesStatus)
|
||||
kubeConfigStr := cluster.KubeConfig
|
||||
|
||||
clusterPublicAddress := s.KubeConf.Cluster.ControlPlaneEndpoint.Address
|
||||
master1 := runtime.GetHostsByRole(common.Master)[0]
|
||||
if clusterPublicAddress == master1.GetInternalAddress() {
|
||||
clusterPublicAddress = master1.GetAddress()
|
||||
}
|
||||
|
||||
oldServer := fmt.Sprintf("https://%s:%d", s.KubeConf.Cluster.ControlPlaneEndpoint.Domain, s.KubeConf.Cluster.ControlPlaneEndpoint.Port)
|
||||
newServer := fmt.Sprintf("https://%s:%d", clusterPublicAddress, s.KubeConf.Cluster.ControlPlaneEndpoint.Port)
|
||||
newKubeConfigStr := strings.Replace(kubeConfigStr, oldServer, newServer, -1)
|
||||
kubeConfigBase64 := base64.StdEncoding.EncodeToString([]byte(newKubeConfigStr))
|
||||
|
||||
config, err := clientcmd.NewClientConfigFromBytes([]byte(newKubeConfigStr))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
restConfig, err := config.ClientConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
clientsetForCluster, err := kube.NewForConfig(restConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespace := &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "kubekey-system",
|
||||
},
|
||||
}
|
||||
if _, err := clientsetForCluster.
|
||||
CoreV1().
|
||||
Namespaces().
|
||||
Get(context.TODO(), namespace.Name, metav1.GetOptions{}); kubeerrors.IsNotFound(err) {
|
||||
if _, err := clientsetForCluster.
|
||||
CoreV1().
|
||||
Namespaces().
|
||||
Create(context.TODO(), namespace, metav1.CreateOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
|
||||
cm := &corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: fmt.Sprintf("%s-kubeconfig", s.KubeConf.ClusterName),
|
||||
},
|
||||
Data: map[string]string{
|
||||
"kubeconfig": kubeConfigBase64,
|
||||
},
|
||||
}
|
||||
|
||||
if _, err := clientsetForCluster.
|
||||
CoreV1().
|
||||
ConfigMaps("kubekey-system").
|
||||
Get(context.TODO(), cm.Name, metav1.GetOptions{}); kubeerrors.IsNotFound(err) {
|
||||
if _, err := clientsetForCluster.
|
||||
CoreV1().
|
||||
ConfigMaps("kubekey-system").
|
||||
Create(context.TODO(), cm, metav1.CreateOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if _, err := clientsetForCluster.
|
||||
CoreV1().
|
||||
ConfigMaps("kubekey-system").
|
||||
Update(context.TODO(), cm, metav1.UpdateOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ConfigureKubernetes struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
@@ -389,10 +389,6 @@ func GetKubeletConfiguration(runtime connector.Runtime, kubeConf *common.KubeCon
|
||||
}
|
||||
}
|
||||
|
||||
if kubeConf.Arg.Debug {
|
||||
logger.Debugf("Set kubeletConfiguration: %v", kubeletConfiguration)
|
||||
}
|
||||
|
||||
return kubeletConfiguration
|
||||
}
|
||||
|
||||
|
||||
@@ -46,11 +46,6 @@ func (m *DeleteKubeSphereCachesModule) Init() {
|
||||
|
||||
type DeployModule struct {
|
||||
common.KubeModule
|
||||
Skip bool
|
||||
}
|
||||
|
||||
func (d *DeployModule) IsSkip() bool {
|
||||
return d.Skip
|
||||
}
|
||||
|
||||
func (d *DeployModule) Init() {
|
||||
@@ -76,11 +71,6 @@ func (d *DeployModule) Init() {
|
||||
|
||||
type CheckResultModule struct {
|
||||
common.KubeModule
|
||||
Skip bool
|
||||
}
|
||||
|
||||
func (c *CheckResultModule) IsSkip() bool {
|
||||
return c.Skip
|
||||
}
|
||||
|
||||
func (c *CheckResultModule) Init() {
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
|
||||
kubekeyapiv1alpha2 "github.com/beclab/Olares/cli/apis/kubekey/v1alpha2"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/bootstrap/confirm"
|
||||
"github.com/beclab/Olares/cli/pkg/bootstrap/os"
|
||||
"github.com/beclab/Olares/cli/pkg/bootstrap/precheck"
|
||||
"github.com/beclab/Olares/cli/pkg/certs"
|
||||
@@ -36,11 +35,11 @@ func NewDarwinClusterPhase(runtime *common.KubeRuntime, manifestMap manifest.Ins
|
||||
},
|
||||
},
|
||||
&kubesphere.DeployMiniKubeModule{},
|
||||
&kubesphere.DeployModule{Skip: !runtime.Cluster.KubeSphere.Enabled},
|
||||
&kubesphere.DeployModule{},
|
||||
&ksplugins.DeployKsCoreConfigModule{}, // ks-core-config
|
||||
&ksplugins.DeployPrometheusModule{},
|
||||
&ksplugins.DeployKsCoreModule{},
|
||||
&kubesphere.CheckResultModule{Skip: !runtime.Cluster.KubeSphere.Enabled},
|
||||
&kubesphere.CheckResultModule{},
|
||||
}
|
||||
|
||||
return m
|
||||
@@ -53,13 +52,6 @@ func NewK3sCreateClusterPhase(runtime *common.KubeRuntime, manifestMap manifest.
|
||||
baseDir = path.Join(runtime.Arg.GetWslUserPath(), cc.DefaultBaseDir)
|
||||
}
|
||||
|
||||
skipLocalStorage := true
|
||||
if runtime.Arg.DeployLocalStorage != nil {
|
||||
skipLocalStorage = !*runtime.Arg.DeployLocalStorage
|
||||
} else if runtime.Cluster.KubeSphere.Enabled {
|
||||
skipLocalStorage = false
|
||||
}
|
||||
|
||||
m := []module.Module{
|
||||
&k3s.StatusModule{},
|
||||
&os.ConfigureOSModule{},
|
||||
@@ -87,13 +79,12 @@ func NewK3sCreateClusterPhase(runtime *common.KubeRuntime, manifestMap manifest.
|
||||
&kubernetes.ConfigureKubernetesModule{},
|
||||
&filesystem.ChownModule{},
|
||||
&certs.AutoRenewCertsModule{Skip: !runtime.Cluster.Kubernetes.EnableAutoRenewCerts()},
|
||||
&k3s.SaveKubeConfigModule{},
|
||||
&storage.DeployLocalVolumeModule{Skip: skipLocalStorage},
|
||||
&kubesphere.DeployModule{Skip: !runtime.Cluster.KubeSphere.Enabled},
|
||||
&storage.DeployLocalVolumeModule{},
|
||||
&kubesphere.DeployModule{},
|
||||
&ksplugins.DeployKsCoreConfigModule{},
|
||||
&ksplugins.DeployPrometheusModule{},
|
||||
&ksplugins.DeployKsCoreModule{},
|
||||
&kubesphere.CheckResultModule{Skip: !runtime.Cluster.KubeSphere.Enabled},
|
||||
&kubesphere.CheckResultModule{},
|
||||
}
|
||||
|
||||
return m
|
||||
@@ -106,16 +97,8 @@ func NewCreateClusterPhase(runtime *common.KubeRuntime, manifestMap manifest.Ins
|
||||
baseDir = path.Join(runtime.Arg.GetWslUserPath(), cc.DefaultBaseDir)
|
||||
}
|
||||
|
||||
skipLocalStorage := true
|
||||
if runtime.Arg.DeployLocalStorage != nil {
|
||||
skipLocalStorage = !*runtime.Arg.DeployLocalStorage
|
||||
} else if runtime.Cluster.KubeSphere.Enabled {
|
||||
skipLocalStorage = false
|
||||
}
|
||||
|
||||
m := []module.Module{
|
||||
&precheck.NodePreCheckModule{},
|
||||
&confirm.InstallConfirmModule{Skip: runtime.Arg.SkipConfirmCheck},
|
||||
&kubernetes.StatusModule{},
|
||||
&os.ConfigureOSModule{},
|
||||
&etcd.PreCheckModule{Skip: runtime.Cluster.Etcd.Type != kubekeyapiv1alpha2.KubeKey},
|
||||
@@ -144,13 +127,12 @@ func NewCreateClusterPhase(runtime *common.KubeRuntime, manifestMap manifest.Ins
|
||||
&filesystem.ChownModule{},
|
||||
&certs.AutoRenewCertsModule{Skip: !runtime.Cluster.Kubernetes.EnableAutoRenewCerts()},
|
||||
&kubernetes.SecurityEnhancementModule{Skip: !runtime.Arg.SecurityEnhancement},
|
||||
&kubernetes.SaveKubeConfigModule{},
|
||||
&storage.DeployLocalVolumeModule{Skip: skipLocalStorage},
|
||||
&kubesphere.DeployModule{Skip: !runtime.Cluster.KubeSphere.Enabled},
|
||||
&storage.DeployLocalVolumeModule{},
|
||||
&kubesphere.DeployModule{},
|
||||
&ksplugins.DeployKsCoreConfigModule{}, // ! ks-core-config
|
||||
&ksplugins.DeployPrometheusModule{},
|
||||
&ksplugins.DeployKsCoreModule{},
|
||||
&kubesphere.CheckResultModule{Skip: !runtime.Cluster.KubeSphere.Enabled}, // check ks-apiserver phase
|
||||
&kubesphere.CheckResultModule{}, // check ks-apiserver phase
|
||||
}
|
||||
|
||||
return m
|
||||
|
||||
@@ -3,8 +3,7 @@ package system
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/gpu"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/amdgpu"
|
||||
"github.com/beclab/Olares/cli/pkg/bootstrap/os"
|
||||
"github.com/beclab/Olares/cli/pkg/bootstrap/patch"
|
||||
"github.com/beclab/Olares/cli/pkg/bootstrap/precheck"
|
||||
@@ -12,6 +11,7 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/container"
|
||||
"github.com/beclab/Olares/cli/pkg/core/module"
|
||||
"github.com/beclab/Olares/cli/pkg/daemon"
|
||||
"github.com/beclab/Olares/cli/pkg/gpu"
|
||||
"github.com/beclab/Olares/cli/pkg/images"
|
||||
"github.com/beclab/Olares/cli/pkg/k3s"
|
||||
"github.com/beclab/Olares/cli/pkg/manifest"
|
||||
@@ -82,6 +82,7 @@ func (l *linuxPhaseBuilder) build() []module.Module {
|
||||
addModule(&terminus.WriteReleaseFileModule{}).
|
||||
addModule(gpuModuleBuilder(func() []module.Module {
|
||||
return []module.Module{
|
||||
&amdgpu.InstallAmdRocmModule{},
|
||||
&gpu.InstallDriversModule{
|
||||
ManifestModule: manifest.ManifestModule{
|
||||
Manifest: l.manifestMap,
|
||||
|
||||
@@ -5,32 +5,27 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/phase/cluster"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func AddNodePipeline(opts *options.AddNodeOptions) error {
|
||||
func AddNodePipeline() error {
|
||||
arg := common.NewArgument()
|
||||
if !arg.SystemInfo.IsLinux() {
|
||||
fmt.Println("error: Only Linux nodes can be added to an Olares cluster!")
|
||||
os.Exit(1)
|
||||
}
|
||||
arg.SetBaseDir(opts.BaseDir)
|
||||
if opts.Version == "" {
|
||||
return errors.New("Olares version must be specified")
|
||||
}
|
||||
arg.SetOlaresVersion(opts.Version)
|
||||
if err := arg.LoadMasterHostConfigIfAny(); err != nil {
|
||||
return errors.Wrap(err, "failed to load master host config")
|
||||
}
|
||||
arg.SetMasterHostOverride(opts.MasterHostConfig)
|
||||
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetConsoleLog("addnode.log", true)
|
||||
|
||||
if err := arg.MasterHostConfig.Validate(); err != nil {
|
||||
return fmt.Errorf("invalid master host config: %w", err)
|
||||
}
|
||||
arg.SetConsoleLog("addnode.log", true)
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating runtime: %v", err)
|
||||
}
|
||||
|
||||
101
cli/pkg/pipelines/amdgpu.go
Normal file
101
cli/pkg/pipelines/amdgpu.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package pipelines
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/amdgpu"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/action"
|
||||
"github.com/beclab/Olares/cli/pkg/core/connector"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/core/module"
|
||||
"github.com/beclab/Olares/cli/pkg/core/pipeline"
|
||||
"github.com/beclab/Olares/cli/pkg/core/task"
|
||||
)
|
||||
|
||||
type singleTaskModule struct {
|
||||
common.KubeModule
|
||||
name string
|
||||
act action.Action
|
||||
}
|
||||
|
||||
func (m *singleTaskModule) Init() {
|
||||
m.Name = m.name
|
||||
m.Tasks = []task.Interface{
|
||||
&task.LocalTask{
|
||||
Name: m.name,
|
||||
Action: m.act,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func AmdGpuInstall() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetConsoleLog("amdgpuinstall.log", true)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p := &pipeline.Pipeline{
|
||||
Name: "InstallAMDGPUDrivers",
|
||||
Runtime: runtime,
|
||||
Modules: []module.Module{
|
||||
&amdgpu.InstallAmdRocmModule{},
|
||||
},
|
||||
}
|
||||
return p.Start()
|
||||
}
|
||||
|
||||
func AmdGpuUninstall() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetConsoleLog("amdgpuuninstall.log", true)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p := &pipeline.Pipeline{
|
||||
Name: "UninstallAMDGPUDrivers",
|
||||
Runtime: runtime,
|
||||
Modules: []module.Module{
|
||||
&singleTaskModule{name: "AmdgpuUninstall", act: new(amdgpu.AmdgpuUninstallAction)},
|
||||
},
|
||||
}
|
||||
return p.Start()
|
||||
}
|
||||
|
||||
func AmdGpuStatus() error {
|
||||
arg := common.NewArgument()
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
runtime.SetRunner(
|
||||
&connector.Runner{
|
||||
Host: &connector.BaseHost{
|
||||
Name: common.LocalHost,
|
||||
Arch: runtime.GetSystemInfo().GetOsArch(),
|
||||
Os: runtime.GetSystemInfo().GetOsType(),
|
||||
},
|
||||
},
|
||||
)
|
||||
amdModel, _ := runtime.GetRunner().SudoCmd("lspci | grep -iE 'VGA|3D|Display' | grep -iE 'AMD|ATI' | head -1 || true", false, false)
|
||||
drvVer, _ := runtime.GetRunner().SudoCmd("modinfo amdgpu 2>/dev/null | awk -F': ' '/^version:/{print $2}' || true", false, false)
|
||||
rocmVer, _ := runtime.GetRunner().SudoCmd("cat /opt/rocm/.info/version 2>/dev/null || true", false, false)
|
||||
|
||||
if strings.TrimSpace(amdModel) != "" {
|
||||
logger.Infof("AMD GPU: %s", strings.TrimSpace(amdModel))
|
||||
} else {
|
||||
logger.Info("AMD GPU: not detected")
|
||||
}
|
||||
if strings.TrimSpace(drvVer) != "" {
|
||||
logger.Infof("AMDGPU driver %s", strings.TrimSpace(drvVer))
|
||||
} else {
|
||||
logger.Info("AMDGPU driver version: unknown")
|
||||
}
|
||||
if strings.TrimSpace(rocmVer) != "" {
|
||||
logger.Infof("ROCm version: %s", strings.TrimSpace(rocmVer))
|
||||
} else {
|
||||
logger.Info("ROCm version: not installed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -2,19 +2,16 @@ package pipelines
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/core/util"
|
||||
"github.com/beclab/Olares/cli/pkg/phase"
|
||||
"github.com/beclab/Olares/cli/pkg/phase/cluster"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func ChangeIPPipeline(opt *options.ChangeIPOptions) error {
|
||||
terminusVersion := opt.Version
|
||||
func ChangeIPPipeline() error {
|
||||
terminusVersion := viper.GetString(common.FlagVersion)
|
||||
kubeType := phase.GetKubeType()
|
||||
if terminusVersion == "" {
|
||||
terminusVersion, _ = phase.GetOlaresVersion()
|
||||
@@ -22,29 +19,20 @@ func ChangeIPPipeline(opt *options.ChangeIPOptions) error {
|
||||
|
||||
var arg = common.NewArgument()
|
||||
arg.SetOlaresVersion(terminusVersion)
|
||||
arg.SetBaseDir(opt.BaseDir)
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetConsoleLog("changeip.log", true)
|
||||
arg.SetKubeVersion(kubeType)
|
||||
arg.SetMinikubeProfile(opt.MinikubeProfile)
|
||||
arg.SetWSLDistribution(opt.WSLDistribution)
|
||||
if err := arg.LoadMasterHostConfigIfAny(); err != nil {
|
||||
return errors.Wrap(err, "failed to load master host config")
|
||||
}
|
||||
if opt.NewMasterHost != "" {
|
||||
if ip := net.ParseIP(opt.NewMasterHost); !util.IsValidIPv4Addr(ip) {
|
||||
return fmt.Errorf("master host %s is not a valid IPv4 address", opt.NewMasterHost)
|
||||
} else {
|
||||
arg.MasterHost = opt.NewMasterHost
|
||||
}
|
||||
}
|
||||
//only run validation if it's a worker node with master host config set
|
||||
arg.SetMinikubeProfile(viper.GetString(common.FlagMiniKubeProfile))
|
||||
arg.SetWSLDistribution(viper.GetString(common.FlagWSLDistribution))
|
||||
|
||||
// Validate master host config only if it's a worker node with master host set
|
||||
if arg.MasterHost != "" {
|
||||
if err := arg.MasterHostConfig.Validate(); err != nil {
|
||||
return fmt.Errorf("invalid master host config: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -56,5 +44,4 @@ func ChangeIPPipeline(opt *options.ChangeIPOptions) error {
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
@@ -3,23 +3,23 @@ package pipelines
|
||||
import (
|
||||
"path"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/phase/download"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func CheckDownloadInstallationPackage(opts *options.CliDownloadOptions) error {
|
||||
func CheckDownloadInstallationPackage() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetOlaresVersion(opts.Version)
|
||||
arg.SetBaseDir(opts.BaseDir)
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
manifest := opts.Manifest
|
||||
manifest := viper.GetString(common.FlagManifest)
|
||||
if manifest == "" {
|
||||
manifest = path.Join(runtime.GetInstallerDir(), "installation.manifest")
|
||||
}
|
||||
|
||||
@@ -4,30 +4,29 @@ import (
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/phase/download"
|
||||
"github.com/beclab/Olares/cli/pkg/utils"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func DownloadInstallationPackage(opts *options.CliDownloadOptions) error {
|
||||
func DownloadInstallationPackage() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetBaseDir(opts.BaseDir)
|
||||
arg.SetKubeVersion(opts.KubeType)
|
||||
arg.SetOlaresVersion(opts.Version)
|
||||
arg.SetOlaresCDNService(opts.CDNService)
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetOlaresCDNService(viper.GetString(common.FlagCDNService))
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ok := utils.CheckUrl(arg.OlaresCDNService); !ok {
|
||||
return fmt.Errorf("--cdn-service invalid")
|
||||
return fmt.Errorf("invalid cdn service")
|
||||
}
|
||||
|
||||
manifest := opts.Manifest
|
||||
manifest := viper.GetString(common.FlagManifest)
|
||||
if manifest == "" {
|
||||
manifest = path.Join(runtime.GetInstallerDir(), "installation.manifest")
|
||||
}
|
||||
|
||||
@@ -3,30 +3,29 @@ package pipelines
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/phase/download"
|
||||
"github.com/beclab/Olares/cli/pkg/utils"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func DownloadInstallationWizard(opts *options.CliDownloadWizardOptions) error {
|
||||
func DownloadInstallationWizard() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetKubeVersion(opts.KubeType)
|
||||
arg.SetOlaresVersion(opts.Version)
|
||||
arg.SetBaseDir(opts.BaseDir)
|
||||
arg.SetOlaresCDNService(opts.CDNService)
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetOlaresCDNService(viper.GetString(common.FlagCDNService))
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ok := utils.CheckUrl(arg.OlaresCDNService); !ok {
|
||||
return fmt.Errorf("--cdn-service invalid")
|
||||
return fmt.Errorf("invalid cdn service")
|
||||
}
|
||||
|
||||
p := download.NewDownloadWizard(runtime, opts.UrlOverride, opts.ReleaseID)
|
||||
p := download.NewDownloadWizard(runtime, viper.GetString(common.FlagURLOverride), viper.GetString(common.FlagReleaseID))
|
||||
if err := p.Start(); err != nil {
|
||||
logger.Errorf("download wizard failed %v", err)
|
||||
return err
|
||||
|
||||
@@ -12,7 +12,7 @@ func DisableGpuNode() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetConsoleLog("gpudisable.log", true)
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ func DisableNouveau() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetConsoleLog("gpudisable-nouveau.log", true)
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -26,5 +26,3 @@ func DisableNouveau() error {
|
||||
|
||||
return p.Start()
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ func EnableGpuNode() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetConsoleLog("gpuenable.log", true)
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -3,22 +3,21 @@ package pipelines
|
||||
import (
|
||||
"path"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/core/module"
|
||||
"github.com/beclab/Olares/cli/pkg/core/pipeline"
|
||||
"github.com/beclab/Olares/cli/pkg/gpu"
|
||||
"github.com/beclab/Olares/cli/pkg/manifest"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func InstallGpuDrivers(opt *options.InstallGpuOptions) error {
|
||||
func InstallGpuDrivers() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetOlaresVersion(opt.Version)
|
||||
arg.SetCudaVersion(opt.Cuda)
|
||||
arg.SetBaseDir(opt.BaseDir)
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetConsoleLog("gpuinstall.log", true)
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
func GpuDriverStatus() error {
|
||||
arg := common.NewArgument()
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ func UninstallGpuDrivers() error {
|
||||
}
|
||||
arg.SetConsoleLog("gpuuninstall.log", true)
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -6,36 +6,41 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/phase"
|
||||
"github.com/beclab/Olares/cli/pkg/phase/cluster"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func CliInstallTerminusPipeline(opts *options.CliTerminusInstallOptions) error {
|
||||
func CliInstallTerminusPipeline() error {
|
||||
var terminusVersion, _ = phase.GetOlaresVersion()
|
||||
if terminusVersion != "" {
|
||||
return errors.New("Olares is already installed, please uninstall it first.")
|
||||
}
|
||||
|
||||
arg := common.NewArgument()
|
||||
arg.SetBaseDir(opts.BaseDir)
|
||||
arg.SetKubeVersion(opts.KubeType)
|
||||
arg.SetOlaresVersion(opts.Version)
|
||||
arg.SetMinikubeProfile(opts.MiniKubeProfile)
|
||||
arg.SetStorage(getStorageValueFromEnv())
|
||||
arg.SetSwapConfig(opts.SwapConfig)
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetKubeVersion(viper.GetString(common.FlagKubeType))
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetMinikubeProfile(viper.GetString(common.FlagMiniKubeProfile))
|
||||
arg.SetStorage(getStorageConfig())
|
||||
arg.SetSwapConfig(common.SwapConfig{
|
||||
EnablePodSwap: viper.GetBool(common.FlagEnablePodSwap),
|
||||
Swappiness: viper.GetInt(common.FlagSwappiness),
|
||||
EnableZRAM: viper.GetBool(common.FlagEnableZRAM),
|
||||
ZRAMSize: viper.GetString(common.FlagZRAMSize),
|
||||
ZRAMSwapPriority: viper.GetInt(common.FlagZRAMSwapPriority),
|
||||
})
|
||||
if err := arg.SwapConfig.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
if opts.WithJuiceFS {
|
||||
arg.WithJuiceFS = true
|
||||
arg.WithJuiceFS = viper.GetBool(common.FlagEnableJuiceFS)
|
||||
if viper.IsSet(common.FlagEnableReverseProxy) {
|
||||
val := viper.GetBool(common.FlagEnableReverseProxy)
|
||||
arg.NetworkSettings.EnableReverseProxy = &val
|
||||
}
|
||||
if opts.EnableReverseProxy != nil {
|
||||
arg.NetworkSettings.EnableReverseProxy = opts.EnableReverseProxy
|
||||
}
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating runtime: %v", err)
|
||||
}
|
||||
|
||||
@@ -4,32 +4,27 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/module"
|
||||
"github.com/beclab/Olares/cli/pkg/core/pipeline"
|
||||
"github.com/beclab/Olares/cli/pkg/terminus"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func MasterInfoPipeline(opts *options.MasterInfoOptions) error {
|
||||
func MasterInfoPipeline() error {
|
||||
arg := common.NewArgument()
|
||||
if !arg.SystemInfo.IsLinux() {
|
||||
fmt.Println("error: Only Linux nodes can be added to an Olares cluster!")
|
||||
os.Exit(1)
|
||||
}
|
||||
arg.SetBaseDir(opts.BaseDir)
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetConsoleLog("masterinfo.log", true)
|
||||
|
||||
if err := arg.LoadMasterHostConfigIfAny(); err != nil {
|
||||
return errors.Wrap(err, "failed to load master host config")
|
||||
}
|
||||
arg.SetMasterHostOverride(opts.MasterHostConfig)
|
||||
if err := arg.MasterHostConfig.Validate(); err != nil {
|
||||
return fmt.Errorf("invalid master host config: %w", err)
|
||||
}
|
||||
arg.SetConsoleLog("masterinfo.log", true)
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating runtime: %v", err)
|
||||
}
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
package pipelines
|
||||
|
||||
import (
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/pkg/bootstrap/precheck"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/module"
|
||||
"github.com/beclab/Olares/cli/pkg/core/pipeline"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func StartPreCheckPipeline(opt *options.PreCheckOptions) error {
|
||||
terminusVersion := opt.Version
|
||||
|
||||
func StartPreCheckPipeline() error {
|
||||
var arg = common.NewArgument()
|
||||
arg.SetOlaresVersion(terminusVersion)
|
||||
arg.SetBaseDir(opt.BaseDir)
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetConsoleLog("precheck.log", true)
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -3,13 +3,11 @@ package pipelines
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/daemon"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
bootstrapos "github.com/beclab/Olares/cli/pkg/bootstrap/os"
|
||||
"github.com/beclab/Olares/cli/pkg/bootstrap/patch"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
@@ -20,23 +18,23 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/manifest"
|
||||
"github.com/beclab/Olares/cli/pkg/phase"
|
||||
"github.com/beclab/Olares/cli/pkg/phase/system"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func PrepareSystemPipeline(opts *options.CliPrepareSystemOptions, components []string) error {
|
||||
func PrepareSystemPipeline(components []string) error {
|
||||
var terminusVersion, _ = phase.GetOlaresVersion()
|
||||
if terminusVersion != "" && len(components) == 0 {
|
||||
return errors.New("Olares is already installed, please uninstall it first.")
|
||||
}
|
||||
|
||||
var arg = common.NewArgument()
|
||||
arg.SetBaseDir(opts.BaseDir)
|
||||
arg.SetKubeVersion(opts.KubeType)
|
||||
arg.SetMinikubeProfile(opts.MinikubeProfile)
|
||||
arg.SetOlaresVersion(opts.Version)
|
||||
arg.SetRegistryMirrors(opts.RegistryMirrors)
|
||||
arg.SetStorage(getStorageValueFromEnv())
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetKubeVersion(viper.GetString(common.FlagKubeType))
|
||||
arg.SetMinikubeProfile(viper.GetString(common.FlagMiniKubeProfile))
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetStorage(getStorageConfig())
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating runtime: %w", err)
|
||||
}
|
||||
@@ -133,24 +131,3 @@ func PrepareSystemPipeline(opts *options.CliPrepareSystemOptions, components []s
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getStorageValueFromEnv() *common.Storage {
|
||||
storageType := os.Getenv(common.ENV_STORAGE)
|
||||
switch storageType {
|
||||
case "":
|
||||
storageType = common.ManagedMinIO
|
||||
}
|
||||
|
||||
return &common.Storage{
|
||||
StorageType: storageType,
|
||||
StorageBucket: os.Getenv(common.ENV_S3_BUCKET),
|
||||
StoragePrefix: os.Getenv(common.ENV_BACKUP_KEY_PREFIX),
|
||||
StorageAccessKey: os.Getenv(common.ENV_AWS_ACCESS_KEY_ID_SETUP),
|
||||
StorageSecretKey: os.Getenv(common.ENV_AWS_SECRET_ACCESS_KEY_SETUP),
|
||||
StorageToken: os.Getenv(common.ENV_AWS_SESSION_TOKEN_SETUP),
|
||||
StorageClusterId: os.Getenv(common.ENV_CLUSTER_ID),
|
||||
StorageSyncSecret: os.Getenv(common.ENV_BACKUP_SECRET),
|
||||
StorageVendor: os.Getenv(common.ENV_TERMINUS_IS_CLOUD_VERSION),
|
||||
BackupClusterBucket: os.Getenv(common.ENV_BACKUP_CLUSTER_BUCKET),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
func StartOlares() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetConsoleLog("start.log", true)
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -31,7 +31,7 @@ func StartOlares() error {
|
||||
func StopOlares(timeout, checkInterval time.Duration) error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetConsoleLog("stop.log", true)
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -4,25 +4,25 @@ import (
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/phase"
|
||||
"github.com/beclab/Olares/cli/pkg/phase/system"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func CliInstallStoragePipeline(opts *options.InstallStorageOptions) error {
|
||||
func CliInstallStoragePipeline() error {
|
||||
var terminusVersion, _ = phase.GetOlaresVersion()
|
||||
if terminusVersion != "" {
|
||||
return errors.New("Olares is already installed, please uninstall it first.")
|
||||
}
|
||||
|
||||
arg := common.NewArgument()
|
||||
arg.SetBaseDir(opts.BaseDir)
|
||||
arg.SetOlaresVersion(opts.Version)
|
||||
arg.SetStorage(getStorageValueFromEnv())
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetStorage(getStorageConfig())
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating runtime: %v", err)
|
||||
}
|
||||
@@ -32,3 +32,22 @@ func CliInstallStoragePipeline(opts *options.InstallStorageOptions) error {
|
||||
|
||||
return system.InstallStoragePipeline(runtime).Start()
|
||||
}
|
||||
|
||||
func getStorageConfig() *common.Storage {
|
||||
storageType := viper.GetString(common.FlagStorageType)
|
||||
if storageType == "" {
|
||||
storageType = common.ManagedMinIO
|
||||
}
|
||||
return &common.Storage{
|
||||
StorageType: storageType,
|
||||
StorageBucket: viper.GetString(common.FlagS3Bucket),
|
||||
StoragePrefix: viper.GetString(common.FlagBackupKeyPrefix),
|
||||
StorageAccessKey: viper.GetString(common.FlagAWSAccessKeyIDSetup),
|
||||
StorageSecretKey: viper.GetString(common.FlagAWSSecretAccessKeySetup),
|
||||
StorageToken: viper.GetString(common.FlagAWSSessionTokenSetup),
|
||||
StorageClusterId: viper.GetString(common.FlagClusterID),
|
||||
StorageSyncSecret: viper.GetString(common.FlagBackupSecret),
|
||||
StorageVendor: viper.GetString(common.FlagIsCloudVersion),
|
||||
BackupClusterBucket: viper.GetString(common.FlagBackupClusterBucket),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,50 +2,46 @@ package pipelines
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/phase"
|
||||
"github.com/beclab/Olares/cli/pkg/phase/cluster"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func UninstallTerminusPipeline(opt *options.CliTerminusUninstallOptions) error {
|
||||
terminusVersion := opt.Version
|
||||
func UninstallTerminusPipeline() error {
|
||||
version := viper.GetString(common.FlagVersion)
|
||||
kubeType := phase.GetKubeType()
|
||||
|
||||
if terminusVersion == "" {
|
||||
terminusVersion, _ = phase.GetOlaresVersion()
|
||||
if version == "" {
|
||||
version, _ = phase.GetOlaresVersion()
|
||||
}
|
||||
|
||||
var arg = common.NewArgument()
|
||||
arg.SetOlaresVersion(terminusVersion)
|
||||
arg.SetBaseDir(opt.BaseDir)
|
||||
arg.SetOlaresVersion(version)
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetConsoleLog("uninstall.log", true)
|
||||
arg.SetKubeVersion(kubeType)
|
||||
arg.SetDeleteCRI(opt.All || (opt.Phase == cluster.PhasePrepare.String() || opt.Phase == cluster.PhaseDownload.String()))
|
||||
arg.SetStorage(&common.Storage{
|
||||
StorageVendor: os.Getenv(common.ENV_TERMINUS_IS_CLOUD_VERSION),
|
||||
StorageType: os.Getenv(common.ENV_STORAGE),
|
||||
StorageBucket: os.Getenv(common.ENV_S3_BUCKET),
|
||||
})
|
||||
arg.SetStorage(getStorageConfig())
|
||||
|
||||
if err := checkPhase(opt.Phase, opt.All, arg.SystemInfo.GetOsType()); err != nil {
|
||||
phase := viper.GetString(common.FlagUninstallPhase)
|
||||
all := viper.GetBool(common.FlagUninstallAll)
|
||||
|
||||
if err := checkPhase(phase, all, arg.SystemInfo.GetOsType()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
phaseName := opt.Phase
|
||||
if opt.All {
|
||||
phaseName = cluster.PhaseDownload.String()
|
||||
if all {
|
||||
phase = cluster.PhaseDownload.String()
|
||||
}
|
||||
|
||||
var p = cluster.UninstallTerminus(phaseName, runtime)
|
||||
var p = cluster.UninstallTerminus(phase, runtime)
|
||||
if err := p.Start(); err != nil {
|
||||
logger.Errorf("uninstall Olares failed: %v", err)
|
||||
return err
|
||||
|
||||
@@ -2,12 +2,13 @@ package pipelines
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/upgrade"
|
||||
"github.com/beclab/Olares/cli/pkg/utils"
|
||||
"github.com/beclab/Olares/cli/version"
|
||||
"path"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/core/module"
|
||||
@@ -16,7 +17,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func UpgradeOlaresPipeline(opts *options.UpgradeOptions) error {
|
||||
func UpgradeOlaresPipeline() error {
|
||||
currentVersionString, err := phase.GetOlaresVersion()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get current Olares version")
|
||||
@@ -31,10 +32,11 @@ func UpgradeOlaresPipeline(opts *options.UpgradeOptions) error {
|
||||
|
||||
// should only be and defaults to the current cli version
|
||||
// this argument is for backwards-compatibility with older olaresd
|
||||
if opts.Version == "" {
|
||||
opts.Version = version.VERSION
|
||||
targetVersionStr := viper.GetString(common.FlagVersion)
|
||||
if targetVersionStr == "" {
|
||||
targetVersionStr = version.VERSION
|
||||
}
|
||||
targetVersion, err := utils.ParseOlaresVersionString(opts.Version)
|
||||
targetVersion, err := utils.ParseOlaresVersionString(targetVersionStr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing target Olares version: %v", err)
|
||||
}
|
||||
@@ -44,12 +46,12 @@ func UpgradeOlaresPipeline(opts *options.UpgradeOptions) error {
|
||||
}
|
||||
|
||||
arg := common.NewArgument()
|
||||
arg.SetBaseDir(opts.BaseDir)
|
||||
arg.SetOlaresVersion(opts.Version)
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetConsoleLog("upgrade.log", true)
|
||||
arg.SetKubeVersion(phase.GetKubeType())
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating runtime: %v", err)
|
||||
}
|
||||
@@ -67,7 +69,7 @@ func UpgradeOlaresPipeline(opts *options.UpgradeOptions) error {
|
||||
Runtime: runtime,
|
||||
}
|
||||
|
||||
logger.Infof("Starting Olares upgrade from %s to %s...", currentVersion, opts.Version)
|
||||
logger.Infof("Starting Olares upgrade from %s to %s...", currentVersion, targetVersion)
|
||||
if err := p.Start(); err != nil {
|
||||
return errors.Wrap(err, "upgrade failed")
|
||||
}
|
||||
@@ -80,7 +82,7 @@ func UpgradePreCheckPipeline() error {
|
||||
var arg = common.NewArgument()
|
||||
arg.SetConsoleLog("upgrade-precheck.log", true)
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -30,11 +30,6 @@ import (
|
||||
|
||||
type DeployLocalVolumeModule struct {
|
||||
common.KubeModule
|
||||
Skip bool
|
||||
}
|
||||
|
||||
func (d *DeployLocalVolumeModule) IsSkip() bool {
|
||||
return d.Skip
|
||||
}
|
||||
|
||||
func (d *DeployLocalVolumeModule) Init() {
|
||||
|
||||
@@ -396,3 +396,17 @@ func (t *DeleteTerminusData) Execute(runtime connector.Runtime) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type CreateSharedLibDir struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (t *CreateSharedLibDir) Execute(runtime connector.Runtime) error {
|
||||
if runtime.GetSystemInfo().IsDarwin() {
|
||||
return nil
|
||||
}
|
||||
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("mkdir -p %s && chown 1000:1000 %s", OlaresSharedLibDir, OlaresSharedLibDir), false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to create shared lib dir")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -33,13 +33,13 @@ type ValidateStorageConfig struct {
|
||||
func (a *ValidateStorageConfig) Execute(runtime connector.Runtime) error {
|
||||
storageConf := a.KubeConf.Arg.Storage
|
||||
if storageConf.StorageBucket == "" {
|
||||
return fmt.Errorf("missing storage bucket, please set it in env %s", common.ENV_S3_BUCKET)
|
||||
return fmt.Errorf("missing storage bucket")
|
||||
}
|
||||
if storageConf.StorageAccessKey == "" {
|
||||
return fmt.Errorf("missing storage access key, please set it in env %s", common.ENV_AWS_ACCESS_KEY_ID_SETUP)
|
||||
return fmt.Errorf("missing storage access key")
|
||||
}
|
||||
if storageConf.StorageSecretKey == "" {
|
||||
return fmt.Errorf("missing storage secret key, please set it in env %s", common.ENV_AWS_SECRET_ACCESS_KEY_SETUP)
|
||||
return fmt.Errorf("missing storage secret key")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -30,20 +30,16 @@ type GetUserInfo struct {
|
||||
|
||||
func (s *GetUserInfo) Execute(runtime connector.Runtime) error {
|
||||
var err error
|
||||
if len(s.KubeConf.Arg.User.DomainName) == 0 {
|
||||
s.KubeConf.Arg.User.DomainName, err = s.getDomainName()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Infof("using Domain Name: %s", s.KubeConf.Arg.User.DomainName)
|
||||
s.KubeConf.Arg.User.DomainName, err = s.getDomainName()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(s.KubeConf.Arg.User.UserName) == 0 {
|
||||
s.KubeConf.Arg.User.UserName, err = s.getUserName()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Infof("using Olares Local Name: %s", s.KubeConf.Arg.User.UserName)
|
||||
logger.Infof("using Domain Name: %s", s.KubeConf.Arg.User.DomainName)
|
||||
s.KubeConf.Arg.User.UserName, err = s.getUserName()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Infof("using Olares Local Name: %s", s.KubeConf.Arg.User.UserName)
|
||||
s.KubeConf.Arg.User.Email, err = s.getUserEmail()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -53,16 +49,20 @@ func (s *GetUserInfo) Execute(runtime connector.Runtime) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Infof("using password: %s", s.KubeConf.Arg.User.Password)
|
||||
if s.KubeConf.Arg.User.Password != "" {
|
||||
logger.Infof("using password: %s", s.KubeConf.Arg.User.Password)
|
||||
} else {
|
||||
logger.Infof("using already encrypted password")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *GetUserInfo) getDomainName() (string, error) {
|
||||
domainName := strings.TrimSpace(os.Getenv("TERMINUS_OS_DOMAINNAME"))
|
||||
domainName := s.KubeConf.Arg.User.DomainName
|
||||
if len(domainName) > 0 {
|
||||
if !utils.IsValidDomain(domainName) {
|
||||
return "", errors.New(fmt.Sprintf("invalid domain name \"%s\" set in env, please reset", domainName))
|
||||
return "", errors.New(fmt.Sprintf("invalid domain name \"%s\", please reset", domainName))
|
||||
}
|
||||
return domainName, nil
|
||||
}
|
||||
@@ -90,14 +90,14 @@ LOOP:
|
||||
}
|
||||
|
||||
func (s *GetUserInfo) getUserName() (string, error) {
|
||||
userName := os.Getenv("TERMINUS_OS_USERNAME")
|
||||
userName := s.KubeConf.Arg.User.UserName
|
||||
if strings.Contains(userName, "@") {
|
||||
userName = strings.Split(userName, "@")[0]
|
||||
}
|
||||
userName = strings.TrimSpace(userName)
|
||||
if len(userName) > 0 {
|
||||
if err := utils.ValidateUserName(userName); err != nil {
|
||||
return "", fmt.Errorf("invalid username \"%s\" set in env: %s, please reset", userName, err.Error())
|
||||
return "", fmt.Errorf("invalid username \"%s\": %s, please reset", userName, err.Error())
|
||||
}
|
||||
return userName, nil
|
||||
}
|
||||
@@ -135,15 +135,23 @@ func (s *GetUserInfo) getUserEmail() (string, error) {
|
||||
}
|
||||
|
||||
func (s *GetUserInfo) getUserPassword() (string, string, error) {
|
||||
userPassword := strings.TrimSpace(os.Getenv("TERMINUS_OS_PASSWORD"))
|
||||
if len(userPassword) != 32 && len(userPassword) != 0 {
|
||||
return "", "", fmt.Errorf("invalid password \"%s\" set in env: length should be equal 32, please reset", userPassword)
|
||||
// currently only used in the installation flow by LarePass -> Olaresd,
|
||||
// when this env var is passed in, it is already encrypted
|
||||
// make this one priority over the password set in the arg specailly
|
||||
// to ensure the larepass installation flow works as expected
|
||||
encryptedPassword := strings.TrimSpace(os.Getenv(common.EnvLegacyEncryptedOSPassword))
|
||||
if len(encryptedPassword) != 32 && len(encryptedPassword) != 0 {
|
||||
return "", "", fmt.Errorf("invalid password \"%s\" set in env: length should be equal 32, please reset", encryptedPassword)
|
||||
|
||||
}
|
||||
if len(userPassword) == 0 {
|
||||
return utils.GenerateEncryptedPassword(8)
|
||||
if len(encryptedPassword) == 0 {
|
||||
if s.KubeConf.Arg.User.Password != "" {
|
||||
return s.KubeConf.Arg.User.Password, utils.EncryptPassword(s.KubeConf.Arg.User.Password), nil
|
||||
} else {
|
||||
return utils.GenerateEncryptedPassword(8)
|
||||
}
|
||||
}
|
||||
return userPassword, userPassword, nil
|
||||
return "", encryptedPassword, nil
|
||||
}
|
||||
|
||||
type SetAccountValues struct {
|
||||
|
||||
@@ -82,10 +82,6 @@ func (u *PrepareAppValues) Execute(runtime connector.Runtime) error {
|
||||
defer cancel()
|
||||
|
||||
ns := fmt.Sprintf("user-space-%s", u.KubeConf.Arg.User.UserName)
|
||||
//redisPassword, err := getRedisPassword(client, runtime)
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
|
||||
bfDocUrl, _ := getDocUrl(ctx, runtime)
|
||||
bflNodeName, err := getBflPod(ctx, ns, client, runtime)
|
||||
@@ -127,13 +123,9 @@ func (u *PrepareAppValues) Execute(runtime connector.Runtime) error {
|
||||
"username": u.KubeConf.Arg.User.UserName,
|
||||
},
|
||||
},
|
||||
"debugVersion": os.Getenv("DEBUG_VERSION") != "",
|
||||
"gpu": gpuType,
|
||||
"fs_type": fsType,
|
||||
"os": appValues,
|
||||
//"kubesphere": map[string]interface{}{
|
||||
// "redis_password": redisPassword,
|
||||
//},
|
||||
"gpu": gpuType,
|
||||
"fs_type": fsType,
|
||||
"os": appValues,
|
||||
common.HelmValuesKeyOlaresRootFSPath: storage.OlaresRootDir,
|
||||
}
|
||||
|
||||
|
||||
@@ -38,12 +38,6 @@ type InstallOsSystem struct {
|
||||
}
|
||||
|
||||
func (t *InstallOsSystem) Execute(runtime connector.Runtime) error {
|
||||
if !runtime.GetSystemInfo().IsDarwin() {
|
||||
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("mkdir -p %s && chown 1000:1000 %s", storage.OlaresSharedLibDir, storage.OlaresSharedLibDir), false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to create shared lib dir")
|
||||
}
|
||||
}
|
||||
|
||||
config, err := ctrl.GetConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -367,6 +361,11 @@ func (m *InstallOsSystemModule) Init() {
|
||||
Action: &CreateUserEnvConfigMap{},
|
||||
}
|
||||
|
||||
createSharedLibDir := &task.LocalTask{
|
||||
Name: "CreateSharedLibDir",
|
||||
Action: &storage.CreateSharedLibDir{},
|
||||
}
|
||||
|
||||
installOsSystem := &task.LocalTask{
|
||||
Name: "InstallOsSystem",
|
||||
Action: &InstallOsSystem{},
|
||||
@@ -399,6 +398,7 @@ func (m *InstallOsSystemModule) Init() {
|
||||
m.Tasks = []task.Interface{
|
||||
applySystemEnv,
|
||||
createUserEnvConfigMap,
|
||||
createSharedLibDir,
|
||||
installOsSystem,
|
||||
createBackupConfigMap,
|
||||
checkSystemService,
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/core/connector"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/core/task"
|
||||
"github.com/beclab/Olares/cli/pkg/utils"
|
||||
)
|
||||
|
||||
type WelcomeMessage struct {
|
||||
@@ -68,6 +69,15 @@ func (t *WelcomeMessage) Execute(runtime connector.Runtime) error {
|
||||
logger.Infof("Username: %s", t.KubeConf.Arg.User.UserName)
|
||||
logger.Infof("Password: %s", t.KubeConf.Arg.User.Password)
|
||||
fmt.Printf("\n------------------------------------------------\n\n\n\n\n")
|
||||
fmt.Println()
|
||||
|
||||
// If AMD GPU on Ubuntu 22.04/24.04, print warning about reboot for ROCm
|
||||
if si := runtime.GetSystemInfo(); si.IsUbuntu() && (si.IsUbuntuVersionEqual(connector.Ubuntu2204) || si.IsUbuntuVersionEqual(connector.Ubuntu2404)) {
|
||||
if hasAmd, _ := utils.HasAmdIGPU(runtime); hasAmd {
|
||||
logger.Warnf("\x1b[31mWarning: To enable ROCm, please reboot your machine after activation.\x1b[0m")
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
32
cli/pkg/upgrade/1_12_5_20260122.go
Normal file
32
cli/pkg/upgrade/1_12_5_20260122.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package upgrade
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/beclab/Olares/cli/pkg/core/task"
|
||||
)
|
||||
|
||||
type upgrader_1_12_5_20260122 struct {
|
||||
breakingUpgraderBase
|
||||
}
|
||||
|
||||
func (u upgrader_1_12_5_20260122) Version() *semver.Version {
|
||||
return semver.MustParse("1.12.3-20260122")
|
||||
}
|
||||
|
||||
func (u upgrader_1_12_5_20260122) UpgradeSystemComponents() []task.Interface {
|
||||
pre := []task.Interface{
|
||||
&task.LocalTask{
|
||||
Name: "UpgradeL4BFLProxy",
|
||||
Action: &upgradeL4BFLProxy{Tag: "v0.3.10"},
|
||||
Retry: 3,
|
||||
Delay: 5 * time.Second,
|
||||
},
|
||||
}
|
||||
return append(pre, u.upgraderBase.UpgradeSystemComponents()...)
|
||||
}
|
||||
|
||||
func init() {
|
||||
registerDailyUpgrader(upgrader_1_12_5_20260122{})
|
||||
}
|
||||
67
cli/pkg/utils/amdgpu.go
Normal file
67
cli/pkg/utils/amdgpu.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/beclab/Olares/cli/pkg/core/connector"
|
||||
)
|
||||
|
||||
func HasAmdIGPU(execRuntime connector.Runtime) (bool, error) {
|
||||
// Detect by CPU model names that bundle AMD AI NPU/graphics
|
||||
targets := []string{
|
||||
"AMD Ryzen AI Max+ 395",
|
||||
"AMD Ryzen AI Max 390",
|
||||
"AMD Ryzen AI Max 385",
|
||||
"AMD Ryzen AI 9 HX 375",
|
||||
"AMD Ryzen AI 9 HX 370",
|
||||
"AMD Ryzen AI 9 365",
|
||||
}
|
||||
// try lscpu first: extract 'Model name' field
|
||||
out, err := execRuntime.GetRunner().SudoCmd("lscpu 2>/dev/null | awk -F': *' '/^Model name/{print $2; exit}' || true", false, false)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if out != "" {
|
||||
lo := strings.ToLower(strings.TrimSpace(out))
|
||||
for _, t := range targets {
|
||||
if strings.Contains(lo, strings.ToLower(t)) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
// fallback to /proc/cpuinfo
|
||||
out, err = execRuntime.GetRunner().SudoCmd("awk -F': *' '/^model name/{print $2; exit}' /proc/cpuinfo 2>/dev/null || true", false, false)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if out != "" {
|
||||
lo := strings.ToLower(strings.TrimSpace(out))
|
||||
for _, t := range targets {
|
||||
if strings.Contains(lo, strings.ToLower(t)) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func RocmVersion() (*semver.Version, error) {
|
||||
const rocmVersionFile = "/opt/rocm/.info/version"
|
||||
data, err := os.ReadFile(rocmVersionFile)
|
||||
if err != nil {
|
||||
// no ROCm installed, nothing to check
|
||||
if os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
curStr := strings.TrimSpace(string(data))
|
||||
cur, err := semver.NewVersion(curStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid rocm version: %s", curStr)
|
||||
}
|
||||
return cur, nil
|
||||
}
|
||||
@@ -224,7 +224,11 @@ func GenerateEncryptedPassword(length int) (string, string, error) {
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return plainText, utils.MD5(plainText + "@Olares2025"), nil
|
||||
return plainText, EncryptPassword(plainText), nil
|
||||
}
|
||||
|
||||
func EncryptPassword(plainText string) string {
|
||||
return utils.MD5(plainText + "@Olares2025")
|
||||
}
|
||||
|
||||
func RemoveAnsiCodes(input string) string {
|
||||
@@ -321,3 +325,54 @@ func GetBufIOReaderOfTerminalInput() (*bufio.Reader, error) {
|
||||
}
|
||||
return bufio.NewReader(tty), nil
|
||||
}
|
||||
|
||||
// ResolveSudoUserHomeAndIDs resolves the home directory, uid, and gid for the user
|
||||
// who invoked sudo. If not running under sudo, it falls back to the current user.
|
||||
// This is useful for commands that need to operate on the invoking user's home
|
||||
// directory rather than /root when running with sudo.
|
||||
func ResolveSudoUserHomeAndIDs(runtime connector.Runtime) (home, uid, gid string, err error) {
|
||||
uid, err = runtime.GetRunner().Cmd("echo ${SUDO_UID:-}", false, false)
|
||||
if err != nil {
|
||||
return "", "", "", errors.Wrap(errors.WithStack(err), "get SUDO_UID failed")
|
||||
}
|
||||
gid, err = runtime.GetRunner().Cmd("echo ${SUDO_GID:-}", false, false)
|
||||
if err != nil {
|
||||
return "", "", "", errors.Wrap(errors.WithStack(err), "get SUDO_GID failed")
|
||||
}
|
||||
uid = strings.TrimSpace(uid)
|
||||
gid = strings.TrimSpace(gid)
|
||||
|
||||
if uid == "" {
|
||||
uid, err = runtime.GetRunner().Cmd("id -u", false, false)
|
||||
if err != nil {
|
||||
return "", "", "", errors.Wrap(errors.WithStack(err), "get current uid failed")
|
||||
}
|
||||
gid, err = runtime.GetRunner().Cmd("id -g", false, false)
|
||||
if err != nil {
|
||||
return "", "", "", errors.Wrap(errors.WithStack(err), "get current gid failed")
|
||||
}
|
||||
uid = strings.TrimSpace(uid)
|
||||
gid = strings.TrimSpace(gid)
|
||||
}
|
||||
|
||||
home, err = runtime.GetRunner().Cmd(fmt.Sprintf(`getent passwd %s | awk -F: 'NR==1{print $6; exit}'`, uid), false, false)
|
||||
if err != nil {
|
||||
home = ""
|
||||
}
|
||||
home = strings.TrimSpace(home)
|
||||
if home == "" {
|
||||
home, _ = runtime.GetRunner().Cmd(fmt.Sprintf(`awk -F: -v uid=%s '$3==uid {print $6; exit}' /etc/passwd 2>/dev/null`, uid), false, false)
|
||||
home = strings.TrimSpace(home)
|
||||
}
|
||||
if home == "" {
|
||||
home, err = runtime.GetRunner().Cmd("echo $HOME", false, false)
|
||||
if err != nil {
|
||||
return "", "", "", errors.Wrap(errors.WithStack(err), "get HOME failed")
|
||||
}
|
||||
home = strings.TrimSpace(home)
|
||||
}
|
||||
if home == "" {
|
||||
return "", "", "", errors.New("resolve user home failed")
|
||||
}
|
||||
return home, uid, gid, nil
|
||||
}
|
||||
|
||||
@@ -1,197 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package kubesphere
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/core/util"
|
||||
"github.com/beclab/Olares/cli/pkg/version/kubesphere/templates"
|
||||
versionutil "k8s.io/apimachinery/pkg/util/version"
|
||||
)
|
||||
|
||||
type KsInstaller struct {
|
||||
Version string
|
||||
CRDTemplate *template.Template
|
||||
ClusterConfigurationTemplate *template.Template
|
||||
K8sSupportVersions []string
|
||||
UpgradeSupportVersions []string
|
||||
}
|
||||
|
||||
func (k *KsInstaller) CCToString() string {
|
||||
str, err := util.Render(k.ClusterConfigurationTemplate, util.Data{
|
||||
"Tag": k.Version,
|
||||
})
|
||||
if err != nil {
|
||||
os.Exit(0)
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
func (k *KsInstaller) K8sSupport(version string) bool {
|
||||
k8sVersion := versionutil.MustParseSemantic(version)
|
||||
for i := range k.K8sSupportVersions {
|
||||
if k.K8sSupportVersions[i] == fmt.Sprintf("v%v.%v", k8sVersion.Major(), k8sVersion.Minor()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (k *KsInstaller) UpgradeSupport(version string) bool {
|
||||
for i := range k.UpgradeSupportVersions {
|
||||
if k.UpgradeSupportVersions[i] == version {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var KsV211 = &KsInstaller{
|
||||
Version: V211.String(),
|
||||
CRDTemplate: templates.KsInstaller,
|
||||
ClusterConfigurationTemplate: templates.V211,
|
||||
K8sSupportVersions: []string{
|
||||
"v1.15",
|
||||
"v1.16",
|
||||
"v1.17",
|
||||
"v1.18",
|
||||
},
|
||||
UpgradeSupportVersions: []string{
|
||||
V211.String(),
|
||||
},
|
||||
}
|
||||
|
||||
var KsV300 = &KsInstaller{
|
||||
Version: V300.String(),
|
||||
CRDTemplate: templates.KsInstaller,
|
||||
ClusterConfigurationTemplate: templates.V300,
|
||||
K8sSupportVersions: []string{
|
||||
"v1.15",
|
||||
"v1.16",
|
||||
"v1.17",
|
||||
"v1.18",
|
||||
},
|
||||
UpgradeSupportVersions: []string{
|
||||
V211.String(),
|
||||
},
|
||||
}
|
||||
|
||||
var KsV310 = &KsInstaller{
|
||||
Version: V310.String(),
|
||||
CRDTemplate: templates.KsInstaller,
|
||||
ClusterConfigurationTemplate: templates.V310,
|
||||
K8sSupportVersions: []string{
|
||||
"v1.15",
|
||||
"v1.16",
|
||||
"v1.17",
|
||||
"v1.18",
|
||||
"v1.19",
|
||||
"v1.20",
|
||||
},
|
||||
UpgradeSupportVersions: []string{
|
||||
V300.String(),
|
||||
},
|
||||
}
|
||||
|
||||
var KsV311 = &KsInstaller{
|
||||
Version: V311.String(),
|
||||
CRDTemplate: templates.KsInstaller,
|
||||
ClusterConfigurationTemplate: templates.V311,
|
||||
K8sSupportVersions: []string{
|
||||
"v1.15",
|
||||
"v1.16",
|
||||
"v1.17",
|
||||
"v1.18",
|
||||
"v1.19",
|
||||
"v1.20",
|
||||
},
|
||||
UpgradeSupportVersions: []string{
|
||||
V300.String(),
|
||||
V310.String(),
|
||||
},
|
||||
}
|
||||
|
||||
var KsV320 = &KsInstaller{
|
||||
Version: V320.String(),
|
||||
CRDTemplate: templates.KsInstaller,
|
||||
ClusterConfigurationTemplate: templates.V320,
|
||||
K8sSupportVersions: []string{
|
||||
"v1.19",
|
||||
"v1.20",
|
||||
"v1.21",
|
||||
"v1.22",
|
||||
},
|
||||
UpgradeSupportVersions: []string{
|
||||
V310.String(),
|
||||
V311.String(),
|
||||
},
|
||||
}
|
||||
|
||||
var KsV321 = &KsInstaller{
|
||||
Version: V321.String(),
|
||||
CRDTemplate: templates.KsInstaller,
|
||||
ClusterConfigurationTemplate: templates.V321,
|
||||
K8sSupportVersions: []string{
|
||||
"v1.19",
|
||||
"v1.20",
|
||||
"v1.21",
|
||||
"v1.22",
|
||||
},
|
||||
UpgradeSupportVersions: []string{
|
||||
V310.String(),
|
||||
V311.String(),
|
||||
V320.String(),
|
||||
},
|
||||
}
|
||||
|
||||
var KsV330 = &KsInstaller{
|
||||
Version: V330.String(),
|
||||
CRDTemplate: templates.KsInstaller,
|
||||
ClusterConfigurationTemplate: templates.V330,
|
||||
K8sSupportVersions: []string{
|
||||
"v1.19",
|
||||
"v1.20",
|
||||
"v1.21",
|
||||
"v1.22",
|
||||
"v1.23",
|
||||
},
|
||||
UpgradeSupportVersions: []string{
|
||||
V320.String(),
|
||||
V321.String(),
|
||||
},
|
||||
}
|
||||
|
||||
var KsV331 = &KsInstaller{
|
||||
Version: V331.String(),
|
||||
CRDTemplate: templates.KsInstaller,
|
||||
ClusterConfigurationTemplate: templates.V331,
|
||||
K8sSupportVersions: []string{
|
||||
"v1.19",
|
||||
"v1.20",
|
||||
"v1.21",
|
||||
"v1.22",
|
||||
"v1.23",
|
||||
},
|
||||
UpgradeSupportVersions: []string{
|
||||
V330.String(),
|
||||
V320.String(),
|
||||
V321.String(),
|
||||
},
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package templates
|
||||
|
||||
import (
|
||||
"github.com/lithammer/dedent"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
var V211 = template.Must(template.New("v2.1.1").Parse(
|
||||
dedent.Dedent(`---
|
||||
apiVersion: v1
|
||||
data:
|
||||
ks-config.yaml: |
|
||||
---
|
||||
local_registry: ""
|
||||
persistence:
|
||||
storageClass: ""
|
||||
etcd:
|
||||
monitoring: true
|
||||
endpointIps: localhost
|
||||
port: 2379
|
||||
tlsEnable: true
|
||||
common:
|
||||
mysqlVolumeSize: 20Gi
|
||||
minioVolumeSize: 20Gi
|
||||
etcdVolumeSize: 20Gi
|
||||
openldapVolumeSize: 2Gi
|
||||
redisVolumSize: 2Gi
|
||||
metrics_server:
|
||||
enabled: false
|
||||
console:
|
||||
enableMultiLogin: False # enable/disable multi login
|
||||
port: 30880
|
||||
monitoring:
|
||||
prometheusReplicas: 1
|
||||
prometheusMemoryRequest: 400Mi
|
||||
prometheusVolumeSize: 20Gi
|
||||
grafana:
|
||||
enabled: false
|
||||
logging:
|
||||
enabled: false
|
||||
elasticsearchMasterReplicas: 1
|
||||
elasticsearchDataReplicas: 1
|
||||
logsidecarReplicas: 2
|
||||
elasticsearchMasterVolumeSize: 4Gi
|
||||
elasticsearchDataVolumeSize: 20Gi
|
||||
logMaxAge: 7
|
||||
elkPrefix: logstash
|
||||
containersLogMountedPath: ""
|
||||
kibana:
|
||||
enabled: false
|
||||
openpitrix:
|
||||
enabled: false
|
||||
devops:
|
||||
enabled: false
|
||||
jenkinsMemoryLim: 2Gi
|
||||
jenkinsMemoryReq: 1500Mi
|
||||
jenkinsVolumeSize: 8Gi
|
||||
jenkinsJavaOpts_Xms: 512m
|
||||
jenkinsJavaOpts_Xmx: 512m
|
||||
jenkinsJavaOpts_MaxRAM: 2g
|
||||
sonarqube:
|
||||
enabled: false
|
||||
postgresqlVolumeSize: 8Gi
|
||||
servicemesh:
|
||||
enabled: false
|
||||
notification:
|
||||
enabled: false
|
||||
alerting:
|
||||
enabled: false
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: ks-installer
|
||||
namespace: kubesphere-system
|
||||
labels:
|
||||
version: {{ .Tag }}
|
||||
`)))
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package templates
|
||||
|
||||
import (
|
||||
"text/template"
|
||||
|
||||
"github.com/lithammer/dedent"
|
||||
)
|
||||
|
||||
var V300 = template.Must(template.New("v3.0.0").Parse(
|
||||
dedent.Dedent(`---
|
||||
apiVersion: installer.kubesphere.io/v1alpha1
|
||||
kind: ClusterConfiguration
|
||||
metadata:
|
||||
name: ks-installer
|
||||
namespace: kubesphere-system
|
||||
labels:
|
||||
version: {{ .Tag }}
|
||||
spec:
|
||||
zone: ""
|
||||
local_registry: ""
|
||||
persistence:
|
||||
storageClass: ""
|
||||
authentication:
|
||||
jwtSecret: ""
|
||||
etcd:
|
||||
monitoring: true
|
||||
endpointIps: localhost
|
||||
port: 2379
|
||||
tlsEnable: true
|
||||
common:
|
||||
es:
|
||||
elasticsearchDataVolumeSize: 20Gi
|
||||
elasticsearchMasterVolumeSize: 4Gi
|
||||
elkPrefix: logstash
|
||||
logMaxAge: 7
|
||||
mysqlVolumeSize: 20Gi
|
||||
minioVolumeSize: 20Gi
|
||||
etcdVolumeSize: 20Gi
|
||||
openldapVolumeSize: 2Gi
|
||||
redisVolumSize: 2Gi
|
||||
console:
|
||||
enableMultiLogin: false # enable/disable multi login
|
||||
port: 30880
|
||||
alerting:
|
||||
enabled: false
|
||||
auditing:
|
||||
enabled: false
|
||||
devops:
|
||||
enabled: false
|
||||
jenkinsMemoryLim: 2Gi
|
||||
jenkinsMemoryReq: 1500Mi
|
||||
jenkinsVolumeSize: 8Gi
|
||||
jenkinsJavaOpts_Xms: 512m
|
||||
jenkinsJavaOpts_Xmx: 512m
|
||||
jenkinsJavaOpts_MaxRAM: 2g
|
||||
events:
|
||||
enabled: false
|
||||
ruler:
|
||||
enabled: true
|
||||
replicas: 2
|
||||
logging:
|
||||
enabled: false
|
||||
logsidecarReplicas: 2
|
||||
metrics_server:
|
||||
enabled: true
|
||||
monitoring:
|
||||
prometheusMemoryRequest: 400Mi
|
||||
prometheusVolumeSize: 20Gi
|
||||
multicluster:
|
||||
clusterRole: none # host | member | none
|
||||
networkpolicy:
|
||||
enabled: enable
|
||||
notification:
|
||||
enabled: false
|
||||
openpitrix:
|
||||
enabled: false
|
||||
servicemesh:
|
||||
enabled: false
|
||||
`)))
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package templates
|
||||
|
||||
import (
|
||||
"github.com/lithammer/dedent"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
var V310 = template.Must(template.New("v3.1.0").Parse(
|
||||
dedent.Dedent(`---
|
||||
apiVersion: installer.kubesphere.io/v1alpha1
|
||||
kind: ClusterConfiguration
|
||||
metadata:
|
||||
name: ks-installer
|
||||
namespace: kubesphere-system
|
||||
labels:
|
||||
version: {{ .Tag }}
|
||||
spec:
|
||||
persistence:
|
||||
storageClass: ""
|
||||
authentication:
|
||||
jwtSecret: ""
|
||||
zone: ""
|
||||
local_registry: ""
|
||||
etcd:
|
||||
monitoring: false
|
||||
endpointIps: localhost
|
||||
port: 2379
|
||||
tlsEnable: true
|
||||
common:
|
||||
redis:
|
||||
enabled: false
|
||||
redisVolumSize: 2Gi
|
||||
openldap:
|
||||
enabled: false
|
||||
openldapVolumeSize: 2Gi
|
||||
minioVolumeSize: 20Gi
|
||||
monitoring:
|
||||
endpoint: http://prometheus-operated.kubesphere-monitoring-system.svc:9090
|
||||
es:
|
||||
elasticsearchMasterVolumeSize: 4Gi
|
||||
elasticsearchDataVolumeSize: 20Gi
|
||||
logMaxAge: 7
|
||||
elkPrefix: logstash
|
||||
basicAuth:
|
||||
enabled: false
|
||||
username: ""
|
||||
password: ""
|
||||
externalElasticsearchUrl: ""
|
||||
externalElasticsearchPort: ""
|
||||
console:
|
||||
enableMultiLogin: true
|
||||
port: 30880
|
||||
alerting:
|
||||
enabled: false
|
||||
# thanosruler:
|
||||
# replicas: 1
|
||||
# resources: {}
|
||||
auditing:
|
||||
enabled: false
|
||||
devops:
|
||||
enabled: false
|
||||
jenkinsMemoryLim: 2Gi
|
||||
jenkinsMemoryReq: 1500Mi
|
||||
jenkinsVolumeSize: 8Gi
|
||||
jenkinsJavaOpts_Xms: 512m
|
||||
jenkinsJavaOpts_Xmx: 512m
|
||||
jenkinsJavaOpts_MaxRAM: 2g
|
||||
events:
|
||||
enabled: false
|
||||
ruler:
|
||||
enabled: true
|
||||
replicas: 2
|
||||
logging:
|
||||
enabled: false
|
||||
logsidecar:
|
||||
enabled: true
|
||||
replicas: 2
|
||||
metrics_server:
|
||||
enabled: false
|
||||
monitoring:
|
||||
storageClass: ""
|
||||
prometheusMemoryRequest: 400Mi
|
||||
prometheusVolumeSize: 20Gi
|
||||
multicluster:
|
||||
clusterRole: none
|
||||
network:
|
||||
networkpolicy:
|
||||
enabled: false
|
||||
ippool:
|
||||
type: none
|
||||
topology:
|
||||
type: none
|
||||
openpitrix:
|
||||
store:
|
||||
enabled: false
|
||||
servicemesh:
|
||||
enabled: false
|
||||
kubeedge:
|
||||
enabled: false
|
||||
cloudCore:
|
||||
nodeSelector: {"node-role.kubernetes.io/worker": ""}
|
||||
tolerations: []
|
||||
cloudhubPort: "10000"
|
||||
cloudhubQuicPort: "10001"
|
||||
cloudhubHttpsPort: "10002"
|
||||
cloudstreamPort: "10003"
|
||||
tunnelPort: "10004"
|
||||
cloudHub:
|
||||
advertiseAddress:
|
||||
- ""
|
||||
nodeLimit: "100"
|
||||
service:
|
||||
cloudhubNodePort: "30000"
|
||||
cloudhubQuicNodePort: "30001"
|
||||
cloudhubHttpsNodePort: "30002"
|
||||
cloudstreamNodePort: "30003"
|
||||
tunnelNodePort: "30004"
|
||||
edgeWatcher:
|
||||
nodeSelector: {"node-role.kubernetes.io/worker": ""}
|
||||
tolerations: []
|
||||
edgeWatcherAgent:
|
||||
nodeSelector: {"node-role.kubernetes.io/worker": ""}
|
||||
tolerations: []
|
||||
`)))
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package templates
|
||||
|
||||
import (
|
||||
"github.com/lithammer/dedent"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
var V311 = template.Must(template.New("v3.1.1").Parse(
|
||||
dedent.Dedent(`---
|
||||
apiVersion: installer.kubesphere.io/v1alpha1
|
||||
kind: ClusterConfiguration
|
||||
metadata:
|
||||
name: ks-installer
|
||||
namespace: kubesphere-system
|
||||
labels:
|
||||
version: {{ .Tag }}
|
||||
spec:
|
||||
persistence:
|
||||
storageClass: ""
|
||||
authentication:
|
||||
jwtSecret: ""
|
||||
zone: ""
|
||||
local_registry: ""
|
||||
etcd:
|
||||
monitoring: false
|
||||
endpointIps: localhost
|
||||
port: 2379
|
||||
tlsEnable: true
|
||||
common:
|
||||
redis:
|
||||
enabled: false
|
||||
redisVolumSize: 2Gi
|
||||
openldap:
|
||||
enabled: false
|
||||
openldapVolumeSize: 2Gi
|
||||
minioVolumeSize: 20Gi
|
||||
monitoring:
|
||||
endpoint: http://prometheus-operated.kubesphere-monitoring-system.svc:9090
|
||||
es:
|
||||
elasticsearchMasterVolumeSize: 4Gi
|
||||
elasticsearchDataVolumeSize: 20Gi
|
||||
logMaxAge: 7
|
||||
elkPrefix: logstash
|
||||
basicAuth:
|
||||
enabled: false
|
||||
username: ""
|
||||
password: ""
|
||||
externalElasticsearchUrl: ""
|
||||
externalElasticsearchPort: ""
|
||||
console:
|
||||
enableMultiLogin: true
|
||||
port: 30880
|
||||
alerting:
|
||||
enabled: false
|
||||
# thanosruler:
|
||||
# replicas: 1
|
||||
# resources: {}
|
||||
auditing:
|
||||
enabled: false
|
||||
devops:
|
||||
enabled: false
|
||||
jenkinsMemoryLim: 2Gi
|
||||
jenkinsMemoryReq: 1500Mi
|
||||
jenkinsVolumeSize: 8Gi
|
||||
jenkinsJavaOpts_Xms: 512m
|
||||
jenkinsJavaOpts_Xmx: 512m
|
||||
jenkinsJavaOpts_MaxRAM: 2g
|
||||
events:
|
||||
enabled: false
|
||||
ruler:
|
||||
enabled: true
|
||||
replicas: 2
|
||||
logging:
|
||||
enabled: false
|
||||
logsidecar:
|
||||
enabled: true
|
||||
replicas: 2
|
||||
metrics_server:
|
||||
enabled: false
|
||||
monitoring:
|
||||
storageClass: ""
|
||||
prometheusMemoryRequest: 400Mi
|
||||
prometheusVolumeSize: 20Gi
|
||||
multicluster:
|
||||
clusterRole: none
|
||||
network:
|
||||
networkpolicy:
|
||||
enabled: false
|
||||
ippool:
|
||||
type: none
|
||||
topology:
|
||||
type: none
|
||||
openpitrix:
|
||||
store:
|
||||
enabled: false
|
||||
servicemesh:
|
||||
enabled: false
|
||||
kubeedge:
|
||||
enabled: false
|
||||
cloudCore:
|
||||
nodeSelector: {"node-role.kubernetes.io/worker": ""}
|
||||
tolerations: []
|
||||
cloudhubPort: "10000"
|
||||
cloudhubQuicPort: "10001"
|
||||
cloudhubHttpsPort: "10002"
|
||||
cloudstreamPort: "10003"
|
||||
tunnelPort: "10004"
|
||||
cloudHub:
|
||||
advertiseAddress:
|
||||
- ""
|
||||
nodeLimit: "100"
|
||||
service:
|
||||
cloudhubNodePort: "30000"
|
||||
cloudhubQuicNodePort: "30001"
|
||||
cloudhubHttpsNodePort: "30002"
|
||||
cloudstreamNodePort: "30003"
|
||||
tunnelNodePort: "30004"
|
||||
edgeWatcher:
|
||||
nodeSelector: {"node-role.kubernetes.io/worker": ""}
|
||||
tolerations: []
|
||||
edgeWatcherAgent:
|
||||
nodeSelector: {"node-role.kubernetes.io/worker": ""}
|
||||
tolerations: []
|
||||
`)))
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user