Merge pull request #1222 from 24sama/master

support init os command to use artifact
This commit is contained in:
KubeSphere CI Bot 2022-04-20 13:50:58 +08:00 committed by GitHub
commit a4c69ae1b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 156 additions and 191 deletions

View File

@ -27,8 +27,7 @@ import (
type InitOsOptions struct {
CommonOptions *options.CommonOptions
ClusterCfgFile string
SourcesDir string
AddImagesRepo bool
Artifact string
}
func NewInitOsOptions() *InitOsOptions {
@ -55,16 +54,14 @@ func NewCmdInitOs() *cobra.Command {
func (o *InitOsOptions) Run() error {
arg := common.Argument{
FilePath: o.ClusterCfgFile,
SourcesDir: o.SourcesDir,
AddImagesRepo: o.AddImagesRepo,
Debug: o.CommonOptions.Verbose,
FilePath: o.ClusterCfgFile,
Debug: o.CommonOptions.Verbose,
Artifact: o.Artifact,
}
return pipelines.InitDependencies(arg)
}
func (o *InitOsOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.ClusterCfgFile, "filename", "f", "", "Path to a configuration file")
cmd.Flags().StringVarP(&o.SourcesDir, "sources", "s", "", "Path to the dependencies' dir")
cmd.Flags().BoolVarP(&o.AddImagesRepo, "add-images-repo", "", false, "Create a local images registry")
cmd.Flags().StringVarP(&o.Artifact, "artifact", "a", "", "Path to a KubeKey artifact")
}

View File

@ -99,9 +99,12 @@ func CreateManifest(arg common.Argument, name string) error {
case "centos":
id = "centos"
version = osImageArr[2]
case "rhel":
id = "rhel"
version = osImageArr[2]
default:
id = strings.ToLower(osImageArr[0])
version = "Didn't get the os version. Please edit it manually."
version = "Can't get the os version. Please edit it manually."
}
osObj := kubekeyv1alpha2.OperatingSystem{

View File

@ -128,47 +128,48 @@ func (c *ClearOSEnvironmentModule) Init() {
}
}
type InitDependenciesModule struct {
type RepositoryOnlineModule struct {
common.KubeModule
Skip bool
}
func (i *InitDependenciesModule) Init() {
i.Name = "InitDependenciesModule"
func (r *RepositoryOnlineModule) IsSkip() bool {
return r.Skip
}
func (r *RepositoryOnlineModule) Init() {
r.Name = "RepositoryOnlineModule"
getOSData := &task.RemoteTask{
Name: "GetOSData",
Desc: "Get OS release",
Hosts: i.Runtime.GetAllHosts(),
Hosts: r.Runtime.GetAllHosts(),
Action: new(GetOSData),
Parallel: true,
}
onlineInstall := &task.RemoteTask{
Name: "OnlineInstallDependencies",
Desc: "Online install dependencies",
Hosts: i.Runtime.GetAllHosts(),
Action: new(OnlineInstallDependencies),
newRepo := &task.RemoteTask{
Name: "NewRepoClient",
Desc: "New repository client",
Hosts: r.Runtime.GetAllHosts(),
Action: new(NewRepoClient),
Parallel: true,
Retry: 1,
}
offlineInstall := &task.RemoteTask{
Name: "OnlineInstallDependencies",
Desc: "Offline install dependencies",
Hosts: i.Runtime.GetAllHosts(),
Action: new(OfflineInstallDependencies),
install := &task.RemoteTask{
Name: "InstallPackage",
Desc: "Install packages",
Hosts: r.Runtime.GetAllHosts(),
Action: new(InstallPackage),
Parallel: true,
Retry: 1,
}
if i.KubeConf.Arg.SourcesDir == "" {
i.Tasks = []task.Interface{
getOSData,
onlineInstall,
}
} else {
i.Tasks = []task.Interface{
getOSData,
offlineInstall,
}
r.Tasks = []task.Interface{
getOSData,
newRepo,
install,
}
}
@ -211,6 +212,16 @@ func (r *RepositoryModule) Init() {
Retry: 1,
}
newRepo := &task.RemoteTask{
Name: "NewRepoClient",
Desc: "New repository client",
Hosts: r.Runtime.GetAllHosts(),
Action: new(NewRepoClient),
Parallel: true,
Retry: 1,
Rollback: new(RollbackUmount),
}
backup := &task.RemoteTask{
Name: "BackupOriginalRepository",
Desc: "Backup original repository",
@ -218,7 +229,7 @@ func (r *RepositoryModule) Init() {
Action: new(BackupOriginalRepository),
Parallel: true,
Retry: 1,
Rollback: new(RollbackUmount),
Rollback: new(RecoverBackupSuccessNode),
}
add := &task.RemoteTask{
@ -262,6 +273,7 @@ func (r *RepositoryModule) Init() {
getOSData,
sync,
mount,
newRepo,
backup,
add,
install,

View File

@ -19,23 +19,24 @@ package repository
import (
"fmt"
"github.com/kubesphere/kubekey/pkg/core/connector"
"strings"
)
type Interface interface {
Backup() error
Backup(runtime connector.Runtime) error
IsAlreadyBackUp() bool
Add(path string) error
Update() error
Install(pkg ...string) error
Reset() error
Add(runtime connector.Runtime, path string) error
Update(runtime connector.Runtime) error
Install(runtime connector.Runtime, pkg ...string) error
Reset(runtime connector.Runtime) error
}
func New(os string, runtime connector.Runtime) (Interface, error) {
switch os {
case "ubuntu":
return NewDeb(runtime), nil
case "centos":
return NewRPM(runtime), nil
func New(os string) (Interface, error) {
switch strings.ToLower(os) {
case "ubuntu", "debian":
return NewDeb(), nil
case "centos", "rhel":
return NewRPM(), nil
default:
return nil, fmt.Errorf("unsupported operation system %s", os)
}

View File

@ -23,26 +23,23 @@ import (
)
type Debian struct {
runtime connector.Runtime
backup bool
backup bool
}
func NewDeb(runtime connector.Runtime) Interface {
return &Debian{
runtime: runtime,
}
func NewDeb() Interface {
return &Debian{}
}
func (d *Debian) Backup() error {
if _, err := d.runtime.GetRunner().SudoCmd("mv /etc/apt/sources.list /etc/apt/sources.list.kubekey.bak", false); err != nil {
func (d *Debian) Backup(runtime connector.Runtime) error {
if _, err := runtime.GetRunner().SudoCmd("mv /etc/apt/sources.list /etc/apt/sources.list.kubekey.bak", false); err != nil {
return err
}
if _, err := d.runtime.GetRunner().SudoCmd("mv /etc/apt/sources.list.d /etc/apt/sources.list.d.kubekey.bak", false); err != nil {
if _, err := runtime.GetRunner().SudoCmd("mv /etc/apt/sources.list.d /etc/apt/sources.list.d.kubekey.bak", false); err != nil {
return err
}
if _, err := d.runtime.GetRunner().SudoCmd("mkdir -p /etc/apt/sources.list.d", false); err != nil {
if _, err := runtime.GetRunner().SudoCmd("mkdir -p /etc/apt/sources.list.d", false); err != nil {
return err
}
d.backup = true
@ -53,51 +50,51 @@ func (d *Debian) IsAlreadyBackUp() bool {
return d.backup
}
func (d *Debian) Add(path string) error {
func (d *Debian) Add(runtime connector.Runtime, path string) error {
if !d.IsAlreadyBackUp() {
return fmt.Errorf("linux repository must be backuped before")
}
if _, err := d.runtime.GetRunner().SudoCmd("rm -rf /etc/apt/sources.list.d/*", false); err != nil {
if _, err := runtime.GetRunner().SudoCmd("rm -rf /etc/apt/sources.list.d/*", false); err != nil {
return err
}
if _, err := d.runtime.GetRunner().SudoCmd(fmt.Sprintf("echo 'deb [trusted=yes] file://%s /' > /etc/apt/sources.list.d/kubekey.list", path),
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("echo 'deb [trusted=yes] file://%s /' > /etc/apt/sources.list.d/kubekey.list", path),
true); err != nil {
return err
}
return nil
}
func (d *Debian) Update() error {
if _, err := d.runtime.GetRunner().Cmd("sudo apt-get update", true); err != nil {
func (d *Debian) Update(runtime connector.Runtime) error {
if _, err := runtime.GetRunner().Cmd("sudo apt-get update", true); err != nil {
return err
}
return nil
}
func (d *Debian) Install(pkg ...string) error {
func (d *Debian) Install(runtime connector.Runtime, pkg ...string) error {
if len(pkg) == 0 {
pkg = []string{"socat", "conntrack", "ipset", "ebtables", "chrony", "ipvsadm"}
}
str := strings.Join(pkg, " ")
if _, err := d.runtime.GetRunner().SudoCmd(fmt.Sprintf("apt install -y %s", str), true); err != nil {
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("apt install -y %s", str), true); err != nil {
return err
}
return nil
}
func (d *Debian) Reset() error {
if _, err := d.runtime.GetRunner().SudoCmd("rm -rf /etc/apt/sources.list.d", false); err != nil {
func (d *Debian) Reset(runtime connector.Runtime) error {
if _, err := runtime.GetRunner().SudoCmd("rm -rf /etc/apt/sources.list.d", false); err != nil {
return err
}
if _, err := d.runtime.GetRunner().SudoCmd("mv /etc/apt/sources.list.kubekey.bak /etc/apt/sources.list", false); err != nil {
if _, err := runtime.GetRunner().SudoCmd("mv /etc/apt/sources.list.kubekey.bak /etc/apt/sources.list", false); err != nil {
return err
}
if _, err := d.runtime.GetRunner().SudoCmd("mv /etc/apt/sources.list.d.kubekey.bak /etc/apt/sources.list.d", false); err != nil {
if _, err := runtime.GetRunner().SudoCmd("mv /etc/apt/sources.list.d.kubekey.bak /etc/apt/sources.list.d", false); err != nil {
return err
}

View File

@ -23,22 +23,19 @@ import (
)
type RedhatPackageManager struct {
runtime connector.Runtime
backup bool
backup bool
}
func NewRPM(runtime connector.Runtime) Interface {
return &RedhatPackageManager{
runtime: runtime,
}
func NewRPM() Interface {
return &RedhatPackageManager{}
}
func (r *RedhatPackageManager) Backup() error {
if _, err := r.runtime.GetRunner().SudoCmd("mv /etc/yum.repos.d /etc/yum.repos.d.kubekey.bak", false); err != nil {
func (r *RedhatPackageManager) Backup(runtime connector.Runtime) error {
if _, err := runtime.GetRunner().SudoCmd("mv /etc/yum.repos.d /etc/yum.repos.d.kubekey.bak", false); err != nil {
return err
}
if _, err := r.runtime.GetRunner().SudoCmd("mkdir -p /etc/yum.repos.d", false); err != nil {
if _, err := runtime.GetRunner().SudoCmd("mkdir -p /etc/yum.repos.d", false); err != nil {
return err
}
r.backup = true
@ -49,12 +46,12 @@ func (r *RedhatPackageManager) IsAlreadyBackUp() bool {
return r.backup
}
func (r *RedhatPackageManager) Add(path string) error {
func (r *RedhatPackageManager) Add(runtime connector.Runtime, path string) error {
if !r.IsAlreadyBackUp() {
return fmt.Errorf("linux repository must be backuped before")
}
if _, err := r.runtime.GetRunner().SudoCmd("rm -rf /etc/yum.repos.d/*", false); err != nil {
if _, err := runtime.GetRunner().SudoCmd("rm -rf /etc/yum.repos.d/*", false); err != nil {
return err
}
@ -70,38 +67,38 @@ gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
EOF
`, path)
if _, err := r.runtime.GetRunner().SudoCmd(content, false); err != nil {
if _, err := runtime.GetRunner().SudoCmd(content, false); err != nil {
return err
}
return nil
}
func (r *RedhatPackageManager) Update() error {
if _, err := r.runtime.GetRunner().SudoCmd("yum clean all && yum makecache", true); err != nil {
func (r *RedhatPackageManager) Update(runtime connector.Runtime) error {
if _, err := runtime.GetRunner().SudoCmd("yum clean all && yum makecache", true); err != nil {
return err
}
return nil
}
func (r *RedhatPackageManager) Install(pkg ...string) error {
func (r *RedhatPackageManager) Install(runtime connector.Runtime, pkg ...string) error {
if len(pkg) == 0 {
pkg = []string{"openssl", "socat", "conntrack", "ipset", "ebtables", "chrony", "ipvsadm"}
}
str := strings.Join(pkg, " ")
if _, err := r.runtime.GetRunner().SudoCmd(fmt.Sprintf("yum install -y %s", str), true); err != nil {
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("yum install -y %s", str), true); err != nil {
return err
}
return nil
}
func (r *RedhatPackageManager) Reset() error {
if _, err := r.runtime.GetRunner().SudoCmd("rm -rf /etc/yum.repos.d", false); err != nil {
func (r *RedhatPackageManager) Reset(runtime connector.Runtime) error {
if _, err := runtime.GetRunner().SudoCmd("rm -rf /etc/yum.repos.d", false); err != nil {
return err
}
if _, err := r.runtime.GetRunner().SudoCmd("mv /etc/yum.repos.d.kubekey.bak /etc/yum.repos.d", false); err != nil {
if _, err := runtime.GetRunner().SudoCmd("mv /etc/yum.repos.d.kubekey.bak /etc/yum.repos.d", false); err != nil {
return err
}

View File

@ -31,6 +31,19 @@ type RollbackUmount struct {
}
func (r *RollbackUmount) Execute(runtime connector.Runtime, result *ending.ActionResult) error {
mountPath := filepath.Join(common.TmpDir, "iso")
umountCmd := fmt.Sprintf("umount %s", mountPath)
if _, err := runtime.GetRunner().SudoCmd(umountCmd, false); err != nil {
return errors.Wrapf(errors.WithStack(err), "umount %s failed", mountPath)
}
return nil
}
type RecoverBackupSuccessNode struct {
common.KubeRollback
}
func (r *RecoverBackupSuccessNode) Execute(runtime connector.Runtime, result *ending.ActionResult) error {
if result.Status == ending.SUCCESS {
host := runtime.RemoteHost()
repo, ok := host.GetCache().Get("repo")
@ -39,7 +52,7 @@ func (r *RollbackUmount) Execute(runtime connector.Runtime, result *ending.Actio
}
re := repo.(repository.Interface)
if err := re.Reset(); err != nil {
if err := re.Reset(runtime); err != nil {
return errors.Wrapf(errors.WithStack(err), "reset repository failed")
}
}
@ -64,7 +77,7 @@ func (r *RecoverRepository) Execute(runtime connector.Runtime, result *ending.Ac
}
re := repo.(repository.Interface)
_ = re.Reset()
_ = re.Reset(runtime)
mountPath := filepath.Join(common.TmpDir, "iso")
umountCmd := fmt.Sprintf("umount %s", mountPath)

View File

@ -246,96 +246,6 @@ func (g *GetOSData) Execute(runtime connector.Runtime) error {
return nil
}
type OnlineInstallDependencies struct {
common.KubeAction
}
func (o *OnlineInstallDependencies) Execute(runtime connector.Runtime) error {
host := runtime.RemoteHost()
pkg, ok := host.GetCache().GetMustString(PkgTool)
if !ok {
return errors.New("get pkgTool failed by root cache")
}
release, ok := host.GetCache().Get(Release)
if !ok {
return errors.New("get os release failed by root cache")
}
r := release.(*osrelease.Data)
switch strings.TrimSpace(pkg) {
case "deb":
if _, err := runtime.GetRunner().SudoCmd(
"apt update;"+
"apt install socat conntrack ipset ebtables chrony ipvsadm -y;",
false); err != nil {
return err
}
case "rpm":
if _, err := runtime.GetRunner().SudoCmd(
"yum install openssl socat conntrack ipset ebtables chrony ipvsadm -y",
false); err != nil {
return err
}
default:
return errors.New(fmt.Sprintf("Unsupported operating system: %s", r.ID))
}
return nil
}
type OfflineInstallDependencies struct {
common.KubeAction
}
func (o *OfflineInstallDependencies) Execute(runtime connector.Runtime) error {
fp, err := filepath.Abs(o.KubeConf.Arg.SourcesDir)
if err != nil {
return errors.Wrap(err, "Failed to look up current directory")
}
host := runtime.RemoteHost()
pkg, ok := host.GetCache().GetMustString(PkgTool)
if !ok {
return errors.New("get pkgTool failed by root cache")
}
release, ok := host.GetCache().Get(Release)
if !ok {
return errors.New("get os release failed by root cache")
}
r := release.(*osrelease.Data)
switch strings.TrimSpace(pkg) {
case "deb":
dirName := fmt.Sprintf("%s-%s-%s-debs", r.ID, r.VersionID, host.GetArch())
srcPath := filepath.Join(fp, dirName)
srcTar := fmt.Sprintf("%s.tar.gz", srcPath)
dstPath := filepath.Join(common.TmpDir, dirName)
dstTar := fmt.Sprintf("%s.tar.gz", dstPath)
_ = runtime.GetRunner().Scp(srcTar, dstTar)
if _, err := runtime.GetRunner().SudoCmd(
fmt.Sprintf("tar -zxvf %s -C %s && dpkg -iR --force-all %s", dstTar, common.TmpDir, dstPath),
false); err != nil {
return err
}
case "rpm":
dirName := fmt.Sprintf("%s-%s-%s-rpms", r.ID, r.VersionID, host.GetArch())
srcPath := filepath.Join(fp, dirName)
srcTar := fmt.Sprintf("%s.tar.gz", srcPath)
dstPath := filepath.Join(common.TmpDir, dirName)
dstTar := fmt.Sprintf("%s.tar.gz", dstPath)
_ = runtime.GetRunner().Scp(srcTar, dstTar)
if _, err := runtime.GetRunner().SudoCmd(
fmt.Sprintf("tar -zxvf %s -C %s && rpm -Uvh --force --nodeps %s", dstTar, common.TmpDir, filepath.Join(dstPath, "*rpm")),
false); err != nil {
return err
}
default:
return errors.New(fmt.Sprintf("Unsupported operating system: %s", r.ID))
}
return nil
}
type SyncRepositoryFile struct {
common.KubeAction
}
@ -383,11 +293,11 @@ func (m *MountISO) Execute(runtime connector.Runtime) error {
return nil
}
type BackupOriginalRepository struct {
type NewRepoClient struct {
common.KubeAction
}
func (b *BackupOriginalRepository) Execute(runtime connector.Runtime) error {
func (n *NewRepoClient) Execute(runtime connector.Runtime) error {
host := runtime.RemoteHost()
release, ok := host.GetCache().Get(Release)
if !ok {
@ -395,19 +305,47 @@ func (b *BackupOriginalRepository) Execute(runtime connector.Runtime) error {
}
r := release.(*osrelease.Data)
repo, err := repository.New(r.ID, runtime)
repo, err := repository.New(r.ID)
if err != nil {
return errors.Wrap(errors.WithStack(err), "new repository manager failed")
}
checkDeb, _ := runtime.GetRunner().SudoCmd("which apt", false)
if strings.Contains(checkDeb, "bin") {
repo = repository.NewDeb()
}
checkRPM, _ := runtime.GetRunner().SudoCmd("which yum", false)
if strings.Contains(checkRPM, "bin") {
repo = repository.NewRPM()
}
if err := repo.Backup(); err != nil {
return errors.Wrap(errors.WithStack(err), "backup repository failed")
if checkDeb == "" && checkRPM == "" {
return errors.Wrap(errors.WithStack(err), "new repository manager failed")
} else if checkDeb != "" && checkRPM != "" {
return errors.New("can't detect the main package repository, only one of apt or yum is supported")
}
}
host.GetCache().Set("repo", repo)
return nil
}
type BackupOriginalRepository struct {
common.KubeAction
}
func (b *BackupOriginalRepository) Execute(runtime connector.Runtime) error {
host := runtime.RemoteHost()
r, ok := host.GetCache().Get("repo")
if !ok {
return errors.New("get repo failed by host cache")
}
repo := r.(repository.Interface)
if err := repo.Backup(runtime); err != nil {
return errors.Wrap(errors.WithStack(err), "backup repository failed")
}
return nil
}
type AddLocalRepository struct {
common.KubeAction
}
@ -420,10 +358,10 @@ func (a *AddLocalRepository) Execute(runtime connector.Runtime) error {
}
repo := r.(repository.Interface)
if installErr := repo.Add(filepath.Join(common.TmpDir, "iso")); installErr != nil {
if installErr := repo.Add(runtime, filepath.Join(common.TmpDir, "iso")); installErr != nil {
return errors.Wrap(errors.WithStack(installErr), "add local repository failed")
}
if installErr := repo.Update(); installErr != nil {
if installErr := repo.Update(runtime); installErr != nil {
return errors.Wrap(errors.WithStack(installErr), "update local repository failed")
}
@ -442,7 +380,7 @@ func (i *InstallPackage) Execute(runtime connector.Runtime) error {
}
r := repo.(repository.Interface)
if installErr := r.Install(); installErr != nil {
if installErr := r.Install(runtime); installErr != nil {
return errors.Wrap(errors.WithStack(installErr), "install repository package failed")
}
return nil
@ -469,7 +407,7 @@ func (r *ResetRepository) Execute(runtime connector.Runtime) error {
}
}()
if resetErr = re.Reset(); resetErr != nil {
if resetErr = re.Reset(runtime); resetErr != nil {
return errors.Wrap(errors.WithStack(resetErr), "reset repository failed")
}

View File

@ -41,9 +41,7 @@ type Argument struct {
IgnoreErr bool
SkipPullImages bool
SKipPushImages bool
AddImagesRepo bool
DeployLocalStorage *bool
SourcesDir string
DownloadCommand func(path, url string) string
SkipConfirmCheck bool
InCluster bool

View File

@ -17,17 +17,24 @@
package pipelines
import (
"github.com/kubesphere/kubekey/pkg/artifact"
"github.com/kubesphere/kubekey/pkg/bootstrap/os"
"github.com/kubesphere/kubekey/pkg/bootstrap/precheck"
"github.com/kubesphere/kubekey/pkg/common"
"github.com/kubesphere/kubekey/pkg/core/module"
"github.com/kubesphere/kubekey/pkg/core/pipeline"
"github.com/kubesphere/kubekey/pkg/filesystem"
)
func NewInitDependenciesPipeline(runtime *common.KubeRuntime) error {
noArtifact := runtime.Arg.Artifact == ""
m := []module.Module{
&precheck.GreetingsModule{},
&os.InitDependenciesModule{},
&artifact.UnArchiveModule{Skip: noArtifact},
&os.RepositoryModule{Skip: noArtifact},
&os.RepositoryOnlineModule{Skip: !noArtifact},
&filesystem.ChownWorkDirModule{},
}
p := pipeline.Pipeline{

View File

@ -26,6 +26,7 @@ import (
"github.com/kubesphere/kubekey/pkg/common"
"github.com/kubesphere/kubekey/pkg/core/module"
"github.com/kubesphere/kubekey/pkg/core/pipeline"
"github.com/kubesphere/kubekey/pkg/filesystem"
)
func NewInitRegistryPipeline(runtime *common.KubeRuntime) error {
@ -38,6 +39,7 @@ func NewInitRegistryPipeline(runtime *common.KubeRuntime) error {
&os.ConfigureOSModule{},
&registry.RegistryCertsModule{},
&registry.InstallRegistryModule{},
&filesystem.ChownWorkDirModule{},
}
p := pipeline.Pipeline{