129 lines
4.6 KiB
JavaScript
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
|