forked from rtucker-mozilla/chorizo
/
chorizo_funcs.go
150 lines (139 loc) · 3.79 KB
/
chorizo_funcs.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package main
import (
"crypto/sha1"
"database/sql"
"encoding/hex"
"fmt"
"github.com/jmcvetta/napping"
_ "github.com/mattn/go-sqlite3"
"time"
restclient "libchorizo/restclient"
log "libchorizo/log"
)
// GUIDHash returns a SHA1 hash of the hostname and timestamp to tag local logging groups
func GUIDHash(hostname string) string {
current_time := time.Now()
hasher := sha1.New()
write_hash_string := []byte(fmt.Sprintf("%s%d", hostname, current_time.UnixNano()))
hasher.Write(write_hash_string)
sha := hex.EncodeToString(hasher.Sum(nil))
return sha
}
func GetSystemId(API_URL string, hostname string) (int, error) {
log := log.GetLogger()
// Add function here to pull from local db
var from_cache = false
log.Debug("from_cache: ", from_cache)
rest_system_id, rest_err := restclient.APIGetSystemId(API_URL, hostname)
// Set value to local db
return rest_system_id, rest_err
}
func DBStartUpdate(db *sql.DB, update_id int) bool {
tx, err := db.Begin()
if err != nil {
return false
}
// insert into state (update_id, finished) values (?, 0)
stmt, err := tx.Prepare("insert into state (update_id, finished) values (?, 0)")
defer stmt.Close()
if err != nil {
panic(err)
}
stmt.Exec(update_id)
stmt.Close()
tx.Commit()
return true
}
func DBGetCurrentUpdateId(db *sql.DB) int {
var update_id = 0
err := db.QueryRow("select update_id from state order by id desc limit 1").Scan(&update_id)
if err != nil {
panic(err)
update_id = 0
}
return update_id
}
func DBEndUpdate(db *sql.DB, update_id int) bool {
tx, err := db.Begin()
if err != nil {
return false
}
// insert into state (update_id, finished) values (?, 0)
stmt, err := tx.Prepare("delete from state")
defer stmt.Close()
if err != nil {
panic(err)
}
stmt.Exec()
stmt.Close()
tx.Commit()
return true
}
func DBSetLastCompletedScript(db *sql.DB, update_id int, script string) bool {
tx, err := db.Begin()
if err != nil {
return false
}
// insert into state (update_id, finished) values (?, 0)
stmt, err := tx.Prepare("update state set last_script_completed = ?")
defer stmt.Close()
if err != nil {
panic(err)
}
stmt.Exec(script)
stmt.Close()
tx.Commit()
return true
}
func ProcessEntry(us chan UpdateScriptResponse, db *sql.DB) {
log := log.GetLogger()
s := <-us
log.Debug("\n===== START LOG CAPTURE OF ExecCommand =====")
log.Debug("ret_code: ", s.ret_code)
log.Debug("stdout: ", s.stdout)
log.Debug("stderr: ", s.stderr)
log.Debug("===== END LOG CAPTURE OF ExecCommand =====\n")
var update_id = 0
if s.is_start {
update_id, _ := restclient.CreateSytemUpdate(s.api_url, s.system_id)
DBStartUpdate(db, update_id)
log.Error("CreateSystemUpdate")
}
if update_id == 0 {
DBGetCurrentUpdateId(db)
}
if s.stderr != "" || s.stdout != "" {
LogCapture(s.api_url, s.system_id, &s)
log.Error("Called LogCapture")
}
DBSetLastCompletedScript(db, update_id, s.update_script.FilePath)
if s.is_end {
restclient.FinishSystemUpdate(s.api_url, s.system_id)
// Here we either delete from the database or mark as completed
// Delete is probably easier
DBEndUpdate(db, update_id)
log.Error("FinishSystemUpdate")
}
log.Debug("Leaving ProcessEntry goroutine")
}
func LogCapture(url string, system_id int, log_object *UpdateScriptResponse) bool {
payload := struct {
Return_code int `json:"return_code"`
Stdout string `json:"stdout"`
Stderr string `json:"stderr"`
System_id int `json:"system_id"`
}{}
return_value := false
var final_url = fmt.Sprintf("%s/logcapture/", url)
payload.System_id = system_id
payload.Stdout = log_object.stdout
payload.Stderr = log_object.stderr
payload.Return_code = log_object.ret_code
resp, err := napping.Post(final_url, &payload, nil, nil)
if resp.Status() == 200 {
return_value = true
} else if err != nil {
return_value = false
}
return return_value
}