From 77ad958ade9f72f97042bd0f7e0f9fa258a64153 Mon Sep 17 00:00:00 2001
From: zhangxiaoyu <zhangxiaoyu58@huawei.com>
Date: Sat, 4 Dec 2021 16:47:24 +0800
Subject: [PATCH 14/17] refactor dependency

Signed-off-by: zhangxiaoyu <zhangxiaoyu58@huawei.com>
---
 .../binary/infrastructure/infrastructure.go   |   4 +-
 pkg/clusterdeployment/runtime/runtime.go      |  40 +--
 pkg/utils/dependency/dependency.go            | 237 ++++++++-----
 pkg/utils/dependency/install.go               | 322 ++++--------------
 4 files changed, 231 insertions(+), 372 deletions(-)

diff --git a/pkg/clusterdeployment/binary/infrastructure/infrastructure.go b/pkg/clusterdeployment/binary/infrastructure/infrastructure.go
index 68faf36..7c55d5f 100644
--- a/pkg/clusterdeployment/binary/infrastructure/infrastructure.go
+++ b/pkg/clusterdeployment/binary/infrastructure/infrastructure.go
@@ -68,7 +68,7 @@ func (it *SetupInfraTask) Run(r runner.Runner, hcg *api.HostConfig) error {
 		return err
 	}
 
-	if err := dependency.InstallDependency(r, it.roleInfra, hcg, it.packageSrc.GetPkgDstPath()); err != nil {
+	if err := dependency.InstallBaseDependency(r, it.roleInfra, hcg, it.packageSrc.GetPkgDstPath()); err != nil {
 		logrus.Errorf("install dependency failed: %v", err)
 		return err
 	}
@@ -325,7 +325,7 @@ func (it *DestroyInfraTask) Run(r runner.Runner, hcg *api.HostConfig) error {
 		return fmt.Errorf("empty host config")
 	}
 
-	dependency.RemoveDependency(r, it.roleInfra, hcg, it.packageSrc.GetPkgDstPath())
+	dependency.RemoveBaseDependency(r, it.roleInfra, hcg, it.packageSrc.GetPkgDstPath())
 
 	if err := removeHostNameIP(r, hcg); err != nil {
 		logrus.Errorf("remove host name ip failed: %v", err)
diff --git a/pkg/clusterdeployment/runtime/runtime.go b/pkg/clusterdeployment/runtime/runtime.go
index edfc4a7..e996dae 100644
--- a/pkg/clusterdeployment/runtime/runtime.go
+++ b/pkg/clusterdeployment/runtime/runtime.go
@@ -3,14 +3,11 @@ package runtime
 import (
 	"encoding/base64"
 	"fmt"
-	"path/filepath"
 	"strings"
 
 	"github.com/sirupsen/logrus"
 	"isula.org/eggo/pkg/api"
 	"isula.org/eggo/pkg/clusterdeployment/binary/commontools"
-	"isula.org/eggo/pkg/constants"
-	"isula.org/eggo/pkg/utils"
 	"isula.org/eggo/pkg/utils/dependency"
 	"isula.org/eggo/pkg/utils/runner"
 	"isula.org/eggo/pkg/utils/template"
@@ -435,7 +432,8 @@ func (ct *DeployRuntimeTask) Run(r runner.Runner, hcg *api.HostConfig) error {
 		return err
 	}
 
-	if err := loadImages(r, ct.workerInfra, ct.packageSrc, ct.runtime, ct.workerConfig.ContainerEngineConf.Runtime); err != nil {
+	if err := dependency.InstallImageDependency(r, ct.workerInfra, ct.packageSrc, ct.runtime.GetRuntimeService(),
+		ct.runtime.GetRuntimeClient(), ct.runtime.GetRuntimeLoadImageCommand()); err != nil {
 		logrus.Errorf("load images failed: %v", err)
 		return err
 	}
@@ -459,40 +457,6 @@ func (ct *DeployRuntimeTask) check(r runner.Runner) error {
 	return nil
 }
 
-func getImages(workerInfra *api.RoleInfra) []*api.PackageConfig {
-	images := []*api.PackageConfig{}
-	for _, s := range workerInfra.Softwares {
-		if s.Type == "image" {
-			images = append(images, s)
-		}
-	}
-
-	return images
-}
-
-func loadImages(r runner.Runner, workerInfra *api.RoleInfra, packageSrc *api.PackageSrcConfig, runtime Runtime, rt string) error {
-	images := getImages(workerInfra)
-	if len(images) == 0 {
-		logrus.Warn("no images load")
-		return nil
-	}
-
-	logrus.Info("do load images...")
-
-	imagePath := filepath.Join(packageSrc.GetPkgDstPath(), constants.DefaultImagePath)
-	imageDep := dependency.NewDependencyImage(imagePath, runtime.GetRuntimeClient(), runtime.GetRuntimeLoadImageCommand(), images)
-	if err := imageDep.Install(r); err != nil {
-		if utils.IsContainerd(rt) {
-			logrus.Warnf("%s not support load images", rt)
-			return nil
-		}
-		return err
-	}
-
-	logrus.Info("load images success")
-	return nil
-}
-
 func GetRuntime(runtime string) Runtime {
 	if runtime == "" {
 		return mapRuntime["docker"]
diff --git a/pkg/utils/dependency/dependency.go b/pkg/utils/dependency/dependency.go
index 2c5dc26..9b464dd 100644
--- a/pkg/utils/dependency/dependency.go
+++ b/pkg/utils/dependency/dependency.go
@@ -19,124 +19,175 @@ import (
 	"fmt"
 	"strings"
 
+	"github.com/sirupsen/logrus"
 	"isula.org/eggo/pkg/api"
 	"isula.org/eggo/pkg/utils/runner"
 	"isula.org/eggo/pkg/utils/template"
 )
 
-type dependency interface {
-	Install(r runner.Runner) error
-	Remove(r runner.Runner) error
+const (
+	PrmTest = "if [ x != x$(which apt 2>/dev/null) ]; then echo apt ; elif [ x != x$(which yum 2>/dev/null) ]; then echo yum ; fi"
+	PmTest  = "if [ x != x$(which dpkg 2>/dev/null) ]; then echo dpkg ; elif [ x != x$(which rpm 2>/dev/null) ]; then echo rpm ; fi"
+)
+
+type managerCommand struct {
+	installCommand string
+	removeCommand  string
 }
 
-// install dependency by repo
-func runRepoCommand(r runner.Runner, software []*api.PackageConfig, command string) error {
-	join := ""
-	for _, s := range software {
-		join += s.Name + " "
+func getPackageRepoManager(r runner.Runner) (*managerCommand, error) {
+	packageRepoManagerCommand := map[string]*managerCommand{
+		"apt": {
+			installCommand: "apt install -y",
+			removeCommand:  "apt remove -y",
+		},
+		"yum": {
+			installCommand: "yum install -y",
+			removeCommand:  "yum remove -y",
+		},
 	}
-	_, err := r.RunCommand(fmt.Sprintf("sudo -E /bin/sh -c \"%s -y %s\"", command, join))
-	return err
-}
 
-type dependencyApt struct {
-	software []*api.PackageConfig
-}
+	output, err := r.RunCommand(fmt.Sprintf("sudo -E /bin/sh -c \"%s\"", PrmTest))
+	if err != nil {
+		logrus.Errorf("package repo manager test failed: %v", err)
+		return nil, err
+	}
 
-func (da *dependencyApt) Install(r runner.Runner) error {
-	command := "apt install"
-	if err := runRepoCommand(r, da.software, command); err != nil {
-		return fmt.Errorf("apt install failed: %v", err)
+	if strings.Contains(output, "apt") {
+		return packageRepoManagerCommand["apt"], nil
+	}
+	if strings.Contains(output, "yum") {
+		return packageRepoManagerCommand["yum"], nil
 	}
 
-	return nil
+	return nil, fmt.Errorf("invalid package repo manager %s", output)
 }
 
-func (da *dependencyApt) Remove(r runner.Runner) error {
-	command := "apt remove"
-	if err := runRepoCommand(r, da.software, command); err != nil {
-		return fmt.Errorf("apt remove failed: %v", err)
+func getPackageManager(r runner.Runner) (*managerCommand, error) {
+	packageManagerCommand := map[string]*managerCommand{
+		"dpkg": {
+			installCommand: "dpkg --force-all -i",
+			removeCommand:  "apt remove -y",
+		},
+		"rpm": {
+			installCommand: "rpm -ivh --force --nodeps",
+			removeCommand:  "yum remove -y",
+		},
 	}
 
-	return nil
+	output, err := r.RunCommand(fmt.Sprintf("sudo -E /bin/sh -c \"%s\"", PmTest))
+	if err != nil {
+		logrus.Errorf("package manager test failed: %v", err)
+		return nil, err
+	}
+
+	if strings.Contains(output, "dpkg") {
+		return packageManagerCommand["dpkg"], nil
+	}
+	if strings.Contains(output, "rpm") {
+		return packageManagerCommand["rpm"], nil
+	}
+
+	return nil, fmt.Errorf("invalid package manager %s", output)
+}
+
+type dependency interface {
+	Install(r runner.Runner) error
+	Remove(r runner.Runner) error
 }
 
-type dependencyYum struct {
+type dependencyRepo struct {
 	software []*api.PackageConfig
 }
 
-func (dy *dependencyYum) Install(r runner.Runner) error {
-	command := "yum install"
-	if err := runRepoCommand(r, dy.software, command); err != nil {
-		return fmt.Errorf("yum install by yum failed: %v", err)
+func (dr *dependencyRepo) Install(r runner.Runner) error {
+	if len(dr.software) == 0 {
+		return nil
 	}
 
-	return nil
-}
+	prManager, err := getPackageRepoManager(r)
+	if err != nil {
+		return err
+	}
 
-func (dy *dependencyYum) Remove(r runner.Runner) error {
-	command := "yum remove"
-	if err := runRepoCommand(r, dy.software, command); err != nil {
-		return fmt.Errorf("yum remove failed: %v", err)
+	join := ""
+	for _, s := range dr.software {
+		join += s.Name + " "
+	}
+	if _, err := r.RunCommand(fmt.Sprintf("sudo -E /bin/sh -c \"%s %s\"", prManager.installCommand, join)); err != nil {
+		return fmt.Errorf("%s failed: %v", prManager.installCommand, err)
 	}
 
 	return nil
 }
 
-// install dependency by pkg
-func runPkgCommand(r runner.Runner, software []*api.PackageConfig, srcPath, command string) error {
-	var sb strings.Builder
-	sb.WriteString(fmt.Sprintf("sudo -E /bin/sh -c \"cd %s && %s ", srcPath, command))
-	for _, s := range software {
-		sb.WriteString(fmt.Sprintf("%s* ", s.Name))
+func (dr *dependencyRepo) Remove(r runner.Runner) error {
+	if len(dr.software) == 0 {
+		return nil
+	}
+
+	prManager, err := getPackageRepoManager(r)
+	if err != nil {
+		return err
+	}
+
+	join := ""
+	for _, s := range dr.software {
+		join += s.Name + " "
+	}
+	if _, err := r.RunCommand(fmt.Sprintf("sudo -E /bin/sh -c \"%s remove -y %s\"", prManager.removeCommand, join)); err != nil {
+		return fmt.Errorf("%s failed: %v", prManager.removeCommand, err)
 	}
-	sb.WriteString("\"")
 
-	_, err := r.RunCommand(sb.String())
-	return err
+	return nil
 }
 
-type dependencyRpm struct {
+type dependencyPkg struct {
 	srcPath  string
 	software []*api.PackageConfig
 }
 
-func (dr *dependencyRpm) Install(r runner.Runner) error {
-	command := "rpm -ivh --force --nodeps"
-	if err := runPkgCommand(r, dr.software, dr.srcPath, command); err != nil {
-		return fmt.Errorf("rpm install failed: %v", err)
+func (dp *dependencyPkg) Install(r runner.Runner) error {
+	if len(dp.software) == 0 {
+		return nil
 	}
 
-	return nil
-}
+	pManager, err := getPackageManager(r)
+	if err != nil {
+		return err
+	}
 
-func (dr *dependencyRpm) Remove(r runner.Runner) error {
-	command := "yum remove -y"
-	if err := runPkgCommand(r, dr.software, dr.srcPath, command); err != nil {
-		return fmt.Errorf("yum remove rpm pkgs failed: %v", err)
+	join := ""
+	for _, s := range dp.software {
+		join += s.Name + "* "
+	}
+
+	if _, err := r.RunCommand(fmt.Sprintf("sudo -E /bin/sh -c \"cd %s && %s %s",
+		dp.srcPath, pManager.installCommand, join)); err != nil {
+		return fmt.Errorf("%s failed: %v", pManager.installCommand, err)
 	}
 
 	return nil
 }
 
-type dependencyDeb struct {
-	srcPath  string
-	software []*api.PackageConfig
-}
+func (dp *dependencyPkg) Remove(r runner.Runner) error {
+	if len(dp.software) == 0 {
+		return nil
+	}
 
-func (dd *dependencyDeb) Install(r runner.Runner) error {
-	command := "dpkg --force-all -i"
-	if err := runPkgCommand(r, dd.software, dd.srcPath, command); err != nil {
-		return fmt.Errorf("dpkg install failed: %v", err)
+	pManager, err := getPackageManager(r)
+	if err != nil {
+		return err
 	}
 
-	return nil
-}
+	join := ""
+	for _, s := range dp.software {
+		join += s.Name + "* "
+	}
 
-func (dd *dependencyDeb) Remove(r runner.Runner) error {
-	command := "apt remove -y"
-	if err := runPkgCommand(r, dd.software, dd.srcPath, command); err != nil {
-		return fmt.Errorf("apt remove deb pkgs failed: %v", err)
+	if _, err := r.RunCommand(fmt.Sprintf("sudo -E /bin/sh -c \"cd %s && %s %s",
+		dp.srcPath, pManager.removeCommand, join)); err != nil {
+		return fmt.Errorf("%s remove failed: %v", pManager.removeCommand, err)
 	}
 
 	return nil
@@ -150,6 +201,10 @@ type dependencyFileDir struct {
 }
 
 func (df *dependencyFileDir) Install(r runner.Runner) error {
+	if len(df.software) == 0 {
+		return nil
+	}
+
 	shell := `
 #!/bin/bash
 cd {{ .srcPath }}
@@ -185,6 +240,10 @@ fi
 }
 
 func (df *dependencyFileDir) Remove(r runner.Runner) error {
+	if len(df.software) == 0 {
+		return nil
+	}
+
 	var sb strings.Builder
 	sb.WriteString("sudo -E /bin/sh -c \"")
 	for _, s := range df.software {
@@ -211,16 +270,11 @@ type dependencyImage struct {
 	image   []*api.PackageConfig
 }
 
-func NewDependencyImage(srcPath, client, command string, image []*api.PackageConfig) *dependencyImage {
-	return &dependencyImage{
-		srcPath: srcPath,
-		client:  client,
-		command: command,
-		image:   image,
+func (di *dependencyImage) Install(r runner.Runner) error {
+	if len(di.image) == 0 {
+		return nil
 	}
-}
 
-func (di *dependencyImage) Install(r runner.Runner) error {
 	var sb strings.Builder
 	sb.WriteString("sudo -E /bin/sh -c \"")
 	for _, i := range di.image {
@@ -255,6 +309,10 @@ func NewDependencyYaml(srcPath, kubeconfig string, yaml []*api.PackageConfig) *d
 }
 
 func (dy *dependencyYaml) Install(r runner.Runner) error {
+	if len(dy.yaml) == 0 {
+		return nil
+	}
+
 	var sb strings.Builder
 	sb.WriteString(fmt.Sprintf("sudo -E /bin/sh -c \"export KUBECONFIG=%s ", dy.kubeconfig))
 	for _, y := range dy.yaml {
@@ -274,6 +332,10 @@ func (dy *dependencyYaml) Install(r runner.Runner) error {
 }
 
 func (dy *dependencyYaml) Remove(r runner.Runner) error {
+	if len(dy.yaml) == 0 {
+		return nil
+	}
+
 	var sb strings.Builder
 	sb.WriteString(fmt.Sprintf("sudo -E /bin/sh -c \"export KUBECONFIG=%s ", dy.kubeconfig))
 	for _, y := range dy.yaml {
@@ -306,6 +368,10 @@ func NewDependencyShell(srcPath string, shell []*api.PackageConfig) *dependencyS
 }
 
 func (ds *dependencyShell) Install(r runner.Runner) error {
+	if len(ds.shell) == 0 {
+		return nil
+	}
+
 	shellTemplate := `
 #!/bin/bash
 {{- range $i, $v := .Envs }}
@@ -354,3 +420,20 @@ func (ds *dependencyShell) Remove(r runner.Runner) error {
 	// nothing to do
 	return nil
 }
+
+type DependencyTask struct {
+	dp dependency
+}
+
+func (dt *DependencyTask) Name() string {
+	return "DependencyTask"
+}
+
+func (dt *DependencyTask) Run(r runner.Runner, hcf *api.HostConfig) error {
+	if err := dt.dp.Install(r); err != nil {
+		logrus.Errorf("install failed for %s: %v", hcf.Address, err)
+		return err
+	}
+
+	return nil
+}
diff --git a/pkg/utils/dependency/install.go b/pkg/utils/dependency/install.go
index 8cb80f6..35c3521 100644
--- a/pkg/utils/dependency/install.go
+++ b/pkg/utils/dependency/install.go
@@ -18,6 +18,7 @@ package dependency
 import (
 	"fmt"
 	"path"
+	"path/filepath"
 	"strings"
 
 	"github.com/sirupsen/logrus"
@@ -29,131 +30,55 @@ import (
 	"isula.org/eggo/pkg/utils/task"
 )
 
-const (
-	PrmTest = "if [ x != x$(which apt 2>/dev/null) ]; then echo apt ; elif [ x != x$(which yum 2>/dev/null) ]; then echo yum ; fi"
-	PmTest  = "if [ x != x$(which dpkg 2>/dev/null) ]; then echo dpkg ; elif [ x != x$(which rpm 2>/dev/null) ]; then echo rpm ; fi"
-)
-
-type DependencyTask struct {
-	dp dependency
-}
-
-func (dt *DependencyTask) Name() string {
-	return "DependencyTask"
-}
-
-func (dt *DependencyTask) Run(r runner.Runner, hcf *api.HostConfig) error {
-	if err := dt.dp.Install(r); err != nil {
-		logrus.Errorf("install failed for %s: %v", hcf.Address, err)
-		return err
-	}
-
-	return nil
-}
-
-func installRepo(r runner.Runner, software []*api.PackageConfig, hcf *api.HostConfig) error {
-	if len(software) == 0 {
-		return nil
-	}
-
-	output, err := r.RunCommand(fmt.Sprintf("sudo -E /bin/sh -c \"%s\"", PrmTest))
-	if err != nil {
-		logrus.Errorf("package repo manager test failed: %v", err)
-		return err
+func newBaseDependency(roleInfra *api.RoleInfra, packagePath string) map[string]dependency {
+	packages := map[string][]*api.PackageConfig{
+		"repo": {},
+		"pkg":  {},
+		"bin":  {},
+		"file": {},
+		"dir":  {},
 	}
 
-	var dp dependency
-	if strings.Contains(output, "apt") {
-		dp = &dependencyApt{
-			software: software,
-		}
-	} else if strings.Contains(output, "yum") {
-		dp = &dependencyYum{
-			software: software,
+	for _, p := range roleInfra.Softwares {
+		if _, exist := packages[p.Type]; !exist {
+			continue
 		}
+		packages[p.Type] = append(packages[p.Type], p)
 	}
 
-	if dp == nil {
-		return fmt.Errorf("invalid package repo manager %s", output)
-	}
-
-	if err := dp.Install(r); err != nil {
-		logrus.Errorf("install failed for %s: %v", hcf.Address, err)
-		return err
-	}
-
-	return nil
-}
-
-func installPkg(r runner.Runner, software []*api.PackageConfig, hcf *api.HostConfig, packagePath string) error {
-	if len(software) == 0 {
-		return nil
-	}
-
-	output, err := r.RunCommand(fmt.Sprintf("sudo -E /bin/sh -c \"%s\"", PmTest))
-	if err != nil {
-		logrus.Errorf("package manager test failed: %v", err)
-		return err
-	}
-
-	var dp dependency
-	if strings.Contains(output, "dpkg") {
-		dp = &dependencyDeb{
-			srcPath:  path.Join(packagePath, constants.DefaultPkgPath),
-			software: software,
-		}
-	} else if strings.Contains(output, "rpm") {
-		dp = &dependencyRpm{
+	baseDependency := map[string]dependency{
+		"repo": &dependencyRepo{
+			software: packages["repo"],
+		},
+		"pkg": &dependencyPkg{
 			srcPath:  path.Join(packagePath, constants.DefaultPkgPath),
-			software: software,
-		}
-	}
-
-	if dp == nil {
-		return fmt.Errorf("invalid package manager %s", output)
-	}
-
-	if err := dp.Install(r); err != nil {
-		logrus.Errorf("install failed for %s: %v", hcf.Address, err)
-		return err
-	}
-
-	return nil
-}
-
-func installFD(r runner.Runner, bin, file, dir []*api.PackageConfig, hcf *api.HostConfig, packagePath string) error {
-	dp := []dependency{}
-
-	if len(bin) != 0 {
-		dp = append(dp, &dependencyFileDir{
-			srcPath:    path.Join(packagePath, constants.DefaultBinPath),
-			software:   bin,
+			software: packages["pkg"],
+		},
+		"bin": &dependencyFileDir{
 			executable: true,
-		})
-	}
-
-	if len(file) != 0 {
-		dp = append(dp, &dependencyFileDir{
+			srcPath:    path.Join(packagePath, constants.DefaultBinPath),
+			software:   packages["bin"],
+		},
+		"file": &dependencyFileDir{
+			executable: false,
 			srcPath:    path.Join(packagePath, constants.DefaultFilePath),
-			software:   file,
+		},
+		"dir": &dependencyFileDir{
 			executable: false,
-		})
-	}
-
-	if len(dir) != 0 {
-		dp = append(dp, &dependencyFileDir{
 			srcPath:    path.Join(packagePath, constants.DefaultDirPath),
-			software:   dir,
-			executable: false,
-		})
+			software:   packages["dir"],
+		},
 	}
 
-	if len(dp) == 0 {
-		return nil
-	}
+	return baseDependency
+}
 
-	for _, d := range dp {
-		if err := d.Install(r); err != nil {
+// install base dependency, include repo, pkg, bin, file, dir
+func InstallBaseDependency(r runner.Runner, roleInfra *api.RoleInfra, hcf *api.HostConfig, packagePath string) error {
+	baseDependency := newBaseDependency(roleInfra, packagePath)
+
+	for _, dep := range baseDependency {
+		if err := dep.Install(r); err != nil {
 			logrus.Errorf("install failed for %s: %v", hcf.Address, err)
 			return err
 		}
@@ -162,170 +87,57 @@ func installFD(r runner.Runner, bin, file, dir []*api.PackageConfig, hcf *api.Ho
 	return nil
 }
 
-func uninstallRepo(r runner.Runner, software []*api.PackageConfig, hcf *api.HostConfig) error {
-	if len(software) == 0 {
-		return nil
-	}
-
-	output, err := r.RunCommand(fmt.Sprintf("sudo -E /bin/sh -c \"%s\"", PrmTest))
-	if err != nil {
-		logrus.Errorf("package repo manager test failed: %v", err)
-		return err
-	}
+func RemoveBaseDependency(r runner.Runner, roleInfra *api.RoleInfra, hcf *api.HostConfig, packagePath string) {
+	baseDependency := newBaseDependency(roleInfra, packagePath)
 
-	var dp dependency
-	if strings.Contains(output, "apt") {
-		dp = &dependencyApt{
-			software: software,
-		}
-	} else if strings.Contains(output, "yum") {
-		dp = &dependencyYum{
-			software: software,
+	for _, dep := range baseDependency {
+		if err := dep.Remove(r); err != nil {
+			logrus.Errorf("uninstall failed for %s: %v", hcf.Address, err)
 		}
 	}
-
-	if dp == nil {
-		return fmt.Errorf("invalid package repo manager %s", output)
-	}
-
-	if err := dp.Remove(r); err != nil {
-		logrus.Errorf("uninstall failed for %s: %v", hcf.Address, err)
-		return err
-	}
-
-	return nil
 }
 
-func uninstallPkg(r runner.Runner, software []*api.PackageConfig, hcf *api.HostConfig, packagePath string) error {
-	if len(software) == 0 {
-		return nil
-	}
-
-	output, err := r.RunCommand(fmt.Sprintf("sudo -E /bin/sh -c \"%s\"", PmTest))
-	if err != nil {
-		logrus.Errorf("package manager test failed: %v", err)
-		return err
-	}
-
-	var dp dependency
-	if strings.Contains(output, "dpkg") {
-		dp = &dependencyDeb{
-			srcPath:  path.Join(packagePath, constants.DefaultPkgPath),
-			software: software,
+func getImages(workerInfra *api.RoleInfra) []*api.PackageConfig {
+	images := []*api.PackageConfig{}
+	for _, s := range workerInfra.Softwares {
+		if s.Type == "image" {
+			images = append(images, s)
 		}
-	} else if strings.Contains(output, "rpm") {
-		dp = &dependencyRpm{
-			srcPath:  path.Join(packagePath, constants.DefaultPkgPath),
-			software: software,
-		}
-	}
-
-	if dp == nil {
-		return fmt.Errorf("invalid package manager %s", output)
 	}
 
-	if err := dp.Remove(r); err != nil {
-		logrus.Errorf("uninstall failed for %s: %v", hcf.Address, err)
-		return err
-	}
-
-	return nil
+	return images
 }
 
-func uninstallFD(r runner.Runner, bin, file, dir []*api.PackageConfig, hcf *api.HostConfig) error {
-	dp := []dependency{}
-
-	if len(bin) != 0 {
-		dp = append(dp, &dependencyFileDir{
-			software: bin,
-		})
-	}
-
-	if len(file) != 0 {
-		dp = append(dp, &dependencyFileDir{
-			software: file,
-		})
-	}
-
-	if len(dir) != 0 {
-		dp = append(dp, &dependencyFileDir{
-			software: dir,
-		})
-	}
-
-	if len(dp) == 0 {
+// install image dependency
+func InstallImageDependency(r runner.Runner, workerInfra *api.RoleInfra, packageSrc *api.PackageSrcConfig,
+	runtime, runtimeClient, runtimeCommand string) error {
+	images := getImages(workerInfra)
+	if len(images) == 0 {
+		logrus.Warn("no images load")
 		return nil
 	}
 
-	for _, d := range dp {
-		if err := d.Remove(r); err != nil {
-			logrus.Errorf("uninstall failed for %s: %v", hcf.Address, err)
-			return err
-		}
-	}
+	logrus.Info("do load images...")
 
-	return nil
-}
-
-func separateSofeware(softwares []*api.PackageConfig) ([]*api.PackageConfig, []*api.PackageConfig, []*api.PackageConfig, []*api.PackageConfig, []*api.PackageConfig) {
-	repo := []*api.PackageConfig{}
-	pkg := []*api.PackageConfig{}
-	bin := []*api.PackageConfig{}
-	file := []*api.PackageConfig{}
-	dir := []*api.PackageConfig{}
-
-	for _, p := range softwares {
-		switch p.Type {
-		case "repo":
-			repo = append(repo, p)
-		case "pkg":
-			pkg = append(pkg, p)
-		case "bin":
-			bin = append(bin, p)
-		case "file":
-			file = append(file, p)
-		case "dir":
-			dir = append(dir, p)
-		}
+	imageDependency := &dependencyImage{
+		srcPath: filepath.Join(packageSrc.GetPkgDstPath(), constants.DefaultImagePath),
+		client:  runtimeClient,
+		command: runtimeCommand,
+		image:   images,
 	}
 
-	return repo, pkg, bin, file, dir
-}
-
-func InstallDependency(r runner.Runner, roleInfra *api.RoleInfra, hcf *api.HostConfig, packagePath string) error {
-	repo, pkg, bin, file, dir := separateSofeware(roleInfra.Softwares)
-
-	if err := installRepo(r, repo, hcf); err != nil {
-		return fmt.Errorf("install repo failed: %v", err)
-	}
-
-	if err := installPkg(r, pkg, hcf, packagePath); err != nil {
-		return fmt.Errorf("install pkg failed: %v", err)
-	}
-
-	if err := installFD(r, bin, file, dir, hcf, packagePath); err != nil {
-		return fmt.Errorf("install file failed: %v", err)
+	if err := imageDependency.Install(r); err != nil {
+		if utils.IsContainerd(runtime) {
+			logrus.Warnf("%s not support load images", runtime)
+			return nil
+		}
+		return err
 	}
 
+	logrus.Info("load images success")
 	return nil
 }
 
-func RemoveDependency(r runner.Runner, roleInfra *api.RoleInfra, hcf *api.HostConfig, packagePath string) {
-	repo, pkg, bin, file, dir := separateSofeware(roleInfra.Softwares)
-
-	if err := uninstallRepo(r, repo, hcf); err != nil {
-		logrus.Errorf("uninstall repo failed: %v", err)
-	}
-
-	if err := uninstallPkg(r, pkg, hcf, packagePath); err != nil {
-		logrus.Errorf("uninstall pkg failed: %v", err)
-	}
-
-	if err := uninstallFD(r, bin, file, dir, hcf); err != nil {
-		logrus.Errorf("uninstall file failed: %v", err)
-	}
-}
-
 func CheckDependency(r runner.Runner, softwares []string) error {
 	for _, s := range softwares {
 		_, err := r.RunCommand(fmt.Sprintf("sudo -E /bin/sh -c \"which %s\"", s))
-- 
2.25.1

