maestro/app/classes/logical/packages/DNFManager.js
2020-02-21 00:36:55 -06:00

129 lines
4.6 KiB
JavaScript

const PackageManager = require('./PackageManager')
class DNFManager extends PackageManager {
_command_install_package = 'dnf install -y %%PACKAGE%%'
_command_uninstall_package = 'dnf remove -y %%PACKAGE%%'
_command_update_package = 'dnf update -y %%PACKAGE%%'
_command_reinstall_package = 'dnf reinstall -y %%PACKAGE%%'
_command_add_repo = 'dnf config-manager -y --add-repo="%%URI%%"'
_command_clear_cache = 'dnf clean all'
_command_count_installed = 'dnf list installed -q | wc -l'
_command_count_available = 'dnf list available -q | wc -l'
async status(pkg) {
const result = await this._host.execute(`dnf info -q --installed ${pkg}`)
if ( result.exit_code === 0 ) {
const data = this._data_from_result(result.clean_out)
data.state = this.constructor.PACKAGE_STATE_INSTALLED
return data
} else {
const available_result = await this._host.execute(`dnf info -q --available ${pkg}`)
if ( available_result.exit_code === 0 ) {
const data = this._data_from_result(available_result.clean_out)
data.state = this.constructor.PACKAGE_STATE_AVAILABLE
return data
} else {
return {
name: pkg,
state: this.constructor.PACKAGE_STATE_UNKNOWN,
}
}
}
}
async list_updates() {
const result = await this._host.execute(`dnf check-update -q`)
// 100 is the known exit code for successful result, but updates pending
if ( ![0, 100].includes(result.exit_code) ) {
throw new Error('Unable to check for updates: '+result.stderr.join('\n'))
}
const updates = []
for ( const line of result.clean_out ) {
const parts = line.trim().split(' ').filter(Boolean)
const data = this._package_info_from_line_parts(parts)
updates.push(data)
}
return updates
}
async list_repos() {
const result = await this._host.execute(`dnf repolist all -q`)
if ( result.exit_code !== 0 ) {
throw new Error('Unable to determine repositories: '+result.stderr.join('\n'))
}
const offset_length = result.clean_out[0].toLowerCase().indexOf('repo name')
return result.clean_out.slice(1).map(line => line.substr(0, offset_length).trim())
}
async list_installed() {
const result = await this._host.execute(`dnf list installed -q`)
if ( result.exit_code !== 0 ) {
throw new Error('Unable to determine installed packages: '+result.stderr.join('\n'))
}
const results = []
for ( const line of result.clean_out.slice(1) ) {
const parts = line.trim().split(' ').filter(Boolean)
const data = this._package_info_from_line_parts(parts)
results.push(data)
}
return results
}
async search(term) {
const result = await this._host.execute(`dnf search ${term} -q`)
if ( result.exit_code !== 0 ) {
throw new Error('Unable to complete search: '+result.stderr.join('\n'))
}
const results = []
for ( const line of result.clean_out ) {
if ( !line.trim().startsWith('=') ) {
const parts = line.split(':').map(x => x.trim())
const data = this._package_info_from_line_parts(parts)
if ( data.version ) {
data.summary = data.version
delete data.version
}
results.push(data)
}
}
return results
}
_data_from_result(stdout) {
const data = {}
for ( const line of stdout ) {
const parts = line.split(':').map(x => String(x).trim())
if ( parts.length > 1 && parts[0] ) {
let key = parts[0].toLowerCase()
if ( key === 'from repo' ) key = 'repo'
data[key] = parts.slice(1).join(':')
}
}
return data
}
_package_info_from_line_parts(parts) {
const data = {}
if ( parts.length > 0 ) {
data.name = parts[0]
if ( data.name.indexOf('.') >= 0 ) {
const arch_parts = data.name.split('.').reverse()
data.architecture = arch_parts[0]
data.name = arch_parts.slice(1).reverse().join('.')
}
}
if ( parts.length > 1 ) data.version = parts[1]
if ( parts.length > 2 ) data.repository = parts[2]
return data
}
}
module.exports = exports = DNFManager