Start adding state classes; update dependencies
This commit is contained in:
@@ -13,6 +13,11 @@ class ServiceConfig extends Injectable {
|
||||
install_to: 'multi-user.target',
|
||||
}
|
||||
|
||||
constructor(merge_data = {}) {
|
||||
super()
|
||||
this._data = {...this._data, ...merge_data}
|
||||
}
|
||||
|
||||
name(set) { return this._get_or_set('name', set) }
|
||||
|
||||
description(set) { return this._get_or_set('description', set) }
|
||||
|
||||
11
app/classes/state/Routine.js
Normal file
11
app/classes/state/Routine.js
Normal file
@@ -0,0 +1,11 @@
|
||||
class Routine {
|
||||
constructor(steps) {
|
||||
this.steps = steps
|
||||
}
|
||||
|
||||
apply_to(host) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = Routine
|
||||
@@ -5,6 +5,8 @@ class DirectoryState extends State {
|
||||
if ( !(await this.check()) ) {
|
||||
const path = await this._path()
|
||||
await path.touch(true)
|
||||
|
||||
// TODO directories
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
const State = require('../State')
|
||||
const UniversalPath = require('../../logical/UniversalPath')
|
||||
|
||||
class FileContentState extends State {
|
||||
static get services() {
|
||||
return [...super.services, 'hosts']
|
||||
}
|
||||
|
||||
async apply() {
|
||||
const target_path = await this._target()
|
||||
if ( target_path.is_valid() ) {
|
||||
|
||||
}
|
||||
|
||||
if ( this._config.source ) {
|
||||
const source_path = await this._source()
|
||||
await source_path.copy_to(target_path)
|
||||
} else {
|
||||
await target_path.echo(this._config.contents)
|
||||
}
|
||||
}
|
||||
|
||||
async check() {
|
||||
if ( this._config.source ) {
|
||||
const source_path = await this._source()
|
||||
const source_hash = await source_path.hash()
|
||||
|
||||
const target_path = await this._target()
|
||||
if ( !target_path.is_file() ) return false
|
||||
const target_hash = await target_path.hash()
|
||||
|
||||
return source_hash === target_hash
|
||||
} else {
|
||||
const localhost = this.hosts.get('localhost')
|
||||
const temp_path = await localhost.get_temp_file()
|
||||
await temp_path.echo(this._config.contents)
|
||||
const source_hash = await temp_path.hash()
|
||||
|
||||
const target_path = await this._target()
|
||||
if ( !target_path.is_file() ) return false
|
||||
const target_hash = await target_path.hash()
|
||||
|
||||
return source_hash === target_hash
|
||||
}
|
||||
}
|
||||
|
||||
async reverse() {
|
||||
await (await this._target()).echo('')
|
||||
}
|
||||
|
||||
async _target() {
|
||||
if ( typeof this._config.target === 'string' ) {
|
||||
return UniversalPath.fromString(this._config.target)
|
||||
} else return this._config.target
|
||||
}
|
||||
|
||||
async _source() {
|
||||
if ( typeof this._config.target === 'string' ) {
|
||||
return UniversalPath.fromString(this._config.target)
|
||||
} else return this._config.target
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = FileContentState
|
||||
@@ -5,6 +5,12 @@ class FileState extends State {
|
||||
if ( !(await this.check()) ) {
|
||||
const path = await this._path()
|
||||
await path.touch()
|
||||
|
||||
if ( this._config.contents ) {
|
||||
await path.echo(this._config.contents)
|
||||
} else if ( this._config.template ) {
|
||||
await path.copy_from(this._config.template)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
28
app/classes/state/os/PackageCacheClearedState.js
Normal file
28
app/classes/state/os/PackageCacheClearedState.js
Normal file
@@ -0,0 +1,28 @@
|
||||
const State = require('../State')
|
||||
|
||||
class PackageCacheClearedState extends State {
|
||||
static get services() {
|
||||
return [...super.services, 'output']
|
||||
}
|
||||
|
||||
constructor(host, config) {
|
||||
if ( !host.packages ) {
|
||||
throw new Error(`Cannot apply package state to host ${host.name}: missing package manager API.`)
|
||||
}
|
||||
super(host, config)
|
||||
}
|
||||
|
||||
async apply() {
|
||||
return this._host.packages.clear_cache()
|
||||
}
|
||||
|
||||
async check() {
|
||||
return false
|
||||
}
|
||||
|
||||
async reverse() {
|
||||
this.output.warn(`Package cache cleared state does not currently support reversal. (Host: ${this._host.name})`)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = PackageCacheClearedState
|
||||
24
app/classes/state/os/PackageState.js
Normal file
24
app/classes/state/os/PackageState.js
Normal file
@@ -0,0 +1,24 @@
|
||||
const State = require('../State')
|
||||
|
||||
class PackageState extends State {
|
||||
constructor(host, config) {
|
||||
if ( !host.packages ) {
|
||||
throw new Error(`Cannot apply package state to host ${host.name}: missing package manager API.`)
|
||||
}
|
||||
super(host, config)
|
||||
}
|
||||
|
||||
async apply() {
|
||||
return this._host.packages.install(this._config.package)
|
||||
}
|
||||
|
||||
async check() {
|
||||
return this._host.packages.is_installed(this._config.package)
|
||||
}
|
||||
|
||||
async reverse() {
|
||||
return this._host.packages.uninstall(this._config.package)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = PackageState
|
||||
28
app/classes/state/os/ServiceDaemonReloadState.js
Normal file
28
app/classes/state/os/ServiceDaemonReloadState.js
Normal file
@@ -0,0 +1,28 @@
|
||||
const State = require('../State')
|
||||
|
||||
class ServiceDaemonReloadState extends State {
|
||||
static get services() {
|
||||
return [...super.services, 'output']
|
||||
}
|
||||
|
||||
constructor(host, config) {
|
||||
if ( !host.services ) {
|
||||
throw new Error(`Cannot apply service state to host ${host.name}: missing service manager API.`)
|
||||
}
|
||||
super(host, config)
|
||||
}
|
||||
|
||||
async apply() {
|
||||
return this._host.services.daemon_reload()
|
||||
}
|
||||
|
||||
async check() {
|
||||
return false
|
||||
}
|
||||
|
||||
async reverse() {
|
||||
this.output.warn(`Service daemon reload state does not currently support reversal. (Host: ${this._host.name})`)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = ServiceDaemonReloadState
|
||||
29
app/classes/state/os/ServiceRestartState.js
Normal file
29
app/classes/state/os/ServiceRestartState.js
Normal file
@@ -0,0 +1,29 @@
|
||||
const State = require('../State')
|
||||
|
||||
class ServiceRestartState extends State {
|
||||
static get services() {
|
||||
return [...super.services, 'output']
|
||||
}
|
||||
|
||||
constructor(host, config) {
|
||||
if ( !host.services ) {
|
||||
throw new Error(`Cannot apply service state to host ${host.name}: missing service manager API.`)
|
||||
}
|
||||
super(host, config)
|
||||
}
|
||||
|
||||
async apply() {
|
||||
const services = Array.isArray(this._config.service) ? this._config.service : [this._config.service]
|
||||
return this._host.services.restart(...services)
|
||||
}
|
||||
|
||||
async check() {
|
||||
return false
|
||||
}
|
||||
|
||||
async reverse() {
|
||||
this.output.warn(`Service restart state does not currently support reversal. (Host: ${this._host.name})`)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = ServiceRestartState
|
||||
29
app/classes/state/os/ServiceState.js
Normal file
29
app/classes/state/os/ServiceState.js
Normal file
@@ -0,0 +1,29 @@
|
||||
const State = require('../State')
|
||||
|
||||
class ServiceState extends State {
|
||||
constructor(host, config) {
|
||||
if ( !host.services ) {
|
||||
throw new Error(`Cannot apply service state to host ${host.name}: missing service manager API.`)
|
||||
}
|
||||
super(host, config)
|
||||
}
|
||||
|
||||
async apply() {
|
||||
const services = Array.isArray(this._config.service) ? this._config.service : [this._config.service]
|
||||
return this._host.services.start(...services)
|
||||
}
|
||||
|
||||
async check() {
|
||||
const services = Array.isArray(this._config.service) ? this._config.service : [this._config.service]
|
||||
let states = await this._host.services.status(...services)
|
||||
if ( !Array.isArray(states) ) states = [states]
|
||||
return states.every(x => x.status === 'running')
|
||||
}
|
||||
|
||||
async reverse() {
|
||||
const services = Array.isArray(this._config.service) ? this._config.service : [this._config.service]
|
||||
return this._host.services.stop(...services)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = ServiceState
|
||||
29
app/classes/state/os/UpdateState.js
Normal file
29
app/classes/state/os/UpdateState.js
Normal file
@@ -0,0 +1,29 @@
|
||||
const State = require('../State')
|
||||
|
||||
class UpdateState extends State {
|
||||
static get services() {
|
||||
return [...super.services, 'output']
|
||||
}
|
||||
|
||||
constructor(host, config) {
|
||||
if ( !host.packages ) {
|
||||
throw new Error(`Cannot apply update state to host ${host.name}: missing package manager API.`)
|
||||
}
|
||||
super(host, config)
|
||||
}
|
||||
|
||||
async apply() {
|
||||
const packages = (await this._host.packages.list_updates()).map(x => x.name)
|
||||
await this._host.packages.update(...packages)
|
||||
}
|
||||
|
||||
async check() {
|
||||
return (await this._host.packages.list_updates()).length === 0
|
||||
}
|
||||
|
||||
async reverse() {
|
||||
this.output.warn(`Update state does not currently support reversing package updates. (Host: ${this._host.name})`)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = exports = UpdateState
|
||||
Reference in New Issue
Block a user