diff --git a/frontend/client/views/overview/index.vue b/frontend/client/views/overview/index.vue index 2a107750..68ac7f0f 100755 --- a/frontend/client/views/overview/index.vue +++ b/frontend/client/views/overview/index.vue @@ -6,13 +6,14 @@
-
- +
+
-
+ -
+
+
this is some text ...
@@ -138,4 +139,29 @@ export default { float: left; } +.outer-box-icon-image { + float: left; + width: 40px; + height: 40px; + overflow: hidden; + border-radius: 50%; + position: relative; + border-color: whitesmoke; + border-style: solid; + margin-right: 10px; +} + +.outer-box-image { + position: absolute; + width: 50px; + height: 50px; + top: 70%; + left: 50%; + transform: translate(-50%, -50%); +} + +.name-link { + margin-top: 5px; +} + diff --git a/gaia.go b/gaia.go index 6d890bb0..292c57db 100644 --- a/gaia.go +++ b/gaia.go @@ -29,10 +29,12 @@ type User struct { // Pipeline represents a single pipeline type Pipeline struct { - Name string `json:"name"` - Repo GitRepo `json:"repo"` - Type PipelineType `json:"type"` - Created time.Time `json:"created"` + Name string `json:"name"` + Repo GitRepo `json:"repo"` + Type PipelineType `json:"type"` + ExecPath string `json:"execpath"` + Jobs []Job `json:"jobs"` + Created time.Time `json:"created"` } // GitRepo represents a single git repository @@ -46,6 +48,14 @@ type GitRepo struct { LocalDest string } +// Job represents a single job of a pipeline +type Job struct { + UniqueID string `json:"id"` + Title string `json:"title"` + Description string `json:"desc"` + Priority int32 `json:"priority"` +} + // CreatePipeline represents a pipeline which is not yet // compiled. type CreatePipeline struct { diff --git a/pipeline/pipeline.go b/pipeline/pipeline.go index e934fe35..cad9818c 100644 --- a/pipeline/pipeline.go +++ b/pipeline/pipeline.go @@ -1,7 +1,9 @@ package pipeline import ( + "errors" "fmt" + "os/exec" "sync" "github.com/gaia-pipeline/gaia" @@ -47,6 +49,10 @@ const ( var ( // GlobalActivePipelines holds globally all current active pipleines. GlobalActivePipelines *ActivePipelines + + // errMissingType is the error thrown when a pipeline is missing the type + // in the file name. + errMissingType = errors.New("couldnt find pipeline type definition") ) // NewBuildPipeline creates a new build pipeline for the given @@ -65,6 +71,22 @@ func NewBuildPipeline(t gaia.PipelineType) BuildPipeline { return bP } +// createPipelineCmd creates the execute command for the plugin system +// dependent on the plugin type. +func createPipelineCmd(p *gaia.Pipeline) *exec.Cmd { + c := &exec.Cmd{} + + // Dependent on the pipeline type + switch p.Type { + case gaia.GOLANG: + c.Path = p.ExecPath + default: + c = nil + } + + return c +} + // NewActivePipelines creates a new instance of ActivePipelines func NewActivePipelines() *ActivePipelines { ap := &ActivePipelines{ diff --git a/pipeline/scheduler.go b/pipeline/scheduler.go new file mode 100644 index 00000000..0262f312 --- /dev/null +++ b/pipeline/scheduler.go @@ -0,0 +1,36 @@ +package pipeline + +import ( + "github.com/gaia-pipeline/gaia" + "github.com/gaia-pipeline/gaia/plugin" +) + +// setPipelineJobs uses the plugin system to get all +// jobs from the given pipeline. +// This function is blocking and might take some time. +func setPipelineJobs(p *gaia.Pipeline) { + // Create the start command for the pipeline + c := createPipelineCmd(p) + if c == nil { + gaia.Cfg.Logger.Debug("cannot set pipeline jobs", "error", errMissingType.Error(), "pipeline", p) + return + } + + // Create new plugin instance + pC := plugin.NewPlugin(c) + + // Connect to plugin(pipeline) + if err := pC.Connect(); err != nil { + gaia.Cfg.Logger.Debug("cannot connect to pipeline", "error", err.Error(), "pipeline", p) + return + } + defer pC.Close() + + // Get jobs + jobs, err := pC.GetJobs() + if err != nil { + gaia.Cfg.Logger.Debug("cannot get jobs from pipeline", "error", err.Error(), "pipeline", p) + return + } + p.Jobs = jobs +} diff --git a/pipeline/ticker.go b/pipeline/ticker.go index 2c72f7b3..742de8eb 100644 --- a/pipeline/ticker.go +++ b/pipeline/ticker.go @@ -1,8 +1,8 @@ package pipeline import ( - "errors" "io/ioutil" + "os" "strings" "time" @@ -15,12 +15,6 @@ const ( tickerIntervalSeconds = 5 ) -var ( - // errMissingType is the error thrown when a pipeline is missing the type - // in the file name. - errMissingType = errors.New("couldnt find pipeline type definition") -) - // InitTicker inititates the pipeline ticker. // This periodic job will check for new pipelines. func InitTicker() { @@ -72,11 +66,15 @@ func checkActivePipelines() { // Create pipeline object and fill it with information p := gaia.Pipeline{ - Name: pName, - Type: pType, - Created: time.Now(), + Name: pName, + Type: pType, + ExecPath: gaia.Cfg.PipelinePath + string(os.PathSeparator) + file.Name(), + Created: time.Now(), } + // Let us try to start the plugin and receive all implemented jobs + setPipelineJobs(&p) + // Append new pipeline GlobalActivePipelines.Append(p) } diff --git a/plugin/plugin.go b/plugin/plugin.go index 3557a829..147df074 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -2,8 +2,10 @@ package plugin import ( "errors" + "io" "os/exec" + "github.com/gaia-pipeline/gaia" "github.com/gaia-pipeline/gaia/proto" plugin "github.com/hashicorp/go-plugin" ) @@ -82,12 +84,50 @@ func (p *Plugin) Execute(j *proto.Job) error { return err } +// GetJobs receives all implemented jobs from the given plugin. +func (p *Plugin) GetJobs() ([]gaia.Job, error) { + l := []gaia.Job{} + + // Get the stream + stream, err := p.pluginConn.GetJobs() + if err != nil { + return nil, err + } + + // receive all jobs + for { + job, err := (*stream).Recv() + + // Got all jobs + if err == io.EOF { + break + } + + // Error during stream + if err != nil { + return nil, err + } + + // Convert proto object to gaia.Job struct + j := gaia.Job{ + UniqueID: job.UniqueId, + Title: job.Title, + Description: job.Description, + Priority: job.Priority, + } + l = append(l, j) + } + + // return list + return l, nil +} + // Close shutdown the plugin and kills the gRPC connection. // Remember to call this when you call plugin.Connect. func (p *Plugin) Close() { // We start the kill command in a goroutine because kill // is blocking until the subprocess successfully exits. - // The user should not notice the stopping process. + // The user should not wait for this. go func() { p.client.Kill() }()