Adding ability to extend existing docker-compose file to include volumes for watching plugins.
This commit is contained in:
parent
26eb8fb3de
commit
694424d0b2
6 changed files with 2296 additions and 34 deletions
|
@ -45,7 +45,8 @@
|
||||||
"pouchdb": "7.3.0",
|
"pouchdb": "7.3.0",
|
||||||
"pouchdb-replication-stream": "1.2.9",
|
"pouchdb-replication-stream": "1.2.9",
|
||||||
"randomstring": "1.1.5",
|
"randomstring": "1.1.5",
|
||||||
"tar": "6.1.11"
|
"tar": "6.1.11",
|
||||||
|
"yaml": "^2.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"copyfiles": "^2.4.1",
|
"copyfiles": "^2.4.1",
|
||||||
|
|
|
@ -11,6 +11,7 @@ exports.CommandWords = {
|
||||||
exports.InitTypes = {
|
exports.InitTypes = {
|
||||||
QUICK: "quick",
|
QUICK: "quick",
|
||||||
DIGITAL_OCEAN: "do",
|
DIGITAL_OCEAN: "do",
|
||||||
|
SINGLE: "single",
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.AnalyticsEvents = {
|
exports.AnalyticsEvents = {
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
const Command = require("../structures/Command")
|
const Command = require("../structures/Command")
|
||||||
const { CommandWords, InitTypes, AnalyticsEvents } = require("../constants")
|
const { CommandWords, InitTypes, AnalyticsEvents } = require("../constants")
|
||||||
const { lookpath } = require("lookpath")
|
const { lookpath } = require("lookpath")
|
||||||
|
const { resolve } = require("path")
|
||||||
const {
|
const {
|
||||||
downloadFile,
|
downloadFile,
|
||||||
logErrorToFile,
|
logErrorToFile,
|
||||||
success,
|
success,
|
||||||
info,
|
info,
|
||||||
|
error,
|
||||||
parseEnv,
|
parseEnv,
|
||||||
} = require("../utils")
|
} = require("../utils")
|
||||||
const { confirmation } = require("../questions")
|
const { confirmation } = require("../questions")
|
||||||
|
@ -14,6 +16,7 @@ const compose = require("docker-compose")
|
||||||
const makeEnv = require("./makeEnv")
|
const makeEnv = require("./makeEnv")
|
||||||
const axios = require("axios")
|
const axios = require("axios")
|
||||||
const { captureEvent } = require("../events")
|
const { captureEvent } = require("../events")
|
||||||
|
const yaml = require("yaml")
|
||||||
|
|
||||||
const BUDIBASE_SERVICES = ["app-service", "worker-service", "proxy-service"]
|
const BUDIBASE_SERVICES = ["app-service", "worker-service", "proxy-service"]
|
||||||
const ERROR_FILE = "docker-error.log"
|
const ERROR_FILE = "docker-error.log"
|
||||||
|
@ -154,11 +157,58 @@ async function update() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function watchPlugins(pluginPath) {
|
||||||
|
const PLUGIN_PATH = "/plugins"
|
||||||
|
// get absolute path
|
||||||
|
pluginPath = resolve(pluginPath)
|
||||||
|
if (!fs.existsSync(pluginPath)) {
|
||||||
|
console.log(
|
||||||
|
error(
|
||||||
|
`The directory "${pluginPath}" does not exist, please create and then try again.`
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const opts = ["docker-compose.yaml", "docker-compose.yml"]
|
||||||
|
let dockerFilePath = opts.find(name => fs.existsSync(name))
|
||||||
|
if (!dockerFilePath) {
|
||||||
|
console.log(error("Unable to locate docker-compose YAML."))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const dockerYaml = fs.readFileSync(dockerFilePath, "utf8")
|
||||||
|
const parsedYaml = yaml.parse(dockerYaml)
|
||||||
|
let service
|
||||||
|
if (parsedYaml["services"]["app-service"]) {
|
||||||
|
service = parsedYaml["services"]["app-service"]
|
||||||
|
}
|
||||||
|
if (!service) {
|
||||||
|
console.log(
|
||||||
|
error(
|
||||||
|
"Unable to locate service within compose file, is it a valid Budibase configuration?"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// set environment variable
|
||||||
|
service.environment["PLUGINS_DIR"] = PLUGIN_PATH
|
||||||
|
// add volumes to parsed yaml
|
||||||
|
if (!service.volumes) {
|
||||||
|
service.volumes = []
|
||||||
|
}
|
||||||
|
const found = service.volumes.find(vol => vol.includes(PLUGIN_PATH))
|
||||||
|
if (found) {
|
||||||
|
service.volumes.splice(service.volumes.indexOf(found), 1)
|
||||||
|
}
|
||||||
|
service.volumes.push(`${pluginPath}:${PLUGIN_PATH}`)
|
||||||
|
fs.writeFileSync(dockerFilePath, yaml.stringify(parsedYaml))
|
||||||
|
console.log(success("Docker compose configuration has been updated!"))
|
||||||
|
}
|
||||||
|
|
||||||
const command = new Command(`${CommandWords.HOSTING}`)
|
const command = new Command(`${CommandWords.HOSTING}`)
|
||||||
.addHelp("Controls self hosting on the Budibase platform.")
|
.addHelp("Controls self hosting on the Budibase platform.")
|
||||||
.addSubOption(
|
.addSubOption(
|
||||||
"--init [type]",
|
"--init [type]",
|
||||||
"Configure a self hosted platform in current directory, type can be unspecified or 'quick'.",
|
"Configure a self hosted platform in current directory, type can be unspecified, 'quick' or 'single'.",
|
||||||
init
|
init
|
||||||
)
|
)
|
||||||
.addSubOption(
|
.addSubOption(
|
||||||
|
@ -181,5 +231,11 @@ const command = new Command(`${CommandWords.HOSTING}`)
|
||||||
"Update the Budibase images to the latest version.",
|
"Update the Budibase images to the latest version.",
|
||||||
update
|
update
|
||||||
)
|
)
|
||||||
|
.addSubOption(
|
||||||
|
"--watch-plugin-dir [directory]",
|
||||||
|
"Add plugin directory watching to a Budibase install.",
|
||||||
|
watchPlugins
|
||||||
|
)
|
||||||
|
.addSubOption("--dev", "")
|
||||||
|
|
||||||
exports.command = command
|
exports.command = command
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
const { getSubHelpDescription, getHelpDescription, error } = require("../utils")
|
const {
|
||||||
|
getSubHelpDescription,
|
||||||
|
getHelpDescription,
|
||||||
|
error,
|
||||||
|
capitaliseFirstLetter,
|
||||||
|
} = require("../utils")
|
||||||
|
|
||||||
class Command {
|
class Command {
|
||||||
constructor(command, func = null) {
|
constructor(command, func = null) {
|
||||||
|
@ -8,6 +13,15 @@ class Command {
|
||||||
this.func = func
|
this.func = func
|
||||||
}
|
}
|
||||||
|
|
||||||
|
convertToCommander(lookup) {
|
||||||
|
const parts = lookup.toLowerCase().split("-")
|
||||||
|
// camel case, separate out first
|
||||||
|
const first = parts.shift()
|
||||||
|
return [first]
|
||||||
|
.concat(parts.map(part => capitaliseFirstLetter(part)))
|
||||||
|
.join("")
|
||||||
|
}
|
||||||
|
|
||||||
addHelp(help) {
|
addHelp(help) {
|
||||||
this.help = help
|
this.help = help
|
||||||
return this
|
return this
|
||||||
|
@ -38,7 +52,9 @@ class Command {
|
||||||
try {
|
try {
|
||||||
let executed = false
|
let executed = false
|
||||||
for (let opt of thisCmd.opts) {
|
for (let opt of thisCmd.opts) {
|
||||||
const lookup = opt.command.split(" ")[0].replace("--", "")
|
let lookup = opt.command.split(" ")[0].replace("--", "")
|
||||||
|
// need to handle how commander converts watch-plugin-dir to watchPluginDir
|
||||||
|
lookup = this.convertToCommander(lookup)
|
||||||
if (!executed && options[lookup]) {
|
if (!executed && options[lookup]) {
|
||||||
const input =
|
const input =
|
||||||
Object.keys(options).length > 1 ? options : options[lookup]
|
Object.keys(options).length > 1 ? options : options[lookup]
|
||||||
|
|
|
@ -84,3 +84,7 @@ exports.moveDirectory = (oldPath, newPath) => {
|
||||||
}
|
}
|
||||||
fs.rmdirSync(oldPath)
|
fs.rmdirSync(oldPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.capitaliseFirstLetter = str => {
|
||||||
|
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue