aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastien Douheret <sebastien.douheret@iot.bzh>2017-05-18 11:01:13 +0200
committerSebastien Douheret <sebastien.douheret@iot.bzh>2017-05-18 11:01:13 +0200
commit2c9ae6a5a27ae2f2e23495c613e7a53aed8e786c (patch)
treeb23dbe9051c50a7ed8f666ae71c833fd52823770
parent51da3506a296b7d5d4185b17364f188292136888 (diff)
Add Cross SDKs support (part 2)
-rw-r--r--.vscode/settings.json4
-rw-r--r--lib/apiv1/apiv1.go8
-rw-r--r--lib/apiv1/make.go12
-rw-r--r--lib/apiv1/sdks.go31
-rw-r--r--lib/crosssdk/sdk.go22
-rw-r--r--lib/crosssdk/sdks.go57
-rw-r--r--lib/model/folder.go9
-rw-r--r--lib/syncthing/st.go2
-rw-r--r--lib/syncthing/stfolder.go14
-rw-r--r--lib/webserver/server.go2
-rw-r--r--lib/xdsconfig/folderconfig.go4
-rw-r--r--main.go7
-rw-r--r--webapp/src/app/app.module.ts11
-rw-r--r--webapp/src/app/build/build.component.html10
-rw-r--r--webapp/src/app/build/build.component.ts16
-rw-r--r--webapp/src/app/common/config.service.ts2
-rw-r--r--webapp/src/app/common/sdk.service.ts43
-rw-r--r--webapp/src/app/common/xdsserver.service.ts15
-rw-r--r--webapp/src/app/config/config.component.html11
-rw-r--r--webapp/src/app/config/config.component.ts9
-rw-r--r--webapp/src/app/sdks/sdkCard.component.ts51
-rw-r--r--webapp/src/app/sdks/sdkSelectDropdown.component.ts44
-rw-r--r--webapp/src/app/sdks/sdksListAccordion.component.ts26
23 files changed, 360 insertions, 50 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 9023297..8274151 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -17,7 +17,7 @@
"cSpell.words": [
"apiv", "gonic", "devel", "csrffound", "Syncthing", "STID",
"ISTCONFIG", "socketio", "ldflags", "SThg", "Intf", "dismissible",
- "rpath", "WSID", "sess", "IXDS", "xdsconfig", "xdsserver", "mfolder",
- "inotify", "Inot", "pname", "pkill"
+ "rpath", "WSID", "sess", "IXDS", "xdsconfig", "xdsserver", "mfolder",
+ "inotify", "Inot", "pname", "pkill", "sdkid", "CLOUDSYNC"
]
} \ No newline at end of file
diff --git a/lib/apiv1/apiv1.go b/lib/apiv1/apiv1.go
index c94849d..7359266 100644
--- a/lib/apiv1/apiv1.go
+++ b/lib/apiv1/apiv1.go
@@ -4,6 +4,7 @@ import (
"github.com/Sirupsen/logrus"
"github.com/gin-gonic/gin"
+ "github.com/iotbzh/xds-server/lib/crosssdk"
"github.com/iotbzh/xds-server/lib/model"
"github.com/iotbzh/xds-server/lib/session"
"github.com/iotbzh/xds-server/lib/xdsconfig"
@@ -16,17 +17,19 @@ type APIService struct {
sessions *session.Sessions
cfg *xdsconfig.Config
mfolder *model.Folder
+ sdks *crosssdk.SDKs
log *logrus.Logger
}
// New creates a new instance of API service
-func New(sess *session.Sessions, cfg *xdsconfig.Config, mfolder *model.Folder, r *gin.Engine) *APIService {
+func New(r *gin.Engine, sess *session.Sessions, cfg *xdsconfig.Config, mfolder *model.Folder, sdks *crosssdk.SDKs) *APIService {
s := &APIService{
router: r,
sessions: sess,
apiRouter: r.Group("/api/v1"),
cfg: cfg,
mfolder: mfolder,
+ sdks: sdks,
log: cfg.Log,
}
@@ -40,6 +43,9 @@ func New(sess *session.Sessions, cfg *xdsconfig.Config, mfolder *model.Folder, r
s.apiRouter.POST("/folder", s.addFolder)
s.apiRouter.DELETE("/folder/:id", s.delFolder)
+ s.apiRouter.GET("/sdks", s.getSdks)
+ s.apiRouter.GET("/sdk/:id", s.getSdk)
+
s.apiRouter.POST("/make", s.buildMake)
s.apiRouter.POST("/make/:id", s.buildMake)
diff --git a/lib/apiv1/make.go b/lib/apiv1/make.go
index 1e6d937..fb6435e 100644
--- a/lib/apiv1/make.go
+++ b/lib/apiv1/make.go
@@ -14,8 +14,9 @@ import (
// MakeArgs is the parameters (json format) of /make command
type MakeArgs struct {
ID string `json:"id"`
- RPath string `json:"rpath"` // relative path into project
- Args string `json:"args"`
+ RPath string `json:"rpath"` // relative path into project
+ Args string `json:"args"` // args to pass to make command
+ SdkID string `json:"sdkid"` // sdk ID to use for setting env
CmdTimeout int `json:"timeout"` // command completion timeout in Second
}
@@ -138,9 +139,10 @@ func (s *APIService) buildMake(c *gin.Context) {
cmdID := makeCommandID
makeCommandID++
- /* SEB TODO . /opt/poky-agl/3.90.0+snapshot/environment-setup-aarch64-agl-linux
- env := os.Environ()
- */
+ // Retrieve env command regarding Sdk ID
+ if envCmd := s.sdks.GetEnvCmd(args.SdkID, prj.DefaultSdk); envCmd != "" {
+ cmd = envCmd + " && " + cmd
+ }
s.log.Debugf("Execute [Cmd ID %d]: %v", cmdID, cmd)
err := common.ExecPipeWs(cmd, sop, sess.ID, cmdID, execTmo, s.log, oCB, eCB)
diff --git a/lib/apiv1/sdks.go b/lib/apiv1/sdks.go
new file mode 100644
index 0000000..5ae2b03
--- /dev/null
+++ b/lib/apiv1/sdks.go
@@ -0,0 +1,31 @@
+package apiv1
+
+import (
+ "net/http"
+ "strconv"
+
+ "github.com/gin-gonic/gin"
+ "github.com/iotbzh/xds-server/lib/common"
+)
+
+// getSdks returns all SDKs configuration
+func (s *APIService) getSdks(c *gin.Context) {
+ c.JSON(http.StatusOK, s.sdks.GetAll())
+}
+
+// getSdk returns a specific Sdk configuration
+func (s *APIService) getSdk(c *gin.Context) {
+ id, err := strconv.Atoi(c.Param("id"))
+ if err != nil {
+ common.APIError(c, "Invalid id")
+ return
+ }
+
+ sdk := s.sdks.Get(id)
+ if sdk.Profile == "" {
+ common.APIError(c, "Invalid id")
+ return
+ }
+
+ c.JSON(http.StatusOK, sdk)
+}
diff --git a/lib/crosssdk/sdk.go b/lib/crosssdk/sdk.go
index 2f22f22..9aeec90 100644
--- a/lib/crosssdk/sdk.go
+++ b/lib/crosssdk/sdk.go
@@ -2,17 +2,20 @@ package crosssdk
import (
"fmt"
- "path"
"path/filepath"
)
// SDK Define a cross tool chain used to build application
type SDK struct {
- Profile string
- Version string
- Arch string
- Path string
- EnvFile string
+ ID string `json:"id" binding:"required"`
+ Name string `json:"name"`
+ Profile string `json:"profile"`
+ Version string `json:"version"`
+ Arch string `json:"arch"`
+ Path string `json:"path"`
+
+ // Not exported fields
+ EnvFile string `json:"-"`
}
// NewCrossSDK creates a new instance of Syncthing
@@ -28,6 +31,9 @@ func NewCrossSDK(path string) (*SDK, error) {
d = filepath.Dir(d)
s.Profile = filepath.Base(d)
+ s.ID = s.Profile + "_" + s.Arch + "_" + s.Version
+ s.Name = s.Arch + " (" + s.Version + ")"
+
envFile := filepath.Join(path, "environment-setup*")
ef, err := filepath.Glob(envFile)
if err != nil {
@@ -41,7 +47,7 @@ func NewCrossSDK(path string) (*SDK, error) {
return &s, nil
}
-// GetEnvCmd returns the command to initialized the environment to use a cross SDK
+// GetEnvCmd returns the command used to initialized the environment
func (s *SDK) GetEnvCmd() string {
- return ". " + path.Join(s.Path, s.EnvFile)
+ return ". " + s.EnvFile
}
diff --git a/lib/crosssdk/sdks.go b/lib/crosssdk/sdks.go
index 435aae6..87bb85d 100644
--- a/lib/crosssdk/sdks.go
+++ b/lib/crosssdk/sdks.go
@@ -3,6 +3,7 @@ package crosssdk
import (
"path"
"path/filepath"
+ "sync"
"github.com/Sirupsen/logrus"
"github.com/iotbzh/xds-server/lib/common"
@@ -10,7 +11,11 @@ import (
)
// SDKs List of installed SDK
-type SDKs []*SDK
+type SDKs struct {
+ Sdks []SDK
+
+ mutex sync.Mutex
+}
// Init creates a new instance of Syncthing
func Init(cfg *xdsconfig.Config, log *logrus.Logger) (*SDKs, error) {
@@ -27,13 +32,61 @@ func Init(cfg *xdsconfig.Config, log *logrus.Logger) (*SDKs, error) {
log.Debugf("Error while retrieving SDKs: dir=%s, error=%s", sdkRD, err.Error())
return &s, err
}
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+
for _, d := range dirs {
sdk, err := NewCrossSDK(d)
if err != nil {
log.Debugf("Error while processing SDK dir=%s, err=%s", d, err.Error())
}
- s = append(s, sdk)
+ s.Sdks = append(s.Sdks, *sdk)
}
}
+
+ log.Debugf("SDKs: %d cross sdks found", len(s.Sdks))
+
return &s, nil
}
+
+// GetAll returns all existing SDKs
+func (s *SDKs) GetAll() []SDK {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ res := s.Sdks
+ return res
+}
+
+// Get returns an SDK from id
+func (s *SDKs) Get(id int) SDK {
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+
+ if id < 0 || id > len(s.Sdks) {
+ return SDK{}
+ }
+ res := s.Sdks[id]
+ return res
+}
+
+// GetEnvCmd returns the command used to initialized the environment for an SDK
+func (s *SDKs) GetEnvCmd(id string, defaultID string) string {
+ if id == "" && defaultID == "" {
+ // no env cmd
+ return ""
+ }
+
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ defaultEnv := ""
+ for _, sdk := range s.Sdks {
+ if sdk.ID == id {
+ return sdk.GetEnvCmd()
+ }
+ if sdk.ID == defaultID {
+ defaultEnv = sdk.GetEnvCmd()
+ }
+ }
+ // Return default env that may be empty
+ return defaultEnv
+}
diff --git a/lib/model/folder.go b/lib/model/folder.go
index 6687b68..be1bc33 100644
--- a/lib/model/folder.go
+++ b/lib/model/folder.go
@@ -71,13 +71,8 @@ func (c *Folder) UpdateFolder(newFolder xdsconfig.FolderConfig) (xdsconfig.Folde
c.Conf.Folders = c.Conf.Folders.Update(xdsconfig.FoldersConfig{newFolder})
- err := c.SThg.FolderChange(st.FolderChangeArg{
- ID: newFolder.ID,
- Label: newFolder.Label,
- RelativePath: newFolder.RelativePath,
- SyncThingID: newFolder.SyncThingID,
- ShareRootDir: c.Conf.ShareRootDir,
- })
+ err := c.SThg.FolderChange(newFolder)
+
newFolder.BuilderSThgID = c.Conf.Builder.SyncThingID // FIXME - should be removed after local ST config rework
newFolder.Status = xdsconfig.FolderStatusEnable
diff --git a/lib/syncthing/st.go b/lib/syncthing/st.go
index 841901d..957dd65 100644
--- a/lib/syncthing/st.go
+++ b/lib/syncthing/st.go
@@ -38,6 +38,7 @@ type SyncThing struct {
logsDir string
exitSTChan chan ExitChan
exitSTIChan chan ExitChan
+ conf *xdsconfig.Config
client *common.HTTPClient
log *logrus.Logger
}
@@ -85,6 +86,7 @@ func NewSyncThing(conf *xdsconfig.Config, log *logrus.Logger) *SyncThing {
binDir: binDir,
logsDir: conf.FileConf.LogsDir,
log: log,
+ conf: conf,
}
return &s
diff --git a/lib/syncthing/stfolder.go b/lib/syncthing/stfolder.go
index d79e579..45ac60d 100644
--- a/lib/syncthing/stfolder.go
+++ b/lib/syncthing/stfolder.go
@@ -4,21 +4,13 @@ import (
"path/filepath"
"strings"
+ "github.com/iotbzh/xds-server/lib/xdsconfig"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/protocol"
)
-// FIXME remove and use an interface on xdsconfig.FolderConfig
-type FolderChangeArg struct {
- ID string
- Label string
- RelativePath string
- SyncThingID string
- ShareRootDir string
-}
-
// FolderChange is called when configuration has changed
-func (s *SyncThing) FolderChange(f FolderChangeArg) error {
+func (s *SyncThing) FolderChange(f xdsconfig.FolderConfig) error {
// Get current config
stCfg, err := s.ConfigGet()
@@ -63,7 +55,7 @@ func (s *SyncThing) FolderChange(f FolderChangeArg) error {
folder := config.FolderConfiguration{
ID: id,
Label: label,
- RawPath: filepath.Join(f.ShareRootDir, f.RelativePath),
+ RawPath: filepath.Join(s.conf.ShareRootDir, f.RelativePath),
}
folder.Devices = append(folder.Devices, config.FolderDeviceConfiguration{
diff --git a/lib/webserver/server.go b/lib/webserver/server.go
index 40ce948..0905c77 100644
--- a/lib/webserver/server.go
+++ b/lib/webserver/server.go
@@ -83,7 +83,7 @@ func (s *Server) Serve() error {
s.sessions = session.NewClientSessions(s.router, s.log, cookieMaxAge)
// Create REST API
- s.api = apiv1.New(s.sessions, s.cfg, s.mfolder, s.router)
+ s.api = apiv1.New(s.router, s.sessions, s.cfg, s.mfolder, s.sdks)
// Websocket routes
s.sIOServer, err = socketio.NewServer(nil)
diff --git a/lib/xdsconfig/folderconfig.go b/lib/xdsconfig/folderconfig.go
index e32f46a..bb2b56f 100644
--- a/lib/xdsconfig/folderconfig.go
+++ b/lib/xdsconfig/folderconfig.go
@@ -29,13 +29,14 @@ type FolderConfig struct {
SyncThingID string `json:"syncThingID"`
BuilderSThgID string `json:"builderSThgID"`
Status string `json:"status"`
+ DefaultSdk string `json:"defaultSdk"`
// Not exported fields
RootPath string `json:"-"`
}
// NewFolderConfig creates a new folder object
-func NewFolderConfig(id, label, rootDir, path string) FolderConfig {
+func NewFolderConfig(id, label, rootDir, path string, defaultSdk string) FolderConfig {
return FolderConfig{
ID: id,
Label: label,
@@ -44,6 +45,7 @@ func NewFolderConfig(id, label, rootDir, path string) FolderConfig {
SyncThingID: "",
Status: FolderStatusDisable,
RootPath: rootDir,
+ DefaultSdk: defaultSdk,
}
}
diff --git a/main.go b/main.go
index 36586cf..6594bdb 100644
--- a/main.go
+++ b/main.go
@@ -168,6 +168,10 @@ func xdsApp(cliCtx *cli.Context) error {
}
// Retrieve initial Syncthing config
+
+ // FIXME: cannot retrieve default SDK, need to save on disk or somewhere
+ // else all config to be able to restore it.
+ defaultSdk := ""
stCfg, err := ctx.SThg.ConfigGet()
if err != nil {
return cli.NewExitError(err, 2)
@@ -177,7 +181,8 @@ func xdsApp(cliCtx *cli.Context) error {
if relativePath == "" {
relativePath = stFld.RawPath
}
- newFld := xdsconfig.NewFolderConfig(stFld.ID, stFld.Label, ctx.Config.ShareRootDir, strings.Trim(relativePath, "/"))
+
+ newFld := xdsconfig.NewFolderConfig(stFld.ID, stFld.Label, ctx.Config.ShareRootDir, strings.Trim(relativePath, "/"), defaultSdk)
ctx.Config.Folders = ctx.Config.Folders.Update(xdsconfig.FoldersConfig{newFld})
}
diff --git a/webapp/src/app/app.module.ts b/webapp/src/app/app.module.ts
index 5c33e43..d4a6918 100644
--- a/webapp/src/app/app.module.ts
+++ b/webapp/src/app/app.module.ts
@@ -19,12 +19,17 @@ import { ConfigComponent } from "./config/config.component";
import { ProjectCardComponent } from "./projects/projectCard.component";
import { ProjectReadableTypePipe } from "./projects/projectCard.component";
import { ProjectsListAccordionComponent } from "./projects/projectsListAccordion.component";
+import { SdkCardComponent } from "./sdks/sdkCard.component";
+import { SdksListAccordionComponent } from "./sdks/sdksListAccordion.component";
+import { SdkSelectDropdownComponent } from "./sdks/sdkSelectDropdown.component";
+
import { HomeComponent } from "./home/home.component";
import { BuildComponent } from "./build/build.component";
import { XDSServerService } from "./common/xdsserver.service";
import { SyncthingService } from "./common/syncthing.service";
import { ConfigService } from "./common/config.service";
import { AlertService } from './common/alert.service';
+import { SdkService } from "./common/sdk.service";
@@ -51,6 +56,9 @@ import { AlertService } from './common/alert.service';
ProjectCardComponent,
ProjectReadableTypePipe,
ProjectsListAccordionComponent,
+ SdkCardComponent,
+ SdksListAccordionComponent,
+ SdkSelectDropdownComponent,
],
providers: [
AppRoutingProviders,
@@ -61,7 +69,8 @@ import { AlertService } from './common/alert.service';
XDSServerService,
ConfigService,
SyncthingService,
- AlertService
+ AlertService,
+ SdkService,
],
bootstrap: [AppComponent]
})
diff --git a/webapp/src/app/build/build.component.html b/webapp/src/app/build/build.component.html
index d2a8da6..2ab7821 100644
--- a/webapp/src/app/build/build.component.html
+++ b/webapp/src/app/build/build.component.html
@@ -21,6 +21,16 @@
</div>
</div>
&nbsp;
+ <div class="row">
+ <div class="col-xs-8">
+ <label>Cross SDK </label>
+ <!-- FIXME why not working ?
+ <sdk-select-dropdown [sdks]="(sdks$ | async)"></sdk-select-dropdown>
+ -->
+ <sdk-select-dropdown></sdk-select-dropdown>
+ </div>
+ </div>
+ &nbsp;
<div class="row ">
<div class="col-xs-8 pull-left ">
<label>Sub-directory</label>
diff --git a/webapp/src/app/build/build.component.ts b/webapp/src/app/build/build.component.ts
index a1a965b..a99a1fe 100644
--- a/webapp/src/app/build/build.component.ts
+++ b/webapp/src/app/build/build.component.ts
@@ -8,6 +8,7 @@ import 'rxjs/add/operator/startWith';
import { XDSServerService, ICmdOutput } from "../common/xdsserver.service";
import { ConfigService, IConfig, IProject } from "../common/config.service";
import { AlertService, IAlert } from "../common/alert.service";
+import { SdkService } from "../common/sdk.service";
@Component({
selector: 'build',
@@ -32,8 +33,11 @@ export class BuildComponent implements OnInit, AfterViewChecked {
private startTime: Map<string, number> = new Map<string, number>();
// I initialize the app component.
- constructor(private configSvr: ConfigService, private sdkSvr: XDSServerService,
- private fb: FormBuilder, private alertSvr: AlertService
+ constructor(private configSvr: ConfigService,
+ private xdsSvr: XDSServerService,
+ private fb: FormBuilder,
+ private alertSvr: AlertService,
+ private sdkSvr: SdkService
) {
this.cmdOutput = "";
this.confValid = false;
@@ -54,12 +58,12 @@ export class BuildComponent implements OnInit, AfterViewChecked {
});
// Command output data tunneling
- this.sdkSvr.CmdOutput$.subscribe(data => {
+ this.xdsSvr.CmdOutput$.subscribe(data => {
this.cmdOutput += data.stdout + "\n";
});
// Command exit
- this.sdkSvr.CmdExit$.subscribe(exit => {
+ this.xdsSvr.CmdExit$.subscribe(exit => {
if (this.startTime.has(exit.cmdID)) {
this.cmdInfo = 'Last command duration: ' + this._computeTime(this.startTime.get(exit.cmdID));
this.startTime.delete(exit.cmdID);
@@ -93,7 +97,9 @@ export class BuildComponent implements OnInit, AfterViewChecked {
let t0 = performance.now();
this.cmdInfo = 'Start build of ' + prjID + ' at ' + t0;
- this.sdkSvr.make(prjID, this.buildForm.value.subpath, args)
+ let sdkid = this.sdkSvr.getCurrentId();
+
+ this.xdsSvr.make(prjID, this.buildForm.value.subpath, args, sdkid)
.subscribe(res => {
this.startTime.set(String(res.cmdID), t0);
},
diff --git a/webapp/src/app/common/config.service.ts b/webapp/src/app/common/config.service.ts
index 67ee14c..201ee8b 100644
--- a/webapp/src/app/common/config.service.ts
+++ b/webapp/src/app/common/config.service.ts
@@ -35,6 +35,7 @@ export interface IProject {
localPrjDef?: any;
isExpanded?: boolean;
visible?: boolean;
+ defaultSdkID?: string;
}
export interface ILocalSTConfig {
@@ -213,6 +214,7 @@ export class ConfigService {
label: prj.label,
path: prj.path,
hostSyncThingID: this.confStore.localSThg.ID,
+ defaultSdkID: prj.defaultSdkID,
};
// Send config to XDS server
diff --git a/webapp/src/app/common/sdk.service.ts b/webapp/src/app/common/sdk.service.ts
new file mode 100644
index 0000000..3f2f32a
--- /dev/null
+++ b/webapp/src/app/common/sdk.service.ts
@@ -0,0 +1,43 @@
+import { Injectable, SecurityContext } from '@angular/core';
+import { Observable } from 'rxjs/Observable';
+import { BehaviorSubject } from 'rxjs/BehaviorSubject';
+
+import { XDSServerService } from "../common/xdsserver.service";
+
+export interface ISdk {
+ id: string;
+ profile: string;
+ version: string;
+ arch: number;
+ path: string;
+}
+
+@Injectable()
+export class SdkService {
+ public Sdks$: Observable<ISdk[]>;
+
+ private _sdksList = [];
+ private current: ISdk;
+ private sdksSubject = <BehaviorSubject<ISdk[]>>new BehaviorSubject(this._sdksList);
+
+ constructor(private xdsSvr: XDSServerService) {
+ this.current = null;
+ this.Sdks$ = this.sdksSubject.asObservable();
+
+ this.xdsSvr.getSdks().subscribe((s) => {
+ this._sdksList = s;
+ this.sdksSubject.next(s);
+ });
+ }
+
+ public setCurrent(s: ISdk) {
+ this.current = s;
+ }
+
+ public getCurrentId(): string {
+ if (this.current && this.current.id) {
+ return this.current.id;
+ }
+ return "";
+ }
+} \ No newline at end of file
diff --git a/webapp/src/app/common/xdsserver.service.ts b/webapp/src/app/common/xdsserver.service.ts
index fd2e32a..6cd9ba3 100644
--- a/webapp/src/app/common/xdsserver.service.ts
+++ b/webapp/src/app/common/xdsserver.service.ts
@@ -7,6 +7,8 @@ import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import * as io from 'socket.io-client';
import { AlertService } from './alert.service';
+import { ISdk } from './sdk.service';
+
// Import RxJs required methods
import 'rxjs/add/operator/map';
@@ -20,6 +22,7 @@ export interface IXDSConfigProject {
path: string;
hostSyncThingID: string;
label?: string;
+ defaultSdkID?: string;
}
interface IXDSBuilderConfig {
@@ -36,6 +39,7 @@ interface IXDSFolderConfig {
syncThingID: string;
builderSThgID?: string;
status?: string;
+ defaultSdkID: string;
}
interface IXDSConfig {
@@ -136,6 +140,10 @@ export class XDSServerService {
}
+ getSdks(): Observable<ISdk[]> {
+ return this._get('/sdks');
+ }
+
getProjects(): Observable<IXDSFolderConfig[]> {
return this._get('/folders');
}
@@ -146,7 +154,8 @@ export class XDSServerService {
label: cfg.label || "",
path: cfg.path,
type: FOLDER_TYPE_CLOUDSYNC,
- syncThingID: cfg.hostSyncThingID
+ syncThingID: cfg.hostSyncThingID,
+ defaultSdkID: cfg.defaultSdkID || "",
};
return this._post('/folder', folder);
}
@@ -163,8 +172,8 @@ export class XDSServerService {
});
}
- make(prjID: string, dir: string, args: string): Observable<any> {
- return this._post('/make', { id: prjID, rpath: dir, args: args });
+ make(prjID: string, dir: string, args: string, sdkid?: string): Observable<any> {
+ return this._post('/make', { id: prjID, rpath: dir, args: args, sdkid: sdkid });
}
diff --git a/webapp/src/app/config/config.component.html b/webapp/src/app/config/config.component.html
index 45b0e14..2a3d322 100644
--- a/webapp/src/app/config/config.component.html
+++ b/webapp/src/app/config/config.component.html
@@ -40,6 +40,17 @@
<div class="panel panel-default">
<div class="panel-heading">
+ <h2 class="panel-title">Cross SDKs Configuration</h2>
+ </div>
+ <div class="panel-body">
+ <div class="row col-xs-12">
+ <sdks-list-accordion [sdks]="(sdks$ | async)"></sdks-list-accordion>
+ </div>
+ </div>
+</div>
+
+<div class="panel panel-default">
+ <div class="panel-heading">
<h2 class="panel-title">Projects Configuration</h2>
</div>
<div class="panel-body">
diff --git a/webapp/src/app/config/config.component.ts b/webapp/src/app/config/config.component.ts
index 681c296..745e9f6 100644
--- a/webapp/src/app/config/config.component.ts
+++ b/webapp/src/app/config/config.component.ts
@@ -11,6 +11,7 @@ import { ConfigService, IConfig, IProject, ProjectType } from "../common/config.
import { XDSServerService, IServerStatus } from "../common/xdsserver.service";
import { SyncthingService, ISyncThingStatus } from "../common/syncthing.service";
import { AlertService } from "../common/alert.service";
+import { ISdk, SdkService } from "../common/sdk.service";
@Component({
templateUrl: './app/config/config.component.html',
@@ -23,6 +24,7 @@ import { AlertService } from "../common/alert.service";
export class ConfigComponent implements OnInit {
config$: Observable<IConfig>;
+ sdks$: Observable<ISdk[]>;
severStatus$: Observable<IServerStatus>;
localSTStatus$: Observable<ISyncThingStatus>;
@@ -44,8 +46,9 @@ export class ConfigComponent implements OnInit {
constructor(
private configSvr: ConfigService,
- private sdkSvr: XDSServerService,
+ private xdsSvr: XDSServerService,
private stSvr: SyncthingService,
+ private sdkSvr: SdkService,
private alert: AlertService,
private fb: FormBuilder
) {
@@ -59,7 +62,8 @@ export class ConfigComponent implements OnInit {
ngOnInit() {
this.config$ = this.configSvr.conf;
- this.severStatus$ = this.sdkSvr.Status$;
+ this.sdks$ = this.sdkSvr.Sdks$;
+ this.severStatus$ = this.xdsSvr.Status$;
this.localSTStatus$ = this.stSvr.Status$;
// Bind syncToolUrl to baseURL
@@ -117,6 +121,7 @@ export class ConfigComponent implements OnInit {
label: formVal['label'],
path: formVal['path'],
type: ProjectType.SYNCTHING,
+ // FIXME: allow to set defaultSdkID from New Project config panel
});
}
diff --git a/webapp/src/app/sdks/sdkCard.component.ts b/webapp/src/app/sdks/sdkCard.component.ts
new file mode 100644
index 0000000..f5d2a54
--- /dev/null
+++ b/webapp/src/app/sdks/sdkCard.component.ts
@@ -0,0 +1,51 @@
+import { Component, Input } from '@angular/core';
+import { ISdk } from "../common/sdk.service";
+
+@Component({
+ selector: 'sdk-card',
+ template: `
+ <div class="row">
+ <div class="col-xs-12">
+ <div class="text-right" role="group">
+ <button disabled class="btn btn-link" (click)="delete(sdk)"><span class="fa fa-trash fa-size-x2"></span></button>
+ </div>
+ </div>
+ </div>
+
+ <table class="table table-striped">
+ <tbody>
+ <tr>
+ <th><span class="fa fa-fw fa-id-badge"></span>&nbsp;<span>Profile</span></th>
+ <td>{{ sdk.profile }}</td>
+ </tr>
+ <tr>
+ <th><span class="fa fa-fw fa-tasks"></span>&nbsp;<span>Architecture</span></th>
+ <td>{{ sdk.arch }}</td>
+ </tr>
+ <tr>
+ <th><span class="fa fa-fw fa-code-fork"></span>&nbsp;<span>Version</span></th>
+ <td>{{ sdk.version }}</td>
+ </tr>
+ <tr>
+ <th><span class="fa fa-fw fa-folder-open-o"></span>&nbsp;<span>Sdk path</span></th>
+ <td>{{ sdk.path}}</td>
+ </tr>
+
+ </tbody>
+ </table >
+ `,
+ styleUrls: ['./app/config/config.component.css']
+})
+
+export class SdkCardComponent {
+
+ @Input() sdk: ISdk;
+
+ constructor() { }
+
+
+ delete(sdk: ISdk) {
+ // Not supported for now
+ }
+
+}
diff --git a/webapp/src/app/sdks/sdkSelectDropdown.component.ts b/webapp/src/app/sdks/sdkSelectDropdown.component.ts
new file mode 100644
index 0000000..5122cd2
--- /dev/null
+++ b/webapp/src/app/sdks/sdkSelectDropdown.component.ts
@@ -0,0 +1,44 @@
+import { Component, Input } from "@angular/core";
+
+import { ISdk, SdkService } from "../common/sdk.service";
+
+@Component({
+ selector: 'sdk-select-dropdown',
+ template: `
+ <div class="btn-group" dropdown *ngIf="curSdk" >
+ <button dropdownToggle type="button" class="btn btn-primary dropdown-toggle" style="width: 20em;">
+ {{curSdk.name}} <span class="caret" style="float: right; margin-top: 8px;"></span>
+ </button>
+ <ul *dropdownMenu class="dropdown-menu" role="menu">
+ <li role="menuitem"><a class="dropdown-item" *ngFor="let sdk of sdks" (click)="select(sdk)">
+ {{sdk.name}}</a>
+ </li>
+ </ul>
+ </div>
+ `
+})
+export class SdkSelectDropdownComponent {
+
+ // FIXME investigate to understand why not working with sdks as input
+ // <sdk-select-dropdown [sdks]="(sdks$ | async)"></sdk-select-dropdown>
+ //@Input() sdks: ISdk[];
+ sdks: ISdk[];
+
+ curSdk: ISdk;
+
+ constructor(private sdkSvr: SdkService) { }
+
+ ngOnInit() {
+ this.sdkSvr.Sdks$.subscribe((s) => {
+ this.sdks = s;
+ this.curSdk = this.sdks.length ? this.sdks[0] : null;
+ this.sdkSvr.setCurrent(this.curSdk);
+ });
+ }
+
+ select(s) {
+ this.sdkSvr.setCurrent(this.curSdk = s);
+ }
+}
+
+
diff --git a/webapp/src/app/sdks/sdksListAccordion.component.ts b/webapp/src/app/sdks/sdksListAccordion.component.ts
new file mode 100644
index 0000000..9094f27
--- /dev/null
+++ b/webapp/src/app/sdks/sdksListAccordion.component.ts
@@ -0,0 +1,26 @@
+import { Component, Input } from "@angular/core";
+
+import { ISdk } from "../common/sdk.service";
+
+@Component({
+ selector: 'sdks-list-accordion',
+ template: `
+ <accordion>
+ <accordion-group #group *ngFor="let sdk of sdks">
+ <div accordion-heading>
+ {{ sdk.name }}
+ <i class="pull-right float-xs-right fa"
+ [ngClass]="{'fa-chevron-down': group.isOpen, 'fa-chevron-right': !group.isOpen}"></i>
+ </div>
+ <sdk-card [sdk]="sdk"></sdk-card>
+ </accordion-group>
+ </accordion>
+ `
+})
+export class SdksListAccordionComponent {
+
+ @Input() sdks: ISdk[];
+
+}
+
+