-
Notifications
You must be signed in to change notification settings - Fork 12
/
setup.go
154 lines (139 loc) · 4 KB
/
setup.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
151
152
153
154
package main
import (
"bytes"
"crypto/x509"
"errors"
"flag"
"fmt"
"io"
"log"
"net/http"
"net/url"
"os"
"os/exec"
"path/filepath"
"runtime/debug"
"time"
"github.com/frou/stdext"
"github.com/frou/yt2pod/internal/xplatform"
)
func introspectOwnVersion() string {
// REF: The `go` command's compile-time interaction with external VCS commands:
// https://github.com/golang/go/blob/master/src/cmd/go/internal/vcs/vcs.go
if buildInfo, ok := debug.ReadBuildInfo(); ok {
var vcs, vcsRevision, vcsModified *string
for _, kvp := range buildInfo.Settings {
value := kvp.Value
switch kvp.Key {
case "vcs":
vcs = &value
case "vcs.revision":
vcsRevision = &value
case "vcs.modified":
vcsModified = &value
}
}
if vcs != nil && vcsRevision != nil && vcsModified != nil {
revision := *vcsRevision
if *vcs == "git" {
// Abbreviate the SHA for display, like git itself does.
const revisionAbbrevLen = 7
if len(revision) > revisionAbbrevLen {
revision = revision[:revisionAbbrevLen]
}
}
dirtyIndicator := ""
if *vcsModified == "true" {
dirtyIndicator = "-dirty"
}
return fmt.Sprintf("%s-%s%s", *vcs, revision, dirtyIndicator)
}
}
return "unknown"
}
func setup() (*config, error) {
flag.Parse()
ownVersion := introspectOwnVersion()
if *flagPrintVersion {
fmt.Println("Version:", ownVersion)
os.Exit(0)
}
// Setup log destination & format.
var (
w io.Writer
flags int
err error
)
if *flagUseSyslog {
executableName := filepath.Base(os.Args[0])
w, err = xplatform.NewSyslog(executableName)
if err != nil {
return nil, err
}
// flags = log.Lshortfile
} else {
w = os.Stderr
flags = log.Ldate | log.Ltime //| log.Lshortfile
}
log.SetOutput(w)
log.SetFlags(flags)
log.Printf("Version: %s", ownVersion)
// Load config from disk.
cfg, err := loadConfig(*flagConfigPath)
if err != nil {
return nil, errors.New("config: " + err.Error())
}
log.Print("Config successfully loaded from ", *flagConfigPath)
// Store a closure over cfg, so that the `downloaderOld` health check can also make use of this function.
getDownloaderCommandVersion = func() (string, error) {
versionBytes, err := exec.Command(cfg.DownloaderName, "--version").Output()
if err != nil {
return "", err
}
return string(bytes.TrimSpace(versionBytes)), nil
}
// Log the name and version of the downloader command that's configured/available.
version, err := getDownloaderCommandVersion()
if err != nil {
// This also catches a custom downloader_name being set in the config file, but that command not existing on PATH.
return nil, fmt.Errorf("Couldn't determine configured downloader command's version: %w", err)
}
log.Printf("Downloader command is %s (currently version %s)", cfg.DownloaderName, version)
// Up front, check that a GET to a http_s_ server works (which needs CA
// certs to be present and correct in the OS)
secureResp, err := http.Get("https://www.googleapis.com/")
if err != nil {
var urlErr *url.Error
var sysRootsErr *x509.SystemRootsError
if errors.As(err, &urlErr) && errors.As(urlErr.Err, &sysRootsErr) {
return nil, sysRootsErr
}
// Not the specific thing we are proactively checking for, so just log it and continue.
log.Print(err)
} else {
secureResp.Body.Close()
}
// Create the data directory.
err = os.Mkdir(*flagDataPath, stdext.OwnerWritableDir)
if err != nil && !os.IsExist(err) {
return nil, err
}
// Change into it (don't want to expose our config file when webserving).
if err := os.Chdir(*flagDataPath); err != nil {
return nil, err
}
// Create its subdirectories.
for _, name := range []string{dataSubdirMetadata, dataSubdirEpisodes} {
err := os.Mkdir(name, stdext.OwnerWritableDir)
if err != nil && !os.IsExist(err) {
return nil, err
}
}
xplatform.RegisterStalenessResetter(func() {
lastTimeAnyFeedWritten.Set(time.Now())
log.Print("The clock for stale feeds was reset")
})
return cfg, nil
}
//nolint:gochecknoglobals
var getDownloaderCommandVersion func() (string, error)