Skip to content

Commit

Permalink
Merge pull request #1215 from lamassu/release-10.0.4
Browse files Browse the repository at this point in the history
Release 10.0.4
  • Loading branch information
RafaelTaranto authored Nov 11, 2024
2 parents 27b25d9 + 7b35435 commit b547bc6
Show file tree
Hide file tree
Showing 11 changed files with 189 additions and 119 deletions.
8 changes: 4 additions & 4 deletions build-scripts/Dockerfile.ci
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ FROM lamassu/upboard-build:3.0 as build
tar -xzf - -C /usr/lib

RUN apt-get install -y libusb-1.0-0-dev
RUN curl -sL https://ssubucket.ams3.digitaloceanspaces.com/libgenmegadevice_amd64_0.7-0.deb.gpg -o /tmp/libgenmegadevice_amd64_0.7-0.deb.gpg && \
gpg --batch --yes --passphrase "$GPG_PASSPHRASE" --output /tmp/libgenmegadevice_amd64_0.7-0.deb --decrypt /tmp/libgenmegadevice_amd64_0.7-0.deb.gpg && \
dpkg -i /tmp/libgenmegadevice_amd64_0.7-0.deb && \
rm /tmp/libgenmegadevice_amd64_0.7-0.deb /tmp/libgenmegadevice_amd64_0.7-0.deb.gpg
RUN curl -sL https://ssubucket.ams3.digitaloceanspaces.com/libgenmegadevice_amd64_0.7-1.deb.gpg -o /tmp/libgenmegadevice_amd64_0.7-1.deb.gpg && \
gpg --batch --yes --passphrase "$GPG_PASSPHRASE" --output /tmp/libgenmegadevice_amd64_0.7-1.deb --decrypt /tmp/libgenmegadevice_amd64_0.7-1.deb.gpg && \
dpkg -i /tmp/libgenmegadevice_amd64_0.7-1.deb && \
rm /tmp/libgenmegadevice_amd64_0.7-1.deb /tmp/libgenmegadevice_amd64_0.7-1.deb.gpg

ARG NPM_TOKEN
COPY ["package.json", "package-lock.json", ".npmrc", "./"]
Expand Down
2 changes: 1 addition & 1 deletion deploy/codebase/ci-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ declare -A boards_and_models=(
["up4000"]="sintra gaia tejo aveiro"
["coincloud"]="jcm-ipro-rc mei-bnr mei-scr"
["generalbytes"]="batm3 batm7in"
["genmega"]="gemini gmuk1 gmuk2"
["genmega"]="gemini gmuk1 gmuk2 wallkiosk"
)

# Loop through each board and its models
Expand Down
121 changes: 100 additions & 21 deletions deploy/codebase/lamassu-machine-manager.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
'use strict';

const cp = require('child_process');
const fs = require('fs');
const { mkdir, writeFile } = require('fs/promises');
const path = require('path');
const async = require('./async');
const cp = require('child_process');
const report = require('./report').report;

const hardwareCode = process.argv[2];
Expand All @@ -14,7 +16,7 @@ const packagePath = `${basePath}/package/subpackage`

const machineWithMultipleCodes = ['upboard', 'up4000', 'coincloud', 'generalbytes', 'genmega']

const path = machineWithMultipleCodes.includes(hardwareCode) ?
const hardwarePath = machineWithMultipleCodes.includes(hardwareCode) ?
`${packagePath}/hardware/${hardwareCode}/${machineCode}` :
`${packagePath}/hardware/${hardwareCode}`

Expand All @@ -27,15 +29,36 @@ const udevPath = `${packagePath}/udev/aaeon`
const TIMEOUT = 600000;
const applicationParentFolder = hardwareCode === 'aaeon' ? '/opt/apps/machine' : '/opt'

const LOG = msg => report(null, msg, () => {})
const ERROR = err => report(err, null, () => {})

function command(cmd, cb) {
console.log(`Running command \`${cmd}\``)
LOG(`Running command \`${cmd}\``)
cp.exec(cmd, {timeout: TIMEOUT}, function(err) {
cb(err);
});
}

const isLMX = () => {
try {
return fs.readFileSync('/etc/os-release', { encoding: 'utf8' })
.split('\n')
.includes('IMAGE_ID=lamassu-machine-xubuntu')
} catch (err) {
return false
}
}

const getOSUser = () => {
try {
return (!machineWithMultipleCodes.includes(hardwareCode) || isLMX()) ? 'lamassu' : 'ubilinux'
} catch (err) {
return 'ubilinux'
}
}

function updateUdev (cb) {
console.log("Updating udev rules")
LOG("Updating udev rules")
if (hardwareCode !== 'aaeon') return cb()
return async.series([
async.apply(command, `cp ${udevPath}/* /etc/udev/rules.d/`),
Expand All @@ -48,59 +71,108 @@ function updateUdev (cb) {
}

function updateSupervisor (cb) {
console.log("Updating Supervisor services")
LOG("Updating Supervisor services")
if (hardwareCode === 'aaeon') return cb()

const isLMX = () =>
fs.readFileSync('/etc/os-release', { encoding: 'utf8' })
.split('\n')
.includes('IMAGE_ID=lamassu-machine-xubuntu')
const getServices = () => {
const extractServices = stdout => {
const services = stdout
.split('\n')
.flatMap(line => {
const service = line.split(' ', 1)?.[0]
return (!service || service === 'lamassu-watchdog') ? [] : [service]
})
.join(' ')
/*
* NOTE: Keep old behavior in case we don't get the expected output:
* update and restart all services. result:finished won't work.
*/
return services.length > 0 ? services : 'all'
}

const getOSUser = () => {
try {
return (!machineWithMultipleCodes.includes(hardwareCode) || isLMX()) ? 'lamassu' : 'ubilinux'
const stdout = cp.execFileSync("supervisorctl", ["status"], { encoding: 'utf8', timeout: 10000 })
return extractServices(stdout)
} catch (err) {
return 'ubilinux'
return err.status === 3 ?
extractServices(err.stdout) :
'all' /* NOTE: see note above */
}
}

const osuser = getOSUser()
const services = getServices()

async.series([
async.apply(command, `cp ${supervisorPath}/* /etc/supervisor/conf.d/`),
async.apply(command, `sed -i 's|^user=.*\$|user=${osuser}|;' /etc/supervisor/conf.d/lamassu-browser.conf || true`),
async.apply(command, 'supervisorctl update'),
async.apply(command, 'supervisorctl restart all'),
async.apply(command, `supervisorctl update ${services}`),
async.apply(command, `supervisorctl restart ${services}`),
], err => {
if (err) throw err;
cb()
})
}

const updateSystemd = cb => {
LOG("Make Supervisor start after X")
const override = dm => `[Unit]\nAfter=${dm}.service\nWants=${dm}.service\n`
const SUPERVISOR_OVERRIDE = "/etc/systemd/system/supervisor.service.d/override.conf"
return mkdir(path.dirname(SUPERVISOR_OVERRIDE), { recursive: true })
.then(() => isLMX() ? 'lightdm' : 'sddm') // Assume Ubilinux if not l-m-x
.then(dm => writeFile(SUPERVISOR_OVERRIDE, override(dm), { mode: 0o600, flush: true }))
.then(() => new Promise((resolve, reject) =>
cp.execFile('systemctl', ['daemon-reload'], { timeout: 10000 },
(error, _stdout, _stderr) => error ? reject(error) : resolve()
)
))
.then(() => cb())
.catch(err => cb(err))
}

function restartWatchdogService (cb) {
async.series([
async.apply(command, 'supervisorctl update lamassu-watchdog'),
async.apply(command, 'supervisorctl restart lamassu-watchdog'),
], err => {
if (err) throw err;
cb()
})
}

function updateAcpChromium (cb) {
console.log("Updating ACP Chromium")
LOG("Updating ACP Chromium")
if (hardwareCode !== 'aaeon') return cb()
return async.series([
async.apply(command, `cp ${path}/sencha-chrome.conf /home/iva/.config/upstart/`),
async.apply(command, `cp ${path}/start-chrome /home/iva/`),
async.apply(command, `cp ${hardwarePath}/sencha-chrome.conf /home/iva/.config/upstart/`),
async.apply(command, `cp ${hardwarePath}/start-chrome /home/iva/`),
], function(err) {
if (err) throw err;
cb()
});
}

function installDeviceConfig (cb) {
console.log("Installing `device_config.json`")
LOG("Installing `device_config.json`")
try {
const currentDeviceConfigPath = `${applicationParentFolder}/lamassu-machine/device_config.json`
const newDeviceConfigPath = `${path}/device_config.json`
const newDeviceConfigPath = `${hardwarePath}/device_config.json`

// Updates don't necessarily need to carry a device_config.json file
if (!fs.existsSync(newDeviceConfigPath)) return cb()

const currentDeviceConfig = require(currentDeviceConfigPath)
const newDeviceConfig = require(newDeviceConfigPath)

if (currentDeviceConfig.frontFacingCamera) {
newDeviceConfig.frontFacingCamera = currentDeviceConfig.frontFacingCamera
}
if (currentDeviceConfig.scanner) {
newDeviceConfig.scanner = currentDeviceConfig.scanner
}
if (currentDeviceConfig.machineLocation) {
newDeviceConfig.machineLocation = currentDeviceConfig.machineLocation
}
if (currentDeviceConfig.cryptomatModel) {
newDeviceConfig.cryptomatModel = currentDeviceConfig.cryptomatModel
}
Expand Down Expand Up @@ -155,14 +227,21 @@ const upgrade = () => {
async.apply(command, `mv ${applicationParentFolder}/lamassu-machine/camera-streamer/camera-streamer.${arch} ${applicationParentFolder}/lamassu-machine/camera-streamer/camera-streamer`),
async.apply(installDeviceConfig),
async.apply(updateSupervisor),
async.apply(updateSystemd),
async.apply(updateUdev),
async.apply(updateAcpChromium),
async.apply(report, null, 'finished.')
async.apply(report, null, 'finished.'),
async.apply(restartWatchdogService),
]

return new Promise((resolve, reject) => {
async.series(commands, function(err) {
return err ? reject(err) : resolve();
if (err) {
ERROR(err)
return reject(err)
} else {
return resolve()
}
});
})
}
Expand Down
2 changes: 1 addition & 1 deletion lib/genmega/genmega-dispenser/genmega-dispenser.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const _ = require('lodash/fp')
const { cdu } = require('genmega')
const { cdu } = require('@lamassu/genmega')

const MAX_SUPPORTED_CASSETTES = 4

Expand Down
2 changes: 1 addition & 1 deletion lib/genmega/genmega-validator/genmega-validator.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { EventEmitter } = require('events')
const util = require('util')
const _ = require('lodash/fp')
const { bau } = require('genmega')
const { bau } = require('@lamassu/genmega')

const BN = require('../../bn')

Expand Down
9 changes: 9 additions & 0 deletions lib/mei/bnr_advance.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ const _ = require('lodash/fp')
const denominationsTable = require('./denominations')
const BN = require('../bn')

const CASH_UNIT_CHANGED = 6154

const BnrAdvance = function () {
EventEmitter.call(this)
this.fiatCode = null
Expand Down Expand Up @@ -72,6 +74,13 @@ BnrAdvance.prototype.run = function run (cb) {
.then(emitter => {
console.log('BNR is ready')
this.bnrEmitter = emitter
this.bnrEmitter.on('event', it => {
if (it.type === 'status' && it.status === CASH_UNIT_CHANGED) {
this.emit('stackerOpen')
this.emit('actionRequiredMaintenance')
}
})

})
.catch(err => {
console.error('Error initializing BNR:', err)
Expand Down
4 changes: 2 additions & 2 deletions lib/printer/genmega.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { rpu } = require('genmega')
const { rpu } = require('@lamassu/genmega')

const ASCII = {
ESC: 0x1b,
Expand Down Expand Up @@ -140,7 +140,7 @@ function printWallet (wallet, printerCfg, code) {
const { return_int: return_intPrintText, return_message: return_messagePrintText } = rpu.printText(buffer)
if (return_intPrintText < 0) return Promise.reject(new Error(return_messagePrintText))

const { return_int: return_intCutPaper, return_message: return_intCutPaper } = rpu.cutPaper()
const { return_int: return_intCutPaper, return_message: return_messageCutPaper } = rpu.cutPaper()
if (return_intCutPaper < 0) return Promise.reject(new Error(return_messageCutPaper))
return Promise.resolve()
})
Expand Down
2 changes: 1 addition & 1 deletion lib/scanner-genmega.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const _ = require('lodash/fp')
const { utils: coinUtils } = require('@lamassu/coins')
const { bcs } = require('genmega')
const { bcs } = require('@lamassu/genmega')

const Pdf417Parser = require('./compliance/parsepdf417')
const scanner = require('./scanner')
Expand Down
13 changes: 10 additions & 3 deletions lib/update/updater.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,21 @@ Updater.prototype._update = function _update () {

function noop () {}

const readConnectionInfo = dataPath => {
try {
const connectionInfoPath = path.resolve(dataPath, 'connection_info.json')
return JSON.parse(fs.readFileSync(connectionInfoPath))
} catch (err) {
return {}
}
}

Updater.prototype.updateHeaders = function updateHeaders (options) {
var dataPath = path.resolve(__dirname, '..', '..', this.config.dataPath)
var machineInfo = machineInfoLoader.load(dataPath)
var watchdogInfo = watchdogInfoLoader.load(dataPath)

var connectionInfoPath = path.resolve(dataPath, 'connection_info.json')
const connectionInfo = JSON.parse(fs.readFileSync(connectionInfoPath))

const connectionInfo = readConnectionInfo(dataPath)
if (connectionInfo.host) {
options = _.assign(options, {
'device-host': crypto.createHash('sha256').update(connectionInfo.host).digest('hex')
Expand Down
Loading

0 comments on commit b547bc6

Please sign in to comment.