Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
deac844d02 | |||
80a3ba4621 | |||
|
774d0b446f | ||
|
ee1147a1a5 | ||
|
186b7d5b29 | ||
|
52eaa63f25 |
@ -3,8 +3,7 @@ import cliutils, docopt, os, sequtils, strutils, tempfile, uuids
|
|||||||
import strawbosspkg/configuration
|
import strawbosspkg/configuration
|
||||||
import strawbosspkg/core
|
import strawbosspkg/core
|
||||||
import strawbosspkg/server
|
import strawbosspkg/server
|
||||||
|
import strawbosspkg/version
|
||||||
let SB_VER = "0.5.0"
|
|
||||||
|
|
||||||
proc logProcOutput*(outMsg, errMsg: TaintedString, cmd: string) =
|
proc logProcOutput*(outMsg, errMsg: TaintedString, cmd: string) =
|
||||||
let prefix = if cmd.len > 0: cmd & ": " else: ""
|
let prefix = if cmd.len > 0: cmd & ": " else: ""
|
||||||
@ -26,7 +25,7 @@ Options
|
|||||||
(strawboss.config.json).
|
(strawboss.config.json).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
let args = docopt(doc, version = "strawboss v" & SB_VER)
|
let args = docopt(doc, version = "strawboss v" & SB_VERSION)
|
||||||
|
|
||||||
let cfgFile = if args["--config-file"]: $args["--config-file"]
|
let cfgFile = if args["--config-file"]: $args["--config-file"]
|
||||||
else: "strawboss.config.json"
|
else: "strawboss.config.json"
|
||||||
|
@ -58,6 +58,7 @@ type
|
|||||||
debug*: bool
|
debug*: bool
|
||||||
logLevel*: Level
|
logLevel*: Level
|
||||||
pathToExe*: string
|
pathToExe*: string
|
||||||
|
port*: int
|
||||||
projects*: seq[ProjectDef]
|
projects*: seq[ProjectDef]
|
||||||
pwdCost*: int8
|
pwdCost*: int8
|
||||||
users*: seq[UserRef]
|
users*: seq[UserRef]
|
||||||
@ -83,6 +84,7 @@ proc `==`*(a, b: StrawBossConfig): bool =
|
|||||||
a.buildDataDir == b.buildDataDir and
|
a.buildDataDir == b.buildDataDir and
|
||||||
a.authSecret == b.authSecret and
|
a.authSecret == b.authSecret and
|
||||||
a.pwdCost == b.pwdCost and
|
a.pwdCost == b.pwdCost and
|
||||||
|
a.port == b.port and
|
||||||
a.maintenancePeriod == b.maintenancePeriod and
|
a.maintenancePeriod == b.maintenancePeriod and
|
||||||
a.logLevel == b.logLevel and
|
a.logLevel == b.logLevel and
|
||||||
sameContents(a.users, b.users) and
|
sameContents(a.users, b.users) and
|
||||||
@ -144,6 +146,7 @@ proc parseStrawBossConfig*(jsonCfg: JsonNode): StrawBossConfig =
|
|||||||
buildDataDir: jsonCfg.getIfExists("buildDataDir").getStr("build-data"),
|
buildDataDir: jsonCfg.getIfExists("buildDataDir").getStr("build-data"),
|
||||||
authSecret: jsonCfg.getOrFail("authSecret", "strawboss config").getStr,
|
authSecret: jsonCfg.getOrFail("authSecret", "strawboss config").getStr,
|
||||||
debug: jsonCfg.getIfExists("debug").getBool(false),
|
debug: jsonCfg.getIfExists("debug").getBool(false),
|
||||||
|
port: int(jsonCfg.getIfExists("port").getInt(8180)),
|
||||||
pwdCost: int8(jsonCfg.getOrFail("pwdCost", "strawboss config").getInt),
|
pwdCost: int8(jsonCfg.getOrFail("pwdCost", "strawboss config").getInt),
|
||||||
projects: jsonCfg.getIfExists("projects").getElems.mapIt(parseProjectDef(it)),
|
projects: jsonCfg.getIfExists("projects").getElems.mapIt(parseProjectDef(it)),
|
||||||
maintenancePeriod: int(jsonCfg.getIfExists("maintenancePeriod").getInt(10000)),
|
maintenancePeriod: int(jsonCfg.getIfExists("maintenancePeriod").getInt(10000)),
|
||||||
@ -296,6 +299,7 @@ proc `%`*(cfg: StrawBossConfig): JsonNode =
|
|||||||
"buildDataDir": cfg.buildDataDir,
|
"buildDataDir": cfg.buildDataDir,
|
||||||
"authSecret": cfg.authSecret,
|
"authSecret": cfg.authSecret,
|
||||||
"debug": cfg.debug,
|
"debug": cfg.debug,
|
||||||
|
"port": cfg.port,
|
||||||
"projects": %cfg.projects,
|
"projects": %cfg.projects,
|
||||||
"pwdCost": cfg.pwdCost,
|
"pwdCost": cfg.pwdCost,
|
||||||
"maintenancePeriod": cfg.maintenancePeriod,
|
"maintenancePeriod": cfg.maintenancePeriod,
|
||||||
|
@ -7,7 +7,7 @@ from asyncnet import send
|
|||||||
from re import re, find
|
from re import re, find
|
||||||
from timeutils import trimNanoSec
|
from timeutils import trimNanoSec
|
||||||
|
|
||||||
import ./configuration, ./core
|
import ./configuration, ./core, ./version
|
||||||
|
|
||||||
type
|
type
|
||||||
Session = object
|
Session = object
|
||||||
@ -161,13 +161,13 @@ proc start*(cfg: StrawBossConfig): void =
|
|||||||
var workers: seq[Worker] = @[]
|
var workers: seq[Worker] = @[]
|
||||||
|
|
||||||
settings:
|
settings:
|
||||||
port = Port(8180)
|
port = Port(cfg.port)
|
||||||
appName = "/api"
|
appName = "/api"
|
||||||
|
|
||||||
routes:
|
routes:
|
||||||
|
|
||||||
get "/ping":
|
get "/version":
|
||||||
resp($(%"pong"), JSON)
|
resp($(%("strawboss v" & SB_VERSION)), JSON)
|
||||||
|
|
||||||
post "/auth-token":
|
post "/auth-token":
|
||||||
var uname, pwd: string
|
var uname, pwd: string
|
||||||
@ -180,7 +180,9 @@ proc start*(cfg: StrawBossConfig): void =
|
|||||||
try:
|
try:
|
||||||
let authToken = makeAuthToken(cfg, uname, pwd)
|
let authToken = makeAuthToken(cfg, uname, pwd)
|
||||||
resp($(%authToken), JSON)
|
resp($(%authToken), JSON)
|
||||||
except: jsonResp(Http401, getCurrentExceptionMsg())
|
except:
|
||||||
|
jsonResp(Http401, getCurrentExceptionMsg())
|
||||||
|
if ctx.cfg.debug: echo getStackTrace()
|
||||||
|
|
||||||
get "/verify-auth":
|
get "/verify-auth":
|
||||||
checkAuth()
|
checkAuth()
|
||||||
@ -266,17 +268,16 @@ proc start*(cfg: StrawBossConfig): void =
|
|||||||
|
|
||||||
checkAuth()
|
checkAuth()
|
||||||
|
|
||||||
|
var details = ""
|
||||||
try:
|
try:
|
||||||
let activeRuns = workers
|
let activeRuns = workers
|
||||||
.filterIt(it.process.running and it.projectName == @"projectName")
|
.filterIt(it.process.running and it.projectName == @"projectName")
|
||||||
.mapIt(cfg.getRun(@"projecName", $it.runId));
|
.mapIt(cfg.getRun(@"projectName", $it.runId));
|
||||||
resp($(%activeRuns), JSON)
|
resp($(%activeRuns), JSON)
|
||||||
|
except NotFoundException:
|
||||||
|
jsonResp(Http404, getCurrentExceptionMsg())
|
||||||
except:
|
except:
|
||||||
try: raise getCurrentException()
|
json500Resp(getCurrentException(), "problem loading active runs")
|
||||||
except NotFoundException:
|
|
||||||
jsonResp(Http404, getCurrentExceptionMsg())
|
|
||||||
except:
|
|
||||||
json500Resp(getCurrentException(), "problem loading active runs")
|
|
||||||
|
|
||||||
get "/project/@projectName/run/@runId":
|
get "/project/@projectName/run/@runId":
|
||||||
## Details for a specific run
|
## Details for a specific run
|
||||||
@ -446,7 +447,7 @@ proc start*(cfg: StrawBossConfig): void =
|
|||||||
|
|
||||||
|
|
||||||
get re".*":
|
get re".*":
|
||||||
jsonResp(Http404)
|
jsonResp(Http404, "URL [" & request.path & "] is not present on this server.")
|
||||||
|
|
||||||
post re".*":
|
post re".*":
|
||||||
jsonResp(Http404)
|
jsonResp(Http404)
|
||||||
|
2
src/main/nim/strawbosspkg/version.nim
Normal file
2
src/main/nim/strawbosspkg/version.nim
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
const SB_VERSION* = "0.5.1"
|
||||||
|
|
@ -6,6 +6,7 @@
|
|||||||
{ "name": "bob@builder.com", "hashedPwd": "$2a$11$lVZ9U4optQMhzPh0E9A7Yu6XndXblUF3gCa.zmEvJy4F.4C4718b." },
|
{ "name": "bob@builder.com", "hashedPwd": "$2a$11$lVZ9U4optQMhzPh0E9A7Yu6XndXblUF3gCa.zmEvJy4F.4C4718b." },
|
||||||
{ "name": "sam@sousa.com", "hashedPwd": "testvalue" }
|
{ "name": "sam@sousa.com", "hashedPwd": "testvalue" }
|
||||||
],
|
],
|
||||||
|
"port": 8180,
|
||||||
"pwdCost": 11,
|
"pwdCost": 11,
|
||||||
"projects": [
|
"projects": [
|
||||||
{ "name": "dummy-project",
|
{ "name": "dummy-project",
|
||||||
|
@ -2,6 +2,7 @@ import cliutils, httpclient, json, os, osproc, sequtils, strutils, tempfile,
|
|||||||
times, unittest, untar, uuids
|
times, unittest, untar, uuids
|
||||||
|
|
||||||
from langutils import sameContents
|
from langutils import sameContents
|
||||||
|
from algorithm import sorted
|
||||||
|
|
||||||
import ../testutil
|
import ../testutil
|
||||||
import ../../../main/nim/strawbosspkg/configuration
|
import ../../../main/nim/strawbosspkg/configuration
|
||||||
@ -205,9 +206,40 @@ suite "strawboss server":
|
|||||||
# Run the "build" step
|
# Run the "build" step
|
||||||
# Kick off a build that depends on "build" (which was run in the last test)
|
# Kick off a build that depends on "build" (which was run in the last test)
|
||||||
|
|
||||||
# TODO
|
test "kick off multiple runs and check the list of active runs via the API":
|
||||||
#test "kick off multiple runs and check the list of active runs via the API":
|
let http = newAuthenticatedHttpClient(apiBase, "bob@builder.com", "password")
|
||||||
# check false
|
|
||||||
|
# Kick off multiple runs of the "long-running" job
|
||||||
|
let queuedRuns = toSeq((1..3)).map(proc (idx: int): Run =
|
||||||
|
let resp = http.post(apiBase & "/project/" & testProjName & "/step/long-running/run/0.3.1")
|
||||||
|
check resp.status.startsWith("200")
|
||||||
|
|
||||||
|
return parseRun(parseJson(resp.body)))
|
||||||
|
|
||||||
|
# Collect run ids.
|
||||||
|
let runIds = queuedRuns.mapIt($(it.id)).sorted(cmpIgnoreCase)
|
||||||
|
|
||||||
|
# Check on the runs
|
||||||
|
let getActiveResp = http.get(apiBase & "/project/" & testProjName & "/runs/active")
|
||||||
|
check getActiveResp.status.startsWith("200")
|
||||||
|
|
||||||
|
let activeRuns = parseJson(getActiveResp.body).getElems().mapIt(parseRun(it))
|
||||||
|
let activeRunIds = activeRuns.mapIt($(it.id)).sorted(cmpIgnoreCase)
|
||||||
|
|
||||||
|
# Make sure we see all runs in the active state.
|
||||||
|
check runIds == activeRunIds
|
||||||
|
|
||||||
|
let completedRuns = runIds.map(proc (runId: string): Run =
|
||||||
|
return http.waitForBuild(apiBase, testProjName, runId))
|
||||||
|
|
||||||
|
# Make sure all are completed and all are accounted for
|
||||||
|
check completedRuns.allIt(it.status.state == BuildState.complete)
|
||||||
|
check completedRuns.mapIt($(it.id)).sorted(cmpIgnoreCase) == runIds;
|
||||||
|
|
||||||
|
# Check that there are no more active runs
|
||||||
|
let getActiveResp2 = http.get(apiBase & "/project/" & testProjName & "/runs/active")
|
||||||
|
let remainingActiveRuns = parseJson(getActiveResp2.body).getElems().mapIt(parseRun(it))
|
||||||
|
check remainingActiveRuns.len == 0
|
||||||
|
|
||||||
# Last-chance catch to kill the server in case some test err'ed and didn't
|
# Last-chance catch to kill the server in case some test err'ed and didn't
|
||||||
# reach it's teardown handler
|
# reach it's teardown handler
|
||||||
|
@ -6,6 +6,7 @@ from langutils import sameContents
|
|||||||
import ../testutil
|
import ../testutil
|
||||||
import ../../../main/nim/strawbosspkg/configuration
|
import ../../../main/nim/strawbosspkg/configuration
|
||||||
import ../../../main/nim/strawbosspkg/server
|
import ../../../main/nim/strawbosspkg/server
|
||||||
|
import ../../../main/nim/strawbosspkg/version
|
||||||
|
|
||||||
let apiBase = "http://localhost:8180/api"
|
let apiBase = "http://localhost:8180/api"
|
||||||
let cfgFilePath = "src/test/json/strawboss.config.json"
|
let cfgFilePath = "src/test/json/strawboss.config.json"
|
||||||
@ -40,11 +41,11 @@ suite "strawboss server":
|
|||||||
let tok = toJWT(cfg, session)
|
let tok = toJWT(cfg, session)
|
||||||
check fromJWT(cfg, tok) == session
|
check fromJWT(cfg, tok) == session
|
||||||
|
|
||||||
test "ping":
|
test "version":
|
||||||
let resp = http.get(apiBase & "/ping")
|
let resp = http.get(apiBase & "/version")
|
||||||
check:
|
check:
|
||||||
resp.status.startsWith("200")
|
resp.status.startsWith("200")
|
||||||
resp.body == "\"pong\""
|
resp.body == "\"strawboss v" & SB_VERSION & "\""
|
||||||
|
|
||||||
test "fail auth":
|
test "fail auth":
|
||||||
let resp = http.post(apiBase & "/auth-token",
|
let resp = http.post(apiBase & "/auth-token",
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 127be8f66fcc6d4d223acf56668d42ff9c37bfb0
|
Subproject commit ab883bd9602a1373347a23c8bee4ed28dd475aec
|
Binary file not shown.
@ -1,7 +1,7 @@
|
|||||||
# Package
|
# Package
|
||||||
|
|
||||||
bin = @["strawboss"]
|
bin = @["strawboss"]
|
||||||
version = "0.5.0"
|
version = "0.5.1"
|
||||||
author = "Jonathan Bernard"
|
author = "Jonathan Bernard"
|
||||||
description = "My personal continious integration worker."
|
description = "My personal continious integration worker."
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
@ -44,3 +44,8 @@ task test, "Runs both the unit and functional test suites.":
|
|||||||
echo "\nRunning functional tests."
|
echo "\nRunning functional tests."
|
||||||
echo "-------------------------"
|
echo "-------------------------"
|
||||||
exec "src/test/nim/run_functional_tests"
|
exec "src/test/nim/run_functional_tests"
|
||||||
|
|
||||||
|
task dist, "Creates distributable package.":
|
||||||
|
exec "nimble build"
|
||||||
|
mkdir "dist"
|
||||||
|
exec "cp strawboss strawboss.config.json example.json dist/."
|
||||||
|
@ -1,24 +1,25 @@
|
|||||||
{
|
{
|
||||||
"name": "strawboss",
|
"name": "strawboss",
|
||||||
|
"containerImage": "nimlang/nim:0.19.0",
|
||||||
"steps": {
|
"steps": {
|
||||||
"compile": {
|
"compile": {
|
||||||
"artifacts": ["strawboss"],
|
"artifacts": ["strawboss"],
|
||||||
"stepCmd": "docker run -v `pwd`:/usr/src/strawboss -w /usr/src/strawboss jdbernard/nim:0.17.2 nimble install"
|
"stepCmd": "nimble build"
|
||||||
},
|
},
|
||||||
"unittest": {
|
"unittest": {
|
||||||
"depends": ["compile"],
|
"depends": ["compile"],
|
||||||
"stepCmd": "docker run -v `pwd`:/usr/src/strawboss -v $compile_DIR:/usr/build/strawboss -w /usr/src/strawboss -i jdbernard/nim:0.17.2 /bin/bash",
|
"stepCmd": "/bin/bash",
|
||||||
"cmdInput": [
|
"cmdInput": [
|
||||||
"cp /usr/build/strawboss/strawboss .",
|
"cp $compile_DIR/strawboss .",
|
||||||
"nimble install --depsOnly",
|
"nimble install --depsOnly",
|
||||||
"nim c -r src/test/nim/run_unit_tests"
|
"nim c -r src/test/nim/run_unit_tests"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"functest": {
|
"functest": {
|
||||||
"depends": ["compile"],
|
"depends": ["compile"],
|
||||||
"stepCmd": "docker run -v `pwd`:/usr/src/strawboss -v $compile_DIR:/usr/build/strawboss -w /usr/src/strawboss -i jdbernard/nim:0.17.2 /bin/bash",
|
"stepCmd": "/bin/bash",
|
||||||
"cmdInput": [
|
"cmdInput": [
|
||||||
"cp /usr/build/strawboss/strawboss .",
|
"cp $compile_DIR/strawboss .",
|
||||||
"nimble install --depsOnly",
|
"nimble install --depsOnly",
|
||||||
"nim c -r src/test/nim/run_functional_tests"
|
"nim c -r src/test/nim/run_functional_tests"
|
||||||
]
|
]
|
||||||
@ -26,9 +27,9 @@
|
|||||||
"build": {
|
"build": {
|
||||||
"artifacts": ["strawboss-$VERSION.zip"],
|
"artifacts": ["strawboss-$VERSION.zip"],
|
||||||
"depends": ["compile", "unittest", "functest"],
|
"depends": ["compile", "unittest", "functest"],
|
||||||
"stepCmd": "docker run -v `pwd`:/usr/src/strawboss -v $compile_DIR:/usr/build/strawboss -w /usr/src/strawboss -i jdbernard/nim:0.17.2 /bin/bash",
|
"stepCmd": "/bin/bash",
|
||||||
"cmdInput": [
|
"cmdInput": [
|
||||||
"cp /usr/build/strawboss/strawboss .",
|
"cp $compile_DIR/strawboss .",
|
||||||
"zip strawboss-$VERSION.zip strawboss strawboss.config.json example.json src/main/systemd/strawboss.service"
|
"zip strawboss-$VERSION.zip strawboss strawboss.config.json example.json src/main/systemd/strawboss.service"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
11
test-spec.txt
Normal file
11
test-spec.txt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
Run a build. Look for:
|
||||||
|
- Run request archived
|
||||||
|
- Output logs archived with the run request
|
||||||
|
- Artifacts archived in the build-data directory.
|
||||||
|
- Configuration for that version archived in configurations directory.
|
||||||
|
- Status for that version archived in the status directory
|
||||||
|
|
||||||
|
Run the build again for the same project and build ref:
|
||||||
|
- Build should be skipped.
|
||||||
|
- Run request should be archived.
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user