Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Bruce Flynn
chart-server
Commits
db11c6fb
Commit
db11c6fb
authored
Sep 17, 2021
by
Bruce Flynn
Browse files
Update chart index on interval rather than on upload
parent
9bdb8747
Pipeline
#31505
failed with stage
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
main.go
View file @
db11c6fb
...
...
@@ -8,6 +8,7 @@ import (
"os"
"os/exec"
"path"
"time"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
...
...
@@ -20,7 +21,7 @@ func httpFail(w http.ResponseWriter, r *http.Request, msg string, err error) {
http
.
Error
(
w
,
msg
,
http
.
StatusInternalServerError
)
}
func
updateIndex
()
error
{
func
updateIndex
(
url
,
dir
string
)
error
{
cmd
:=
exec
.
Command
(
"helm"
,
"repo"
,
"index"
,
"--url"
,
url
,
dir
)
cmd
.
Stderr
=
os
.
Stderr
err
:=
cmd
.
Run
()
...
...
@@ -30,92 +31,32 @@ func updateIndex() error {
return
nil
}
func
handleUpload
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
p
:=
path
.
Join
(
dir
,
r
.
URL
.
Path
)
st
,
err
:=
os
.
Stat
(
p
)
// got an error and the file exists... something interesting perhaps?
if
err
!=
nil
&&
!
os
.
IsNotExist
(
err
)
{
http
.
Error
(
w
,
"InternalServerError"
,
http
.
StatusInternalServerError
)
return
}
// got a stat result, file must exist already and we should not overwrite
if
st
!=
nil
{
http
.
Error
(
w
,
"File exists"
,
http
.
StatusForbidden
)
return
}
// file does not exist, proceed with upload
f
,
err
:=
os
.
Create
(
p
)
if
err
!=
nil
{
httpFail
(
w
,
r
,
"Could not complete upload"
,
err
)
return
}
if
_
,
err
:=
io
.
Copy
(
f
,
r
.
Body
);
err
!=
nil
{
httpFail
(
w
,
r
,
"Could not complete upload"
,
err
)
return
}
err
=
updateIndex
()
if
err
!=
nil
{
httpFail
(
w
,
r
,
"Could not update index"
,
err
)
// best-effort to remove the file if we could not update the index
os
.
Remove
(
p
)
return
}
log
.
Printf
(
"successfully handled chart %s"
,
path
.
Base
(
p
))
}
func
handleGetHome
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
w
.
Write
([]
byte
(
fmt
.
Sprintf
(
`
<div>
<h1>Chart Repository</h1>
<p>
To add this repostory to Helm, run:
<code>
<pre>
helm repo add <name> %s
</pre>
</code>
</p>
<h3>API</h3>
<dl>
<dt>GET /index.yaml</dt>
<dd>Get chart index file used by Helm</dd>
<dt>GET /<version>-<version>.tgz</dt>
<dd>Get a Heml chart package</dd>
<dt>PUT /<version>-<version>.tgz</dt>
<dd>Upload a new chart package to the index</dd>
<dt>GET /files</dt>
<dd>Basic file listing of chart directory</code></dd>
<dt>GET /status</dt>
<dd>Health check that simply returns <code>OK!</code></dd>
</dl>
</div>
`
,
url
)))
}
func
createUploadHandler
(
dir
string
)
http
.
HandlerFunc
{
return
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
p
:=
path
.
Join
(
dir
,
r
.
URL
.
Path
)
st
,
err
:=
os
.
Stat
(
p
)
// got an error and the file exists... something interesting perhaps?
if
err
!=
nil
&&
!
os
.
IsNotExist
(
err
)
{
http
.
Error
(
w
,
"InternalServerError"
,
http
.
StatusInternalServerError
)
return
}
// got a stat result, file must exist already and we should not overwrite
if
st
!=
nil
{
http
.
Error
(
w
,
"File exists"
,
http
.
StatusForbidden
)
return
}
func
handleGetFile
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
p
:=
path
.
Join
(
dir
,
r
.
URL
.
Path
)
st
,
err
:=
os
.
Stat
(
p
)
if
err
!=
nil
&&
os
.
IsNotExist
(
err
)
||
st
!=
nil
&&
st
.
IsDir
()
{
http
.
Error
(
w
,
"Not Found"
,
http
.
StatusNotFound
)
return
}
f
,
err
:=
os
.
Open
(
p
)
if
err
!=
nil
{
httpFail
(
w
,
r
,
"InternalServerError"
,
err
)
return
}
if
_
,
err
:=
io
.
Copy
(
w
,
f
);
err
!=
nil
{
httpFail
(
w
,
r
,
"InternalServerError"
,
err
)
return
// file does not exist, proceed with upload
f
,
err
:=
os
.
Create
(
p
)
if
err
!=
nil
{
httpFail
(
w
,
r
,
"Could not complete upload"
,
err
)
return
}
if
_
,
err
:=
io
.
Copy
(
f
,
r
.
Body
);
err
!=
nil
{
httpFail
(
w
,
r
,
"Could not complete upload"
,
err
)
return
}
log
.
Printf
(
"successfully handled chart %s"
,
path
.
Base
(
p
))
}
}
...
...
@@ -132,9 +73,6 @@ func getEnvDefault(name, def string) string {
}
var
(
dir
string
host
string
url
string
buildStr
string
)
...
...
@@ -157,6 +95,10 @@ Options can also be specified as environment variables $CHART_SVR_<name>
fmt
.
Fprintf
(
os
.
Stderr
,
"
\n
%s
\n
"
,
buildStr
)
}
var
(
dir
,
host
,
url
string
)
pflag
.
StringVar
(
&
dir
,
"dir"
,
getEnvDefault
(
"CHART_SVR_DIR"
,
"."
),
"Chart report dir"
)
pflag
.
StringVar
(
&
host
,
"host"
,
getEnvDefault
(
"CHART_SVR_HOST"
,
":8080"
),
"Host to bind to [<host>]:<port>"
)
pflag
.
StringVar
(
&
url
,
"url"
,
getEnvDefault
(
"CHART_SVR_URL"
,
""
),
"Externally accessible URL to the chart repository"
)
...
...
@@ -178,11 +120,21 @@ Options can also be specified as environment variables $CHART_SVR_<name>
r
:=
mux
.
NewRouter
()
r
.
HandleFunc
(
"/status"
,
handleStatus
)
.
Methods
(
"GET"
)
// Limit to only index.yaml and chart (.tgz) files
r
.
HandleFunc
(
`/{chart:.*-.*.tgz}`
,
handl
eUpload
)
.
Methods
(
"PUT"
)
r
.
HandleFunc
(
`/{chart:.*-.*.tgz}`
,
creat
eUpload
Handler
(
dir
)
)
.
Methods
(
"PUT"
)
r
.
PathPrefix
(
"/"
)
.
Handler
(
http
.
FileServer
(
http
.
Dir
(
dir
)))
h
:=
handlers
.
CombinedLoggingHandler
(
os
.
Stdout
,
handlers
.
CORS
()(
r
))
go
func
()
{
tick
:=
time
.
NewTicker
(
time
.
Minute
)
for
{
<-
tick
.
C
if
err
:=
updateIndex
(
url
,
dir
);
err
!=
nil
{
log
.
Printf
(
"failed to update chart index at %s: %s"
,
dir
,
err
)
}
}
}()
log
.
Printf
(
"serving charts from %s on %s"
,
dir
,
host
)
log
.
Fatal
(
http
.
ListenAndServe
(
host
,
h
))
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment