Add unpack state, command not found errors

This commit is contained in:
garrettmills 2020-03-03 21:06:59 -06:00
parent 9291c52383
commit ec8047361c
No known key found for this signature in database
GPG Key ID: 6ACD58D6ADACFC6E
6 changed files with 91 additions and 7 deletions

View File

@ -63,6 +63,16 @@ class UniversalPath extends Injectable {
return path.dirname(this.path)
}
async parent() {
await this.classify()
if ( this.is_directory() ) return path.resolve(this.path, '..')
return this.directory()
}
name() {
return path.basename(this.path)
}
async classify() {
const dir_result = await this._host.execute(`${this._directory_classify_command} ${this._path}`)
if ( dir_result.exit_code === 0 ) {

View File

@ -0,0 +1,5 @@
class CommandNotFoundError extends Error {
}
module.exports = exports = CommandNotFoundError

View File

@ -1,6 +1,7 @@
const { Injectable } = require('flitter-di')
const ImplementationError = require('libflitter/errors/ImplementationError')
const PermissionDeniedError = require('../logical/error/PermissionDeniedError')
const CommandNotFoundError = require('../logical/error/CommandNotFoundError')
const uuid = require('uuid/v4')
const UniversalPath = require('../logical/UniversalPath')
const SystemMetrics = require('../logical/SystemMetrics')
@ -213,10 +214,18 @@ class Host extends Injectable {
'permission denied'
]
const not_found_phrases = [
'command not found',
]
for ( const phrase of access_denied_phrases ) {
if ( both.includes(phrase) ) return PermissionDeniedError
}
for ( const phrase of not_found_phrases ) {
if ( both.includes(phrase) ) return CommandNotFoundError
}
return Error
}
}

View File

@ -0,0 +1,60 @@
const State = require('../State')
class PackState extends State {
async apply() {
if ( !(await this.check()) ) {
const path = await this._path()
const destination = await this._destination()
const type = await this._get_type()
const cd_cmd = await this._host.get_directory_change_command(await path.parent())
if ( type === 'tar' ) {
const tar_cmd = `${cd_cmd} && tar czf "${destination.path}" "${path.name()}"`
await this._host.run(tar_cmd)
} else if ( type === 'zip' ) {
const zip_cmd = `${cd_cmd} && zip -r "${destination.path}" "${path.name()}"`
await this._host.run(zip_cmd)
}
}
}
async check() {
const dest = await this._destination()
return dest.is_valid()
}
async reverse() {
if ( await this.check() ) {
const destination = await this._destination()
await destination.classify()
if (destination.is_valid()) await destination.unlink()
}
}
async _get_type() {
if ( this._config.format ) {
if ( this._config.format === 'tar' ) return 'tar'
else if ( this._config.format === 'zip' ) return 'zip'
throw new Error('Invalid unpack format: ' + this._config.type)
} else {
const dest = await this._destination()
if ( dest.path.endsWith('.tar.gz') || dest.path.endsWith('.tgz') ) return 'tar'
else if ( dest.path.endsWith('.zip') ) return 'zip'
throw new Error(`Unable to determine unpack type from destination: ${dest}`)
}
}
async _destination() {
if ( !this._config.destination ) throw new Error('Missing destination config for PackState.')
return await this._host.get_path(this._config.destination)
}
async _path() {
const path = await this._host.get_path(this._config.path)
await path.classify()
if ( !path.is_valid() ) throw new Error(`Invalid path for PathState: ${path}`)
return path
}
}
module.exports = exports = PackState

View File

@ -34,10 +34,10 @@ class UnpackState extends State {
}
async _get_type() {
if ( this._config.type ) {
if ( this._config.type === 'tar' ) return 'tar'
else if ( this._config.type === 'zip' ) return 'zip'
throw new Error('Invalid unpack type: ' + this._config.type)
if ( this._config.format ) {
if ( this._config.format === 'tar' ) return 'tar'
else if ( this._config.format === 'zip' ) return 'zip'
throw new Error('Invalid unpack format: ' + this._config.type)
} else {
const path = await this._path()
if ( path.path.endsWith('.tar.gz') || path.path.endsWith('.tgz') ) return 'tar'

View File

@ -12,15 +12,15 @@ const { Service } = require('flitter-di')
class StatesService extends Service {
static #state_map = {
// TODO apache and nginx states - virtual host, reverse proxy
// TODO file pack state - zip, tarball
// TODO package repository states - import keys, install repository
// TODO service manager states - service enabled, service installed, running, stopped
// TODO service manager states - service enabled, service installed, stopped
// TODO git states - clone repo, ref checked out
// TODO package states - installed, uninstalled
// TODO package states - uninstalled
'fs.file': require('../classes/state/fs/FileState'),
'fs.directory': require('../classes/state/fs/DirectoryState'),
'fs.unpack': require('../classes/state/fs/UnpackState'),
'fs.pack': require('../classes/state/fs/PackState'),
'fs.permission': require('../classes/state/fs/PermissionState'),
'fs.ownership': require('../classes/state/fs/OwnerState'),