Reworking runs to include an id, save the run request.
This commit is contained in:
		@@ -1,4 +1,4 @@
 | 
			
		||||
import docopt, os, sequtils, tempfile
 | 
			
		||||
import docopt, os, sequtils, tempfile, uuids
 | 
			
		||||
 | 
			
		||||
import strawbosspkg/private/util
 | 
			
		||||
import strawbosspkg/configuration
 | 
			
		||||
@@ -31,6 +31,9 @@ Options
 | 
			
		||||
 | 
			
		||||
  -r --reference <ref>        Build the project at this commit reference.
 | 
			
		||||
 | 
			
		||||
  -i --run-id <id>            Use the given UUID as the run ID. If not given, a
 | 
			
		||||
                              new UUID is generated for this run.
 | 
			
		||||
 | 
			
		||||
  -w --workspace <workspace>  Use the given directory as the build workspace.
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
@@ -51,14 +54,17 @@ Options
 | 
			
		||||
 | 
			
		||||
  if args["run"]:
 | 
			
		||||
 | 
			
		||||
    let req = RunRequest(
 | 
			
		||||
      projectName: $args["<project>"],
 | 
			
		||||
      stepName: $args["<step>"],
 | 
			
		||||
      buildRef: if args["--reference"]: $args["--reference"] else: nil,
 | 
			
		||||
      forceRebuild: args["--force-rebuild"],
 | 
			
		||||
      workspaceDir: if args["--workspace"]: $args["<workspace>"] else: mkdtemp())
 | 
			
		||||
    let wkspDir = if args["--workspace"]: $args["--workspace"] else: mkdtemp()
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
      let req = RunRequest(
 | 
			
		||||
        id: if args["--run-id"]: parseUUID($args["--run-id"]) else: genUUID(),
 | 
			
		||||
        projectName: $args["<project>"],
 | 
			
		||||
        stepName: $args["<step>"],
 | 
			
		||||
        buildRef: if args["--reference"]: $args["--reference"] else: nil,
 | 
			
		||||
        forceRebuild: args["--force-rebuild"],
 | 
			
		||||
        workspaceDir: wkspDir)
 | 
			
		||||
 | 
			
		||||
      let status = core.runStep(cfg, req, logProcOutput)
 | 
			
		||||
      if status.state == "failed": raiseEx status.details
 | 
			
		||||
      echo "strawboss: build passed."
 | 
			
		||||
@@ -66,7 +72,7 @@ Options
 | 
			
		||||
      echo "strawboss: build FAILED: " & getCurrentExceptionMsg() & "."
 | 
			
		||||
      quit(QuitFailure)
 | 
			
		||||
    finally:
 | 
			
		||||
      if existsDir(req.workspaceDir): removeDir(req.workspaceDir)
 | 
			
		||||
      if existsDir(wkspDir): removeDir(wkspDir)
 | 
			
		||||
 | 
			
		||||
  elif args["serve"]: server.start(cfg)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
import logging, json, os, nre, sequtils, strtabs, tables, times
 | 
			
		||||
import logging, json, os, nre, sequtils, strtabs, tables, times, uuids
 | 
			
		||||
import private/util
 | 
			
		||||
 | 
			
		||||
from langutils import sameContents
 | 
			
		||||
@@ -25,6 +25,7 @@ type
 | 
			
		||||
    envVars*: StringTableRef
 | 
			
		||||
 | 
			
		||||
  RunRequest* = object
 | 
			
		||||
    id*: UUID
 | 
			
		||||
    projectName*, stepName*, buildRef*, workspaceDir*: string
 | 
			
		||||
    forceRebuild*: bool
 | 
			
		||||
 | 
			
		||||
@@ -67,6 +68,15 @@ proc `==`*(a, b: StrawBossConfig): bool =
 | 
			
		||||
    sameContents(a.users, b.users) and
 | 
			
		||||
    sameContents(a.projects, b.projects)
 | 
			
		||||
 | 
			
		||||
proc `==`*(a, b: RunRequest): bool =
 | 
			
		||||
  result =
 | 
			
		||||
    a.id == b.id and
 | 
			
		||||
    a.projectName == b.projectName and
 | 
			
		||||
    a.stepName == b.stepName and
 | 
			
		||||
    a.buildRef == b.buildRef and
 | 
			
		||||
    a.workspaceDir == b.workspaceDir and
 | 
			
		||||
    a.forceRebuild == b.forceRebuild
 | 
			
		||||
 | 
			
		||||
# Util methods on custom types
 | 
			
		||||
proc findProject*(cfg: StrawBossConfig, projectName: string): ProjectDef =
 | 
			
		||||
  let candidates = cfg.projects.filterIt(it.name == projectName)
 | 
			
		||||
@@ -182,12 +192,9 @@ proc loadBuildStatus*(statusFile: string): BuildStatus =
 | 
			
		||||
    state: jsonObj.getOrFail("state", "build status").getStr,
 | 
			
		||||
    details: jsonObj.getIfExists("details").getStr("") )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# TODO: unused and untested, add tests if we start using this
 | 
			
		||||
proc parseRunRequest*(reqStr: string): RunRequest =
 | 
			
		||||
  let reqJson = parseJson(reqStr)
 | 
			
		||||
 | 
			
		||||
proc parseRunRequest*(reqJson: JsonNode): RunRequest =
 | 
			
		||||
  result = RunRequest(
 | 
			
		||||
    id: parseUUID(reqJson.getOrFail("id", "RunRequest").getStr),
 | 
			
		||||
    projectName: reqJson.getOrFail("projectName", "RunRequest").getStr,
 | 
			
		||||
    stepName: reqJson.getOrFail("stepName", "RunRequest").getStr,
 | 
			
		||||
    buildRef: reqJson.getOrFail("buildRef", "RunRequest").getStr,
 | 
			
		||||
@@ -213,6 +220,7 @@ proc `%`*(p: ProjectDef): JsonNode =
 | 
			
		||||
 | 
			
		||||
proc `%`*(req: RunRequest): JsonNode =
 | 
			
		||||
  result = %* {
 | 
			
		||||
    "id": $req.id,
 | 
			
		||||
    "projectName": req.projectName,
 | 
			
		||||
    "stepName": req.stepName,
 | 
			
		||||
    "buildRef": req.buildRef,
 | 
			
		||||
 
 | 
			
		||||
@@ -168,6 +168,14 @@ proc runStep*(cfg: StrawBossConfig, req: RunRequest,
 | 
			
		||||
    # Find the project definition
 | 
			
		||||
    let projectDef = cfg.findProject(req.projectName)
 | 
			
		||||
 | 
			
		||||
    # Make sure our directory in the artifacts repo exists
 | 
			
		||||
    if not existsDir(cfg.artifactsRepo & "/" & projectDef.name & "/run-requests"):
 | 
			
		||||
      createDir(cfg.artifactsRepo & "/" & projectDef.name & "/run-requests")
 | 
			
		||||
 | 
			
		||||
    # Save the run request
 | 
			
		||||
    writeFile(cfg.artifactsRepo & "/" & projectDef.name &
 | 
			
		||||
      "/run-requests/" & $req.id & ".json", $req)
 | 
			
		||||
 | 
			
		||||
    # Read in the existing system environment
 | 
			
		||||
    var env = loadEnv()
 | 
			
		||||
    env["GIT_DIR"] = ".git"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,10 @@
 | 
			
		||||
import algorithm, asyncdispatch, bcrypt, jester, json, jwt, logging, os, osproc,
 | 
			
		||||
  sequtils, strutils, tempfile, times, unittest
 | 
			
		||||
  sequtils, strutils, tempfile, times, unittest, uuids
 | 
			
		||||
 | 
			
		||||
import ./configuration, ./core, private/util
 | 
			
		||||
 | 
			
		||||
type Worker = object
 | 
			
		||||
  runId*: UUID
 | 
			
		||||
  process*: Process
 | 
			
		||||
  workingDir*: string
 | 
			
		||||
 | 
			
		||||
@@ -76,10 +77,11 @@ proc spawnWorker(cfg: StrawBossConfig, req: RunRequest): Worker =
 | 
			
		||||
 | 
			
		||||
  let dir = mkdtemp()
 | 
			
		||||
  var args = @["run", req.projectName, req.stepName, "-r", req.buildRef,
 | 
			
		||||
               "-w", dir, "-c", cfg.filePath]
 | 
			
		||||
               "-w", dir, "-c", cfg.filePath, "-i", req.id]
 | 
			
		||||
  if req.forceRebuild: args.add("-f")
 | 
			
		||||
  debug "Launching worker: " & cfg.pathToExe & " " & args.join(" ")
 | 
			
		||||
  result = Worker(
 | 
			
		||||
    runId: req.id,
 | 
			
		||||
    process: startProcess(cfg.pathToExe, ".", args, loadEnv(), {poUsePath}),
 | 
			
		||||
    workingDir: dir)
 | 
			
		||||
 | 
			
		||||
@@ -238,7 +240,20 @@ proc start*(cfg: StrawBossConfig): void =
 | 
			
		||||
      ## List all runs
 | 
			
		||||
 | 
			
		||||
      checkAuth(); if not authed: return true
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
      # Make sure we know about that project
 | 
			
		||||
      var project: ProjectDef
 | 
			
		||||
      try: project = cfg.findProject(@"projectName")
 | 
			
		||||
      except: resp(Http404, makeJsonResp(Http404, getCurrentExceptionMsg()), JSON)
 | 
			
		||||
 | 
			
		||||
      let runsDir = cfg.artifactsRepo & "/" & project.name & "/runs"
 | 
			
		||||
      if not existsDir(runsDir): resp("[]", JSON)
 | 
			
		||||
 | 
			
		||||
      let runPaths = toSeq(walkFiles(runsDir & "/*.json"))
 | 
			
		||||
      let runRequests = runPaths.mapIt(parseRunRequest(parseFile(it)))
 | 
			
		||||
 | 
			
		||||
      resp($(%runRequests), JSON)
 | 
			
		||||
 | 
			
		||||
      # TODO
 | 
			
		||||
      resp(Http501, makeJsonResp(Http501), JSON)
 | 
			
		||||
 | 
			
		||||
@@ -279,7 +294,8 @@ proc start*(cfg: StrawBossConfig): void =
 | 
			
		||||
 | 
			
		||||
      checkAuth(); if not authed: return true
 | 
			
		||||
 | 
			
		||||
      workers.add(spawnWorker(RunRequest(
 | 
			
		||||
      let runRequest = RunRequest(
 | 
			
		||||
        id: genUUID(),
 | 
			
		||||
        projectName: @"projectName",
 | 
			
		||||
        stepName: @"stepName",
 | 
			
		||||
        buildRef: if @"buildRef" != "": @"buildRef" else: nil,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
import json, strtabs, tables, unittest
 | 
			
		||||
import json, strtabs, tables, unittest, uuids
 | 
			
		||||
 | 
			
		||||
from langutils import sameContents
 | 
			
		||||
import ../../../main/nim/strawbosspkg/configuration
 | 
			
		||||
 | 
			
		||||
@@ -18,6 +19,18 @@ suite "load and save configuration objects":
 | 
			
		||||
    defaultBranch: "deploy",
 | 
			
		||||
    envVars: newStringTable("VAR1", "value", modeCaseInsensitive))
 | 
			
		||||
 | 
			
		||||
  test "parseRunRequest":
 | 
			
		||||
    let rr1 = RunRequest(
 | 
			
		||||
      id: genUUID(),
 | 
			
		||||
      projectName: testProjDef.name,
 | 
			
		||||
      stepName: "build",
 | 
			
		||||
      buildRef: "master",
 | 
			
		||||
      workspaceDir: "/no-real/dir",
 | 
			
		||||
      forceRebuild: true)
 | 
			
		||||
 | 
			
		||||
    let rrStr = $rr1
 | 
			
		||||
    let rr2 = parseRunRequest(parseJson(rrStr))
 | 
			
		||||
    check rr1 == rr2
 | 
			
		||||
 | 
			
		||||
  test "parseProjectDef":
 | 
			
		||||
    let pd = parseProjectDef(parseJson(testProjDefStr))
 | 
			
		||||
 
 | 
			
		||||
@@ -9,10 +9,14 @@ srcDir        = "src/main/nim"
 | 
			
		||||
 | 
			
		||||
# Dependencies
 | 
			
		||||
 | 
			
		||||
requires @["nim >= 0.16.1", "docopt >= 0.1.0", "tempfile", "jester", "bcrypt", "untar"]
 | 
			
		||||
requires @["nim >= 0.16.1", "docopt >= 0.1.0", "tempfile", "jester", "bcrypt",
 | 
			
		||||
           "untar", "uuids"]
 | 
			
		||||
 | 
			
		||||
requires "https://github.com/yglukhov/nim-jwt"
 | 
			
		||||
requires "https://git.jdb-labs.com/jdb/nim-lang-utils.git"
 | 
			
		||||
 | 
			
		||||
# Tasks
 | 
			
		||||
#
 | 
			
		||||
task functest, "Runs the functional test suite.":
 | 
			
		||||
  exec "nim c -r src/test/nim/run_functional_tests.nim"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user