-
Notifications
You must be signed in to change notification settings - Fork 0
/
progress.go
120 lines (107 loc) · 3.86 KB
/
progress.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
110
111
112
113
114
115
116
117
118
119
120
package main
import (
"bytes"
"encoding/json"
"log"
"strings"
)
/* Json format of the progress information from docker remote API
*
*
{
"status":"Extracting",
"progressDetail":
{
"current":61833216,
"total":65785947
},
"progress":"[==============================================\u003e ] 61.83 MB/65.79 MB",
"id":"83e4dde6b9cf"
}
*/
type ProgressDetail struct {
Current int64 // bytes that have been downloaded
Total int64 // total number of bytes to be downloaded
}
type ProgressInfo struct {
Status string // A description of current status
Error string // If there is an error
ProgressDetail ProgressDetail // detailed number counts
Id string // id of the fs layer being pulled
}
func NewProgressInfoFile(status string, errStr string, current int64, total int64) *ProgressInfo {
return &ProgressInfo{Status: status, Error: errStr, ProgressDetail: ProgressDetail{Current: current, Total: total}}
}
func NewProgressInfoDocker(info []byte) *ProgressInfo {
pInfo := ProgressInfo{}
err := json.Unmarshal(info, &pInfo)
if err != nil {
splitted := bytes.Split(info, []byte(`}{`))
if len(splitted) > 1 {
oneInfo := splitted[len(splitted)-1]
if len(oneInfo) > 0 {
newOneInfo := "{" + string(oneInfo)
err := json.Unmarshal([]byte(newOneInfo), &pInfo)
log.Printf("NewProgressInfoDocker:try unmarshal again with - %s", newOneInfo)
if err == nil {
//log.Printf("NewProgressInfoDocker: ProgressInfo to be returned (second unmarshal) - %+v", pInfo)
return &pInfo
} else {
log.Printf("NewProgressInfoDocker error: %s", err.Error())
}
}
}
log.Printf("NewProgressInfoDocker error: %s", err.Error())
log.Printf("NewProgressInfoDocker: %s", string(info))
return &ProgressInfo{Status: "Failed to unmarchal status information from docker"}
} else {
//log.Printf("NewProgressInfoDocker: ProgressInfo to be returned (first unmarshal) - %+v", pInfo)
return &pInfo
}
}
type DownloadProgressInfo struct {
ImageName string // name of the docker image being pulled
Progress []*ProgressInfo // list of progress info, one for each unique value of the id field
}
func NewDownloadProgressInfo(image string, progressInfo *ProgressInfo) *DownloadProgressInfo {
return &DownloadProgressInfo{ImageName: image, Progress: []*ProgressInfo{progressInfo}}
}
func NewFailureDownloadProgressInfo(image string, err error) *DownloadProgressInfo {
return &DownloadProgressInfo{ImageName: image, Progress: []*ProgressInfo{&ProgressInfo{Status: "Error - " + err.Error()}}}
}
func NewNotStartedDownloadProgressInfo(image string) *DownloadProgressInfo {
return &DownloadProgressInfo{ImageName: image, Progress: []*ProgressInfo{&ProgressInfo{Status: "Not started"}}}
}
func (dockerPullProgressInfo *DownloadProgressInfo) AddDockerPullAPIProgressInfo(apiProgressInfo *ProgressInfo) {
if apiProgressInfo.Id != "" {
// the ProgressInfo to be added has an id entry
replaced := false
for i, entry := range dockerPullProgressInfo.Progress {
// replace the existing entry that has an id field with the same value
if strings.EqualFold(entry.Id, apiProgressInfo.Id) {
replaced = true
dockerPullProgressInfo.Progress[i] = apiProgressInfo
break
}
}
if !replaced {
// append
dockerPullProgressInfo.Progress = append(dockerPullProgressInfo.Progress, apiProgressInfo)
}
} else {
// the ProgressInfo to be added does not have an id entry or id entry is empty string
replaced := false
for i, entry := range dockerPullProgressInfo.Progress {
// replace the existing entry that does not hava an id field or id field is empty
if entry.Id == "" {
replaced = true
dockerPullProgressInfo.Progress[i] = apiProgressInfo
break
}
}
if !replaced {
// append
dockerPullProgressInfo.Progress = append(dockerPullProgressInfo.Progress, apiProgressInfo)
}
}
}