5
5
package zip
6
6
7
7
import (
8
+ "archive/zip"
8
9
"fmt"
9
10
"os"
10
11
"os/exec"
11
12
"path/filepath"
12
- "strings"
13
13
14
14
"github.com/elastic/beats/v7/x-pack/agent/pkg/agent/errors"
15
15
"github.com/elastic/beats/v7/x-pack/agent/pkg/artifact"
@@ -35,37 +35,72 @@ func NewInstaller(config *artifact.Config) (*Installer, error) {
35
35
// Install performs installation of program in a specific version.
36
36
// It expects package to be already downloaded.
37
37
func (i * Installer ) Install (programName , version , installDir string ) error {
38
- if err := i .unzip (programName , version , installDir ); err != nil {
38
+ artifactPath , err := artifact .GetArtifactPath (programName , version , i .config .OS (), i .config .Arch (), i .config .TargetDirectory )
39
+ if err != nil {
39
40
return err
40
41
}
41
42
42
- oldPath := filepath .Join (installDir , fmt .Sprintf ("%s-%s-windows" , programName , version ))
43
- newPath := filepath .Join (installDir , strings .Title (programName ))
44
- if err := os .Rename (oldPath , newPath ); err != nil {
45
- return errors .New (err , errors .TypeFilesystem , errors .M (errors .MetaKeyPath , newPath ))
43
+ if err := i .unzip (artifactPath , programName , version ); err != nil {
44
+ return err
46
45
}
47
46
48
- return i .runInstall (programName , installDir )
49
- }
50
-
51
- func (i * Installer ) unzip (programName , version , installPath string ) error {
52
- artifactPath , err := artifact .GetArtifactPath (programName , version , i .config .OS (), i .config .Arch (), i .config .TargetDirectory )
47
+ rootDir , err := i .getRootDir (artifactPath )
53
48
if err != nil {
54
49
return err
55
50
}
56
51
52
+ // if root directory is not the same as desired directory rename
53
+ // e.g contains `-windows-` or `-SNAPSHOT-`
54
+ if rootDir != installDir {
55
+ if err := os .Rename (rootDir , installDir ); err != nil {
56
+ return errors .New (err , errors .TypeFilesystem , errors .M (errors .MetaKeyPath , installDir ))
57
+ }
58
+ }
59
+
60
+ return i .runInstall (programName , version , installDir )
61
+ }
62
+
63
+ func (i * Installer ) unzip (artifactPath , programName , version string ) error {
57
64
if _ , err := os .Stat (artifactPath ); err != nil {
58
65
return errors .New (fmt .Sprintf ("artifact for '%s' version '%s' could not be found at '%s'" , programName , version , artifactPath ), errors .TypeFilesystem , errors .M (errors .MetaKeyPath , artifactPath ))
59
66
}
60
67
61
- powershellArg := fmt .Sprintf ("Expand-Archive -Path \" %s\" -DestinationPath \" %s\" " , artifactPath , installPath )
68
+ powershellArg := fmt .Sprintf ("Expand-Archive -LiteralPath \" %s\" -DestinationPath \" %s\" " , artifactPath , i . config . InstallPath )
62
69
installCmd := exec .Command ("powershell" , "-command" , powershellArg )
63
70
return installCmd .Run ()
64
71
}
65
72
66
- func (i * Installer ) runInstall (programName , installPath string ) error {
73
+ func (i * Installer ) runInstall (programName , version , installPath string ) error {
67
74
powershellCmd := fmt .Sprintf (powershellCmdTemplate , installPath , programName )
68
-
69
75
installCmd := exec .Command ("powershell" , "-command" , powershellCmd )
76
+
70
77
return installCmd .Run ()
71
78
}
79
+
80
+ // retrieves root directory from zip archive
81
+ func (i * Installer ) getRootDir (zipPath string ) (dir string , err error ) {
82
+ defer func () {
83
+ if dir != "" {
84
+ dir = filepath .Join (i .config .InstallPath , dir )
85
+ }
86
+ }()
87
+
88
+ zipReader , err := zip .OpenReader (zipPath )
89
+ if err != nil {
90
+ return "" , err
91
+ }
92
+ defer zipReader .Close ()
93
+
94
+ var rootDir string
95
+ for _ , f := range zipReader .File {
96
+ if filepath .Base (f .Name ) == filepath .Dir (f .Name ) {
97
+ return f .Name , nil
98
+ }
99
+
100
+ if currentDir := filepath .Dir (f .Name ); rootDir == "" || len (currentDir ) < len (rootDir ) {
101
+ rootDir = currentDir
102
+ }
103
+ }
104
+
105
+ return rootDir , nil
106
+ }
0 commit comments