This repository has been archived by the owner on Jun 13, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
/
binary.go
109 lines (97 loc) · 2.88 KB
/
binary.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2018 Datadog, Inc.
package setup
import (
"bufio"
"fmt"
"io"
"net/http"
"os"
"os/exec"
"strings"
"time"
"github.com/golang/glog"
)
type depBinary struct {
archivePath string
binaryABSPath string
archiveURL string
version string
}
type exeBinary struct {
depBinary
commandVersion []string
}
const downloadBinaryRetryDelay = time.Second * 5
func (x *exeBinary) isUpToDate() bool {
b, err := exec.Command(x.binaryABSPath, x.commandVersion...).CombinedOutput()
output := strings.Trim(string(b), "\n")
if err != nil {
glog.Errorf("Cannot check version for %s: %s, %v", x.binaryABSPath, output, err)
return false
}
glog.V(4).Infof("Binary %s version: %s, wanted: %s", x.binaryABSPath, strings.Split(output, "\n"), x.version)
upToDate := strings.Contains(output, x.version)
if upToDate {
return true
}
glog.V(2).Infof("Need to update the binary %s version: %s, wanted: %s", x.binaryABSPath, strings.Split(output, "\n"), x.version)
return false
}
func (d *depBinary) downloadToFile() error {
glog.V(2).Infof("Downloading the archive %s to %s", d.archiveURL, d.archivePath)
client := &http.Client{Timeout: time.Minute * 15}
resp, err := client.Get(d.archiveURL)
if err != nil {
glog.Errorf("Cannot download %s: %v", d.archiveURL, err)
return err
}
if resp.StatusCode != http.StatusOK {
err = fmt.Errorf("status code: %d", resp.StatusCode)
glog.Errorf("Cannot download %s, status code != 200, %s", d.archiveURL, err)
return err
}
f, err := os.OpenFile(d.archivePath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0400)
if err != nil {
if !os.IsNotExist(err) {
glog.Errorf("Cannot open %s: %v", d.archivePath, err)
return err
}
}
defer f.Close()
dst := bufio.NewWriter(f)
_, err = io.Copy(dst, resp.Body)
if err != nil {
glog.Errorf("Cannot write %s in %s: %v", resp.Request.URL.RawQuery, f.Name(), err)
return err
}
glog.V(2).Infof("Successfully downloaded %s to %s", d.archiveURL, d.archivePath)
return dst.Flush()
}
func (d *depBinary) download() error {
_, err := os.Stat(d.archivePath)
if err == nil {
glog.V(2).Infof("Archive already here: %s", d.archivePath)
return nil
}
err = d.downloadToFile()
if err != nil {
glog.Errorf("Fail to download %s: %v", d.archiveURL, err)
glog.Infof("Retrying to download in %s ...", downloadBinaryRetryDelay.String())
time.Sleep(downloadBinaryRetryDelay)
// we don't need to delete the file as we open it with O_TRUNC
return d.downloadToFile()
}
return nil
}
func (d *depBinary) removeArchive() error {
err := os.Remove(d.archivePath)
if err != nil {
glog.Infof("Cannot remove the archive %s: %v", d.archivePath, err)
return err
}
glog.V(2).Infof("Removed %s", d.archivePath)
return nil
}