parent
afb35ebad8
commit
f5b84b530c
@ -0,0 +1,17 @@
|
|||||||
|
const { Unit } = require('libflitter')
|
||||||
|
const RunDirective = require('./classes/routine/RunDirective')
|
||||||
|
const Rollcall = require('./classes/directive/Rollcall')
|
||||||
|
const Routine = require('./classes/directive/Routine')
|
||||||
|
|
||||||
|
class AppUnit extends Unit {
|
||||||
|
static get name() { return 'misc' }
|
||||||
|
|
||||||
|
directives() {
|
||||||
|
return {
|
||||||
|
Rollcall,
|
||||||
|
Routine,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = exports = AppUnit
|
@ -0,0 +1,73 @@
|
|||||||
|
const Directive = require('flitter-cli/Directive')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
class Rollcall extends Directive {
|
||||||
|
static get services() {
|
||||||
|
return [...super.services, 'configs', 'hosts']
|
||||||
|
}
|
||||||
|
|
||||||
|
static options() {
|
||||||
|
return [
|
||||||
|
'--hosts -h {host file} | path to the host definition file'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
static name() {
|
||||||
|
return 'rollcall'
|
||||||
|
}
|
||||||
|
|
||||||
|
static help() {
|
||||||
|
return 'Ping the configured hosts to determine if we can access them'
|
||||||
|
}
|
||||||
|
|
||||||
|
async handle(app, argv) {
|
||||||
|
const host_path = this.option('hosts')
|
||||||
|
|
||||||
|
if ( host_path ) {
|
||||||
|
try {
|
||||||
|
// Override the host config externally
|
||||||
|
const host_conf = require(path.resolve(host_path))
|
||||||
|
if (typeof host_conf === 'object') {
|
||||||
|
this.configs.canonical_items.hosts = host_conf
|
||||||
|
this.info('Loaded host definition file.')
|
||||||
|
} else {
|
||||||
|
this.error('Invalid host definition file!')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.error('Invalid host definition file!')
|
||||||
|
this.output.debug(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const successes = []
|
||||||
|
const failures = []
|
||||||
|
|
||||||
|
const host_config = this.configs.get('hosts')
|
||||||
|
const hostnames = Object.keys(host_config)
|
||||||
|
for ( const name of hostnames ) {
|
||||||
|
this.info(`Pinging ${name}...`)
|
||||||
|
|
||||||
|
try {
|
||||||
|
const host = this.hosts.get(name)
|
||||||
|
const is_alive = await host.is_alive()
|
||||||
|
if ( !is_alive ) {
|
||||||
|
failures.push(name)
|
||||||
|
this.error('Unable to ping host and verify execution.')
|
||||||
|
} else {
|
||||||
|
successes.push(name)
|
||||||
|
this.success('Connected to host and verified execution.')
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
failures.push(name)
|
||||||
|
this.error('Unable to ping host and verify execution.')
|
||||||
|
this.output.debug(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.hosts.close()
|
||||||
|
this.info(`Successfully pinged ${successes.length} host(s).`)
|
||||||
|
if ( failures.length > 0 ) this.info(`Unable to ping ${failures.length} host(s): ${failures.join(', ')}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = exports = Rollcall
|
@ -0,0 +1,100 @@
|
|||||||
|
const Directive = require('flitter-cli/Directive')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
class Routine extends Directive {
|
||||||
|
static get services() {
|
||||||
|
return [...super.services, 'configs', 'hosts', 'routines']
|
||||||
|
}
|
||||||
|
|
||||||
|
static options() {
|
||||||
|
return [
|
||||||
|
'--hosts -h {host file} | path to the host definition file',
|
||||||
|
'--target -t {host name} | the host to run the routine on',
|
||||||
|
'--routine -r {routine file} | path to the routine definition file',
|
||||||
|
'--type -t {run type} | how to execute the routine: checks | apply'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
static name() {
|
||||||
|
return 'routine'
|
||||||
|
}
|
||||||
|
|
||||||
|
static help() {
|
||||||
|
return 'Run the specified routine file'
|
||||||
|
}
|
||||||
|
|
||||||
|
async handle(app, argv) {
|
||||||
|
const host_path = this.option('hosts')
|
||||||
|
const routine_path = this.option('routine')
|
||||||
|
const target_host = this.option('target')
|
||||||
|
const run_type = this.option('type')
|
||||||
|
|
||||||
|
if ( host_path ) {
|
||||||
|
try {
|
||||||
|
// Override the host config externally
|
||||||
|
const host_conf = require(path.resolve(host_path))
|
||||||
|
if (typeof host_conf === 'object') {
|
||||||
|
this.configs.canonical_items.hosts = host_conf
|
||||||
|
this.info('Loaded host definition file.')
|
||||||
|
} else {
|
||||||
|
this.error('Invalid host definition file!')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.error('Invalid host definition file!')
|
||||||
|
this.output.debug(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// loaded_from_cli
|
||||||
|
|
||||||
|
const host = this.hosts.get(target_host)
|
||||||
|
if ( !host ) {
|
||||||
|
this.error('Invalid host name. Unable to find configuration for host with that name.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !['checks', 'apply'].includes(run_type) ) {
|
||||||
|
this.error('Invalid run type. Must be one of: checks, apply')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( routine_path ) {
|
||||||
|
try {
|
||||||
|
// Override the routine config externally
|
||||||
|
const routine_conf = require(path.resolve(routine_path))
|
||||||
|
if (typeof routine_conf === 'object') {
|
||||||
|
routine_conf.hosts = [target_host]
|
||||||
|
routine_conf.type = run_type
|
||||||
|
if ( Array.isArray(routine_conf.steps) ) {
|
||||||
|
routine_conf.steps = routine_conf.steps.map(step => {
|
||||||
|
step.host = target_host
|
||||||
|
return step
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.configs.canonical_items['routines:loaded_from_cli'] = routine_conf
|
||||||
|
this.info('Loaded routine definition file.')
|
||||||
|
} else {
|
||||||
|
this.error('Invalid routine definition file!')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.error('Invalid routine definition file!')
|
||||||
|
this.output.debug(e)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.error('Missing required parameter: --routine')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const routine = await this.routines.get('loaded_from_cli')
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await routine.execute(true)
|
||||||
|
} catch (e) {
|
||||||
|
this.output.error(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.hosts.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = exports = Routine
|
@ -0,0 +1,48 @@
|
|||||||
|
const Directive = require('flitter-cli/Directive')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
class RunDirective extends Directive {
|
||||||
|
static options() {
|
||||||
|
return [
|
||||||
|
'--hosts -h {host file} | path to the host definition file',
|
||||||
|
'{routine file} | path to the routine definition file',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
static name() {
|
||||||
|
return 'run'
|
||||||
|
}
|
||||||
|
|
||||||
|
static help() {
|
||||||
|
return 'Run a specified routine'
|
||||||
|
}
|
||||||
|
|
||||||
|
async handle(app, argv) {
|
||||||
|
const routine_path = this.option('routine file')
|
||||||
|
const host_path = this.option('hosts')
|
||||||
|
|
||||||
|
if ( !host_path )
|
||||||
|
return this.error('Missing required parameter: --hosts')
|
||||||
|
|
||||||
|
let routine_conf
|
||||||
|
let host_conf
|
||||||
|
|
||||||
|
try {
|
||||||
|
routine_conf = require(path.resolve(routine_path))
|
||||||
|
} catch (e) {
|
||||||
|
this.error('Routine file is invalid.')
|
||||||
|
return this.output.debug(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
host_conf = require(path.resolve(host_path))
|
||||||
|
} catch (e) {
|
||||||
|
this.error('Host definition file is invalid.')
|
||||||
|
return this.output.debug(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log({ routine_conf, host_conf })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = exports = RunDirective
|
@ -0,0 +1,36 @@
|
|||||||
|
const AbstractGitState = require('./AbstractGitState')
|
||||||
|
|
||||||
|
class PullState extends AbstractGitState {
|
||||||
|
static get services() {
|
||||||
|
return [...super.services, 'output']
|
||||||
|
}
|
||||||
|
|
||||||
|
async apply() {
|
||||||
|
if ( !(await this.check()) ) {
|
||||||
|
const repo = await this._repo()
|
||||||
|
await repo.pull(this._config.target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async check() {
|
||||||
|
return true // TODO support a better check here
|
||||||
|
}
|
||||||
|
|
||||||
|
async reverse() {
|
||||||
|
this.output.warn('Pull state does not currently support automatic reversal.')
|
||||||
|
}
|
||||||
|
|
||||||
|
failure_message() {
|
||||||
|
return `The Git repo at "${this._config.path}" on host "${this._host.name}" will be pulled.`
|
||||||
|
}
|
||||||
|
|
||||||
|
check_message() {
|
||||||
|
return this.failure_message()
|
||||||
|
}
|
||||||
|
|
||||||
|
display() {
|
||||||
|
return `Pull refs in repo ${this._config.path}...`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = exports = PullState
|
Loading…
Reference in new issue