Check Release/Stemcell versions in-line with HTTP requests

This way, end users get better feedback when they give invalid behavior.
All the "short" verification checks can be done synchronously, and the
"long" work tasks in a goroutine.

Fixes #6
This commit is contained in:
James Hunt 2016-10-29 10:54:57 -04:00
parent 0fc9fa4e1c
commit 989dcc800e
4 changed files with 72 additions and 59 deletions

View File

@ -114,8 +114,8 @@ func (api ReleaseAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) {
vers := extract(r, `/v1/release/[^/]+/v/([^/]+)`)
log.Debugf("checking for version '%s' of release '%s'", vers, name)
go CheckReleaseVersion(api.db, name, vers)
respond(w, nil, 200, "task started in background")
err := CheckReleaseVersion(api.db, name, vers)
respond(w, err, 200, "task started in background")
return
case match(r, `DELETE /v1/release/[^/]+/v/[^/]+`):

View File

@ -114,8 +114,8 @@ func (api StemcellAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) {
vers := extract(r, `/v1/stemcell/[^/]+/v/([^/]+)`)
log.Debugf("checking for version '%s' of stemcell '%s'", vers, name)
go CheckStemcellVersion(api.db, name, vers)
respond(w, nil, 200, "task started in background")
err := CheckStemcellVersion(api.db, name, vers)
respond(w, err, 200, "task started in background")
return
case match(r, `DELETE /v1/stemcell/[^/]+/v/[^/]+`):

View File

@ -206,11 +206,11 @@ func DeleteReleaseVersion(d *db.DB, name, version string) error {
return d.Exec(`DELETE FROM release_versions WHERE name = $1 AND version = $2`, name, version)
}
func CheckReleaseVersion(d *db.DB, name, version string) {
func CheckReleaseVersion(d *db.DB, name, version string) error {
release, err := FindRelease(d, name)
if err != nil {
log.Debugf("unable to find release '%s': %s", name, err)
return
return err
}
/* generate the URL from the template */
@ -222,34 +222,40 @@ func CheckReleaseVersion(d *db.DB, name, version string) {
if n == 0 {
recheck = false
num, err := vnum(version)
if err == nil {
d.Exec(`INSERT INTO release_versions (name, version, vnum, valid) VALUES ($1, $2, $3, 0)`,
name, version, num)
if err != nil {
return err
}
d.Exec(`INSERT INTO release_versions (name, version, vnum, valid) VALUES ($1, $2, $3, 0)`,
name, version, num)
}
/* download and SHA1 the file */
sha1, err := sha1sum(url)
if err != nil {
log.Debugf("download/sha1sum failed: %s...", err)
if !recheck {
d.Exec(`DELETE FROM release_versions WHERE name = $1 AND version = $2`,
name, version)
/* do the async part in its own goroutine */
go func() {
/* download and SHA1 the file */
sha1, err := sha1sum(url)
if err != nil {
log.Debugf("download/sha1sum failed: %s...", err)
if !recheck {
d.Exec(`DELETE FROM release_versions WHERE name = $1 AND version = $2`,
name, version)
}
return
}
return
}
err = d.Exec(`
UPDATE release_versions
SET valid = 1,
url = $3,
sha1 = $4
err = d.Exec(`
UPDATE release_versions
SET valid = 1,
url = $3,
sha1 = $4
WHERE name = $1
AND version = $2`, name, version, url, sha1)
WHERE name = $1
AND version = $2`, name, version, url, sha1)
if err != nil {
log.Debugf("unable to check version '%s' of '%s': %s", version, name, err)
return
}
if err != nil {
log.Debugf("unable to check version '%s' of '%s': %s", version, name, err)
return
}
}()
return nil;
}

View File

@ -206,11 +206,11 @@ func DeleteStemcellVersion(d *db.DB, name, version string) error {
return d.Exec(`DELETE FROM stemcell_versions WHERE name = $1 AND version = $2`, name, version)
}
func CheckStemcellVersion(d *db.DB, name, version string) {
func CheckStemcellVersion(d *db.DB, name, version string) error {
stemcell, err := FindStemcell(d, name)
if err != nil {
log.Debugf("unable to find stemcell '%s': %s", name, err)
return
return err
}
/* generate the URL from the template */
@ -222,37 +222,44 @@ func CheckStemcellVersion(d *db.DB, name, version string) {
if n == 0 {
recheck = false
num, err := vnum(version)
if err == nil {
err = d.Exec(`INSERT INTO stemcell_versions (name, version, vnum, valid) VALUES ($1, $2, $3, 0)`,
name, version, num)
if err != nil {
log.Debugf("unable to check version '%s' of '%s': %s", version, name, err)
if err != nil {
return err
}
err = d.Exec(`INSERT INTO stemcell_versions (name, version, vnum, valid) VALUES ($1, $2, $3, 0)`,
name, version, num)
if err != nil {
log.Debugf("unable to check version '%s' of '%s': %s", version, name, err)
return err
}
}
/* do the async part in its own goroutine */
go func() {
/* download and SHA1 the file */
sha1, err := sha1sum(url)
if err != nil {
log.Debugf("download/sha1sum failed: %s...", err)
if !recheck {
d.Exec(`DELETE FROM stemcell_versions WHERE name = $1 AND version = $2`,
name, version)
}
return
}
}
/* download and SHA1 the file */
sha1, err := sha1sum(url)
if err != nil {
log.Debugf("download/sha1sum failed: %s...", err)
if !recheck {
d.Exec(`DELETE FROM stemcell_versions WHERE name = $1 AND version = $2`,
name, version)
err = d.Exec(`
UPDATE stemcell_versions
SET valid = 1,
url = $3,
sha1 = $4
WHERE name = $1
AND version = $2`, name, version, url, sha1)
if err != nil {
log.Debugf("unable to check version '%s' of '%s': %s", version, name, err)
return
}
return
}
}()
err = d.Exec(`
UPDATE stemcell_versions
SET valid = 1,
url = $3,
sha1 = $4
WHERE name = $1
AND version = $2`, name, version, url, sha1)
if err != nil {
log.Debugf("unable to check version '%s' of '%s': %s", version, name, err)
return
}
return nil
}