Skip to content

Commit 70e6a51

Browse files
authored
Add generic tools installation support (#252)
* Add generic installer support
1 parent c3ef37d commit 70e6a51

File tree

6 files changed

+269
-2
lines changed

6 files changed

+269
-2
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ require (
2222
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8
2323
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect
2424
gopkg.in/yaml.v2 v2.4.0
25+
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
2526
)

pkg/os/apt/common.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package apt
2+
3+
import (
4+
"fmt"
5+
"github.com/linuxsuren/http-downloader/pkg/exec"
6+
"runtime"
7+
)
8+
9+
// CommonInstaller is the installer of Conntrack in CentOS
10+
type CommonInstaller struct {
11+
Name string
12+
}
13+
14+
// Available check if support current platform
15+
func (d *CommonInstaller) Available() (ok bool) {
16+
if runtime.GOOS == "linux" {
17+
_, err := exec.LookPath("apt-get")
18+
ok = err == nil
19+
}
20+
return
21+
}
22+
23+
// Install installs the Conntrack
24+
func (d *CommonInstaller) Install() (err error) {
25+
if err = exec.RunCommand("apt-get", "update", "-y"); err != nil {
26+
return
27+
}
28+
if err = exec.RunCommand("apt-get", "install", "-y", d.Name); err != nil {
29+
return
30+
}
31+
return
32+
}
33+
34+
// Uninstall uninstalls the Conntrack
35+
func (d *CommonInstaller) Uninstall() (err error) {
36+
err = exec.RunCommand("apt-get", "remove", "-y", d.Name)
37+
return
38+
}
39+
40+
// WaitForStart waits for the service be started
41+
func (d *CommonInstaller) WaitForStart() (ok bool, err error) {
42+
ok = true
43+
return
44+
}
45+
46+
// Start starts the Conntrack service
47+
func (d *CommonInstaller) Start() error {
48+
fmt.Println("not supported yet")
49+
return nil
50+
}
51+
52+
// Stop stops the Conntrack service
53+
func (d *CommonInstaller) Stop() error {
54+
fmt.Println("not supported yet")
55+
return nil
56+
}

pkg/os/core/types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package core
22

33
// Installer is the interface of a installer
4+
// Deprecated use AdvanceInstaller instead
45
type Installer interface {
56
Available() bool
67
Install() error
@@ -11,6 +12,13 @@ type Installer interface {
1112
Stop() error
1213
}
1314

15+
// AdvanceInstaller is a generic installer
16+
type AdvanceInstaller interface {
17+
Installer
18+
19+
IsService() bool
20+
}
21+
1422
// InstallerRegistry is the interface of install registry
1523
type InstallerRegistry interface {
1624
Registry(string, Installer)

pkg/os/generic_installer.go

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
package os
2+
3+
import (
4+
"fmt"
5+
"github.com/linuxsuren/http-downloader/pkg/exec"
6+
"github.com/linuxsuren/http-downloader/pkg/os/apt"
7+
"github.com/linuxsuren/http-downloader/pkg/os/core"
8+
"github.com/linuxsuren/http-downloader/pkg/os/yum"
9+
"gopkg.in/yaml.v3"
10+
"io/ioutil"
11+
"runtime"
12+
"strings"
13+
)
14+
15+
type genericPackages struct {
16+
Version string `yaml:"version"`
17+
Packages []genericPackage `yaml:"packages"`
18+
}
19+
20+
type preInstall struct {
21+
IssuePrefix string `yaml:"issuePrefix"`
22+
Cmd CmdWithArgs `yaml:"cmd"`
23+
}
24+
25+
type genericPackage struct {
26+
Alias string `yaml:"alias"`
27+
Name string `yaml:"name"`
28+
OS string `yaml:"os"`
29+
PackageManager string `yaml:"packageManager"`
30+
PreInstall []preInstall `yaml:"preInstall"`
31+
Dependents []string `yaml:"dependents"`
32+
InstallCmd CmdWithArgs `yaml:"install"`
33+
UninstallCmd CmdWithArgs `yaml:"uninstall"`
34+
Service bool `yaml:"isService"`
35+
StartCmd CmdWithArgs `yaml:"start"`
36+
StopCmd CmdWithArgs `yaml:"stop"`
37+
38+
CommonInstaller core.Installer
39+
}
40+
41+
// CmdWithArgs is a command with arguments
42+
type CmdWithArgs struct {
43+
Cmd string `yaml:"cmd"`
44+
Args []string `yaml:"args"`
45+
}
46+
47+
func parseGenericPackages(configFile string, genericPackages *genericPackages) (err error) {
48+
var data []byte
49+
if data, err = ioutil.ReadFile(configFile); err != nil {
50+
err = fmt.Errorf("cannot read config file [%s], error: %v", configFile, err)
51+
return
52+
}
53+
54+
if err = yaml.Unmarshal(data, genericPackages); err != nil {
55+
err = fmt.Errorf("failed to parse config file [%s], error: %v", configFile, err)
56+
return
57+
}
58+
return
59+
}
60+
61+
// GenericInstallerRegistry registries a generic installer
62+
func GenericInstallerRegistry(configFile string, registry core.InstallerRegistry) (err error) {
63+
genericPackages := &genericPackages{}
64+
if err = parseGenericPackages(configFile, genericPackages); err != nil {
65+
return
66+
}
67+
68+
// registry all the packages
69+
for i := range genericPackages.Packages {
70+
genericPackage := genericPackages.Packages[i]
71+
72+
switch genericPackage.PackageManager {
73+
case "apt-get":
74+
genericPackage.CommonInstaller = &apt.CommonInstaller{Name: genericPackage.Name}
75+
case "yum":
76+
genericPackage.CommonInstaller = &yum.CommonInstaller{Name: genericPackage.Name}
77+
}
78+
79+
registry.Registry(genericPackage.Name, &genericPackage)
80+
}
81+
return
82+
}
83+
84+
func (i *genericPackage) Available() (ok bool) {
85+
if i.CommonInstaller != nil {
86+
ok = i.CommonInstaller.Available()
87+
}
88+
return
89+
}
90+
func (i *genericPackage) Install() (err error) {
91+
for index := range i.PreInstall {
92+
preInstall := i.PreInstall[index]
93+
94+
if preInstall.IssuePrefix != "" && runtime.GOOS == "linux" {
95+
var data []byte
96+
if data, err = ioutil.ReadFile("/etc/issue"); err != nil {
97+
return
98+
}
99+
100+
if strings.HasPrefix(string(data), preInstall.IssuePrefix) {
101+
if err = exec.RunCommand(preInstall.Cmd.Cmd, preInstall.Cmd.Args...); err != nil {
102+
return
103+
}
104+
}
105+
}
106+
}
107+
108+
if i.CommonInstaller != nil {
109+
err = i.CommonInstaller.Install()
110+
} else {
111+
err = fmt.Errorf("not support yet")
112+
}
113+
return
114+
}
115+
func (i *genericPackage) Uninstall() (err error) {
116+
if i.CommonInstaller != nil {
117+
err = i.CommonInstaller.Uninstall()
118+
} else {
119+
err = fmt.Errorf("not support yet")
120+
}
121+
return
122+
}
123+
func (i *genericPackage) IsService() bool {
124+
return i.Service
125+
}
126+
func (i *genericPackage) WaitForStart() (bool, error) {
127+
return true, nil
128+
}
129+
func (i *genericPackage) Start() error {
130+
return nil
131+
}
132+
func (i *genericPackage) Stop() error {
133+
return nil
134+
}

pkg/os/installer.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import (
77
"github.com/linuxsuren/http-downloader/pkg/os/core"
88
"github.com/linuxsuren/http-downloader/pkg/os/docker"
99
"github.com/linuxsuren/http-downloader/pkg/os/yum"
10+
"github.com/mitchellh/go-homedir"
11+
"path"
12+
"path/filepath"
1013
)
1114

1215
// DefaultInstallerRegistry is the default installer registry
@@ -24,6 +27,15 @@ func init() {
2427
apt.SetInstallerRegistry(defaultInstallerRegistry)
2528
brew.SetInstallerRegistry(defaultInstallerRegistry)
2629
docker.SetInstallerRegistry(defaultInstallerRegistry)
30+
31+
var userHome string
32+
var err error
33+
if userHome, err = homedir.Dir(); err == nil {
34+
configDir := path.Join(userHome, "/.config/hd-home")
35+
if err = GenericInstallerRegistry(filepath.Join(configDir, "config/generic.yaml"), defaultInstallerRegistry); err != nil {
36+
fmt.Println(err)
37+
}
38+
}
2739
}
2840

2941
// Registry registries a DockerInstaller
@@ -45,8 +57,8 @@ func GetInstallers(name string) (installers []core.Installer, ok bool) {
4557
// HasPackage finds if the target package installer exist
4658
func HasPackage(name string) bool {
4759
if installers, ok := GetInstallers(name); ok {
48-
for _, installer := range installers {
49-
if installer.Available() {
60+
for _, item := range installers {
61+
if item.Available() {
5062
return true
5163
}
5264
}

pkg/os/yum/common.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package yum
2+
3+
import (
4+
"fmt"
5+
"github.com/linuxsuren/http-downloader/pkg/exec"
6+
"runtime"
7+
)
8+
9+
// CommonInstaller is the installer of Conntrack in CentOS
10+
type CommonInstaller struct {
11+
Name string
12+
}
13+
14+
// Available check if support current platform
15+
func (d *CommonInstaller) Available() (ok bool) {
16+
if runtime.GOOS == "linux" {
17+
_, err := exec.LookPath("yum")
18+
ok = err == nil
19+
}
20+
return
21+
}
22+
23+
// Install installs the Conntrack
24+
func (d *CommonInstaller) Install() (err error) {
25+
if err = exec.RunCommand("yum", "update", "-y"); err != nil {
26+
return
27+
}
28+
if err = exec.RunCommand("yum", "install", "-y", d.Name); err != nil {
29+
return
30+
}
31+
return
32+
}
33+
34+
// Uninstall uninstalls the Conntrack
35+
func (d *CommonInstaller) Uninstall() (err error) {
36+
err = exec.RunCommand("yum", "remove", "-y", d.Name)
37+
return
38+
}
39+
40+
// WaitForStart waits for the service be started
41+
func (d *CommonInstaller) WaitForStart() (ok bool, err error) {
42+
ok = true
43+
return
44+
}
45+
46+
// Start starts the Conntrack service
47+
func (d *CommonInstaller) Start() error {
48+
fmt.Println("not supported yet")
49+
return nil
50+
}
51+
52+
// Stop stops the Conntrack service
53+
func (d *CommonInstaller) Stop() error {
54+
fmt.Println("not supported yet")
55+
return nil
56+
}

0 commit comments

Comments
 (0)