Skip to content

Commit

Permalink
hot reload hates me
Browse files Browse the repository at this point in the history
  • Loading branch information
vkorbes committed Oct 21, 2019
1 parent 39d48d1 commit 6cb54f9
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 54 deletions.
123 changes: 77 additions & 46 deletions garden-service/src/plugins/go-container/go-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

// import { omit, get } from "lodash"
import { omit } from "lodash"
import { copy, pathExists, readFile, writeFile, ensureDir } from "fs-extra"
import { createGardenPlugin } from "../../types/plugin/plugin"
import {
Expand All @@ -17,7 +17,7 @@ import {
ContainerTaskSpec,
ContainerBuildSpec,
} from "../container/config"
import { joiArray, joiProviderName, joi } from "../../config/common"
import { joiProviderName, joi } from "../../config/common"
import { Module } from "../../types/module"
import { resolve } from "path"
// import { RuntimeError, ConfigurationError } from "../../exceptions"
Expand All @@ -32,6 +32,9 @@ import { ModuleConfig, baseBuildSpecSchema } from "../../config/module"
import { ConfigureModuleParams } from "../../types/plugin/module/configure"
import { GetBuildStatusParams } from "../../types/plugin/module/getBuildStatus"
import { BuildModuleParams } from "../../types/plugin/module/build"
import { HotReloadServiceParams } from "../../types/plugin/service/hotReloadService"
import { LogEntry } from "../../logger/log-entry"
import execa = require("execa")
// import { binary } from "@hapi/joi"

const defaultDockerfileName = "go-container.Dockerfile"
Expand All @@ -40,9 +43,8 @@ const defaultDockerfilePath = resolve(STATIC_DIR, "go-container", defaultDockerf
interface GoContainerBuildSpec extends ContainerBuildSpec {
debug: boolean
compress: boolean | number
run: string
buildFlags: string
//other fields here
// run: string
// buildFlags: string
}

export interface GoContainerModuleSpec extends ContainerModuleSpec {
Expand All @@ -65,22 +67,27 @@ const goKeys = {
By default, Garden passes the '-w' flag to the linker to omit this information and make the resulting binaries smaller.
If you do want this information, set this option to \`true\`.
`)
// .example(true).default(false),
.example("false"),
// compress: joi.alternatives().try(
// joi.boolean(),
// joi.number(),
// joi.number().integer().min(1).max(9),
// ).description(dedent`
// "By default, Garden will compress the resulting Go binary with UPX \(upx.github.io\).
// By default, Garden will compress the resulting Go binary with UPX \(upx.github.io\).
// This can be disabled with \`false\`, or adjusted with
// an integer in the 1–9 range, where 1 is fastest and 9 is smaller.
// For this functionality to work with macOS, UPX needs
// to first be installed with Homebrew using \`brew install upx\`.
// `)
// .example("1"),
buildFlags: joi.string()
.description("Use this to pass custom build flags to the Go compiler."),
// run: joiArray(joi.string())
// .description("Use this to add arbitrary an arbitrary RUN command to the default Dockerfile."),
// .example(1).default(1),
// buildFlags: joi.string()
// buildFlags: joi.array().items(joi.string())
// .description("Use this to pass custom build flags to the Go compiler."),
// run: joi.array().items(joi.string())
// run: joi.string()
// .description("Use this to add arbitrary an arbitrary RUN command to the default Dockerfile."),
// .default([" "]), //.example([["apk", "add", "curl"]]),

}

const goContainerModuleSpecSchema = containerModuleSpecSchema.keys({
Expand All @@ -96,6 +103,7 @@ export const gardenPlugin = createGardenPlugin({
dependencies: ["container"],

// TODO
// ALSO REFERENCE DOCS
createModuleTypes: [{
name: "go-container",
base: "container",
Expand All @@ -105,7 +113,7 @@ export const gardenPlugin = createGardenPlugin({
Rather than build the JAR inside the container (or in a multi-stage build) this plugin runs \`mvn package\`
ahead of building the container, which tends to be much more performant, especially when building locally
with a warm artifact cache.
with a warm artifact cache.i
A default Dockerfile is also provided for convenience, but you may override it by including one in the module
directory.
Expand All @@ -118,6 +126,7 @@ export const gardenPlugin = createGardenPlugin({
configure: configureGoContainerModule,
getBuildStatus,
build,
hotReloadService,
},
}],
})
Expand All @@ -126,9 +135,28 @@ export async function configureGoContainerModule(params: ConfigureModuleParams<G
const { base, moduleConfig } = params

let containerConfig: ContainerModuleConfig = { ...moduleConfig, type: "container" }
containerConfig.spec = <ContainerModuleSpec>omit(moduleConfig.spec, Object.keys(goKeys))

containerConfig.spec.hotReload = containerConfig.spec.hotReload || {
sync: [{ source: "bin", target: "/app" }],
// sync: [{ source: "bin/binary", target: "/app/binary" }],
}

for (const service of containerConfig.spec.services) {
// service.hotReloadCommand = service.hotReloadCommand || ["ls", "/"]
service.hotReloadCommand = service.hotReloadCommand || ["/bin/sh", "/app/myscript.sh"]
}

const configured = await base!({ ...params, moduleConfig: containerConfig })

// if vlue="" valiue=default
// if (!moduleConfig.spec.build.run) {
// moduleConfig.spec.build.run = ""
// }
// containerConfig.spec.buildArgs = {
// EXTRA_RUN: moduleConfig.spec.build.run, //.join(" "),
// }

return {
moduleConfig: {
...configured.moduleConfig,
Expand All @@ -143,24 +171,34 @@ export async function configureGoContainerModule(params: ConfigureModuleParams<G
}
}

async function hotReloadService(params: HotReloadServiceParams<GoContainerModule>) {
const { base, module, log } = params
await buildBinary(module, log, true)
console.log("I'm in the hotReloadService function.")
return base!(params)
}

async function build(params: BuildModuleParams<GoContainerModule>) {
const { base, module, log } = params
await buildBinary(module, log, false)
return base!(params)
}

async function getBuildStatus(params: GetBuildStatusParams<GoContainerModule>) {
// const { base, module, log } = params
const { base } = params

// await prepareBuild(module, log)

return base!(params)
}

async function build(params: BuildModuleParams<GoContainerModule>) {
const { base, module, log } = params
async function buildBinary(module: GoContainerModule, log: LogEntry, hotReload: boolean) {
// GoContainerModule<GoContainerModuleSpec, ContainerServiceSpec, ContainerTestSpec, ContainerTaskSpec>
// let { debug, compress, buildFlags, run } = module.spec
let { debug } = module.spec.build

log.setState(`Starting Go build process...`)
const status = log.info(`Starting Go build process...`)

// Check if any imports have changed
console.log(`Checking for new dependencies...`)
status.setState(`Checking for new dependencies...`)
let tidy
try {
tidy = await go.exec({
Expand All @@ -170,23 +208,21 @@ async function build(params: BuildModuleParams<GoContainerModule>) {
})
} catch (err) {
console.log(err.stderr)
status.setState(err.stderr)
}
console.log(tidy.stdout)

// If they did, update the vendor directory
console.log(`Downloading new dependencies...`)
if (tidy.stdout != "") {
if (tidy.stdout) {
status.setState(`Downloading new dependencies...`)
await go.exec({
args: ["mod", "vendor"],
cwd: module.path,
log,
})
}

try {
await ensureDir(resolve(module.path, "bin"))
} catch (err) {
console.error(err)
}

let buildArgs = [
"build",
Expand All @@ -205,22 +241,27 @@ async function build(params: BuildModuleParams<GoContainerModule>) {
buildArgs = buildArgs.concat(debugArgs)
}

console.log(`Building...`)
status.setState(`Building Go binary...`)
let goOutput: any = "default go"
try {
await go.exec({
console.log("Module dot build path:", module.buildPath)
// let goOutput = await execa("mkdir", ["foo" + Math.random()], {cwd: module.buildPath})
goOutput = await go.exec({
args: buildArgs,
cwd: module.buildPath,
cwd: hotReload ? module.path : module.buildPath,
log,
env: {
CGO_ENABLED: "0",
GOOS: "linux",
GOCACHE: resolve(module.buildPath, "cache"),
// GOCACHE: resolve(module.buildPath, "cache"),
},
})
} catch (err) {
console.log(err.stdout)
status.setState(err.stderr)
}

console.log("goOutput:", goOutput.stdout)
// if (compress != "") {
// await upx.exec({
// args: ["mod", "vendor"],
Expand All @@ -231,8 +272,13 @@ async function build(params: BuildModuleParams<GoContainerModule>) {
const dockerFileBuild = resolve(module.buildPath, defaultDockerfileName)
await copy(defaultDockerfilePath, dockerFileBuild)

const scriptName = "myscript.sh"
const scriptPath = resolve(STATIC_DIR, "go-container", scriptName)
const scriptBuild = resolve(module.buildPath, "bin", scriptName)
await copy(scriptPath, scriptBuild)

// if (run != "") {
// let dockerFile = await readFile(dockerFileBuild, "utf8")
// let dockerFile = await readFile(dockerFileBuild, "utf8")
// dockerFile = dockerFile.replace(/echo/g, run)
// try {
// await writeFile(dockerFileBuild, dockerFile, "utf8")
Expand All @@ -251,19 +297,4 @@ async function build(params: BuildModuleParams<GoContainerModule>) {
)
}

// What was this for?
// await copy(resolvedJarPath, resolve(module.buildPath, "app.jar"))

// Build the container
// await prepareBuild(module, log)
return base!(params)
}

// async function prepareBuild(module: MavenContainerModule, log: LogEntry) {
// // Copy the default Dockerfile to the build directory, if the module doesn't provide one
// // Note: Doing this here so that the build status check works as expected.
// if (module.spec.dockerfile === defaultDockerfileName || !(await containerHelpers.hasDockerfile(module))) {
// log.debug(`Using default Dockerfile`)
// await copy(defaultDockerfilePath, resolve(module.buildPath, defaultDockerfileName))
// }
// }
1 change: 0 additions & 1 deletion garden-service/src/plugins/go-container/go.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ export const go = new BinaryCmd({
specs: {
darwin: macos,
linux: penguin,
// Is the "32" here really 32 or is it just the name?
win32: windows,
},
})
11 changes: 4 additions & 7 deletions garden-service/static/go-container/go-container.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
FROM alpine
RUN apk add entr ca-certificates
RUN mkdir app
FROM alpine:3.10.2
RUN apk add entr ca-certificates & mkdir app
WORKDIR /app
EXPOSE 8080

COPY bin/ /app/

CMD ls binary | entr -r ./binary
# RUN ${EXTRA_RUN}
ENTRYPOINT ["/app/binary"]
3 changes: 3 additions & 0 deletions garden-service/static/go-container/myscript.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#/bin/sh
apk add entr
ls binary | entr -r ./binary

0 comments on commit 6cb54f9

Please sign in to comment.