Compare commits

...

51 Commits
v1.2 ... master

Author SHA1 Message Date
Tim Shannon eaf4d9c4f5 gobs webhook test 2016-07-05 12:19:56 -05:00
Tim Shannon cb9cea887e Merge branch 'master' of git.townsourced.com:townsourced/ironsmith 2016-07-05 12:17:42 -05:00
Tim Shannon 74c85da725 Merge branch 'master' of https://git.townsourced.com/townsourced/ironsmith 2016-06-23 16:50:37 -05:00
Tim Shannon 29412a68ff Merge branch 'master' of https://git.townsourced.com/townsourced/ironsmith 2016-06-23 16:41:42 -05:00
Tim Shannon 2bc13eca6c Merge branch 'master' of https://git.townsourced.com/townsourced/ironsmith 2016-06-23 16:36:23 -05:00
Tim Shannon f8d5ddb469 removed verbose from build script 2016-05-05 10:51:57 -05:00
Tim Shannon 3bbb8d7c20 removed verbose from build script 2016-05-05 10:51:57 -05:00
Tim Shannon c7745beb28 removed verbose from build script 2016-05-05 10:51:57 -05:00
Tim Shannon f4dea30265 Changed forced build to be only off of trigger
instead of anytime that it's not polled
2016-05-05 10:30:50 -05:00
Tim Shannon 479175baa0 Changed forced build to be only off of trigger
instead of anytime that it's not polled
2016-05-05 10:30:50 -05:00
Tim Shannon dbf41e948b Changed forced build to be only off of trigger
instead of anytime that it's not polled
2016-05-05 10:30:50 -05:00
Tim Shannon 1e3eb54ea2 Added max version limit for projects 2016-05-04 15:39:56 -05:00
Tim Shannon b1c259640e Added max version limit for projects 2016-05-04 15:39:56 -05:00
Tim Shannon 35ec632334 Added max version limit for projects 2016-05-04 15:39:56 -05:00
Tim Shannon 52750bad48 Changed behavior so triggered builds ignore version
Version checks are only done on polling projects.
2016-05-04 08:35:36 -05:00
Tim Shannon f75d91d4c0 Changed behavior so triggered builds ignore version
Version checks are only done on polling projects.
2016-05-04 08:35:36 -05:00
Tim Shannon 22db2cfdad Changed behavior so triggered builds ignore version
Version checks are only done on polling projects.
2016-05-04 08:35:36 -05:00
Tim Shannon 85d8ad8221 Added max project size starting point 2016-05-03 21:04:06 -05:00
Tim Shannon f0e7c794c6 Added max project size starting point 2016-05-03 21:04:06 -05:00
Tim Shannon d0b745cc9f Added max project size starting point 2016-05-03 21:04:06 -05:00
Tim Shannon 6e3ddacbf4 Fixed small issue with logs in table formatting 2016-04-28 15:12:50 +00:00
Tim Shannon 0ab64982da Fixed small issue with logs in table formatting 2016-04-28 15:12:50 +00:00
Tim Shannon a5e982f508 Fixed small issue with logs in table formatting 2016-04-28 15:12:50 +00:00
Tim Shannon 1a161d9554 Fixed last release file issue
trimmed logs in tables some more
2016-04-25 21:39:11 +00:00
Tim Shannon a3a7c4f66b Fixed last release file issue
trimmed logs in tables some more
2016-04-25 21:39:11 +00:00
Tim Shannon 07d499456b Changed log view formatting in tables a bit 2016-04-25 21:09:16 +00:00
Tim Shannon 21ebb286a6 Changed log view formatting in tables a bit 2016-04-25 21:09:16 +00:00
Tim Shannon 8d79ded661 Added time took to release log statement
Changed release file name handling to only include the base of the file
path.
2016-04-25 21:02:01 +00:00
Tim Shannon 24b541801a Added time took to release log statement
Changed release file name handling to only include the base of the file
path.
2016-04-25 21:02:01 +00:00
Tim Shannon 04060ee63d Added pre-version version
No fetch and load errors can be properly seen without having to run
ironsmith manually.
2016-04-25 19:41:03 +00:00
Tim Shannon 345062d93a Added pre-version version
No fetch and load errors can be properly seen without having to run
ironsmith manually.
2016-04-25 19:41:03 +00:00
Tim Shannon 7a0b821be4 Another small change in the same code 2016-04-25 16:56:48 +00:00
Tim Shannon e586626a69 Another small change in the same code 2016-04-25 16:56:48 +00:00
Tim Shannon 2066c68257 Fixed issue with new projects
If they haven't done a single poll the UI was filing to find a last
version.
2016-04-25 16:51:01 +00:00
Tim Shannon 6afd073f57 Fixed issue with new projects
If they haven't done a single poll the UI was filing to find a last
version.
2016-04-25 16:51:01 +00:00
Tim Shannon 4785efdfc2 Testing git hooks with ironsmith 2016-04-25 15:44:04 +00:00
Tim Shannon dd12b9dfbf Testing git hooks with ironsmith 2016-04-25 15:44:04 +00:00
Tim Shannon 78d160247d Added / stole some code to handle cmd execs better
It'll now use any custom environment path to lookup executables to run
as part of the project scripts
2016-04-22 21:25:33 +00:00
Tim Shannon 01f655a2a1 Added / stole some code to handle cmd execs better
It'll now use any custom environment path to lookup executables to run
as part of the project scripts
2016-04-22 21:25:33 +00:00
Tim Shannon 6ca5b8668a Added better error handling.
Moved main project list columns around
2016-04-22 20:39:06 +00:00
Tim Shannon 0cabc10fd7 Added better error handling.
Moved main project list columns around
2016-04-22 20:39:06 +00:00
Tim Shannon 358b2069d6 Build script change 2016-04-21 13:41:21 +00:00
Tim Shannon 9cb1f8c347 Build script change 2016-04-21 13:41:21 +00:00
Tim Shannon 066ae7aa32 Updated build script 2016-04-20 16:42:16 +00:00
Tim Shannon 0908c91a7d Updated build script 2016-04-20 16:42:16 +00:00
Tim Shannon 9632d7f2b6 Post trigger test 2016-04-20 16:22:42 +00:00
Tim Shannon 19d11b456b Post trigger test 2016-04-20 16:22:42 +00:00
Tim Shannon f0735abb32 Fixed issue with environment not getting set in projects 2016-04-20 16:15:53 +00:00
Tim Shannon b1ee0c640e Fixed issue with environment not getting set in projects 2016-04-20 16:15:53 +00:00
Tim Shannon cf681a83f5 Updated build script, and addded environment option for projects 2016-04-20 18:38:53 +05:00
Tim Shannon 481c2574a6 Updated build script, and addded environment option for projects 2016-04-20 06:38:53 +05:00
9 changed files with 135 additions and 40 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,3 @@
#!/bin/bash
go-bindata web/... && go build -a -v -o ironsmith
go-bindata web/... && go build -a -o ironsmith

View File

@ -27,7 +27,7 @@ Project life cycle:
// load is the beginning of the cycle. Loads / reloads the project file to make sure that the scripts are up-to-date
// call's fetch and triggers the next poll if one exists
func (p *Project) load() {
func (p *Project) load(forceBuild bool) {
p.processing.Lock() // ensure only one cycle is running at a time per project
defer p.processing.Unlock()
@ -64,24 +64,25 @@ func (p *Project) load() {
p.setData(new)
p.fetch()
p.fetch(forceBuild)
p.setStage(stageWait)
//full cycle completed
p.errHandled(p.ds.TrimVersions(p.MaxVersions))
if p.poll > 0 {
//start polling
go func() {
time.AfterFunc(p.poll, p.load)
}()
time.AfterFunc(p.poll, func() {
p.load(false)
})
}
}
// fetch first runs the fetch script into a temporary directory
// then it runs the version script in the temp directory to see if there is a newer version of the
// fetched code, if there is then the temp dir is renamed to the version name
func (p *Project) fetch() {
func (p *Project) fetch(forceBuild bool) {
p.setStage(stageFetch)
p.start = time.Now()
@ -110,18 +111,20 @@ func (p *Project) fetch() {
p.setVersion(strings.TrimSpace(string(version)))
// check if this specific version has attempted a build yet
lVer, err := p.ds.LastVersion(stageBuild)
if err != datastore.ErrNotFound && p.errHandled(err) {
return
}
if !forceBuild {
// if not forced build, then check if this specific version has attempted a build yet
lVer, err := p.ds.LastVersion(stageBuild)
if err != datastore.ErrNotFound && p.errHandled(err) {
return
}
if p.version == "" || p.version == lVer.Version {
// no new build clean up temp dir
p.errHandled(os.RemoveAll(tempDir))
if p.version == "" || p.version == lVer.Version {
// no new build clean up temp dir
p.errHandled(os.RemoveAll(tempDir))
vlog("No new version found for Project: %s Version: %s.\n", p.id(), p.version)
return
vlog("No new version found for Project: %s Version: %s.\n", p.id(), p.version)
return
}
}
//remove any existing data that matches version hash

View File

@ -67,6 +67,83 @@ func (ds *Store) Close() error {
return ds.bolt.Close()
}
// TrimVersions Removes versions from the datastore file until it reaches the maxVersions count
func (ds *Store) TrimVersions(maxVersions int) error {
if maxVersions <= 0 {
// no max set
return nil
}
versions, err := ds.Versions()
if err != nil {
return err
}
if len(versions) <= maxVersions {
return nil
}
remove := versions[maxVersions:]
for i := range remove {
err = ds.deleteVersion(remove[i].Version)
if err != nil {
return err
}
}
return nil
}
// removes the earliest instance of a specific version
func (ds *Store) deleteVersion(version string) error {
return ds.bolt.Update(func(tx *bolt.Tx) error {
// remove all logs for this version
c := tx.Bucket([]byte(bucketLog)).Cursor()
for k, v := c.First(); k != nil; k, v = c.Next() {
lg := &Log{}
err := json.Unmarshal(v, lg)
if err != nil {
return err
}
if lg.Version != version {
break
}
err = c.Delete()
if err != nil {
return err
}
}
// remove all releases for this version
release, err := ds.Release(version)
if err == ErrNotFound {
return nil
}
if err != nil {
return err
}
err = tx.Bucket([]byte(bucketReleases)).Delete(release.FileKey.Bytes())
if err != nil {
return err
}
// remove release file for this version
err = tx.Bucket([]byte(bucketFiles)).Delete(release.FileKey.Bytes())
if err != nil {
return err
}
return nil
})
}
func (ds *Store) get(bucket string, key []byte, result interface{}) error {
return ds.bolt.View(func(tx *bolt.Tx) error {
dsValue := tx.Bucket([]byte(bucket)).Get(key)
@ -93,9 +170,3 @@ func (ds *Store) put(bucket string, key []byte, value interface{}) error {
return tx.Bucket([]byte(bucket)).Put(key, dsValue)
})
}
func (ds *Store) delete(bucket string, key []byte) error {
return ds.bolt.Update(func(tx *bolt.Tx) error {
return tx.Bucket([]byte(bucket)).Delete(key)
})
}

View File

@ -28,13 +28,13 @@ const (
// AddRelease adds a new Release
func (ds *Store) AddRelease(version, fileName string, fileData []byte) error {
fileKey := NewTimeKey()
key := NewTimeKey()
r := &Release{
When: fileKey.Time(),
When: key.Time(),
Version: version,
FileName: fileName,
FileKey: fileKey,
FileKey: key,
}
dsValue, err := json.Marshal(r)
@ -43,12 +43,12 @@ func (ds *Store) AddRelease(version, fileName string, fileData []byte) error {
}
return ds.bolt.Update(func(tx *bolt.Tx) error {
err = tx.Bucket([]byte(bucketReleases)).Put([]byte(version), dsValue)
err = tx.Bucket([]byte(bucketReleases)).Put(key.Bytes(), dsValue)
if err != nil {
return err
}
return tx.Bucket([]byte(bucketFiles)).Put(fileKey.Bytes(), fileData)
return tx.Bucket([]byte(bucketFiles)).Put(key.Bytes(), fileData)
})
}
@ -80,10 +80,27 @@ func (ds *Store) ReleaseFile(fileKey TimeKey) ([]byte, error) {
// Release gets the release record for a specific version
func (ds *Store) Release(version string) (*Release, error) {
r := &Release{}
err := ds.get(bucketReleases, []byte(version), r)
err := ds.bolt.View(func(tx *bolt.Tx) error {
c := tx.Bucket([]byte(bucketReleases)).Cursor()
for k, v := c.Last(); k != nil; k, v = c.Prev() {
err := json.Unmarshal(v, r)
if err != nil {
return err
}
if r.Version == version {
return nil
}
}
return ErrNotFound
})
if err != nil {
return nil, err
}
return r, nil
}
@ -119,9 +136,8 @@ func (ds *Store) LastRelease() (*Release, error) {
r := &Release{}
err := ds.bolt.View(func(tx *bolt.Tx) error {
c := tx.Bucket([]byte(bucketReleases)).Cursor()
_, v := tx.Bucket([]byte(bucketReleases)).Cursor().Last()
_, v := c.First() // this is confusing
if v == nil {
return ErrNotFound
}

View File

@ -59,14 +59,14 @@ func lookPath(file string, env []string) (string, error) {
if err == nil {
return file, nil
}
return "", &exec.Error{file, err}
return "", &exec.Error{Name: file, Err: err}
}
for i := range env {
if strings.HasPrefix(env[i], "PATH=") {
pathenv := env[i][5:]
if pathenv == "" {
return "", &exec.Error{file, exec.ErrNotFound}
return "", &exec.Error{Name: file, Err: exec.ErrNotFound}
}
for _, dir := range strings.Split(pathenv, ":") {
if dir == "" {
@ -78,7 +78,7 @@ func lookPath(file string, env []string) (string, error) {
return path, nil
}
}
return "", &exec.Error{file, exec.ErrNotFound}
return "", &exec.Error{Name: file, Err: exec.ErrNotFound}
}
}

View File

@ -60,6 +60,7 @@ type Project struct {
ReleaseFile string `json:"releaseFile"`
PollInterval string `json:"pollInterval,omitempty"` // if not poll interval is specified, this project is trigger only
TriggerSecret string `json:"triggerSecret,omitempty"` //secret to be included with a trigger call
MaxVersions int `json:"maxVersions,omitempty"` // Max number of versions to keep in the project datastore
filename string
poll time.Duration
@ -287,6 +288,7 @@ func (p *Project) setData(new *Project) {
p.ReleaseFile = new.ReleaseFile
p.PollInterval = new.PollInterval
p.TriggerSecret = new.TriggerSecret
p.MaxVersions = new.MaxVersions
if p.PollInterval != "" {
var err error
@ -324,6 +326,8 @@ var projectTemplate = &Project{
ReleaseFile: "release.tar.gz",
PollInterval: "15m",
MaxVersions: 100,
}
func prepTemplateProject() error {
@ -423,7 +427,7 @@ func (p *projectList) add(name string) {
log.Printf("Error opening datastore for Project: %s Error: %s\n", prj.id(), err)
return
}
prj.load()
prj.load(false)
}()
}

View File

@ -177,7 +177,7 @@
<td>
<a href="/project/{{.id}}/{{.lastLog.version}}">{{.lastLog.version}}</a>
</td>
<td title="{{.lastLog.log}}">{{#if .lastLog.log && .lastLog.length > 100}}{{.lastLog.log.substring(0,100)}}...{{else}}{{.lastLog.log}}{{/if}}</td>
<td title="{{.lastLog.log}}">{{#if .lastLog.log && .lastLog.log.length > 150}}{{.lastLog.log.substring(0,150)}}...{{else}}{{.lastLog.log}}{{/if}}</td>
<td>
<a href="/project/{{.id}}/{{.releaseVersion}}">{{.releaseVersion}}</a>
</td>
@ -213,7 +213,7 @@
<a href="/project/{{project.id}}/{{.version}}">{{.version}}</a>
</td>
<td>{{.stage}}</td>
<td title="{{.log}}">{{#if .log && .log.length > 100}}{{.log.substring(0,100)}}...{{else}}{{.log}}{{/if}}</td>
<td title="{{.log}}">{{#if .log && .log.length > 150}}{{.log.substring(0,150)}}...{{else}}{{.log}}{{/if}}</td>
<td>
{{#if releases[project.id + .version]}}
<a href="/release/{{project.id}}/{{.version}}?file">{{releases[project.id + .version].fileName}}</a>

View File

@ -259,6 +259,6 @@ func triggerPost(w http.ResponseWriter, r *http.Request) {
}
go func() {
project.load()
project.load(true)
}()
}