mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2024-12-24 07:46:41 +00:00
Merge pull request #1221 from balena-io/lint-js
Update to balena-lint and enable javascript linting
This commit is contained in:
commit
198c1a8fab
@ -2,7 +2,7 @@
|
||||
"*.coffee": [
|
||||
"resin-lint"
|
||||
],
|
||||
"*.ts": [
|
||||
"*.ts$|!(*webpack.config).js$": [
|
||||
"resin-lint --typescript --fix",
|
||||
],
|
||||
"test/**/*.coffee": [
|
||||
|
@ -66,7 +66,7 @@ COPY src /usr/src/app/src
|
||||
COPY test /usr/src/app/test
|
||||
COPY typings /usr/src/app/typings
|
||||
|
||||
RUN npm test \
|
||||
RUN npm run test-nolint \
|
||||
&& npm run build
|
||||
|
||||
##############################################################################
|
||||
|
68
circle.yml
68
circle.yml
@ -24,8 +24,7 @@ defaults: &defaults
|
||||
name: Install npm dependencies
|
||||
working_directory: /tmp/build/automation
|
||||
command: |
|
||||
JOBS=max npm install \
|
||||
&& npm cache clean --force
|
||||
JOBS=max npm install
|
||||
- run:
|
||||
name: Initialize the submodules (yocto layers)
|
||||
command: |
|
||||
@ -62,6 +61,22 @@ defaults: &defaults
|
||||
|
||||
version: 2
|
||||
jobs:
|
||||
generic:
|
||||
docker:
|
||||
- image: library/node:10
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Run tests
|
||||
command: |
|
||||
JOBS=max npm ci && npm test
|
||||
environment:
|
||||
DOCKER_USERNAME: travisciresin
|
||||
ARCH: amd64
|
||||
PUSH_IMAGES: 'true'
|
||||
STAGING_API_ENDPOINT: https://api.balena-staging.com
|
||||
PRODUCTION_API_ENDPOINT: https://api.balena-cloud.com
|
||||
DEBUG: ''
|
||||
amd64:
|
||||
<<: *defaults
|
||||
environment:
|
||||
@ -175,15 +190,40 @@ workflows:
|
||||
version: 2
|
||||
build_and_maybe_deploy:
|
||||
jobs:
|
||||
- amd64
|
||||
- i386
|
||||
- rpi
|
||||
- armv7hf
|
||||
- aarch64
|
||||
- i386-nlp
|
||||
- amd64-debug
|
||||
- i386-debug
|
||||
- rpi-debug
|
||||
- armv7hf-debug
|
||||
- aarch64-debug
|
||||
- i386-nlp-debug
|
||||
- generic
|
||||
- amd64:
|
||||
requires:
|
||||
- generic
|
||||
- i386:
|
||||
requires:
|
||||
- generic
|
||||
- rpi:
|
||||
requires:
|
||||
- generic
|
||||
- armv7hf:
|
||||
requires:
|
||||
- generic
|
||||
- aarch64:
|
||||
requires:
|
||||
- generic
|
||||
- i386-nlp:
|
||||
requires:
|
||||
- generic
|
||||
- amd64-debug:
|
||||
requires:
|
||||
- generic
|
||||
- i386-debug:
|
||||
requires:
|
||||
- generic
|
||||
- rpi-debug:
|
||||
requires:
|
||||
- generic
|
||||
- armv7hf-debug:
|
||||
requires:
|
||||
- generic
|
||||
- aarch64-debug:
|
||||
requires:
|
||||
- generic
|
||||
- i386-nlp-debug:
|
||||
requires:
|
||||
- generic
|
||||
|
129
package-lock.json
generated
129
package-lock.json
generated
@ -82,6 +82,71 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@balena/lint": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@balena/lint/-/lint-4.1.0.tgz",
|
||||
"integrity": "sha512-5db6EhVYblBh70J8k9LZYww1ntd3xwL/4hkysyB70itS/wBQLIMqGIVaiqfpayN61mYdbs24Fm5ijgDkhT4OLQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/depcheck": "^0.6.0",
|
||||
"@types/glob": "^7.1.1",
|
||||
"@types/lodash": "^4.14.149",
|
||||
"@types/node": "^8.10.59",
|
||||
"@types/optimist": "0.0.29",
|
||||
"@types/prettier": "^1.18.3",
|
||||
"coffee-script": "^1.10.0",
|
||||
"coffeelint": "^1.15.0",
|
||||
"coffeescope2": "^0.4.5",
|
||||
"depcheck": "^0.6.7",
|
||||
"glob": "^7.1.6",
|
||||
"lodash": "^4.17.15",
|
||||
"optimist": "^0.6.1",
|
||||
"prettier": "^1.19.1",
|
||||
"tslint": "^5.20.1",
|
||||
"tslint-config-prettier": "^1.18.0",
|
||||
"tslint-no-unused-expression-chai": "^0.1.4",
|
||||
"typescript": "^3.7.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/glob": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
|
||||
"integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/events": "*",
|
||||
"@types/minimatch": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "8.10.59",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.59.tgz",
|
||||
"integrity": "sha512-8RkBivJrDCyPpBXhVZcjh7cQxVBSmRk9QM7hOketZzp6Tg79c0N8kkpAIito9bnJ3HCVCHVYz+KHTEbfQNfeVQ==",
|
||||
"dev": true
|
||||
},
|
||||
"coffee-script": {
|
||||
"version": "1.12.7",
|
||||
"resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz",
|
||||
"integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==",
|
||||
"dev": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@resin.io/types-hidepath": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@resin.io/types-hidepath/-/types-hidepath-1.0.1.tgz",
|
||||
@ -398,9 +463,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/prettier": {
|
||||
"version": "1.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.0.tgz",
|
||||
"integrity": "sha512-gDE8JJEygpay7IjA/u3JiIURvwZW08f0cZSZLAzFoX/ZmeqvS0Sqv+97aKuHpNsalAMMhwPe+iAS6fQbfmbt7A==",
|
||||
"version": "1.19.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz",
|
||||
"integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/range-parser": {
|
||||
@ -6363,7 +6428,7 @@
|
||||
"dependencies": {
|
||||
"ansi-escapes": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
|
||||
"resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
|
||||
"integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
|
||||
"dev": true
|
||||
},
|
||||
@ -7059,7 +7124,7 @@
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz",
|
||||
"resolved": "http://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz",
|
||||
"integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@ -9673,60 +9738,6 @@
|
||||
"lodash": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"resin-lint": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/resin-lint/-/resin-lint-3.2.4.tgz",
|
||||
"integrity": "sha512-VtsEAG8fgSkZMnZ2CPLtukEqJMjFBSya8T//AjUHGEqFr/M8aUfdSZvIXq8vVFholaCMW84XBmVu9zWK8H0arg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/depcheck": "^0.6.0",
|
||||
"@types/glob": "^5.0.35",
|
||||
"@types/lodash": "^4.14.149",
|
||||
"@types/node": "^8.10.59",
|
||||
"@types/optimist": "0.0.29",
|
||||
"@types/prettier": "^1.18.3",
|
||||
"coffee-script": "^1.10.0",
|
||||
"coffeelint": "^1.15.0",
|
||||
"coffeescope2": "^0.4.5",
|
||||
"depcheck": "^0.6.7",
|
||||
"glob": "^7.1.6",
|
||||
"lodash": "^4.17.15",
|
||||
"optimist": "^0.6.1",
|
||||
"prettier": "^1.19.1",
|
||||
"tslint": "^5.20.1",
|
||||
"tslint-config-prettier": "^1.18.0",
|
||||
"tslint-no-unused-expression-chai": "^0.1.4",
|
||||
"typescript": "^3.7.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "8.10.59",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.59.tgz",
|
||||
"integrity": "sha512-8RkBivJrDCyPpBXhVZcjh7cQxVBSmRk9QM7hOketZzp6Tg79c0N8kkpAIito9bnJ3HCVCHVYz+KHTEbfQNfeVQ==",
|
||||
"dev": true
|
||||
},
|
||||
"coffee-script": {
|
||||
"version": "1.12.7",
|
||||
"resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz",
|
||||
"integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==",
|
||||
"dev": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"resin-register-device": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "http://registry.npmjs.org/resin-register-device/-/resin-register-device-3.0.0.tgz",
|
||||
|
19
package.json
19
package.json
@ -9,25 +9,24 @@
|
||||
},
|
||||
"scripts": {
|
||||
"start": "./entry.sh",
|
||||
"build": "webpack",
|
||||
"build:debug": "npm run typescript:release && npm run coffeescript:release && npm run migrations:copy && npm run packagejson:copy",
|
||||
"build": "npm run typescript:release && webpack",
|
||||
"build:debug": "npm run typescript:release && npm run coffeescript:release && npm run packagejson:copy",
|
||||
"lint": "npm run lint:coffee && npm run lint:typescript",
|
||||
"test": "npm run lint && npm run test:build && TEST=1 JUNIT_REPORT_PATH=report.xml istanbul cover _mocha && npm run coverage",
|
||||
"test:build": "npm run typescript:test-build && npm run coffeescript:test && npm run testitems:copy && npm run migrations:copy-test && npm run packagejson:copy",
|
||||
"test": "npm run lint && npm run test-nolint",
|
||||
"test-nolint": "npm run test:build && TEST=1 JUNIT_REPORT_PATH=report.xml istanbul cover _mocha && npm run coverage",
|
||||
"test:build": "npm run typescript:test-build && npm run coffeescript:test && npm run testitems:copy && npm run packagejson:copy",
|
||||
"coverage": "istanbul report text && istanbul report html",
|
||||
"test:fast": "TEST=1 mocha --opts test/fast-mocha.opts",
|
||||
"test:debug": "npm run test:build && TEST=1 mocha --inspect-brk",
|
||||
"prettify": "resin-lint --typescript --fix src/ test/ typings/",
|
||||
"prettify": "balena-lint -e ts -e js --typescript --fix src/ test/ typings/ webpack.config.js",
|
||||
"typescript:test-build": "tsc --project tsconfig.json",
|
||||
"typescript:release": "tsc --project tsconfig.release.json && cp -r build/src/* build && rm -rf build/src",
|
||||
"coffeescript:test": "coffee -m -c -o build .",
|
||||
"coffeescript:release": "coffee -m -c -o build src",
|
||||
"migrations:copy": "cp -r src/migrations build/",
|
||||
"migrations:copy-test": "cp -r src/migrations build/src",
|
||||
"packagejson:copy": "cp package.json build/",
|
||||
"testitems:copy": "cp -r test/data build/test/",
|
||||
"lint:coffee": "resin-lint src/ test/",
|
||||
"lint:typescript": "resin-lint --typescript src/ test/ typings/ && tsc --noEmit"
|
||||
"lint:coffee": "balena-lint src/ test/",
|
||||
"lint:typescript": "balena-lint -e ts -e js --typescript src/ test/ typings/ && tsc --noEmit"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
@ -38,6 +37,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@balena/contrato": "^0.2.1",
|
||||
"@balena/lint": "^4.1.0",
|
||||
"@types/bluebird": "^3.5.30",
|
||||
"@types/chai": "^4.2.10",
|
||||
"@types/chai-as-promised": "^7.1.2",
|
||||
@ -104,7 +104,6 @@
|
||||
"pinejs-client-request": "^5.2.0",
|
||||
"pretty-ms": "^5.1.0",
|
||||
"request": "^2.88.2",
|
||||
"resin-lint": "^3.2.4",
|
||||
"resin-register-device": "^3.0.0",
|
||||
"resumable-request": "^2.0.0",
|
||||
"rimraf": "^2.6.2",
|
||||
|
@ -7,130 +7,150 @@
|
||||
// a few dropColumn and dropTable calls to delete things that were removed throughout the supervisor's
|
||||
// history without actually adding drop statements (mostly just becoming unused, but still there).
|
||||
|
||||
exports.up = function (knex, Promise) {
|
||||
const addColumn = function (table, column, type) {
|
||||
return knex.schema.hasColumn(table, column)
|
||||
.then((exists) => {
|
||||
if (!exists) {
|
||||
return knex.schema.table(table, (t) => { return t[type](column) })
|
||||
}
|
||||
})
|
||||
}
|
||||
const dropColumn = function (table, column) {
|
||||
return knex.schema.hasColumn(table, column)
|
||||
.then((exists) => {
|
||||
if (exists) {
|
||||
return knex.schema.table(table, (t) => { return t.dropColumn(column) })
|
||||
}
|
||||
})
|
||||
}
|
||||
const createTableOrRun = function (tableName, tableCreator, runIfTableExists) {
|
||||
return knex.schema.hasTable(tableName)
|
||||
.then((exists) => {
|
||||
if (!exists) {
|
||||
return knex.schema.createTable(tableName, tableCreator)
|
||||
} else if (runIfTableExists != null) {
|
||||
return runIfTableExists()
|
||||
}
|
||||
})
|
||||
}
|
||||
const dropTable = function (tableName) {
|
||||
return knex.schema.hasTable(tableName)
|
||||
.then((exists) => {
|
||||
if (exists) {
|
||||
return knex.schema.dropTable(tableName)
|
||||
}
|
||||
})
|
||||
}
|
||||
exports.up = function(knex, Promise) {
|
||||
const addColumn = function(table, column, type) {
|
||||
return knex.schema.hasColumn(table, column).then(exists => {
|
||||
if (!exists) {
|
||||
return knex.schema.table(table, t => {
|
||||
return t[type](column);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
const dropColumn = function(table, column) {
|
||||
return knex.schema.hasColumn(table, column).then(exists => {
|
||||
if (exists) {
|
||||
return knex.schema.table(table, t => {
|
||||
return t.dropColumn(column);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
const createTableOrRun = function(tableName, tableCreator, runIfTableExists) {
|
||||
return knex.schema.hasTable(tableName).then(exists => {
|
||||
if (!exists) {
|
||||
return knex.schema.createTable(tableName, tableCreator);
|
||||
} else if (runIfTableExists != null) {
|
||||
return runIfTableExists();
|
||||
}
|
||||
});
|
||||
};
|
||||
const dropTable = function(tableName) {
|
||||
return knex.schema.hasTable(tableName).then(exists => {
|
||||
if (exists) {
|
||||
return knex.schema.dropTable(tableName);
|
||||
}
|
||||
});
|
||||
};
|
||||
return Promise.all([
|
||||
createTableOrRun('config', (t) => {
|
||||
t.string('key').primary()
|
||||
t.string('value')
|
||||
createTableOrRun('config', t => {
|
||||
t.string('key').primary();
|
||||
t.string('value');
|
||||
}),
|
||||
createTableOrRun('deviceConfig', (t) => {
|
||||
t.json('values')
|
||||
t.json('targetValues')
|
||||
createTableOrRun('deviceConfig', t => {
|
||||
t.json('values');
|
||||
t.json('targetValues');
|
||||
}).then(() => {
|
||||
return knex('deviceConfig').select()
|
||||
.then((deviceConfigs) => {
|
||||
if (deviceConfigs.length == 0) {
|
||||
return knex('deviceConfig').insert({ values: '{}', targetValues: '{}' })
|
||||
return knex('deviceConfig')
|
||||
.select()
|
||||
.then(deviceConfigs => {
|
||||
if (deviceConfigs.length === 0) {
|
||||
return knex('deviceConfig').insert({
|
||||
values: '{}',
|
||||
targetValues: '{}',
|
||||
});
|
||||
}
|
||||
})
|
||||
}),
|
||||
createTableOrRun('app', (t) => {
|
||||
t.increments('id').primary()
|
||||
t.string('name')
|
||||
t.string('containerName')
|
||||
t.string('commit')
|
||||
t.string('imageId')
|
||||
t.string('appId')
|
||||
t.boolean('privileged')
|
||||
t.json('env')
|
||||
t.json('config')
|
||||
t.boolean('markedForDeletion')
|
||||
}, () => {
|
||||
return Promise.all([
|
||||
addColumn('app', 'commit', 'string'),
|
||||
addColumn('app', 'appId', 'string'),
|
||||
addColumn('app', 'containerName', 'string'),
|
||||
addColumn('app', 'config', 'json'),
|
||||
addColumn('app', 'markedForDeletion', 'boolean'),
|
||||
dropColumn('app', 'containerId')
|
||||
]).then(() => {
|
||||
//When updating from older supervisors, config can be null
|
||||
return knex('app').update({ config: '{}' }).whereNull('config')
|
||||
.then(() => {
|
||||
knex('app').update({ markedForDeletion: false }).whereNull('markedForDeletion')
|
||||
})
|
||||
})
|
||||
}),
|
||||
createTableOrRun('dependentApp', (t) => {
|
||||
t.increments('id').primary()
|
||||
t.string('appId')
|
||||
t.string('parentAppId')
|
||||
t.string('name')
|
||||
t.string('commit')
|
||||
t.string('imageId')
|
||||
t.json('config')
|
||||
t.json('environment')
|
||||
}, () => {
|
||||
return addColumn('dependentApp', 'environment', 'json')
|
||||
}),
|
||||
createTableOrRun('dependentDevice', (t) => {
|
||||
t.increments('id').primary()
|
||||
t.string('uuid')
|
||||
t.string('appId')
|
||||
t.string('localId')
|
||||
t.string('device_type')
|
||||
t.string('logs_channel')
|
||||
t.string('deviceId')
|
||||
t.boolean('is_online')
|
||||
t.string('name')
|
||||
t.string('status')
|
||||
t.string('download_progress')
|
||||
t.string('is_managed_by')
|
||||
t.dateTime('lock_expiry_date')
|
||||
t.string('commit')
|
||||
t.string('targetCommit')
|
||||
t.json('environment')
|
||||
t.json('targetEnvironment')
|
||||
t.json('config')
|
||||
t.json('targetConfig')
|
||||
t.boolean('markedForDeletion')
|
||||
}, () => {
|
||||
return Promise.all([
|
||||
addColumn('dependentDevice', 'markedForDeletion', 'boolean'),
|
||||
addColumn('dependentDevice', 'localId', 'string'),
|
||||
addColumn('dependentDevice', 'is_managed_by', 'string'),
|
||||
addColumn('dependentDevice', 'lock_expiry_date', 'dateTime')
|
||||
])
|
||||
});
|
||||
}),
|
||||
createTableOrRun(
|
||||
'app',
|
||||
t => {
|
||||
t.increments('id').primary();
|
||||
t.string('name');
|
||||
t.string('containerName');
|
||||
t.string('commit');
|
||||
t.string('imageId');
|
||||
t.string('appId');
|
||||
t.boolean('privileged');
|
||||
t.json('env');
|
||||
t.json('config');
|
||||
t.boolean('markedForDeletion');
|
||||
},
|
||||
() => {
|
||||
return Promise.all([
|
||||
addColumn('app', 'commit', 'string'),
|
||||
addColumn('app', 'appId', 'string'),
|
||||
addColumn('app', 'containerName', 'string'),
|
||||
addColumn('app', 'config', 'json'),
|
||||
addColumn('app', 'markedForDeletion', 'boolean'),
|
||||
dropColumn('app', 'containerId'),
|
||||
]).then(() => {
|
||||
//When updating from older supervisors, config can be null
|
||||
return knex('app')
|
||||
.update({ config: '{}' })
|
||||
.whereNull('config')
|
||||
.then(() => {
|
||||
knex('app')
|
||||
.update({ markedForDeletion: false })
|
||||
.whereNull('markedForDeletion');
|
||||
});
|
||||
});
|
||||
},
|
||||
),
|
||||
createTableOrRun(
|
||||
'dependentApp',
|
||||
t => {
|
||||
t.increments('id').primary();
|
||||
t.string('appId');
|
||||
t.string('parentAppId');
|
||||
t.string('name');
|
||||
t.string('commit');
|
||||
t.string('imageId');
|
||||
t.json('config');
|
||||
t.json('environment');
|
||||
},
|
||||
() => {
|
||||
return addColumn('dependentApp', 'environment', 'json');
|
||||
},
|
||||
),
|
||||
createTableOrRun(
|
||||
'dependentDevice',
|
||||
t => {
|
||||
t.increments('id').primary();
|
||||
t.string('uuid');
|
||||
t.string('appId');
|
||||
t.string('localId');
|
||||
t.string('device_type');
|
||||
t.string('logs_channel');
|
||||
t.string('deviceId');
|
||||
t.boolean('is_online');
|
||||
t.string('name');
|
||||
t.string('status');
|
||||
t.string('download_progress');
|
||||
t.string('is_managed_by');
|
||||
t.dateTime('lock_expiry_date');
|
||||
t.string('commit');
|
||||
t.string('targetCommit');
|
||||
t.json('environment');
|
||||
t.json('targetEnvironment');
|
||||
t.json('config');
|
||||
t.json('targetConfig');
|
||||
t.boolean('markedForDeletion');
|
||||
},
|
||||
() => {
|
||||
return Promise.all([
|
||||
addColumn('dependentDevice', 'markedForDeletion', 'boolean'),
|
||||
addColumn('dependentDevice', 'localId', 'string'),
|
||||
addColumn('dependentDevice', 'is_managed_by', 'string'),
|
||||
addColumn('dependentDevice', 'lock_expiry_date', 'dateTime'),
|
||||
]);
|
||||
},
|
||||
),
|
||||
dropTable('image'),
|
||||
dropTable('container')
|
||||
])
|
||||
}
|
||||
dropTable('container'),
|
||||
]);
|
||||
};
|
||||
|
||||
exports.down = function(knex, Promise) {
|
||||
return Promise.reject(new Error('Not implemented'))
|
||||
}
|
||||
return Promise.reject(new Error('Not implemented'));
|
||||
};
|
||||
|
@ -1,24 +1,23 @@
|
||||
const _ = require('lodash')
|
||||
const _ = require('lodash');
|
||||
|
||||
var tryParse = function (obj) {
|
||||
var tryParse = function(obj) {
|
||||
try {
|
||||
return JSON.parse(obj)
|
||||
return JSON.parse(obj);
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
catch(e) {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var singleToMulticontainerApp = function (app) {
|
||||
var singleToMulticontainerApp = function(app) {
|
||||
// From *very* old supervisors, env or config may be null
|
||||
// so we ignore errors parsing them
|
||||
const conf = tryParse(app.config)
|
||||
const env = tryParse(app.env)
|
||||
const environment = {}
|
||||
const appId = parseInt(app.appId)
|
||||
const conf = tryParse(app.config);
|
||||
const env = tryParse(app.env);
|
||||
const environment = {};
|
||||
const appId = parseInt(app.appId, 10);
|
||||
for (let key in env) {
|
||||
if (!/^RESIN_/.test(key)) {
|
||||
environment[key] = env[key]
|
||||
environment[key] = env[key];
|
||||
}
|
||||
}
|
||||
const newApp = {
|
||||
@ -27,13 +26,17 @@ var singleToMulticontainerApp = function (app) {
|
||||
name: app.name,
|
||||
releaseId: 1,
|
||||
networks: {},
|
||||
volumes: {}
|
||||
}
|
||||
const defaultVolume = 'resin-data'
|
||||
newApp.volumes[defaultVolume] = {}
|
||||
const updateStrategy = _.get(conf, 'RESIN_SUPERVISOR_UPDATE_STRATEGY', 'download-then-kill')
|
||||
const handoverTimeout = _.get(conf, 'RESIN_SUPERVISOR_HANDOVER_TIMEOUT', '')
|
||||
const restartPolicy = _.get(conf, 'RESIN_APP_RESTART_POLICY', 'always')
|
||||
volumes: {},
|
||||
};
|
||||
const defaultVolume = 'resin-data';
|
||||
newApp.volumes[defaultVolume] = {};
|
||||
const updateStrategy = _.get(
|
||||
conf,
|
||||
'RESIN_SUPERVISOR_UPDATE_STRATEGY',
|
||||
'download-then-kill',
|
||||
);
|
||||
const handoverTimeout = _.get(conf, 'RESIN_SUPERVISOR_HANDOVER_TIMEOUT', '');
|
||||
const restartPolicy = _.get(conf, 'RESIN_APP_RESTART_POLICY', 'always');
|
||||
newApp.services = [
|
||||
{
|
||||
serviceId: 1,
|
||||
@ -45,9 +48,7 @@ var singleToMulticontainerApp = function (app) {
|
||||
image: app.imageId,
|
||||
privileged: true,
|
||||
networkMode: 'host',
|
||||
volumes: [
|
||||
`${defaultVolume}:/data`
|
||||
],
|
||||
volumes: [`${defaultVolume}:/data`],
|
||||
labels: {
|
||||
'io.resin.features.kernel-modules': '1',
|
||||
'io.resin.features.firmware': '1',
|
||||
@ -56,26 +57,26 @@ var singleToMulticontainerApp = function (app) {
|
||||
'io.resin.features.resin-api': '1',
|
||||
'io.resin.update.strategy': updateStrategy,
|
||||
'io.resin.update.handover-timeout': handoverTimeout,
|
||||
'io.resin.legacy-container': '1'
|
||||
'io.resin.legacy-container': '1',
|
||||
},
|
||||
environment: environment,
|
||||
restart: restartPolicy,
|
||||
running: true
|
||||
}
|
||||
]
|
||||
return newApp
|
||||
}
|
||||
running: true,
|
||||
},
|
||||
];
|
||||
return newApp;
|
||||
};
|
||||
|
||||
var jsonifyAppFields = function (app) {
|
||||
const newApp = _.clone(app)
|
||||
newApp.services = JSON.stringify(app.services)
|
||||
newApp.networks = JSON.stringify(app.networks)
|
||||
newApp.volumes = JSON.stringify(app.volumes)
|
||||
return newApp
|
||||
}
|
||||
var jsonifyAppFields = function(app) {
|
||||
const newApp = _.clone(app);
|
||||
newApp.services = JSON.stringify(app.services);
|
||||
newApp.networks = JSON.stringify(app.networks);
|
||||
newApp.volumes = JSON.stringify(app.volumes);
|
||||
return newApp;
|
||||
};
|
||||
|
||||
var imageForApp = function (app) {
|
||||
const service = app.services[0]
|
||||
var imageForApp = function(app) {
|
||||
const service = app.services[0];
|
||||
return {
|
||||
name: service.image,
|
||||
appId: service.appId,
|
||||
@ -83,11 +84,11 @@ var imageForApp = function (app) {
|
||||
serviceName: service.serviceName,
|
||||
imageId: service.imageId,
|
||||
releaseId: service.releaseId,
|
||||
dependent: 0
|
||||
}
|
||||
}
|
||||
dependent: 0,
|
||||
};
|
||||
};
|
||||
|
||||
var imageForDependentApp = function (app) {
|
||||
var imageForDependentApp = function(app) {
|
||||
return {
|
||||
name: app.image,
|
||||
appId: app.appId,
|
||||
@ -95,203 +96,225 @@ var imageForDependentApp = function (app) {
|
||||
serviceName: null,
|
||||
imageId: app.imageId,
|
||||
releaseId: null,
|
||||
dependent: 1
|
||||
}
|
||||
}
|
||||
dependent: 1,
|
||||
};
|
||||
};
|
||||
|
||||
// TODO: this whole thing is WIP
|
||||
exports.up = function (knex, Promise) {
|
||||
return knex.schema.createTable('image', (t) => {
|
||||
t.increments('id').primary()
|
||||
t.string('name')
|
||||
t.integer('appId')
|
||||
t.integer('serviceId')
|
||||
t.string('serviceName')
|
||||
t.integer('imageId')
|
||||
t.integer('releaseId')
|
||||
t.boolean('dependent')
|
||||
exports.up = function(knex, Promise) {
|
||||
return knex.schema
|
||||
.createTable('image', t => {
|
||||
t.increments('id').primary();
|
||||
t.string('name');
|
||||
t.integer('appId');
|
||||
t.integer('serviceId');
|
||||
t.string('serviceName');
|
||||
t.integer('imageId');
|
||||
t.integer('releaseId');
|
||||
t.boolean('dependent');
|
||||
})
|
||||
.then(() => knex('app').select().whereNot({ markedForDeletion: true }).orWhereNull('markedForDeletion'))
|
||||
.tap((apps) => {
|
||||
.then(() =>
|
||||
knex('app')
|
||||
.select()
|
||||
.whereNot({ markedForDeletion: true })
|
||||
.orWhereNull('markedForDeletion'),
|
||||
)
|
||||
.tap(apps => {
|
||||
if (apps.length > 0) {
|
||||
return knex('config').insert({ key: 'legacyAppsPresent', value: 'true' })
|
||||
return knex('config').insert({
|
||||
key: 'legacyAppsPresent',
|
||||
value: 'true',
|
||||
});
|
||||
}
|
||||
})
|
||||
.tap(() => {
|
||||
// We're in a transaction, and it's easier to drop and recreate
|
||||
// than to migrate each field...
|
||||
return knex.schema.dropTable('app')
|
||||
.then(() => {
|
||||
return knex.schema.createTable('app', (t) => {
|
||||
t.increments('id').primary()
|
||||
t.string('name')
|
||||
t.integer('releaseId')
|
||||
t.string('commit')
|
||||
t.integer('appId')
|
||||
t.json('services')
|
||||
t.json('networks')
|
||||
t.json('volumes')
|
||||
})
|
||||
})
|
||||
return knex.schema.dropTable('app').then(() => {
|
||||
return knex.schema.createTable('app', t => {
|
||||
t.increments('id').primary();
|
||||
t.string('name');
|
||||
t.integer('releaseId');
|
||||
t.string('commit');
|
||||
t.integer('appId');
|
||||
t.json('services');
|
||||
t.json('networks');
|
||||
t.json('volumes');
|
||||
});
|
||||
});
|
||||
})
|
||||
.map((app) => {
|
||||
const migratedApp = singleToMulticontainerApp(app)
|
||||
return knex('app').insert(jsonifyAppFields(migratedApp))
|
||||
.then(() => knex('image').insert(imageForApp(migratedApp)))
|
||||
.map(app => {
|
||||
const migratedApp = singleToMulticontainerApp(app);
|
||||
return knex('app')
|
||||
.insert(jsonifyAppFields(migratedApp))
|
||||
.then(() => knex('image').insert(imageForApp(migratedApp)));
|
||||
})
|
||||
.then(() => {
|
||||
// For some reason dropping a column in this table doesn't work. Anyways, we don't want to store old targetValues.
|
||||
// Instead, on first run the supervisor will store current device config values as targets - so we want to
|
||||
// make the old values that refer to supervisor config be the *current* values, and we do that by inserting
|
||||
// to the config table.
|
||||
return knex('deviceConfig').select()
|
||||
.then((deviceConf) => {
|
||||
return knex.schema.dropTable('deviceConfig')
|
||||
.then(() => {
|
||||
const values = JSON.parse(deviceConf[0].values)
|
||||
const configKeys = {
|
||||
'RESIN_SUPERVISOR_POLL_INTERVAL': 'appUpdatePollInterval',
|
||||
'RESIN_SUPERVISOR_LOCAL_MODE': 'localMode',
|
||||
'RESIN_SUPERVISOR_CONNECTIVITY_CHECK': 'connectivityCheckEnabled',
|
||||
'RESIN_SUPERVISOR_LOG_CONTROL': 'loggingEnabled',
|
||||
'RESIN_SUPERVISOR_DELTA': 'delta',
|
||||
'RESIN_SUPERVISOR_DELTA_REQUEST_TIMEOUT': 'deltaRequestTimeout',
|
||||
'RESIN_SUPERVISOR_DELTA_APPLY_TIMEOUT': 'deltaApplyTimeout',
|
||||
'RESIN_SUPERVISOR_DELTA_RETRY_COUNT': 'deltaRetryCount',
|
||||
'RESIN_SUPERVISOR_DELTA_RETRY_INTERVAL': 'deltaRequestTimeout',
|
||||
'RESIN_SUPERVISOR_OVERRIDE_LOCK': 'lockOverride'
|
||||
return knex('deviceConfig')
|
||||
.select()
|
||||
.then(deviceConf => {
|
||||
return knex.schema.dropTable('deviceConfig').then(() => {
|
||||
const values = JSON.parse(deviceConf[0].values);
|
||||
const configKeys = {
|
||||
RESIN_SUPERVISOR_POLL_INTERVAL: 'appUpdatePollInterval',
|
||||
RESIN_SUPERVISOR_LOCAL_MODE: 'localMode',
|
||||
RESIN_SUPERVISOR_CONNECTIVITY_CHECK: 'connectivityCheckEnabled',
|
||||
RESIN_SUPERVISOR_LOG_CONTROL: 'loggingEnabled',
|
||||
RESIN_SUPERVISOR_DELTA: 'delta',
|
||||
RESIN_SUPERVISOR_DELTA_REQUEST_TIMEOUT: 'deltaRequestTimeout',
|
||||
RESIN_SUPERVISOR_DELTA_APPLY_TIMEOUT: 'deltaApplyTimeout',
|
||||
RESIN_SUPERVISOR_DELTA_RETRY_COUNT: 'deltaRetryCount',
|
||||
RESIN_SUPERVISOR_DELTA_RETRY_INTERVAL: 'deltaRequestTimeout',
|
||||
RESIN_SUPERVISOR_OVERRIDE_LOCK: 'lockOverride',
|
||||
};
|
||||
return Promise.map(Object.keys(values), envVarName => {
|
||||
if (configKeys[envVarName] != null) {
|
||||
return knex('config').insert({
|
||||
key: configKeys[envVarName],
|
||||
value: values[envVarName],
|
||||
});
|
||||
}
|
||||
return Promise.map(Object.keys(values), (envVarName) => {
|
||||
if (configKeys[envVarName] != null) {
|
||||
return knex('config').insert({ key: configKeys[envVarName], value: values[envVarName]})
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
return knex.schema.createTable('deviceConfig', (t) => {
|
||||
t.json('targetValues')
|
||||
})
|
||||
return knex.schema.createTable('deviceConfig', t => {
|
||||
t.json('targetValues');
|
||||
});
|
||||
})
|
||||
.then(() => knex('deviceConfig').insert({ targetValues: '{}' }))
|
||||
.then(() => knex('deviceConfig').insert({ targetValues: '{}' }));
|
||||
})
|
||||
.then(() => knex('dependentApp').select())
|
||||
.then((dependentApps) => {
|
||||
return knex.schema.dropTable('dependentApp')
|
||||
.then(dependentApps => {
|
||||
return knex.schema
|
||||
.dropTable('dependentApp')
|
||||
.then(() => {
|
||||
return knex.schema.createTable('dependentApp', (t) => {
|
||||
t.increments('id').primary()
|
||||
t.integer('appId')
|
||||
t.integer('parentApp')
|
||||
t.string('name')
|
||||
t.string('commit')
|
||||
t.integer('releaseId')
|
||||
t.integer('imageId')
|
||||
t.string('image')
|
||||
t.json('environment')
|
||||
t.json('config')
|
||||
})
|
||||
return knex.schema.createTable('dependentApp', t => {
|
||||
t.increments('id').primary();
|
||||
t.integer('appId');
|
||||
t.integer('parentApp');
|
||||
t.string('name');
|
||||
t.string('commit');
|
||||
t.integer('releaseId');
|
||||
t.integer('imageId');
|
||||
t.string('image');
|
||||
t.json('environment');
|
||||
t.json('config');
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
return knex.schema.createTable('dependentAppTarget', (t) => {
|
||||
t.increments('id').primary()
|
||||
t.integer('appId')
|
||||
t.integer('parentApp')
|
||||
t.string('name')
|
||||
t.string('commit')
|
||||
t.integer('releaseId')
|
||||
t.integer('imageId')
|
||||
t.string('image')
|
||||
t.json('environment')
|
||||
t.json('config')
|
||||
})
|
||||
return knex.schema.createTable('dependentAppTarget', t => {
|
||||
t.increments('id').primary();
|
||||
t.integer('appId');
|
||||
t.integer('parentApp');
|
||||
t.string('name');
|
||||
t.string('commit');
|
||||
t.integer('releaseId');
|
||||
t.integer('imageId');
|
||||
t.string('image');
|
||||
t.json('environment');
|
||||
t.json('config');
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
return Promise.map(dependentApps, (app) => {
|
||||
return Promise.map(dependentApps, app => {
|
||||
const newApp = {
|
||||
appId: parseInt(app.appId),
|
||||
parentApp: parseInt(app.parentAppId),
|
||||
appId: parseInt(app.appId, 10),
|
||||
parentApp: parseInt(app.parentAppId, 10),
|
||||
image: app.imageId,
|
||||
releaseId: null,
|
||||
commit: app.commit,
|
||||
name: app.name,
|
||||
config: JSON.stringify(tryParse(app.config)),
|
||||
environment: JSON.stringify(tryParse(app.environment))
|
||||
}
|
||||
const image = imageForDependentApp(newApp)
|
||||
return knex('image').insert(image)
|
||||
environment: JSON.stringify(tryParse(app.environment)),
|
||||
};
|
||||
const image = imageForDependentApp(newApp);
|
||||
return knex('image')
|
||||
.insert(image)
|
||||
.then(() => knex('dependentApp').insert(newApp))
|
||||
.then(() => knex('dependentAppTarget').insert(newApp))
|
||||
})
|
||||
})
|
||||
.then(() => knex('dependentAppTarget').insert(newApp));
|
||||
});
|
||||
});
|
||||
})
|
||||
.then(() => knex('dependentDevice').select())
|
||||
.then((dependentDevices) => {
|
||||
return knex.schema.dropTable('dependentDevice')
|
||||
.then(dependentDevices => {
|
||||
return knex.schema
|
||||
.dropTable('dependentDevice')
|
||||
.then(() => {
|
||||
return knex.schema.createTable('dependentDevice', (t) => {
|
||||
t.increments('id').primary()
|
||||
t.string('uuid')
|
||||
t.integer('appId')
|
||||
t.string('localId')
|
||||
t.string('device_type')
|
||||
t.string('logs_channel')
|
||||
t.integer('deviceId')
|
||||
t.boolean('is_online')
|
||||
t.string('name')
|
||||
t.string('status')
|
||||
t.string('download_progress')
|
||||
t.integer('is_managed_by')
|
||||
t.dateTime('lock_expiry_date')
|
||||
t.string('commit')
|
||||
t.string('targetCommit')
|
||||
t.json('environment')
|
||||
t.json('targetEnvironment')
|
||||
t.json('config')
|
||||
t.json('targetConfig')
|
||||
t.boolean('markedForDeletion')
|
||||
})
|
||||
return knex.schema.createTable('dependentDevice', t => {
|
||||
t.increments('id').primary();
|
||||
t.string('uuid');
|
||||
t.integer('appId');
|
||||
t.string('localId');
|
||||
t.string('device_type');
|
||||
t.string('logs_channel');
|
||||
t.integer('deviceId');
|
||||
t.boolean('is_online');
|
||||
t.string('name');
|
||||
t.string('status');
|
||||
t.string('download_progress');
|
||||
t.integer('is_managed_by');
|
||||
t.dateTime('lock_expiry_date');
|
||||
t.string('commit');
|
||||
t.string('targetCommit');
|
||||
t.json('environment');
|
||||
t.json('targetEnvironment');
|
||||
t.json('config');
|
||||
t.json('targetConfig');
|
||||
t.boolean('markedForDeletion');
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
return knex.schema.createTable('dependentDeviceTarget', (t) => {
|
||||
t.increments('id').primary()
|
||||
t.string('uuid')
|
||||
t.string('name')
|
||||
t.json('apps')
|
||||
})
|
||||
return knex.schema.createTable('dependentDeviceTarget', t => {
|
||||
t.increments('id').primary();
|
||||
t.string('uuid');
|
||||
t.string('name');
|
||||
t.json('apps');
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
return Promise.map(dependentDevices, (device) => {
|
||||
const newDevice = _.clone(device)
|
||||
newDevice.appId = parseInt(device.appId)
|
||||
newDevice.deviceId = parseInt(device.deviceId)
|
||||
return Promise.map(dependentDevices, device => {
|
||||
const newDevice = _.clone(device);
|
||||
newDevice.appId = parseInt(device.appId, 10);
|
||||
newDevice.deviceId = parseInt(device.deviceId, 10);
|
||||
if (device.is_managed_by != null) {
|
||||
newDevice.is_managed_by = parseInt(device.is_managed_by)
|
||||
newDevice.is_managed_by = parseInt(device.is_managed_by, 10);
|
||||
}
|
||||
newDevice.config = JSON.stringify(tryParse(device.config))
|
||||
newDevice.environment = JSON.stringify(tryParse(device.environment))
|
||||
newDevice.targetConfig = JSON.stringify(tryParse(device.targetConfig))
|
||||
newDevice.targetEnvironment = JSON.stringify(tryParse(device.targetEnvironment))
|
||||
newDevice.config = JSON.stringify(tryParse(device.config));
|
||||
newDevice.environment = JSON.stringify(
|
||||
tryParse(device.environment),
|
||||
);
|
||||
newDevice.targetConfig = JSON.stringify(
|
||||
tryParse(device.targetConfig),
|
||||
);
|
||||
newDevice.targetEnvironment = JSON.stringify(
|
||||
tryParse(device.targetEnvironment),
|
||||
);
|
||||
if (newDevice.markedForDeletion == null) {
|
||||
newDevice.markedForDeletion = false
|
||||
newDevice.markedForDeletion = false;
|
||||
}
|
||||
const deviceTarget = {
|
||||
uuid: device.uuid,
|
||||
name: device.name,
|
||||
apps: {}
|
||||
}
|
||||
apps: {},
|
||||
};
|
||||
deviceTarget.apps[device.appId] = {
|
||||
commit: newDevice.targetCommit,
|
||||
config: newDevice.targetConfig,
|
||||
environment: newDevice.targetEnvironment
|
||||
}
|
||||
return knex('dependentDevice').insert(newDevice)
|
||||
.then(() => knex('dependentDeviceTarget').insert(deviceTarget))
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
environment: newDevice.targetEnvironment,
|
||||
};
|
||||
return knex('dependentDevice')
|
||||
.insert(newDevice)
|
||||
.then(() => knex('dependentDeviceTarget').insert(deviceTarget));
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.down = function(knex, Promise) {
|
||||
return Promise.reject(new Error('Not implemented'))
|
||||
}
|
||||
return Promise.reject(new Error('Not implemented'));
|
||||
};
|
||||
|
@ -1,10 +1,10 @@
|
||||
// Adds a dockerImageId column to the image table to identify images downloaded with deltas
|
||||
exports.up = function (knex, Promise) {
|
||||
return knex.schema.table('image', (t) => {
|
||||
t.string('dockerImageId')
|
||||
})
|
||||
}
|
||||
exports.up = function(knex, Promise) {
|
||||
return knex.schema.table('image', t => {
|
||||
t.string('dockerImageId');
|
||||
});
|
||||
};
|
||||
|
||||
exports.down = function(knex, Promise) {
|
||||
return Promise.reject(new Error('Not implemented'))
|
||||
}
|
||||
return Promise.reject(new Error('Not implemented'));
|
||||
};
|
||||
|
@ -1,39 +1,45 @@
|
||||
const fs = require('fs');
|
||||
const configJsonPath = process.env.CONFIG_MOUNT_POINT;
|
||||
|
||||
exports.up = function (knex, Promise) {
|
||||
exports.up = function(knex, Promise) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!configJsonPath) {
|
||||
console.log('Unable to locate config.json! Things may fail unexpectedly!');
|
||||
console.log(
|
||||
'Unable to locate config.json! Things may fail unexpectedly!',
|
||||
);
|
||||
resolve({});
|
||||
}
|
||||
fs.readFile(configJsonPath, (err, data) => {
|
||||
if (err) {
|
||||
console.log('Failed to read config.json! Things may fail unexpectedly!');
|
||||
console.log(
|
||||
'Failed to read config.json! Things may fail unexpectedly!',
|
||||
);
|
||||
resolve({});
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const parsed = JSON.parse(data.toString());
|
||||
resolve(parsed);
|
||||
} catch(e) {
|
||||
console.log('Failed to parse config.json! Things may fail unexpectedly!');
|
||||
} catch (e) {
|
||||
console.log(
|
||||
'Failed to parse config.json! Things may fail unexpectedly!',
|
||||
);
|
||||
resolve({});
|
||||
}
|
||||
});
|
||||
})
|
||||
.then((config) => {
|
||||
return knex.schema.table('app', (t) => {
|
||||
}).then(config => {
|
||||
return knex.schema
|
||||
.table('app', t => {
|
||||
// Create a new column on the table and add the apiEndpoint config json
|
||||
// field if it exists
|
||||
t.string('source');
|
||||
})
|
||||
.then(() => {
|
||||
return knex('app').update({ source: (config.apiEndpoint || '') });
|
||||
});
|
||||
});
|
||||
}
|
||||
.then(() => {
|
||||
return knex('app').update({ source: config.apiEndpoint || '' });
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.down = function (knex, Promise) {
|
||||
return Promise.reject(new Error('Not Implemented'))
|
||||
}
|
||||
exports.down = function(knex, Promise) {
|
||||
return Promise.reject(new Error('Not Implemented'));
|
||||
};
|
||||
|
@ -1,16 +1,20 @@
|
||||
const fs = require('fs');
|
||||
const configJsonPath = process.env.CONFIG_MOUNT_POINT;
|
||||
|
||||
exports.up = function (knex, Promise) {
|
||||
exports.up = function(knex, Promise) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!configJsonPath) {
|
||||
console.log('Unable to locate config.json! Things may fail unexpectedly!');
|
||||
console.log(
|
||||
'Unable to locate config.json! Things may fail unexpectedly!',
|
||||
);
|
||||
resolve({});
|
||||
return;
|
||||
}
|
||||
fs.readFile(configJsonPath, (err, data) => {
|
||||
if (err) {
|
||||
console.log('Failed to read config.json! Things may fail unexpectedly!');
|
||||
console.log(
|
||||
'Failed to read config.json! Things may fail unexpectedly!',
|
||||
);
|
||||
resolve({});
|
||||
return;
|
||||
}
|
||||
@ -18,7 +22,9 @@ exports.up = function (knex, Promise) {
|
||||
const parsed = JSON.parse(data.toString());
|
||||
resolve(parsed);
|
||||
} catch (e) {
|
||||
console.log('Failed to parse config.json! Things may fail unexpectedly!');
|
||||
console.log(
|
||||
'Failed to parse config.json! Things may fail unexpectedly!',
|
||||
);
|
||||
resolve({});
|
||||
}
|
||||
});
|
||||
@ -26,18 +32,20 @@ exports.up = function (knex, Promise) {
|
||||
.tap(() => {
|
||||
// take the logsChannelSecret, and the apiEndpoint config field,
|
||||
// and store them in a new table
|
||||
return knex.schema.hasTable('logsChannelSecret').then((exists) => {
|
||||
return knex.schema.hasTable('logsChannelSecret').then(exists => {
|
||||
if (!exists) {
|
||||
return knex.schema.createTable('logsChannelSecret', (t) => {
|
||||
return knex.schema.createTable('logsChannelSecret', t => {
|
||||
t.string('backend');
|
||||
t.string('secret');
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
.then((config) => {
|
||||
return knex('config').where({ key: 'logsChannelSecret' }).select('value')
|
||||
.then((results) => {
|
||||
.then(config => {
|
||||
return knex('config')
|
||||
.where({ key: 'logsChannelSecret' })
|
||||
.select('value')
|
||||
.then(results => {
|
||||
if (results.length === 0) {
|
||||
return { config, secret: null };
|
||||
}
|
||||
@ -47,15 +55,16 @@ exports.up = function (knex, Promise) {
|
||||
.then(({ config, secret }) => {
|
||||
return knex('logsChannelSecret').insert({
|
||||
backend: config.apiEndpoint || '',
|
||||
secret
|
||||
secret,
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
return knex('config').where('key', 'logsChannelSecret').del();
|
||||
return knex('config')
|
||||
.where('key', 'logsChannelSecret')
|
||||
.del();
|
||||
});
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
exports.down = function (knex, Promise) {
|
||||
exports.down = function(knex, Promise) {
|
||||
return Promise.reject(new Error('Not Implemented'));
|
||||
}
|
||||
};
|
||||
|
@ -1,11 +1,10 @@
|
||||
|
||||
exports.up = (knex, Promise) => {
|
||||
return knex.schema.createTable('engineSnapshot', (t) => {
|
||||
return knex.schema.createTable('engineSnapshot', t => {
|
||||
t.string('snapshot'); // Engine snapshot encoded as JSON.
|
||||
t.string('timestamp'); // When the snapshot was created.
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
exports.down = (knex, Promise) => {
|
||||
return Promise.reject(new Error('Not Implemented'));
|
||||
}
|
||||
};
|
||||
|
@ -3,18 +3,21 @@ const _ = require('lodash');
|
||||
// We take legacy deviceConfig targets and store them without the RESIN_ prefix
|
||||
// (we also strip the BALENA_ prefix for completeness, even though no supervisors
|
||||
// using this prefix made it to production)
|
||||
exports.up = function (knex, Promise) {
|
||||
return knex('deviceConfig').select('targetValues')
|
||||
.then((devConfigs) => {
|
||||
exports.up = function(knex, Promise) {
|
||||
return knex('deviceConfig')
|
||||
.select('targetValues')
|
||||
.then(devConfigs => {
|
||||
const devConfig = devConfigs[0];
|
||||
const targetValues = JSON.parse(devConfig.targetValues);
|
||||
const filteredTargetValues = _.mapKeys(targetValues, (_v, k) => {
|
||||
return k.replace(/^(?:RESIN|BALENA)_(.*)/, '$1');
|
||||
});
|
||||
return knex('deviceConfig').update({ targetValues: JSON.stringify(filteredTargetValues) });
|
||||
return knex('deviceConfig').update({
|
||||
targetValues: JSON.stringify(filteredTargetValues),
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.down = function (knex, Promise) {
|
||||
exports.down = function(knex, Promise) {
|
||||
return Promise.reject(new Error('Not Implemented'));
|
||||
};
|
||||
|
@ -3,9 +3,11 @@ const configJsonPath = process.env.CONFIG_MOUNT_POINT;
|
||||
|
||||
const { checkTruthy } = require('../lib/validation');
|
||||
|
||||
exports.up = function (knex, Promise) {
|
||||
return knex('config').where({ key: 'localMode' }).select('value')
|
||||
.then((results) => {
|
||||
exports.up = function(knex, Promise) {
|
||||
return knex('config')
|
||||
.where({ key: 'localMode' })
|
||||
.select('value')
|
||||
.then(results => {
|
||||
if (results.length === 0) {
|
||||
// We don't need to do anything
|
||||
return;
|
||||
@ -14,15 +16,19 @@ exports.up = function (knex, Promise) {
|
||||
let value = checkTruthy(results[0].value);
|
||||
value = value != null ? value : false;
|
||||
|
||||
return new Promise((resolve) => {
|
||||
return new Promise(resolve => {
|
||||
if (!configJsonPath) {
|
||||
console.log('Unable to locate config.json! Things may fail unexpectedly!');
|
||||
console.log(
|
||||
'Unable to locate config.json! Things may fail unexpectedly!',
|
||||
);
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
fs.readFile(configJsonPath, (err, data) => {
|
||||
if (err) {
|
||||
console.log('Failed to read config.json! Things may fail unexpectedly!');
|
||||
console.log(
|
||||
'Failed to read config.json! Things may fail unexpectedly!',
|
||||
);
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
@ -31,27 +37,30 @@ exports.up = function (knex, Promise) {
|
||||
// Assign the local mode value
|
||||
parsed.localMode = value;
|
||||
|
||||
fs.writeFile(configJsonPath, JSON.stringify(parsed), (err) => {
|
||||
if (err) {
|
||||
console.log('Failed to write config.json! Things may fail unexpectedly!');
|
||||
fs.writeFile(configJsonPath, JSON.stringify(parsed), err2 => {
|
||||
if (err2) {
|
||||
console.log(
|
||||
'Failed to write config.json! Things may fail unexpectedly!',
|
||||
);
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
console.log('Failed to parse config.json! Things may fail unexpectedly!');
|
||||
console.log(
|
||||
'Failed to parse config.json! Things may fail unexpectedly!',
|
||||
);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
return knex('config').where('key', 'localMode').del();
|
||||
});
|
||||
}).then(() => {
|
||||
return knex('config')
|
||||
.where('key', 'localMode')
|
||||
.del();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.down = function (knex, Promise) {
|
||||
exports.down = function(knex, Promise) {
|
||||
return Promise.reject(new Error('Not Implemented'));
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -3,16 +3,20 @@ const configJsonPath = process.env.CONFIG_MOUNT_POINT;
|
||||
|
||||
const { checkTruthy } = require('../lib/validation');
|
||||
|
||||
exports.up = function (knex, Promise) {
|
||||
exports.up = function(knex, Promise) {
|
||||
return new Promise(resolve => {
|
||||
if (!configJsonPath) {
|
||||
console.log('Unable to locate config.json! Things may fail unexpectedly!');
|
||||
console.log(
|
||||
'Unable to locate config.json! Things may fail unexpectedly!',
|
||||
);
|
||||
return resolve(false);
|
||||
}
|
||||
|
||||
fs.readFile(configJsonPath, (err, data) => {
|
||||
if (err) {
|
||||
console.log('Failed to read config.json! Things may fail unexpectedly!');
|
||||
console.log(
|
||||
'Failed to read config.json! Things may fail unexpectedly!',
|
||||
);
|
||||
return resolve();
|
||||
}
|
||||
try {
|
||||
@ -22,7 +26,9 @@ exports.up = function (knex, Promise) {
|
||||
}
|
||||
return resolve(false);
|
||||
} catch (e) {
|
||||
console.log('Failed to parse config.json! Things may fail unexpectedly!');
|
||||
console.log(
|
||||
'Failed to parse config.json! Things may fail unexpectedly!',
|
||||
);
|
||||
return resolve(false);
|
||||
}
|
||||
});
|
||||
@ -36,6 +42,6 @@ exports.up = function (knex, Promise) {
|
||||
});
|
||||
};
|
||||
|
||||
exports.down = function (knex, Promise) {
|
||||
exports.down = function(knex, Promise) {
|
||||
return Promise.reject(new Error('Not Implemented'));
|
||||
};
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 5b1459007cea18b5891d6bdf4b0694241487cc8b
|
||||
Subproject commit e413fcedb9e3a5365da91c01a45e633d620947af
|
@ -8,7 +8,8 @@
|
||||
"outDir": "./build/",
|
||||
"skipLibCheck": true,
|
||||
"lib": ["es6"],
|
||||
"resolveJsonModule": true
|
||||
"resolveJsonModule": true,
|
||||
"allowJs": true
|
||||
},
|
||||
"include": ["src/**/*.ts", "test/**/*.ts", "typings/**/*.d.ts"]
|
||||
"include": ["src/**/*.ts", "src/**/*.js", "test/**/*.ts", "typings/**/*.d.ts"]
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
{
|
||||
"extends": ["resin-lint/config/tslint-prettier.json"]
|
||||
"extends": ["@balena/lint/config/tslint-prettier.json"]
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ var webpack = require('webpack');
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var _ = require('lodash');
|
||||
var path = require('path');
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
var ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
|
||||
|
||||
@ -102,7 +101,7 @@ module.exports = function(env) {
|
||||
use: require.resolve('coffee-loader'),
|
||||
},
|
||||
{
|
||||
test: /\.ts$/,
|
||||
test: /\.ts$|\.js$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
@ -122,7 +121,7 @@ module.exports = function(env) {
|
||||
(m instanceof RegExp && m.test(request))
|
||||
) {
|
||||
return callback(null, 'commonjs ' + request);
|
||||
} else if (typeof m != 'string' && !(m instanceof RegExp)) {
|
||||
} else if (typeof m !== 'string' && !(m instanceof RegExp)) {
|
||||
throw new Error('Invalid entry in external modules: ' + m);
|
||||
}
|
||||
}
|
||||
@ -134,13 +133,13 @@ module.exports = function(env) {
|
||||
}),
|
||||
new CopyWebpackPlugin([
|
||||
{
|
||||
from: './src/migrations',
|
||||
from: './build/migrations',
|
||||
to: 'migrations',
|
||||
},
|
||||
]),
|
||||
new webpack.ContextReplacementPlugin(
|
||||
/\.\/migrations/,
|
||||
path.resolve(__dirname, 'src/migrations')
|
||||
path.resolve(__dirname, 'build/migrations')
|
||||
),
|
||||
],
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user