mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-04-25 05:19:59 +00:00
Standardise all supervisor output logging
Also use the supervisor's own container logging monitoring code when running livepush on the supervisor container. Change-type: minor Signed-off-by: Cameron Diver <cameron@balena.io>
This commit is contained in:
parent
2c1164cd62
commit
2276dd54e1
588
package-lock.json
generated
588
package-lock.json
generated
@ -77,6 +77,25 @@
|
||||
"strip-ansi": "^3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"log-symbols": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
|
||||
@ -85,6 +104,21 @@
|
||||
"requires": {
|
||||
"chalk": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -326,7 +360,7 @@
|
||||
},
|
||||
"@types/optimist": {
|
||||
"version": "0.0.29",
|
||||
"resolved": "https://registry.npmjs.org/@types/optimist/-/optimist-0.0.29.tgz",
|
||||
"resolved": "http://registry.npmjs.org/@types/optimist/-/optimist-0.0.29.tgz",
|
||||
"integrity": "sha1-qIc1gLOoS2msHmhzI7Ffu+uQR5o=",
|
||||
"dev": true
|
||||
},
|
||||
@ -686,12 +720,6 @@
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
|
||||
"dev": true
|
||||
},
|
||||
"any-observable": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz",
|
||||
@ -773,12 +801,6 @@
|
||||
"integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=",
|
||||
"dev": true
|
||||
},
|
||||
"array-flatten": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
|
||||
"integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==",
|
||||
"dev": true
|
||||
},
|
||||
"array-map": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz",
|
||||
@ -928,6 +950,44 @@
|
||||
"chalk": "^1.1.3",
|
||||
"esutils": "^2.0.2",
|
||||
"js-tokens": "^3.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"babel-messages": {
|
||||
@ -1230,6 +1290,36 @@
|
||||
"underscore.string": "^3.2.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"docker-toolbelt": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/docker-toolbelt/-/docker-toolbelt-1.4.0.tgz",
|
||||
@ -1243,6 +1333,12 @@
|
||||
"semver": "^5.2.0",
|
||||
"tar-stream": "^1.5.2"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1424,19 +1520,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"bonjour": {
|
||||
"version": "git+https://github.com/resin-io/bonjour.git#e018851dc823b4b3f670f658f71d0c1c7f3e637c",
|
||||
"from": "git+https://github.com/resin-io/bonjour.git#fixed-mdns",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"array-flatten": "^2.1.0",
|
||||
"deep-equal": "^1.0.1",
|
||||
"dns-equal": "^1.0.0",
|
||||
"dns-txt": "^2.0.2",
|
||||
"multicast-dns": "git+https://github.com/resin-io-modules/multicast-dns.git#a15c63464eb43e8925b187ed5cb9de6892e8aacc",
|
||||
"multicast-dns-service-types": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
@ -1603,12 +1686,6 @@
|
||||
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
|
||||
"dev": true
|
||||
},
|
||||
"buffer-indexof": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
|
||||
"integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==",
|
||||
"dev": true
|
||||
},
|
||||
"buffer-xor": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
|
||||
@ -1765,19 +1842,6 @@
|
||||
"integrity": "sha1-xVEoN4+bs5nplPAAUhUZhO1uvnA=",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"check-error": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
|
||||
@ -1938,6 +2002,17 @@
|
||||
"string-width": "^1.0.1",
|
||||
"strip-ansi": "^3.0.1",
|
||||
"wrap-ansi": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"clone": {
|
||||
@ -1976,7 +2051,7 @@
|
||||
"dependencies": {
|
||||
"coffee-script": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.11.1.tgz",
|
||||
"resolved": "http://registry.npmjs.org/coffee-script/-/coffee-script-1.11.1.tgz",
|
||||
"integrity": "sha1-vxxHrWREOg2V0S3ysUfMCk2q1uk=",
|
||||
"dev": true
|
||||
},
|
||||
@ -2019,6 +2094,16 @@
|
||||
"object-visit": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"color": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz",
|
||||
"integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^1.9.1",
|
||||
"color-string": "^1.5.2"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
@ -2034,6 +2119,38 @@
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
||||
"dev": true
|
||||
},
|
||||
"color-string": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
|
||||
"integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "^1.0.0",
|
||||
"simple-swizzle": "^0.2.2"
|
||||
}
|
||||
},
|
||||
"colornames": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz",
|
||||
"integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y=",
|
||||
"dev": true
|
||||
},
|
||||
"colors": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
|
||||
"integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==",
|
||||
"dev": true
|
||||
},
|
||||
"colorspace": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz",
|
||||
"integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color": "3.0.x",
|
||||
"text-hex": "1.0.x"
|
||||
}
|
||||
},
|
||||
"columnify": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz",
|
||||
@ -2042,6 +2159,17 @@
|
||||
"requires": {
|
||||
"strip-ansi": "^3.0.0",
|
||||
"wcwidth": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"combined-stream": {
|
||||
@ -2375,12 +2503,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"deep-equal": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
|
||||
"integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
|
||||
"dev": true
|
||||
},
|
||||
"deep-extend": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
||||
@ -2559,6 +2681,17 @@
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups="
|
||||
},
|
||||
"diagnostics": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz",
|
||||
"integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"colorspace": "1.1.x",
|
||||
"enabled": "1.0.x",
|
||||
"kuler": "1.0.x"
|
||||
}
|
||||
},
|
||||
"diff": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
|
||||
@ -2586,31 +2719,6 @@
|
||||
"path-type": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"dns-equal": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
|
||||
"integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=",
|
||||
"dev": true
|
||||
},
|
||||
"dns-packet": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz",
|
||||
"integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ip": "^1.1.0",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"dns-txt": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz",
|
||||
"integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"buffer-indexof": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"docker-delta": {
|
||||
"version": "2.2.9",
|
||||
"resolved": "https://registry.npmjs.org/docker-delta/-/docker-delta-2.2.9.tgz",
|
||||
@ -3005,6 +3113,15 @@
|
||||
"integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
|
||||
"dev": true
|
||||
},
|
||||
"enabled": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz",
|
||||
"integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"env-variable": "0.0.x"
|
||||
}
|
||||
},
|
||||
"encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
@ -3039,6 +3156,12 @@
|
||||
"tapable": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"env-variable": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.5.tgz",
|
||||
"integrity": "sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA==",
|
||||
"dev": true
|
||||
},
|
||||
"errno": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
|
||||
@ -3485,6 +3608,18 @@
|
||||
"integrity": "sha1-pFr/NFGWAG1AbKbNzQX2kFHvNbg=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-safe-stringify": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz",
|
||||
"integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==",
|
||||
"dev": true
|
||||
},
|
||||
"fecha": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz",
|
||||
"integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==",
|
||||
"dev": true
|
||||
},
|
||||
"fetch-ponyfill": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz",
|
||||
@ -4446,6 +4581,16 @@
|
||||
"string-width": "^1.0.1",
|
||||
"strip-ansi": "^3.0.1",
|
||||
"wide-align": "^1.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"get-caller-file": {
|
||||
@ -5088,6 +5233,25 @@
|
||||
"integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"cli-cursor": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
|
||||
@ -5129,6 +5293,21 @@
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
"strip-ansi": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -5761,6 +5940,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"kuler": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz",
|
||||
"integrity": "sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"colornames": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"lcid": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
|
||||
@ -6233,6 +6421,25 @@
|
||||
"strip-ansi": "^3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^2.2.1",
|
||||
"escape-string-regexp": "^1.0.2",
|
||||
"has-ansi": "^2.0.0",
|
||||
"strip-ansi": "^3.0.0",
|
||||
"supports-color": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"log-symbols": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
|
||||
@ -6241,6 +6448,21 @@
|
||||
"requires": {
|
||||
"chalk": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -6303,9 +6525,9 @@
|
||||
}
|
||||
},
|
||||
"livepush": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/livepush/-/livepush-1.2.4.tgz",
|
||||
"integrity": "sha512-AKGlJ+QuelyDoOV0cbGfeskLf2RaYIcHnKogfircvTl9//BNDrGVhrcO6bN3kcVaJnYKnvXwXOtGOyrsl6wI9A==",
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/livepush/-/livepush-1.2.5.tgz",
|
||||
"integrity": "sha512-aPeBngn6Fr4dusLcbEcA4hM90zl4jJCqMNrYIeXqUPTNZwyA7D2SmQJp9EEYJ/9/Q8cOxi78CTY7CYdvdOR0ng==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bluebird": "^3.5.1",
|
||||
@ -6333,7 +6555,7 @@
|
||||
},
|
||||
"load-json-file": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
|
||||
"resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
|
||||
"integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
@ -6354,7 +6576,7 @@
|
||||
},
|
||||
"pify": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
|
||||
"dev": true
|
||||
}
|
||||
@ -6523,6 +6745,27 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"logform": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/logform/-/logform-2.1.2.tgz",
|
||||
"integrity": "sha512-+lZh4OpERDBLqjiwDLpAWNQu6KMjnlXH2ByZwCuSqVPJletw0kTWJf5CgSNAUKn1KUkv3m2cUz/LK8zyEy7wzQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"colors": "^1.2.1",
|
||||
"fast-safe-stringify": "^2.0.4",
|
||||
"fecha": "^2.3.3",
|
||||
"ms": "^2.1.1",
|
||||
"triple-beam": "^1.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"lolex": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz",
|
||||
@ -7027,21 +7270,6 @@
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||
"dev": true
|
||||
},
|
||||
"multicast-dns": {
|
||||
"version": "git+https://github.com/resin-io-modules/multicast-dns.git#a15c63464eb43e8925b187ed5cb9de6892e8aacc",
|
||||
"from": "git+https://github.com/resin-io-modules/multicast-dns.git#listen-on-all-interfaces",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"dns-packet": "^1.0.1",
|
||||
"thunky": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"multicast-dns-service-types": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
|
||||
"integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=",
|
||||
"dev": true
|
||||
},
|
||||
"mute-stream": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz",
|
||||
@ -7464,6 +7692,12 @@
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"one-time": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz",
|
||||
"integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=",
|
||||
"dev": true
|
||||
},
|
||||
"onetime": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
|
||||
@ -7555,7 +7789,7 @@
|
||||
},
|
||||
"get-stream": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
|
||||
"resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
|
||||
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
|
||||
"dev": true
|
||||
}
|
||||
@ -8220,7 +8454,7 @@
|
||||
},
|
||||
"pify": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
|
||||
"dev": true
|
||||
},
|
||||
@ -8461,9 +8695,22 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bluebird": "^3.0.0",
|
||||
"bonjour": "git+https://github.com/resin-io/bonjour.git#e018851dc823b4b3f670f658f71d0c1c7f3e637c",
|
||||
"ip": "^1.1.4",
|
||||
"lodash": "^4.17.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"bonjour": {
|
||||
"version": "git+https://github.com/resin-io/bonjour.git#e018851dc823b4b3f670f658f71d0c1c7f3e637c",
|
||||
"from": "git+https://github.com/resin-io/bonjour.git#e018851dc823b4b3f670f658f71d0c1c7f3e637c",
|
||||
"requires": {
|
||||
"array-flatten": "^2.1.0",
|
||||
"deep-equal": "^1.0.1",
|
||||
"dns-equal": "^1.0.0",
|
||||
"dns-txt": "^2.0.2",
|
||||
"multicast-dns": "git+https://github.com/resin-io-modules/multicast-dns.git#a15c63464eb43e8925b187ed5cb9de6892e8aacc",
|
||||
"multicast-dns-service-types": "^1.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"resin-lint": {
|
||||
@ -8938,6 +9185,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"simple-swizzle": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
|
||||
"integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-arrayish": "^0.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"is-arrayish": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
||||
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"sinon": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/sinon/-/sinon-2.4.1.tgz",
|
||||
@ -9312,6 +9576,12 @@
|
||||
"safe-buffer": "^5.1.1"
|
||||
}
|
||||
},
|
||||
"stack-trace": {
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
|
||||
"integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=",
|
||||
"dev": true
|
||||
},
|
||||
"staged-git-files": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/staged-git-files/-/staged-git-files-1.1.2.tgz",
|
||||
@ -9429,6 +9699,16 @@
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
"strip-ansi": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
@ -9450,14 +9730,6 @@
|
||||
"is-regexp": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"strip-bom": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
|
||||
@ -9475,12 +9747,6 @@
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
||||
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
|
||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||
"dev": true
|
||||
},
|
||||
"symbol-observable": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
|
||||
@ -9722,6 +9988,12 @@
|
||||
"integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=",
|
||||
"dev": true
|
||||
},
|
||||
"text-hex": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
||||
"integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==",
|
||||
"dev": true
|
||||
},
|
||||
"thenify": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz",
|
||||
@ -9755,12 +10027,6 @@
|
||||
"xtend": "~4.0.1"
|
||||
}
|
||||
},
|
||||
"thunky": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "http://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz",
|
||||
"integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=",
|
||||
"dev": true
|
||||
},
|
||||
"tildify": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz",
|
||||
@ -9883,6 +10149,12 @@
|
||||
"ski": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"triple-beam": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz",
|
||||
"integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==",
|
||||
"dev": true
|
||||
},
|
||||
"ts-loader": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.3.1.tgz",
|
||||
@ -9928,16 +10200,24 @@
|
||||
}
|
||||
},
|
||||
"ts-node": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.1.0.tgz",
|
||||
"integrity": "sha512-34jpuOrxDuf+O6iW1JpgTRDFynUZ1iEqtYruBqh35gICNjN8x+LpVcPAcwzLPi9VU6mdA3ym+x233nZmZp445A==",
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.2.0.tgz",
|
||||
"integrity": "sha512-m8XQwUurkbYqXrKqr3WHCW310utRNvV5OnRVeISeea7LoCWVcdfeB/Ntl8JYWFh+WRoUAdBgESrzKochQt7sMw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arg": "^4.1.0",
|
||||
"diff": "^3.1.0",
|
||||
"diff": "^4.0.1",
|
||||
"make-error": "^1.1.1",
|
||||
"source-map-support": "^0.5.6",
|
||||
"yn": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"diff": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz",
|
||||
"integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
@ -11382,6 +11662,55 @@
|
||||
"string-width": "^1.0.2 || 2"
|
||||
}
|
||||
},
|
||||
"winston": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/winston/-/winston-3.2.1.tgz",
|
||||
"integrity": "sha512-zU6vgnS9dAWCEKg/QYigd6cgMVVNwyTzKs81XZtTFuRwJOcDdBg7AU0mXVyNbs7O5RH2zdv+BdNZUlx7mXPuOw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"async": "^2.6.1",
|
||||
"diagnostics": "^1.1.1",
|
||||
"is-stream": "^1.1.0",
|
||||
"logform": "^2.1.1",
|
||||
"one-time": "0.0.4",
|
||||
"readable-stream": "^3.1.1",
|
||||
"stack-trace": "0.0.x",
|
||||
"triple-beam": "^1.3.0",
|
||||
"winston-transport": "^4.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"async": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
|
||||
"integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash": "^4.17.11"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
|
||||
"integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"winston-transport": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz",
|
||||
"integrity": "sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"readable-stream": "^2.3.6",
|
||||
"triple-beam": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"wordwrap": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
|
||||
@ -11405,6 +11734,17 @@
|
||||
"requires": {
|
||||
"string-width": "^1.0.1",
|
||||
"strip-ansi": "^3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
|
@ -73,7 +73,7 @@
|
||||
"json-mask": "^0.3.8",
|
||||
"knex": "~0.15.2",
|
||||
"lint-staged": "^8.1.0",
|
||||
"livepush": "^1.2.4",
|
||||
"livepush": "^1.2.5",
|
||||
"lockfile": "^1.0.1",
|
||||
"lodash": "^4.17.5",
|
||||
"log-timestamp": "^0.1.2",
|
||||
@ -101,6 +101,7 @@
|
||||
"typed-error": "^2.0.0",
|
||||
"typescript": "^3.2.2",
|
||||
"webpack": "^4.25.0",
|
||||
"webpack-cli": "^3.1.2"
|
||||
"webpack-cli": "^3.1.2",
|
||||
"winston": "^3.2.1"
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,8 @@ import { DeviceApplicationState } from './types/state';
|
||||
|
||||
import { SchemaReturn as ConfigSchemaType } from './config/schema-type';
|
||||
|
||||
import log from './lib/supervisor-console';
|
||||
|
||||
const REPORT_SUCCESS_DELAY = 1000;
|
||||
const MAX_REPORT_RETRY_DELAY = 60000;
|
||||
|
||||
@ -143,7 +145,7 @@ export class APIBinder {
|
||||
);
|
||||
|
||||
if (unmanaged) {
|
||||
console.log('Unmanaged mode is set, skipping API client initialization');
|
||||
log.debug('Unmanaged mode is set, skipping API client initialization');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -167,11 +169,11 @@ export class APIBinder {
|
||||
if (!exists) {
|
||||
return;
|
||||
}
|
||||
console.log('Migration backup detected');
|
||||
log.info('Migration backup detected');
|
||||
const targetState = await this.getTargetState();
|
||||
await this.deviceState.restoreBackup(targetState);
|
||||
} catch (err) {
|
||||
console.log('Error restoring migration backup, retrying: ', err);
|
||||
log.error(`Error restoring migration backup, retrying: ${err}`);
|
||||
|
||||
await Bluebird.delay(retryDelay);
|
||||
return this.loadBackupFromMigration(retryDelay);
|
||||
@ -188,7 +190,7 @@ export class APIBinder {
|
||||
const { unmanaged, bootstrapRetryDelay } = conf;
|
||||
|
||||
if (unmanaged) {
|
||||
console.log('Unmanaged mode is set, skipping API binder initialization');
|
||||
log.info('Unmanaged mode is set, skipping API binder initialization');
|
||||
// If we are offline because there is no apiEndpoint, there's a chance
|
||||
// we've went through a deprovision. We need to set the initialConfigReported
|
||||
// value to '', to ensure that when we do re-provision, we'll report
|
||||
@ -199,7 +201,7 @@ export class APIBinder {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Ensuring device is provisioned');
|
||||
log.debug('Ensuring device is provisioned');
|
||||
await this.provisionDevice();
|
||||
const conf2 = await this.config.getMany([
|
||||
'initialConfigReported',
|
||||
@ -210,17 +212,17 @@ export class APIBinder {
|
||||
|
||||
// Either we haven't reported our initial config or we've been re-provisioned
|
||||
if (apiEndpoint !== initialConfigReported) {
|
||||
console.log('Reporting initial configuration');
|
||||
log.info('Reporting initial configuration');
|
||||
await this.reportInitialConfig(apiEndpoint, bootstrapRetryDelay);
|
||||
}
|
||||
|
||||
console.log('Starting current state report');
|
||||
log.debug('Starting current state report');
|
||||
await this.startCurrentStateReport();
|
||||
|
||||
await this.loadBackupFromMigration(bootstrapRetryDelay);
|
||||
|
||||
this.readyForUpdates = true;
|
||||
console.log('Starting target state poll');
|
||||
log.debug('Starting target state poll');
|
||||
this.startTargetStatePoll();
|
||||
}
|
||||
|
||||
@ -506,7 +508,7 @@ export class APIBinder {
|
||||
// We don't want this to be classed as a report error, as this will cause
|
||||
// the watchdog to kill the supervisor - and killing the supervisor will
|
||||
// not help in this situation
|
||||
console.error(
|
||||
log.error(
|
||||
`Non-200 response from API! Status code: ${e.statusCode} - message: ${
|
||||
e.message
|
||||
}`,
|
||||
@ -564,7 +566,7 @@ export class APIBinder {
|
||||
}
|
||||
})
|
||||
.tapCatch(err => {
|
||||
console.error(`Failed to get target state for device: ${err}`);
|
||||
log.error(`Failed to get target state for device: ${err}`);
|
||||
})
|
||||
.finally(() => {
|
||||
this.lastTargetStateFetch = process.hrtime();
|
||||
@ -645,8 +647,7 @@ export class APIBinder {
|
||||
// task has been completed
|
||||
await this.config.remove('pinDevice');
|
||||
} catch (e) {
|
||||
console.log('Could not pin device to release!');
|
||||
console.log('Error: ', e);
|
||||
log.error(`Could not pin device to release! ${e}`);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
@ -713,7 +714,7 @@ export class APIBinder {
|
||||
try {
|
||||
await this.reportInitialEnv(apiEndpoint);
|
||||
} catch (err) {
|
||||
console.error('Error reporting initial configuration, will retry', err);
|
||||
log.error('Error reporting initial configuration, will retry', err);
|
||||
await Bluebird.delay(retryDelay);
|
||||
await this.reportInitialConfig(apiEndpoint, retryDelay);
|
||||
}
|
||||
@ -791,11 +792,11 @@ export class APIBinder {
|
||||
): Promise<Device> {
|
||||
try {
|
||||
const device = await this.exchangeKeyAndGetDevice(opts);
|
||||
console.log('Key exchange succeeded');
|
||||
log.debug('Key exchange succeeded');
|
||||
return device;
|
||||
} catch (e) {
|
||||
if (e instanceof ExchangeKeyError) {
|
||||
console.log('Exchanging key failed, re-registering...');
|
||||
log.error('Exchanging key failed, re-registering...');
|
||||
await this.config.regenerateRegistrationFields();
|
||||
}
|
||||
throw e;
|
||||
@ -804,7 +805,6 @@ export class APIBinder {
|
||||
|
||||
private async provision() {
|
||||
let device: Device | null = null;
|
||||
// FIXME: Config typing
|
||||
const opts = await this.config.get('provisioningOptions');
|
||||
if (
|
||||
opts.registered_at == null ||
|
||||
@ -812,17 +812,17 @@ export class APIBinder {
|
||||
opts.provisioningApiKey != null
|
||||
) {
|
||||
if (opts.registered_at != null && opts.deviceId == null) {
|
||||
console.log(
|
||||
log.debug(
|
||||
'Device is registered but no device id available, attempting key exchange',
|
||||
);
|
||||
device = (await this.exchangeKeyAndGetDeviceOrRegenerate(opts)) || null;
|
||||
} else if (opts.registered_at == null) {
|
||||
console.log('New device detected. Provisioning...');
|
||||
log.info('New device detected. Provisioning...');
|
||||
try {
|
||||
device = await deviceRegister.register(opts).timeout(opts.apiTimeout);
|
||||
} catch (err) {
|
||||
if (DuplicateUuidError(err)) {
|
||||
console.log('UUID already registered, trying a key exchange');
|
||||
log.debug('UUID already registered, trying a key exchange');
|
||||
device = await this.exchangeKeyAndGetDeviceOrRegenerate(opts);
|
||||
} else {
|
||||
throw err;
|
||||
@ -830,7 +830,7 @@ export class APIBinder {
|
||||
}
|
||||
opts.registered_at = Date.now();
|
||||
} else if (opts.provisioningApiKey != null) {
|
||||
console.log(
|
||||
log.debug(
|
||||
'Device is registered but we still have an apiKey, attempting key exchange',
|
||||
);
|
||||
device = await this.exchangeKeyAndGetDevice(opts);
|
||||
@ -864,12 +864,12 @@ export class APIBinder {
|
||||
|
||||
if (pinValue != null) {
|
||||
if (pinValue.app == null || pinValue.commit == null) {
|
||||
console.log(
|
||||
log.error(
|
||||
`Malformed pinDevice fields in supervisor database: ${pinValue}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
console.log('Attempting to pin device to preloaded release...');
|
||||
log.info('Attempting to pin device to preloaded release...');
|
||||
return this.pinDevice(pinValue);
|
||||
}
|
||||
}
|
||||
@ -932,7 +932,7 @@ export class APIBinder {
|
||||
.catch(_.noop);
|
||||
res.sendStatus(204);
|
||||
} else {
|
||||
console.log(
|
||||
log.debug(
|
||||
'Ignoring update notification because instant updates are disabled',
|
||||
);
|
||||
res.sendStatus(202);
|
||||
|
@ -260,7 +260,7 @@ module.exports = class ApplicationManager extends EventEmitter
|
||||
dependent[appId].images[image.imageId] = _.pick(image, [ 'status' ])
|
||||
dependent[appId].images[image.imageId].download_progress = image.downloadProgress
|
||||
else
|
||||
console.log('Ignoring legacy dependent image', image)
|
||||
log.debug('Ignoring legacy dependent image', image)
|
||||
|
||||
obj = { local: apps, dependent }
|
||||
obj.commit = currentCommit
|
||||
|
@ -18,6 +18,8 @@ import * as validation from '../lib/validation';
|
||||
import Logger from '../logger';
|
||||
import { ImageDownloadBackoffError } from './errors';
|
||||
|
||||
import log from '../lib/supervisor-console';
|
||||
|
||||
interface ImageEvents {
|
||||
change: void;
|
||||
}
|
||||
@ -452,7 +454,7 @@ export class Images extends (EventEmitter as new () => ImageEventEmitter) {
|
||||
public async cleanup() {
|
||||
const images = await this.getImagesForCleanup();
|
||||
for (const image of images) {
|
||||
console.log(`Cleaning up ${image}`);
|
||||
log.debug(`Cleaning up ${image}`);
|
||||
try {
|
||||
await this.docker.getImage(image).remove({ force: true });
|
||||
delete this.imageCleanupFailures[image];
|
||||
|
@ -8,6 +8,8 @@ import { ENOENT, NotFoundError } from '../lib/errors';
|
||||
import { Logger } from '../logger';
|
||||
import { Network, NetworkOptions } from './network';
|
||||
|
||||
import log from '../lib/supervisor-console';
|
||||
|
||||
export class NetworkManager {
|
||||
private docker: Docker;
|
||||
private logger: Logger;
|
||||
@ -101,7 +103,7 @@ export class NetworkManager {
|
||||
}
|
||||
})
|
||||
.catch(NotFoundError, () => {
|
||||
console.log(`Creating ${constants.supervisorNetworkInterface} network`);
|
||||
log.debug(`Creating ${constants.supervisorNetworkInterface} network`);
|
||||
return Bluebird.resolve(
|
||||
this.docker.createNetwork({
|
||||
Name: constants.supervisorNetworkInterface,
|
||||
|
@ -2,6 +2,8 @@ import * as _ from 'lodash';
|
||||
|
||||
import { ConfigMap, ServiceComposeConfig } from './types/service';
|
||||
|
||||
import log from '../lib/supervisor-console';
|
||||
|
||||
// TODO: Generate these fields from the interface we define
|
||||
// in service-types.
|
||||
const supportedComposeFields = [
|
||||
@ -71,10 +73,8 @@ export function sanitiseComposeConfig(
|
||||
}) as ServiceComposeConfig;
|
||||
|
||||
if (filtered.length > 0) {
|
||||
console.log(
|
||||
`Warning: Ignoring unsupported or unknown compose fields: ${filtered.join(
|
||||
', ',
|
||||
)}`,
|
||||
log.warn(
|
||||
`Ignoring unsupported or unknown compose fields: ${filtered.join(', ')}`,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@ import { checkInt, isValidDeviceName } from '../lib/validation';
|
||||
import { Service } from './service';
|
||||
import { serviceNetworksToDockerNetworks } from './utils';
|
||||
|
||||
import log from '../lib/supervisor-console';
|
||||
|
||||
interface ServiceConstructOpts {
|
||||
docker: Docker;
|
||||
logger: Logger;
|
||||
@ -388,7 +390,7 @@ export class ServiceManager extends (EventEmitter as new () => ServiceManagerEve
|
||||
});
|
||||
|
||||
stream.on('error', e => {
|
||||
console.error(`Error on docker events stream:`, e);
|
||||
log.error(`Error on docker events stream:`, e);
|
||||
});
|
||||
const parser = JSONStream.parse();
|
||||
parser.on('data', async (data: { status: string; id: string }) => {
|
||||
@ -434,7 +436,7 @@ export class ServiceManager extends (EventEmitter as new () => ServiceManagerEve
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error on docker event:', e, e.stack);
|
||||
log.error('Error on docker event:', e, e.stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -443,7 +445,7 @@ export class ServiceManager extends (EventEmitter as new () => ServiceManagerEve
|
||||
return new Promise((resolve, reject) => {
|
||||
parser
|
||||
.on('error', (e: Error) => {
|
||||
console.error('Error on docker events stream:', e);
|
||||
log.error('Error on docker events stream:', e);
|
||||
reject(e);
|
||||
})
|
||||
.on('end', resolve);
|
||||
@ -453,7 +455,7 @@ export class ServiceManager extends (EventEmitter as new () => ServiceManagerEve
|
||||
|
||||
Bluebird.resolve(listen())
|
||||
.catch(e => {
|
||||
console.error('Error listening to events:', e, e.stack);
|
||||
log.error('Error listening to events:', e, e.stack);
|
||||
})
|
||||
.finally(() => {
|
||||
this.listening = false;
|
||||
@ -645,7 +647,7 @@ export class ServiceManager extends (EventEmitter as new () => ServiceManagerEve
|
||||
await Bluebird.delay(pollInterval);
|
||||
return wait();
|
||||
} else {
|
||||
console.log(
|
||||
log.info(
|
||||
`Handover timeout has passed, assuming handover was completed for service ${
|
||||
service.serviceName
|
||||
}`,
|
||||
@ -653,14 +655,14 @@ export class ServiceManager extends (EventEmitter as new () => ServiceManagerEve
|
||||
}
|
||||
});
|
||||
|
||||
console.log(
|
||||
log.info(
|
||||
`Waiting for handover to be completed for service: ${
|
||||
service.serviceName
|
||||
}`,
|
||||
);
|
||||
|
||||
return wait().then(() => {
|
||||
console.log(`Handover complete for service ${service.serviceName}`);
|
||||
log.success(`Handover complete for service ${service.serviceName}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ import * as constants from '../lib/constants';
|
||||
import * as updateLock from '../lib/update-lock';
|
||||
import { sanitiseComposeConfig } from './sanitise';
|
||||
|
||||
import log from '../lib/supervisor-console';
|
||||
|
||||
export class Service {
|
||||
public appId: number | null;
|
||||
public imageId: number | null;
|
||||
@ -138,13 +140,13 @@ export class Service {
|
||||
// Check for unsupported networkMode entries
|
||||
if (config.networkMode != null) {
|
||||
if (/service:(\s*)?.+/.test(config.networkMode)) {
|
||||
console.log(
|
||||
'Warning: A network_mode referencing a service is not yet supported. Ignoring.',
|
||||
log.warn(
|
||||
'A network_mode referencing a service is not yet supported. Ignoring.',
|
||||
);
|
||||
delete config.networkMode;
|
||||
} else if (/container:(\s*)?.+/.test(config.networkMode)) {
|
||||
console.log(
|
||||
'Warning: A network_mode referencing a container is not supported. Ignoring.',
|
||||
log.warn(
|
||||
'A network_mode referencing a container is not supported. Ignoring.',
|
||||
);
|
||||
delete config.networkMode;
|
||||
}
|
||||
@ -317,8 +319,11 @@ export class Service {
|
||||
if (config.cpus != null) {
|
||||
config.cpus = Math.round(Number(config.cpus) * 10 ** 9);
|
||||
if (_.isNaN(config.cpus)) {
|
||||
console.log('Warning: config.cpus value cannot be parsed. Ignoring.');
|
||||
console.log(` Value: ${config.cpus}`);
|
||||
log.warn(
|
||||
`config.cpus value cannot be parsed. Ignoring.\n Value:${
|
||||
config.cpus
|
||||
}`,
|
||||
);
|
||||
config.cpus = undefined;
|
||||
}
|
||||
}
|
||||
@ -666,7 +671,7 @@ export class Service {
|
||||
if (!(sameConfig && sameNetworks)) {
|
||||
// Add some console output for why a service is not matching
|
||||
// so that if we end up in a restart loop, we know exactly why
|
||||
console.log(
|
||||
log.debug(
|
||||
`Replacing container for service ${
|
||||
this.serviceName
|
||||
} because of config changes:`,
|
||||
@ -680,14 +685,14 @@ export class Service {
|
||||
() => 'hidden',
|
||||
);
|
||||
}
|
||||
console.log(' Non-array fields: ', JSON.stringify(diffObj));
|
||||
log.debug(' Non-array fields: ', JSON.stringify(diffObj));
|
||||
}
|
||||
if (differentArrayFields.length > 0) {
|
||||
console.log(' Array Fields: ', differentArrayFields.join(','));
|
||||
log.debug(' Array Fields: ', differentArrayFields.join(','));
|
||||
}
|
||||
|
||||
if (!sameNetworks) {
|
||||
console.log(' Network changes detected');
|
||||
log.debug(' Network changes detected');
|
||||
}
|
||||
}
|
||||
return sameNetworks && sameConfig;
|
||||
@ -725,10 +730,9 @@ export class Service {
|
||||
if (!path.isAbsolute(bindSource)) {
|
||||
const match = bindSource.match(/[0-9]+_(.+)/);
|
||||
if (match == null) {
|
||||
console.log(
|
||||
'Error: There was an error parsing a volume bind source, ignoring.',
|
||||
log.error(
|
||||
`Error: There was an error parsing a volume bind source, ignoring.\nBind source: ${bindSource}`,
|
||||
);
|
||||
console.log(' bind source: ', bindSource);
|
||||
return null;
|
||||
}
|
||||
return match[1];
|
||||
@ -914,7 +918,7 @@ export class Service {
|
||||
}
|
||||
volumes.push(volumeDef);
|
||||
} else {
|
||||
console.log(`Ignoring invalid bind mount ${volume}`);
|
||||
log.warn(`Ignoring invalid bind mount ${volume}`);
|
||||
}
|
||||
} else {
|
||||
volumes.push(volume);
|
||||
|
@ -16,6 +16,8 @@ import {
|
||||
ServiceHealthcheck,
|
||||
} from './types/service';
|
||||
|
||||
import log from '../lib/supervisor-console';
|
||||
|
||||
export function camelCaseConfig(
|
||||
literalConfig: ConfigMap,
|
||||
): ServiceComposeConfig {
|
||||
@ -80,9 +82,7 @@ export function createRestartPolicy(name?: string): string {
|
||||
// Ensure that name is a string, otherwise the below could
|
||||
// throw
|
||||
if (!_.isString(name)) {
|
||||
console.log(
|
||||
`Warning: Non-string argument for restart field: ${name} - ignoring.`,
|
||||
);
|
||||
log.warn(`Non-string argument for restart field: ${name} - ignoring.`);
|
||||
return 'always';
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,8 @@ import * as fsUtils from '../lib/fs-utils';
|
||||
|
||||
const childProcess: any = Promise.promisifyAll(childProcessSync);
|
||||
|
||||
import log from '../lib/supervisor-console';
|
||||
|
||||
export interface ConfigOptions {
|
||||
[key: string]: string | string[];
|
||||
}
|
||||
@ -147,9 +149,7 @@ export class RPiConfigBackend extends DeviceConfigBackend {
|
||||
const [, key, value] = keyValue;
|
||||
conf[key] = value;
|
||||
} else {
|
||||
console.log(
|
||||
`Warning - Could not parse config.txt entry: ${configStr}. Ignoring.`,
|
||||
);
|
||||
log.warn(`Could not parse config.txt entry: ${configStr}. Ignoring.`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -362,7 +362,7 @@ export class ExtlinuxConfigBackend extends DeviceConfigBackend {
|
||||
for (const line of lines) {
|
||||
const match = line.match(/^\s*(\w+)\s?(.*)$/);
|
||||
if (match == null) {
|
||||
console.log('Warning - Could not read extlinux entry: ${line}');
|
||||
log.warn(`Could not read extlinux entry: ${line}`);
|
||||
continue;
|
||||
}
|
||||
let directive = match[1].toUpperCase();
|
||||
|
@ -10,6 +10,8 @@ import * as constants from '../lib/constants';
|
||||
import { writeAndSyncFile, writeFileAtomic } from '../lib/fs-utils';
|
||||
import * as osRelease from '../lib/os-release';
|
||||
|
||||
import log from '../lib/supervisor-console';
|
||||
|
||||
export default class ConfigJsonConfigBackend {
|
||||
private readLockConfigJson: () => Promise.Disposer<() => void>;
|
||||
private writeLockConfigJson: () => Promise.Disposer<() => void>;
|
||||
@ -88,7 +90,7 @@ export default class ConfigJsonConfigBackend {
|
||||
|
||||
public path(): Promise<string> {
|
||||
return this.pathOnHost().catch(err => {
|
||||
console.error(err.message);
|
||||
log.error('There was an error detecting the config.json path', err);
|
||||
return constants.configJsonNonAtomicPath;
|
||||
});
|
||||
}
|
||||
@ -97,7 +99,7 @@ export default class ConfigJsonConfigBackend {
|
||||
let atomicWritePossible = true;
|
||||
return this.pathOnHost()
|
||||
.catch(err => {
|
||||
console.error(err.message);
|
||||
log.error('There was an error detecting the config.json path', err);
|
||||
atomicWritePossible = false;
|
||||
return constants.configJsonNonAtomicPath;
|
||||
})
|
||||
|
@ -12,6 +12,7 @@ import {
|
||||
} from '../lib/messages';
|
||||
import { doPurge, doRestart, serviceAction } from './common';
|
||||
|
||||
import log from '../lib/supervisor-console';
|
||||
import supervisorVersion = require('../lib/supervisor-version');
|
||||
|
||||
export function createV2Api(router: Router, applications: ApplicationManager) {
|
||||
@ -193,8 +194,11 @@ export function createV2Api(router: Router, applications: ApplicationManager) {
|
||||
images.forEach(img => {
|
||||
const appName = appNameById[img.appId];
|
||||
if (appName == null) {
|
||||
console.log('Image found for unknown application!');
|
||||
console.log(' Image: ', JSON.stringify(img));
|
||||
log.warn(
|
||||
`Image found for unknown application!\nImage: ${JSON.stringify(
|
||||
img,
|
||||
)}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@ updateLock = require './lib/update-lock'
|
||||
{ DeviceConfig } = require './device-config'
|
||||
ApplicationManager = require './application-manager'
|
||||
|
||||
{ log } = require './lib/supervisor-console'
|
||||
|
||||
validateLocalState = (state) ->
|
||||
if state.name?
|
||||
throw new Error('Invalid device name') if not validation.isValidShortText(state.name)
|
||||
@ -120,7 +122,7 @@ module.exports = class DeviceState extends EventEmitter
|
||||
@deviceConfig = new DeviceConfig({ @db, @config, @logger })
|
||||
@applications = new ApplicationManager({ @config, @logger, @db, @eventTracker, deviceState: this })
|
||||
@on 'error', (err) ->
|
||||
console.error('Error in deviceState: ', err, err.stack)
|
||||
log.error('deviceState error: ', err)
|
||||
@_currentVolatile = {}
|
||||
@_writeLock = updateLock.writeLock
|
||||
@_readLock = updateLock.readLock
|
||||
@ -134,9 +136,9 @@ module.exports = class DeviceState extends EventEmitter
|
||||
@on 'apply-target-state-end', (err) ->
|
||||
if err?
|
||||
if not (err instanceof UpdatesLockedError)
|
||||
console.log("Apply error #{err}")
|
||||
log.error('Device state apply error', err)
|
||||
else
|
||||
console.log('Apply success!')
|
||||
log.success('Device state apply success')
|
||||
@applications.on('change', @reportCurrentState)
|
||||
|
||||
healthcheck: =>
|
||||
@ -149,23 +151,23 @@ module.exports = class DeviceState extends EventEmitter
|
||||
return applyTargetHealthy
|
||||
|
||||
migrateLegacyApps: (balenaApi) =>
|
||||
console.log('Migrating ids for legacy app...')
|
||||
log.info('Migrating ids for legacy app...')
|
||||
@db.models('app').select()
|
||||
.then (apps) =>
|
||||
if apps.length == 0
|
||||
console.log('No app to migrate')
|
||||
log.debug('No app to migrate')
|
||||
return
|
||||
Promise.map apps, (app) =>
|
||||
services = JSON.parse(app.services)
|
||||
# Check there's a main service, with legacy-container set
|
||||
if services.length != 1
|
||||
console.log("App doesn't have a single service, ignoring")
|
||||
log.debug("App doesn't have a single service, ignoring")
|
||||
return
|
||||
service = services[0]
|
||||
if !service.labels['io.resin.legacy-container'] and !service.labels['io.balena.legacy-container']
|
||||
console.log('Service is not marked as legacy, ignoring')
|
||||
log.debug('Service is not marked as legacy, ignoring')
|
||||
return
|
||||
console.log("Getting release #{app.commit} for app #{app.appId} from API")
|
||||
log.debug("Getting release #{app.commit} for app #{app.appId} from API")
|
||||
balenaApi.get(
|
||||
resource: 'release'
|
||||
options:
|
||||
@ -179,7 +181,7 @@ module.exports = class DeviceState extends EventEmitter
|
||||
)
|
||||
.then (releasesFromAPI) =>
|
||||
if releasesFromAPI.length == 0
|
||||
console.log("No compatible releases found in API, removing #{app.appId} from target state")
|
||||
log.warn("No compatible releases found in API, removing #{app.appId} from target state")
|
||||
return @db.models('app').where({ appId: app.appId }).del()
|
||||
release = releasesFromAPI[0]
|
||||
releaseId = release.id
|
||||
@ -189,8 +191,7 @@ module.exports = class DeviceState extends EventEmitter
|
||||
imageUrl = image.is_stored_at__image_location
|
||||
if image.content_hash
|
||||
imageUrl += "@#{image.content_hash}"
|
||||
console.log("Found a release with releaseId #{releaseId}, imageId #{imageId}, serviceId #{serviceId}")
|
||||
console.log("Image location is #{imageUrl}")
|
||||
log.debug("Found a release with releaseId #{releaseId}, imageId #{imageId}, serviceId #{serviceId}\nImage location is #{imageUrl}")
|
||||
Promise.join(
|
||||
@applications.docker.getImage(service.image).inspect().catchReturn(NotFoundError, null)
|
||||
@db.models('image').where(name: service.image).select()
|
||||
@ -198,13 +199,13 @@ module.exports = class DeviceState extends EventEmitter
|
||||
@db.transaction (trx) ->
|
||||
Promise.try ->
|
||||
if imagesFromDB.length > 0
|
||||
console.log('Deleting existing image entry in db')
|
||||
log.debug('Deleting existing image entry in db')
|
||||
trx('image').where(name: service.image).del()
|
||||
else
|
||||
console.log('No image in db to delete')
|
||||
log.debug('No image in db to delete')
|
||||
.then ->
|
||||
if imageFromDocker?
|
||||
console.log('Inserting fixed image entry in db')
|
||||
log.debug('Inserting fixed image entry in db')
|
||||
newImage = {
|
||||
name: imageUrl,
|
||||
appId: app.appId,
|
||||
@ -217,7 +218,7 @@ module.exports = class DeviceState extends EventEmitter
|
||||
}
|
||||
trx('image').insert(newImage)
|
||||
else
|
||||
console.log('Image is not downloaded, so not saving it to db')
|
||||
log.debug('Image is not downloaded, so not saving it to db')
|
||||
.then ->
|
||||
service.image = imageUrl
|
||||
service.serviceID = serviceId
|
||||
@ -227,7 +228,8 @@ module.exports = class DeviceState extends EventEmitter
|
||||
delete service.labels['io.balena.legacy-container']
|
||||
app.services = JSON.stringify([ service ])
|
||||
app.releaseId = releaseId
|
||||
console.log('Updating app entry in db')
|
||||
log.debug('Updating app entry in db')
|
||||
log.success('Successfully migrated legacy applciation')
|
||||
trx('app').update(app).where({ appId: app.appId })
|
||||
)
|
||||
|
||||
@ -236,10 +238,10 @@ module.exports = class DeviceState extends EventEmitter
|
||||
# We also need to get the releaseId, serviceId, imageId and updated image URL
|
||||
@migrateLegacyApps(balenaApi)
|
||||
.then =>
|
||||
console.log('Killing legacy containers')
|
||||
log.debug('Killing legacy containers')
|
||||
@applications.services.killAllLegacy()
|
||||
.then =>
|
||||
console.log('Migrating legacy app volumes')
|
||||
log.debug('Migrating legacy app volumes')
|
||||
@applications.getTargetApps()
|
||||
.then(_.keys)
|
||||
.map (appId) =>
|
||||
@ -269,7 +271,7 @@ module.exports = class DeviceState extends EventEmitter
|
||||
@saveInitialConfig()
|
||||
.then =>
|
||||
@initNetworkChecks(conf)
|
||||
console.log('Reporting initial state, supervisor version and API info')
|
||||
log.info('Reporting initial state, supervisor version and API info')
|
||||
@reportCurrentState(
|
||||
api_port: conf.listenPort
|
||||
api_secret: conf.apiSecret
|
||||
@ -292,7 +294,7 @@ module.exports = class DeviceState extends EventEmitter
|
||||
.finally =>
|
||||
@config.set({ targetStateSet: 'true' })
|
||||
else
|
||||
console.log('Skipping preloading')
|
||||
log.debug('Skipping preloading')
|
||||
if conf.provisioned and !_.isEmpty(targetApps)
|
||||
# If we're in this case, it's because we've updated from an older supervisor
|
||||
# and we need to mark that the target state has been set so that
|
||||
@ -309,7 +311,7 @@ module.exports = class DeviceState extends EventEmitter
|
||||
@config.on 'change', (changedConfig) ->
|
||||
if changedConfig.connectivityCheckEnabled?
|
||||
network.enableConnectivityCheck(changedConfig.connectivityCheckEnabled)
|
||||
console.log('Starting periodic check for IP addresses')
|
||||
log.debug('Starting periodic check for IP addresses')
|
||||
network.startIPAddressUpdate() (addresses) =>
|
||||
@reportCurrentState(
|
||||
ip_address: addresses.join(' ')
|
||||
@ -441,7 +443,7 @@ module.exports = class DeviceState extends EventEmitter
|
||||
if !s.isDirectory()
|
||||
throw new Error("Invalid backup: #{volumeName} is not a directory")
|
||||
if volumes[volumeName]?
|
||||
console.log("Creating volume #{volumeName} from backup")
|
||||
log.debug("Creating volume #{volumeName} from backup")
|
||||
# If the volume exists (from a previous incomplete run of this restoreBackup), we delete it first
|
||||
@applications.volumes.get({ appId, name: volumeName })
|
||||
.then =>
|
||||
@ -457,14 +459,14 @@ module.exports = class DeviceState extends EventEmitter
|
||||
rimraf(path.join(constants.rootMountPoint, 'mnt/data', constants.migrationBackupFile))
|
||||
|
||||
loadTargetFromFile: (appsPath) ->
|
||||
console.log('Attempting to load preloaded apps...')
|
||||
log.info('Attempting to load preloaded apps...')
|
||||
appsPath ?= constants.appsJsonPath
|
||||
fs.readFileAsync(appsPath, 'utf8')
|
||||
.then(JSON.parse)
|
||||
.then (stateFromFile) =>
|
||||
if _.isArray(stateFromFile)
|
||||
# This is a legacy apps.json
|
||||
console.log('Legacy apps.json detected')
|
||||
log.debug('Legacy apps.json detected')
|
||||
return @_convertLegacyAppsJson(stateFromFile)
|
||||
else
|
||||
return stateFromFile
|
||||
@ -503,11 +505,11 @@ module.exports = class DeviceState extends EventEmitter
|
||||
local: stateFromFile
|
||||
})
|
||||
.then =>
|
||||
console.log('Preloading complete')
|
||||
log.success('Preloading complete')
|
||||
if stateFromFile.pinDevice
|
||||
# multi-app warning!
|
||||
# The following will need to be changed once running multiple applications is possible
|
||||
console.log('Device will be pinned')
|
||||
log.debug('Device will be pinned')
|
||||
if commitToPin? and appToPin?
|
||||
@config.set
|
||||
pinDevice: {
|
||||
@ -519,7 +521,7 @@ module.exports = class DeviceState extends EventEmitter
|
||||
# on host, the docker daemon creates an empty directory when
|
||||
# the bind mount is added
|
||||
.catch ENOENT, EISDIR, ->
|
||||
console.log('No apps.json file present, skipping preload')
|
||||
log.debug('No apps.json file present, skipping preload')
|
||||
.catch (err) =>
|
||||
@eventTracker.track('Loading preloaded apps failed', { error: err })
|
||||
|
||||
@ -580,16 +582,16 @@ module.exports = class DeviceState extends EventEmitter
|
||||
@reportCurrentState(update_failed: true)
|
||||
if @scheduledApply?
|
||||
if not (err instanceof UpdatesLockedError)
|
||||
console.log("Updating failed, but there's another update scheduled immediately: ", err)
|
||||
log.error("Updating failed, but there's another update scheduled immediately: ", err)
|
||||
else
|
||||
delay = Math.min((2 ** @failedUpdates) * constants.backoffIncrement, @maxPollTime)
|
||||
# If there was an error then schedule another attempt briefly in the future.
|
||||
if err instanceof UpdatesLockedError
|
||||
message = "Updates are locked, retrying in #{prettyMs(delay, compact: true)}..."
|
||||
@logger.logSystemMessage(message, {}, 'updateLocked', false)
|
||||
console.log(message)
|
||||
log.info(message)
|
||||
else
|
||||
console.log('Scheduling another update attempt due to failure: ', delay, err)
|
||||
log.error("Scheduling another update attempt in #{delay}ms due to failure: ", err)
|
||||
@triggerApplyTarget({ force, delay, initial })
|
||||
|
||||
applyTarget: ({ force = false, initial = false, intermediate = false, skipLock = false, nextDelay = 200, retryCount = 0 } = {}) =>
|
||||
@ -627,7 +629,7 @@ module.exports = class DeviceState extends EventEmitter
|
||||
if _.isEmpty(steps)
|
||||
@emitAsync('apply-target-state-end', null)
|
||||
if !intermediate
|
||||
console.log('Finished applying target state')
|
||||
log.debug('Finished applying target state')
|
||||
@applications.timeSpentFetching = 0
|
||||
@failedUpdates = 0
|
||||
@lastSuccessfulUpdate = Date.now()
|
||||
@ -685,7 +687,7 @@ module.exports = class DeviceState extends EventEmitter
|
||||
Promise.delay(delay)
|
||||
.then =>
|
||||
@lastApplyStart = process.hrtime()
|
||||
console.log('Applying target state')
|
||||
log.info('Applying target state')
|
||||
@applyTarget({ force, initial })
|
||||
.finally =>
|
||||
@applyInProgress = false
|
||||
|
@ -5,6 +5,7 @@ import * as memoizee from 'memoizee';
|
||||
import Mixpanel = require('mixpanel');
|
||||
|
||||
import Config from './config';
|
||||
import log from './lib/supervisor-console';
|
||||
import supervisorVersion = require('./lib/supervisor-version');
|
||||
|
||||
export type EventTrackProperties = Dictionary<any>;
|
||||
@ -63,16 +64,14 @@ export class EventTracker {
|
||||
});
|
||||
|
||||
this.isEnabled = await config.get('mixpanelReport');
|
||||
console.log(
|
||||
log.info(
|
||||
`Mixpanel reporting is ${this.isEnabled ? 'enabled' : 'disabled'}`,
|
||||
);
|
||||
config.on('change', conf => {
|
||||
const mixpanelReport = conf.mixpanelReport;
|
||||
if (mixpanelReport != null && mixpanelReport !== this.isEnabled) {
|
||||
this.isEnabled = mixpanelReport;
|
||||
console.log(
|
||||
`${mixpanelReport ? 'A' : 'Dea'}ctivating mixpanel reporting`,
|
||||
);
|
||||
log.info(`${mixpanelReport ? 'A' : 'Dea'}ctivating mixpanel reporting`);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -117,7 +116,7 @@ export class EventTracker {
|
||||
);
|
||||
|
||||
private logEvent(...args: string[]) {
|
||||
console.log(...args);
|
||||
log.event(...args);
|
||||
}
|
||||
|
||||
private assignDefaultProperties(
|
||||
|
@ -2,12 +2,14 @@ import * as _ from 'lodash';
|
||||
|
||||
import { EnvVarObject } from './types';
|
||||
|
||||
import log from '../lib/supervisor-console';
|
||||
|
||||
export function envArrayToObject(env: string[]): EnvVarObject {
|
||||
const toPair = (keyVal: string) => {
|
||||
const m = keyVal.match(/^([^=]+)=([^]*)$/);
|
||||
if (m == null) {
|
||||
console.log(
|
||||
`WARNING: Could not correctly parse env var ${keyVal}. ` +
|
||||
log.warn(
|
||||
`Could not correctly parse env var ${keyVal}. ` +
|
||||
'Please fix this var and recreate the container.',
|
||||
);
|
||||
return [null, null];
|
||||
|
@ -16,6 +16,8 @@ import {
|
||||
import { request, requestLib, resumable } from './request';
|
||||
import { EnvVarObject } from './types';
|
||||
|
||||
import log from './supervisor-console';
|
||||
|
||||
export type FetchOptions = SchemaReturn<'fetchOptions'>;
|
||||
export type DeltaFetchOptions = FetchOptions & {
|
||||
deltaSourceId: string;
|
||||
@ -77,11 +79,11 @@ export class DockerUtils extends DockerToolbelt {
|
||||
|
||||
const timeout = deltaOpts.deltaApplyTimeout;
|
||||
|
||||
const log = (str: string) =>
|
||||
console.log(`delta([${serviceName}] ${deltaOpts.deltaSource}): ${str}`);
|
||||
const logFn = (str: string) =>
|
||||
log.debug(`delta([${serviceName}] ${deltaOpts.deltaSource}): ${str}`);
|
||||
|
||||
if (!_.includes([2, 3], deltaOpts.deltaVersion)) {
|
||||
log(
|
||||
logFn(
|
||||
`Unsupported delta version: ${
|
||||
deltaOpts.deltaVersion
|
||||
}. Failling back to regular pull`,
|
||||
@ -92,12 +94,12 @@ export class DockerUtils extends DockerToolbelt {
|
||||
// Since the supevisor never calls this function with a source anymore,
|
||||
// this should never happen, but w ehandle it anyway
|
||||
if (deltaOpts.deltaSource == null) {
|
||||
log('Falling back to regular pull due to lack of a delta source');
|
||||
logFn('Falling back to regular pull due to lack of a delta source');
|
||||
return this.fetchImageWithProgress(imgDest, deltaOpts, onProgress);
|
||||
}
|
||||
|
||||
const docker = this;
|
||||
log(`Starting delta to ${imgDest}`);
|
||||
logFn(`Starting delta to ${imgDest}`);
|
||||
|
||||
const [dstInfo, srcInfo] = await Promise.all([
|
||||
this.getRegistryAndName(imgDest),
|
||||
@ -153,7 +155,7 @@ export class DockerUtils extends DockerToolbelt {
|
||||
timeout,
|
||||
resumeOpts,
|
||||
onProgress,
|
||||
log,
|
||||
logFn,
|
||||
);
|
||||
break;
|
||||
case 3:
|
||||
@ -177,7 +179,7 @@ export class DockerUtils extends DockerToolbelt {
|
||||
name,
|
||||
token,
|
||||
onProgress,
|
||||
log,
|
||||
logFn,
|
||||
);
|
||||
break;
|
||||
default:
|
||||
@ -187,19 +189,19 @@ export class DockerUtils extends DockerToolbelt {
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof OutOfSyncError) {
|
||||
log('Falling back to regular pull due to delta out of sync error');
|
||||
logFn('Falling back to regular pull due to delta out of sync error');
|
||||
return await this.fetchImageWithProgress(
|
||||
imgDest,
|
||||
deltaOpts,
|
||||
onProgress,
|
||||
);
|
||||
} else {
|
||||
log(`Delta failed with ${e}`);
|
||||
logFn(`Delta failed with ${e}`);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
log(`Delta applied successfully`);
|
||||
logFn(`Delta applied successfully`);
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -228,7 +230,7 @@ export class DockerUtils extends DockerToolbelt {
|
||||
try {
|
||||
return envArrayToObject(_.get(inspect, ['Config', 'Env'], []));
|
||||
} catch (e) {
|
||||
console.log('Error getting env from image', e, e.stack);
|
||||
log.error('Error getting env from image', e);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
@ -259,9 +261,9 @@ export class DockerUtils extends DockerToolbelt {
|
||||
applyTimeout: number,
|
||||
opts: RsyncApplyOptions,
|
||||
onProgress: ProgressCallback,
|
||||
log: (str: string) => void,
|
||||
logFn: (str: string) => void,
|
||||
): Promise<string> {
|
||||
log('Applying rsync delta...');
|
||||
logFn('Applying rsync delta...');
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = resumable(Object.assign({ url: deltaUrl }, opts));
|
||||
@ -280,14 +282,14 @@ export class DockerUtils extends DockerToolbelt {
|
||||
reject(new Error('Invalid delta URL'));
|
||||
} else {
|
||||
const deltaStream = applyDelta(imgSrc, {
|
||||
log,
|
||||
log: logFn,
|
||||
timeout: applyTimeout,
|
||||
});
|
||||
res
|
||||
.pipe(deltaStream)
|
||||
.on('id', id => resolve(`sha256:${id}`))
|
||||
.on('error', err => {
|
||||
log(`Delta stream emitted error: ${err}`);
|
||||
logFn(`Delta stream emitted error: ${err}`);
|
||||
req.abort();
|
||||
reject(err);
|
||||
});
|
||||
@ -301,13 +303,13 @@ export class DockerUtils extends DockerToolbelt {
|
||||
deltaImg: string,
|
||||
token: string | null,
|
||||
onProgress: ProgressCallback,
|
||||
log: (str: string) => void,
|
||||
logFn: (str: string) => void,
|
||||
): Promise<string> {
|
||||
log('Applying balena delta...');
|
||||
logFn('Applying balena delta...');
|
||||
|
||||
let auth: Dictionary<unknown> | undefined;
|
||||
if (token != null) {
|
||||
log('Using registry auth token');
|
||||
logFn('Using registry auth token');
|
||||
auth = {
|
||||
authconfig: {
|
||||
registrytoken: token,
|
||||
|
@ -2,6 +2,8 @@ import * as Bluebird from 'bluebird';
|
||||
import * as fs from 'fs';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import log from './supervisor-console';
|
||||
|
||||
// FIXME: Don't use synchronous file reading and change call sites to support a promise
|
||||
function getOSReleaseField(path: string, field: string): string | undefined {
|
||||
try {
|
||||
@ -21,7 +23,7 @@ function getOSReleaseField(path: string, field: string): string | undefined {
|
||||
// Remove enclosing quotes: http://stackoverflow.com/a/19156197/2549019
|
||||
return releaseItems[field].replace(/^"(.+(?="$))"$/, '$1');
|
||||
} catch (err) {
|
||||
console.log('Could not get OS release field: ', err.message);
|
||||
log.error('Could not get OS release field: ', err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
90
src/lib/supervisor-console.ts
Normal file
90
src/lib/supervisor-console.ts
Normal file
@ -0,0 +1,90 @@
|
||||
import * as _ from 'lodash';
|
||||
import { TransformableInfo } from 'logform';
|
||||
import * as winston from 'winston';
|
||||
|
||||
const levels = {
|
||||
error: 0,
|
||||
warn: 1,
|
||||
success: 2,
|
||||
event: 3,
|
||||
api: 4,
|
||||
info: 5,
|
||||
debug: 6,
|
||||
};
|
||||
|
||||
type logLevel = keyof typeof levels;
|
||||
|
||||
const colors: { [key in logLevel]: string | string[] } = {
|
||||
error: 'red',
|
||||
warn: 'yellow',
|
||||
success: 'green',
|
||||
event: 'cyan',
|
||||
info: 'blue',
|
||||
debug: 'magenta',
|
||||
api: ['black', 'bgWhite'],
|
||||
};
|
||||
|
||||
const maxLevelLength = _(levels)
|
||||
.map((_v, k) => k.length)
|
||||
.max();
|
||||
|
||||
const uncolorize = winston.format.uncolorize();
|
||||
|
||||
const formatter = winston.format.printf(args => {
|
||||
const { level, message } = args;
|
||||
const { level: strippedLevel } = uncolorize.transform(args, {
|
||||
level: true,
|
||||
message: true,
|
||||
}) as TransformableInfo;
|
||||
return `[${level}]${_.repeat(
|
||||
' ',
|
||||
maxLevelLength! - strippedLevel.length + 1,
|
||||
)}${message}`;
|
||||
});
|
||||
|
||||
export const winstonLog = (winston.createLogger({
|
||||
format: winston.format.combine(winston.format.colorize(), formatter),
|
||||
transports: [new winston.transports.Console()],
|
||||
// In the future we can reduce this logging level in
|
||||
// certain scenarios, but for now we don't want to ignore
|
||||
// any debugging without a rock solid method of making
|
||||
// sure that debug logs are shown. For example a switch on
|
||||
// the dashboard, a supervisor api call and supervisor
|
||||
// process crash detection
|
||||
level: 'debug',
|
||||
levels,
|
||||
// A bit hacky to get all the correct types for the logger
|
||||
// below, we first cast to unknown so we can do what we
|
||||
// like, and then assign every log level a function (which
|
||||
// is what happens internally in winston)
|
||||
}) as unknown) as { [key in logLevel]: (message: string) => void };
|
||||
|
||||
winston.addColors(colors);
|
||||
|
||||
const messageFormatter = (printFn: (message: string) => void) => {
|
||||
return (...parts: any[]) => {
|
||||
parts
|
||||
.map(p => {
|
||||
if (p instanceof Error) {
|
||||
return p.stack;
|
||||
}
|
||||
return p;
|
||||
})
|
||||
.join(' ')
|
||||
.replace('\n', '\n ')
|
||||
.split('\n')
|
||||
.forEach(printFn);
|
||||
};
|
||||
};
|
||||
|
||||
export const log: { [key in logLevel]: (...messageParts: any[]) => void } = {
|
||||
error: messageFormatter(winstonLog.error),
|
||||
warn: messageFormatter(winstonLog.warn),
|
||||
success: messageFormatter(winstonLog.success),
|
||||
event: messageFormatter(winstonLog.event),
|
||||
info: messageFormatter(winstonLog.info),
|
||||
debug: messageFormatter(winstonLog.debug),
|
||||
api: messageFormatter(winstonLog.api),
|
||||
};
|
||||
|
||||
export default log;
|
@ -3,6 +3,8 @@ import { inspect } from 'util';
|
||||
|
||||
import { EnvVarObject, LabelObject } from './types';
|
||||
|
||||
import log from './supervisor-console';
|
||||
|
||||
export interface CheckIntOptions {
|
||||
positive?: boolean;
|
||||
}
|
||||
@ -100,29 +102,37 @@ export function isValidShortText(t: string): boolean {
|
||||
*/
|
||||
export function isValidEnv(obj: EnvVarObject): boolean {
|
||||
if (!_.isObject(obj)) {
|
||||
console.log('debug: Non-object passed to validation.isValidEnv');
|
||||
console.log(`\tobj: ${inspect(obj)}`);
|
||||
log.debug(
|
||||
`Non-object passed to validation.isValidEnv\nobj: ${inspect(obj)}`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return _.every(obj, (val, key) => {
|
||||
if (!isValidShortText(key)) {
|
||||
console.log(
|
||||
'debug: Non-valid short text env var key passed to validation.isValidEnv',
|
||||
log.debug(
|
||||
`Non-valid short text env var key passed to validation.isValidEnv\nKey: ${inspect(
|
||||
key,
|
||||
)}`,
|
||||
);
|
||||
console.log(`\tKey: ${inspect(key)}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ENV_VAR_KEY_REGEX.test(key)) {
|
||||
console.log('debug: Invalid env var key passed to validation.isValidEnv');
|
||||
console.log(`\tKey: ${inspect(key)}`);
|
||||
log.debug(
|
||||
`Invalid env var key passed to validation.isValidEnv\nKey: ${inspect(
|
||||
key,
|
||||
)}`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_.isString(val)) {
|
||||
console.log('debug: Non-string value passed to validation.isValidEnv');
|
||||
console.log(`\tval: ${inspect(key)}`);
|
||||
log.debug(
|
||||
`Non-string value passed to validation.isValidEnv\nValue: ${inspect(
|
||||
key,
|
||||
)}`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -136,33 +146,39 @@ export function isValidEnv(obj: EnvVarObject): boolean {
|
||||
*/
|
||||
export function isValidLabelsObject(obj: LabelObject): boolean {
|
||||
if (!_.isObject(obj)) {
|
||||
console.log('debug: Non-object passed to validation.isValidLabelsObject');
|
||||
console.log(`\tobj: ${inspect(obj)}`);
|
||||
log.debug(
|
||||
`Non-object passed to validation.isValidLabelsObject\nobj: ${inspect(
|
||||
obj,
|
||||
)}`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return _.every(obj, (val, key) => {
|
||||
if (!isValidShortText(key)) {
|
||||
console.log(
|
||||
'debug: Non-valid short text label key passed to validation.isValidLabelsObject',
|
||||
log.debug(
|
||||
`Non-valid short text label key passed to validation.isValidLabelsObject\nKey: ${inspect(
|
||||
key,
|
||||
)}`,
|
||||
);
|
||||
console.log(`\tkey: ${inspect(key)}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!LABEL_NAME_REGEX.test(key)) {
|
||||
console.log(
|
||||
'debug: Invalid label name passed to validation.isValidLabelsObject',
|
||||
log.debug(
|
||||
`Invalid label name passed to validation.isValidLabelsObject\nKey: ${inspect(
|
||||
key,
|
||||
)}`,
|
||||
);
|
||||
console.log(`\tkey: ${inspect(key)}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_.isString(val)) {
|
||||
console.log(
|
||||
'debug: Non-string value passed to validation.isValidLabelsObject',
|
||||
log.debug(
|
||||
`Non-string value passed to validation.isValidLabelsObject\nValue: ${inspect(
|
||||
val,
|
||||
)}`,
|
||||
);
|
||||
console.log(`\tval: ${inspect(val)}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -174,8 +190,8 @@ export function isValidDeviceName(name: string): boolean {
|
||||
// currently the only disallowed value in a device name is a newline
|
||||
const newline = name.indexOf('\n') !== -1;
|
||||
if (newline) {
|
||||
console.log(
|
||||
'debug: newline found in device name. This is invalid and should be removed',
|
||||
log.debug(
|
||||
'Newline found in device name. This is invalid and should be removed',
|
||||
);
|
||||
}
|
||||
return !newline;
|
||||
@ -194,10 +210,10 @@ function undefinedOrValidEnv(val: EnvVarObject): boolean {
|
||||
*/
|
||||
export function isValidDependentAppsObject(apps: any): boolean {
|
||||
if (!_.isObject(apps)) {
|
||||
console.log(
|
||||
'debug: non-object passed to validation.isValidDependentAppsObject',
|
||||
log.debug(
|
||||
'Non-object passed to validation.isValidDependentAppsObject\nApps:',
|
||||
inspect(apps),
|
||||
);
|
||||
console.log(`\tapps: ${inspect(apps)}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -210,60 +226,60 @@ export function isValidDependentAppsObject(apps: any): boolean {
|
||||
});
|
||||
|
||||
if (!isValidShortText(appId) || !checkInt(appId)) {
|
||||
console.log(
|
||||
'debug: Invalid appId passed to validation.isValidDependentAppsObject',
|
||||
log.debug(
|
||||
'Invalid appId passed to validation.isValidDependentAppsObject\nappId:',
|
||||
inspect(appId),
|
||||
);
|
||||
console.log(`\tappId: ${inspect(appId)}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
return _.conformsTo(val, {
|
||||
name: (n: any) => {
|
||||
if (!isValidShortText(n)) {
|
||||
console.log(
|
||||
'debug: Invalid name passed to validation.isValidDependentAppsObject',
|
||||
log.debug(
|
||||
'Invalid name passed to validation.isValidDependentAppsObject\nName:',
|
||||
inspect(n),
|
||||
);
|
||||
console.log(`\tname: ${inspect(n)}`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
image: (i: any) => {
|
||||
if (val.commit != null && !isValidShortText(i)) {
|
||||
console.log(
|
||||
'debug: non valid image passed to validation.isValidDependentAppsObject',
|
||||
log.debug(
|
||||
'Non valid image passed to validation.isValidDependentAppsObject\nImage:',
|
||||
inspect(i),
|
||||
);
|
||||
console.log(`\timage: ${inspect(i)}`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
commit: (c: any) => {
|
||||
if (c != null && !isValidShortText(c)) {
|
||||
console.log(
|
||||
'debug: invalid commit passed to validation.isValidDependentAppsObject',
|
||||
log.debug(
|
||||
'invalid commit passed to validation.isValidDependentAppsObject\nCommit:',
|
||||
inspect(c),
|
||||
);
|
||||
console.log(`\tcommit: ${inspect(c)}`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
config: (c: any) => {
|
||||
if (!undefinedOrValidEnv(c)) {
|
||||
console.log(
|
||||
'debug; Invalid config passed to validation.isValidDependentAppsObject',
|
||||
log.debug(
|
||||
'Invalid config passed to validation.isValidDependentAppsObject\nConfig:',
|
||||
inspect(c),
|
||||
);
|
||||
console.log(`\tconfig: ${inspect(c)}`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
environment: (e: any) => {
|
||||
if (!undefinedOrValidEnv(e)) {
|
||||
console.log(
|
||||
'debug; Invalid environment passed to validation.isValidDependentAppsObject',
|
||||
log.debug(
|
||||
'Invalid environment passed to validation.isValidDependentAppsObject\nEnvironment:',
|
||||
inspect(e),
|
||||
);
|
||||
console.log(`\tenvironment: ${inspect(e)}`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -274,56 +290,60 @@ export function isValidDependentAppsObject(apps: any): boolean {
|
||||
|
||||
function isValidService(service: any, serviceId: string): boolean {
|
||||
if (!isValidShortText(serviceId) || !checkInt(serviceId)) {
|
||||
console.log(
|
||||
'debug: Invalid service id passed to validation.isValidService',
|
||||
log.debug(
|
||||
'Invalid service id passed to validation.isValidService\nService ID:',
|
||||
inspect(serviceId),
|
||||
);
|
||||
console.log(`\tserviceId: ${inspect(serviceId)}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
return _.conformsTo(service, {
|
||||
serviceName: (n: any) => {
|
||||
if (!isValidShortText(n)) {
|
||||
console.log(
|
||||
'debug: Invalid service name passed to validation.isValidService',
|
||||
log.debug(
|
||||
'Invalid service name passed to validation.isValidService\nService Name:',
|
||||
inspect(n),
|
||||
);
|
||||
console.log(`\tserviceName: ${inspect(n)}`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
image: (i: any) => {
|
||||
if (!isValidShortText(i)) {
|
||||
console.log('debug: Invalid image passed to validation.isValidService');
|
||||
console.log(`\timage: ${inspect(i)}`);
|
||||
log.debug(
|
||||
'Invalid image passed to validation.isValidService\nImage:',
|
||||
inspect(i),
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
environment: (e: any) => {
|
||||
if (!isValidEnv(e)) {
|
||||
console.log('debug: Invalid env passed to validation.isValidService');
|
||||
console.log(`\tenvironment: ${inspect(e)}`);
|
||||
log.debug(
|
||||
'Invalid env passed to validation.isValidService\nEnvironment:',
|
||||
inspect(e),
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
imageId: (i: any) => {
|
||||
if (checkInt(i) == null) {
|
||||
console.log(
|
||||
'debug: Invalid image id passed to validation.isValidService',
|
||||
log.debug(
|
||||
'Invalid image id passed to validation.isValidService\nImage ID:',
|
||||
inspect(i),
|
||||
);
|
||||
console.log(`\timageId: ${inspect(i)}`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
labels: (l: any) => {
|
||||
if (!isValidLabelsObject(l)) {
|
||||
console.log(
|
||||
'debug: Invalid labels object passed to validation.isValidService',
|
||||
log.debug(
|
||||
'Invalid labels object passed to validation.isValidService\nLabels:',
|
||||
inspect(l),
|
||||
);
|
||||
console.log(`\tlabels: ${inspect(l)}`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -341,56 +361,58 @@ function isValidService(service: any, serviceId: string): boolean {
|
||||
*/
|
||||
export function isValidAppsObject(obj: any): boolean {
|
||||
if (!_.isObject(obj)) {
|
||||
console.log('debug: Invalid object passed to validation.isValidAppsObject');
|
||||
console.log(`\tobj: ${inspect(obj)}`);
|
||||
log.debug(
|
||||
'Invalid object passed to validation.isValidAppsObject\nobj:',
|
||||
inspect(obj),
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return _.every(obj, (val, appId) => {
|
||||
if (!isValidShortText(appId) || !checkInt(appId)) {
|
||||
console.log(
|
||||
'debug: Invalid appId passed to validation.isValidAppsObject',
|
||||
log.debug(
|
||||
'Invalid appId passed to validation.isValidAppsObject\nApp ID:',
|
||||
inspect(appId),
|
||||
);
|
||||
console.log(`\tappId: ${inspect(appId)}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
return _.conformsTo(_.defaults(_.clone(val), { releaseId: undefined }), {
|
||||
name: (n: any) => {
|
||||
if (!isValidShortText(n)) {
|
||||
console.log(
|
||||
'debug: Invalid service name passed to validation.isValidAppsObject',
|
||||
log.debug(
|
||||
'Invalid service name passed to validation.isValidAppsObject\nName:',
|
||||
inspect(n),
|
||||
);
|
||||
console.log(`\tname: ${inspect(n)}`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
releaseId: (r: any) => {
|
||||
if (r != null && checkInt(r) == null) {
|
||||
console.log(
|
||||
'debug: Invalid releaseId passed to validation.isValidAppsObject',
|
||||
log.debug(
|
||||
'Invalid releaseId passed to validation.isValidAppsObject\nRelease ID',
|
||||
inspect(r),
|
||||
);
|
||||
console.log(`\treleaseId: ${inspect(r)}`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
services: (s: any) => {
|
||||
if (!_.isObject(s)) {
|
||||
console.log(
|
||||
'debug: Non-object service passed to validation.isValidAppsObject',
|
||||
log.debug(
|
||||
'Non-object service passed to validation.isValidAppsObject\nServices:',
|
||||
inspect(s),
|
||||
);
|
||||
console.log(`\tservices: ${inspect(s)}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
return _.every(s, (svc, svcId) => {
|
||||
if (!isValidService(svc, svcId)) {
|
||||
console.log(
|
||||
'debug: Invalid service object passed to validation.isValidAppsObject',
|
||||
log.debug(
|
||||
'Invalid service object passed to validation.isValidAppsObject\nService:',
|
||||
inspect(svc),
|
||||
);
|
||||
console.log(`\tsvc: ${inspect(svc)}`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -407,45 +429,45 @@ export function isValidAppsObject(obj: any): boolean {
|
||||
*/
|
||||
export function isValidDependentDevicesObject(devices: any): boolean {
|
||||
if (!_.isObject(devices)) {
|
||||
console.log(
|
||||
'debug: Non-object passed to validation.isValidDependentDevicesObject',
|
||||
log.debug(
|
||||
'Non-object passed to validation.isValidDependentDevicesObject\nDevices:',
|
||||
inspect(devices),
|
||||
);
|
||||
console.log(`\tdevices: ${inspect(devices)}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
return _.every(devices, (val, uuid) => {
|
||||
if (!isValidShortText(uuid)) {
|
||||
console.log(
|
||||
'debug: Invalid uuid passed to validation.isValidDependentDevicesObject',
|
||||
log.debug(
|
||||
'Invalid uuid passed to validation.isValidDependentDevicesObject\nuuid:',
|
||||
inspect(uuid),
|
||||
);
|
||||
console.log(`\tuuid: ${inspect(uuid)}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
return _.conformsTo(val, {
|
||||
name: (n: any) => {
|
||||
if (!isValidShortText(n)) {
|
||||
console.log(
|
||||
'debug: Invalid device name passed to validation.isValidDependentDevicesObject',
|
||||
log.debug(
|
||||
'Invalid device name passed to validation.isValidDependentDevicesObject\nName:',
|
||||
inspect(n),
|
||||
);
|
||||
console.log(`\tname: ${inspect(n)}`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
apps: (a: any) => {
|
||||
if (!_.isObject(a)) {
|
||||
console.log(
|
||||
'debug: Invalid apps object passed to validation.isValidDependentDevicesObject',
|
||||
log.debug(
|
||||
'Invalid apps object passed to validation.isValidDependentDevicesObject\nApps:',
|
||||
inspect(a),
|
||||
);
|
||||
console.log(`\tapps: ${inspect(a)}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_.isEmpty(a)) {
|
||||
console.log(
|
||||
'debug: Empty object passed to validation.isValidDependentDevicesObject',
|
||||
log.debug(
|
||||
'Empty object passed to validation.isValidDependentDevicesObject',
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@ -458,20 +480,20 @@ export function isValidDependentDevicesObject(devices: any): boolean {
|
||||
return _.conformsTo(app, {
|
||||
config: (c: any) => {
|
||||
if (!undefinedOrValidEnv(c)) {
|
||||
console.log(
|
||||
'debug: Invalid config passed to validation.isValidDependentDevicesObject',
|
||||
log.debug(
|
||||
'Invalid config passed to validation.isValidDependentDevicesObject\nConfig:',
|
||||
inspect(c),
|
||||
);
|
||||
console.log(`\tconfig: ${inspect(c)}`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
environment: (e: any) => {
|
||||
if (!undefinedOrValidEnv(e)) {
|
||||
console.log(
|
||||
'debug: Invalid environment passed to validation.isValidDependentDevicesObject',
|
||||
log.debug(
|
||||
'Invalid environment passed to validation.isValidDependentDevicesObject\nConfig:',
|
||||
inspect(e),
|
||||
);
|
||||
console.log(`\tconfig: ${inspect(e)}`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -6,6 +6,8 @@ import Config from './config';
|
||||
import Database from './db';
|
||||
import { Logger } from './logger';
|
||||
|
||||
import log from './lib/supervisor-console';
|
||||
|
||||
/**
|
||||
* This class handles any special cases necessary for switching
|
||||
* modes in localMode.
|
||||
@ -43,7 +45,7 @@ export class LocalModeManager {
|
||||
// as local mode needs to be set
|
||||
let unmanagedLocalMode = false;
|
||||
if (await this.config.get('unmanaged')) {
|
||||
console.log('Starting up in unmanaged mode, activating local mode');
|
||||
log.info('Starting up in unmanaged mode, activating local mode');
|
||||
await this.config.set({ localMode: true });
|
||||
unmanagedLocalMode = true;
|
||||
}
|
||||
@ -64,11 +66,11 @@ export class LocalModeManager {
|
||||
const containers = await this.getLocalModeContainers(images);
|
||||
|
||||
await Bluebird.map(containers, containerId => {
|
||||
console.log('Removing local mode container: ', containerId);
|
||||
log.debug('Removing local mode container: ', containerId);
|
||||
return this.docker.getContainer(containerId).remove({ force: true });
|
||||
});
|
||||
await Bluebird.map(images, imageId => {
|
||||
console.log('Removing local mode image: ', imageId);
|
||||
log.debug('Removing local mode image: ', imageId);
|
||||
return this.docker.getImage(imageId).remove({ force: true });
|
||||
});
|
||||
|
||||
@ -78,7 +80,7 @@ export class LocalModeManager {
|
||||
.del()
|
||||
.where({ source: 'local' });
|
||||
} catch (e) {
|
||||
console.log('There was an error clearing local mode artifacts: ', e);
|
||||
log.error('There was an error clearing local mode artifacts: ', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,8 @@ import {
|
||||
} from './logging';
|
||||
import LogMonitor from './logging/monitor';
|
||||
|
||||
import log from './lib/supervisor-console';
|
||||
|
||||
interface LoggerSetupOptions {
|
||||
apiEndpoint: string;
|
||||
uuid: string;
|
||||
@ -69,11 +71,11 @@ export class Logger {
|
||||
if (localMode) {
|
||||
// Use the local mode backend
|
||||
this.backend = this.localBackend;
|
||||
console.log('Switching logging backend to LocalLogBackend');
|
||||
log.info('Switching logging backend to LocalLogBackend');
|
||||
} else {
|
||||
// Use the balena backend
|
||||
this.backend = this.balenaBackend;
|
||||
console.log('Switching logging backend to BalenaLogBackend');
|
||||
log.info('Switching logging backend to BalenaLogBackend');
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,7 +148,7 @@ export class Logger {
|
||||
const logs = new ContainerLogs(containerId, docker);
|
||||
this.containerLogs[containerId] = logs;
|
||||
logs.on('error', err => {
|
||||
console.error(`Container log retrieval error: ${err}`);
|
||||
log.error('Container log retrieval error', err);
|
||||
delete this.containerLogs[containerId];
|
||||
});
|
||||
logs.on('log', async logMessage => {
|
||||
@ -184,7 +186,7 @@ export class Logger {
|
||||
if (_.isEmpty(errorMessage)) {
|
||||
errorMessage =
|
||||
obj.error.name !== 'Error' ? obj.error.name : 'Unknown cause';
|
||||
console.error('Warning: invalid error message', obj.error);
|
||||
log.warn('Invalid error message', obj.error);
|
||||
}
|
||||
message += ` due to '${errorMessage}'`;
|
||||
}
|
||||
@ -214,7 +216,7 @@ export class Logger {
|
||||
}
|
||||
|
||||
public async clearOutOfDateDBLogs(containerIds: string[]) {
|
||||
console.log('Performing database cleanup for container log timestamps');
|
||||
log.debug('Performing database cleanup for container log timestamps');
|
||||
await this.db
|
||||
.models('containerLogs')
|
||||
.whereNotIn('containerId', containerIds)
|
||||
|
@ -7,6 +7,8 @@ import * as zlib from 'zlib';
|
||||
|
||||
import { LogBackend, LogMessage } from './log-backend';
|
||||
|
||||
import log from '../lib/supervisor-console';
|
||||
|
||||
const ZLIB_TIMEOUT = 100;
|
||||
const COOLDOWN_PERIOD = 5 * 1000;
|
||||
const KEEPALIVE_TIMEOUT = 60 * 1000;
|
||||
@ -105,7 +107,7 @@ export class BalenaLogBackend extends LogBackend {
|
||||
// only reason for the server to prematurely respond is to
|
||||
// communicate an error. So teardown the connection immediately
|
||||
this.req.on('response', res => {
|
||||
console.log(
|
||||
log.error(
|
||||
'LogBackend: server responded with status code:',
|
||||
res.statusCode,
|
||||
);
|
||||
@ -115,7 +117,7 @@ export class BalenaLogBackend extends LogBackend {
|
||||
this.req.on('timeout', () => this.teardown());
|
||||
this.req.on('close', () => this.teardown());
|
||||
this.req.on('error', err => {
|
||||
console.log('LogBackend: unexpected error:', err);
|
||||
log.error('LogBackend: unexpected error:', err);
|
||||
this.teardown();
|
||||
});
|
||||
|
||||
|
@ -5,6 +5,8 @@ import { Readable } from 'stream';
|
||||
import { checkInt } from '../lib/validation';
|
||||
import { LogBackend, LogMessage } from './log-backend';
|
||||
|
||||
import log from '../lib/supervisor-console';
|
||||
|
||||
export class LocalLogBackend extends LogBackend {
|
||||
private globalListeners: Readable[] = [];
|
||||
|
||||
@ -21,10 +23,10 @@ export class LocalLogBackend extends LogBackend {
|
||||
}
|
||||
const svcId = checkInt(message.serviceId);
|
||||
if (svcId == null) {
|
||||
console.log(
|
||||
'Warning: Non-integer service id found in local logs: ',
|
||||
log.warn(
|
||||
'Non-integer service id found in local logs:\n',
|
||||
JSON.stringify(message),
|
||||
);
|
||||
console.log(` ${JSON.stringify(message)}`);
|
||||
return null;
|
||||
}
|
||||
// TODO: Can we cache this value? The service ids are reused, so
|
||||
@ -44,7 +46,7 @@ export class LocalLogBackend extends LogBackend {
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
console.log('Error streaming local log output: ', e);
|
||||
log.error('Error streaming local log output:', e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
import Database from '../db';
|
||||
|
||||
import log from '../lib/supervisor-console';
|
||||
|
||||
// Flush every 10 mins
|
||||
const DB_FLUSH_INTERVAL = 10 * 60 * 1000;
|
||||
|
||||
@ -46,8 +48,9 @@ export class LogMonitor {
|
||||
this.timestamps[containerId] = timestampObj.lastSentTimestamp;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(
|
||||
`There was an error retrieving the container log timestamps: ${e}`,
|
||||
log.error(
|
||||
'There was an error retrieving the container log timestamps:',
|
||||
e,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -55,7 +58,7 @@ export class LogMonitor {
|
||||
}
|
||||
|
||||
private async flushDb() {
|
||||
console.log('Attempting container log timestamp flush...');
|
||||
log.debug('Attempting container log timestamp flush...');
|
||||
const containerIds = Object.getOwnPropertyNames(this.timestamps);
|
||||
try {
|
||||
for (const containerId of containerIds) {
|
||||
@ -71,11 +74,9 @@ export class LogMonitor {
|
||||
this.writeRequired[containerId] = false;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(
|
||||
`There was an error storing the container log timestamps: ${e}`,
|
||||
);
|
||||
log.error('There was an error storing the container log timestamps:', e);
|
||||
}
|
||||
console.log('Container log timestamp flush complete');
|
||||
log.debug('Container log timestamp flush complete');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,8 @@ import { checkTruthy } from './lib/validation';
|
||||
|
||||
import blink = require('./lib/blink');
|
||||
|
||||
import log from './lib/supervisor-console';
|
||||
|
||||
const networkPattern = {
|
||||
blinks: 4,
|
||||
pause: 1000,
|
||||
@ -57,13 +59,13 @@ export const startConnectivityCheck = _.once(
|
||||
) => {
|
||||
enableConnectivityCheck(enable);
|
||||
if (!apiEndpoint) {
|
||||
console.log('No API endpoint specified, skipping connectivity check');
|
||||
log.debug('No API endpoint specified, skipping connectivity check');
|
||||
return;
|
||||
}
|
||||
|
||||
await Bluebird.resolve(fs.mkdir(constants.vpnStatusPath))
|
||||
.catch(EEXIST, () => {
|
||||
console.log('VPN status path exists.');
|
||||
log.debug('VPN status path exists.');
|
||||
})
|
||||
.then(() => {
|
||||
fs.watch(constants.vpnStatusPath, vpnStatusInotifyCallback);
|
||||
@ -88,10 +90,10 @@ export const startConnectivityCheck = _.once(
|
||||
onChangeCallback(connected);
|
||||
}
|
||||
if (connected) {
|
||||
console.log('Internet Connectivity: OK');
|
||||
log.info('Internet Connectivity: OK');
|
||||
blink.pattern.stop();
|
||||
} else {
|
||||
console.log('Waiting for connectivity...');
|
||||
log.info('Waiting for connectivity...');
|
||||
blink.pattern.start(networkPattern);
|
||||
}
|
||||
},
|
||||
@ -103,7 +105,7 @@ export function enableConnectivityCheck(enable: boolean) {
|
||||
const boolEnable = checkTruthy(enable);
|
||||
enable = boolEnable != null ? boolEnable : true;
|
||||
enableCheck(enable);
|
||||
console.log(`Connectivity check enabled: ${enable}`);
|
||||
log.debug(`Connectivity check enabled: ${enable}`);
|
||||
}
|
||||
|
||||
export const connectivityCheckEnabled = Bluebird.method(
|
||||
|
@ -11,6 +11,8 @@ bodyParser = require 'body-parser'
|
||||
execAsync = Promise.promisify(require('child_process').exec)
|
||||
url = require 'url'
|
||||
|
||||
{ log } = require './lib/supervisor-console'
|
||||
|
||||
isDefined = _.negate(_.isUndefined)
|
||||
|
||||
parseDeviceFields = (device) ->
|
||||
@ -110,7 +112,7 @@ createProxyvisorRouter = (proxyvisor) ->
|
||||
.then ->
|
||||
res.status(201).send(dev)
|
||||
.catch (err) ->
|
||||
console.error("Error on #{req.method} #{url.parse(req.url).pathname}", err, err.stack)
|
||||
log.error("Error on #{req.method} #{url.parse(req.url).pathname}", err)
|
||||
res.status(503).send(err?.message or err or 'Unknown error')
|
||||
|
||||
router.get '/v1/devices/:uuid', (req, res) ->
|
||||
@ -121,7 +123,7 @@ createProxyvisorRouter = (proxyvisor) ->
|
||||
return res.status(410).send('Device deleted') if device.markedForDeletion
|
||||
res.json(parseDeviceFields(device))
|
||||
.catch (err) ->
|
||||
console.error("Error on #{req.method} #{url.parse(req.url).pathname}", err, err.stack)
|
||||
log.error("Error on #{req.method} #{url.parse(req.url).pathname}", err)
|
||||
res.status(503).send(err?.message or err or 'Unknown error')
|
||||
|
||||
router.post '/v1/devices/:uuid/logs', (req, res) ->
|
||||
@ -139,7 +141,7 @@ createProxyvisorRouter = (proxyvisor) ->
|
||||
proxyvisor.logger.logDependent(m, uuid)
|
||||
res.status(202).send('OK')
|
||||
.catch (err) ->
|
||||
console.error("Error on #{req.method} #{url.parse(req.url).pathname}", err, err.stack)
|
||||
log.error("Error on #{req.method} #{url.parse(req.url).pathname}", err)
|
||||
res.status(503).send(err?.message or err or 'Unknown error')
|
||||
|
||||
router.put '/v1/devices/:uuid', (req, res) ->
|
||||
@ -192,7 +194,7 @@ createProxyvisorRouter = (proxyvisor) ->
|
||||
.then ([ device ]) ->
|
||||
res.json(parseDeviceFields(device))
|
||||
.catch (err) ->
|
||||
console.error("Error on #{req.method} #{url.parse(req.url).pathname}", err, err.stack)
|
||||
log.error("Error on #{req.method} #{url.parse(req.url).pathname}", err)
|
||||
res.status(503).send(err?.message or err or 'Unknown error')
|
||||
|
||||
router.get '/v1/dependent-apps/:appId/assets/:commit', (req, res) ->
|
||||
@ -207,7 +209,7 @@ createProxyvisorRouter = (proxyvisor) ->
|
||||
.then ->
|
||||
res.sendFile(dest)
|
||||
.catch (err) ->
|
||||
console.error("Error on #{req.method} #{url.parse(req.url).pathname}", err, err.stack)
|
||||
log.error("Error on #{req.method} #{url.parse(req.url).pathname}", err)
|
||||
res.status(503).send(err?.message or err or 'Unknown error')
|
||||
|
||||
router.get '/v1/dependent-apps', (req, res) ->
|
||||
@ -222,7 +224,7 @@ createProxyvisorRouter = (proxyvisor) ->
|
||||
.then (apps) ->
|
||||
res.json(apps)
|
||||
.catch (err) ->
|
||||
console.error("Error on #{req.method} #{url.parse(req.url).pathname}", err, err.stack)
|
||||
log.error("Error on #{req.method} #{url.parse(req.url).pathname}", err)
|
||||
res.status(503).send(err?.message or err or 'Unknown error')
|
||||
|
||||
return router
|
||||
@ -605,7 +607,7 @@ module.exports = class Proxyvisor
|
||||
@acknowledgedState[device.uuid] = null
|
||||
throw new Error("Hook returned #{response.statusCode}: #{body}") if response.statusCode != 202
|
||||
.catch (err) ->
|
||||
return console.error("Error updating device #{device.uuid}", err, err.stack)
|
||||
return log.error("Error updating device #{device.uuid}", err)
|
||||
|
||||
sendDeleteHook: ({ uuid }, timeout, endpoint) =>
|
||||
request.delAsync("#{endpoint}#{uuid}")
|
||||
@ -616,7 +618,7 @@ module.exports = class Proxyvisor
|
||||
else
|
||||
throw new Error("Hook returned #{response.statusCode}: #{body}")
|
||||
.catch (err) ->
|
||||
return console.error("Error deleting device #{uuid}", err, err.stack)
|
||||
return log.error("Error deleting device #{uuid}", err)
|
||||
|
||||
sendUpdates: ({ uuid }) =>
|
||||
Promise.join(
|
||||
@ -624,7 +626,7 @@ module.exports = class Proxyvisor
|
||||
@config.get('apiTimeout')
|
||||
([ dev ], apiTimeout) =>
|
||||
if !dev?
|
||||
console.log("Warning, trying to send update to non-existent device #{uuid}")
|
||||
log.warn("Trying to send update to non-existent device #{uuid}")
|
||||
return
|
||||
@normaliseDependentDeviceFromDB(dev)
|
||||
.then (device) =>
|
||||
|
@ -9,6 +9,8 @@ import blink = require('./lib/blink');
|
||||
import * as iptables from './lib/iptables';
|
||||
import { checkTruthy } from './lib/validation';
|
||||
|
||||
import log from './lib/supervisor-console';
|
||||
|
||||
function getKeyFromReq(req: express.Request): string | null {
|
||||
const queryKey = req.query.apikey;
|
||||
if (queryKey != null) {
|
||||
@ -54,9 +56,9 @@ function authenticate(config: Config): express.RequestHandler {
|
||||
};
|
||||
}
|
||||
|
||||
const expressLogger = morgan((tokens, req, res) =>
|
||||
const expressLogger = morgan(
|
||||
(tokens, req, res) =>
|
||||
[
|
||||
'Supervisor API:',
|
||||
tokens.method(req, res),
|
||||
req.path,
|
||||
tokens.status(req, res),
|
||||
@ -64,6 +66,9 @@ const expressLogger = morgan((tokens, req, res) =>
|
||||
tokens['response-time'](req, res),
|
||||
'ms',
|
||||
].join(' '),
|
||||
{
|
||||
stream: { write: d => log.api(d.toString().trimRight()) },
|
||||
},
|
||||
);
|
||||
|
||||
interface SupervisorAPIConstructOpts {
|
||||
@ -169,16 +174,16 @@ export class SupervisorAPI {
|
||||
try {
|
||||
if (checkTruthy(allInterfaces)) {
|
||||
await iptables.removeRejections(port);
|
||||
console.log('Supervisor API listening on all interfaces');
|
||||
log.debug('Supervisor API listening on all interfaces');
|
||||
} else {
|
||||
await iptables.rejectOnAllInterfacesExcept(allowedInterfaces, port);
|
||||
console.log('Supervisor API listening on allowed interfaces only');
|
||||
log.debug('Supervisor API listening on allowed interfaces only');
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(
|
||||
'Error on switching supervisor API listening rules - stopping API.',
|
||||
log.error(
|
||||
'Error on switching supervisor API listening rules - stopping API.\n',
|
||||
err,
|
||||
);
|
||||
console.log(' ', err);
|
||||
this.stop();
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,9 @@ DeviceState = require './device-state'
|
||||
{ SupervisorAPI } = require './supervisor-api'
|
||||
{ Logger } = require './logger'
|
||||
|
||||
version = require './lib/supervisor-version'
|
||||
{ log } = require './lib/supervisor-console'
|
||||
|
||||
constants = require './lib/constants'
|
||||
|
||||
startupConfigFields = [
|
||||
@ -56,6 +59,9 @@ module.exports = class Supervisor extends EventEmitter
|
||||
})
|
||||
|
||||
init: =>
|
||||
|
||||
log.info("Supervisor v#{version} starting up...")
|
||||
|
||||
@db.init()
|
||||
.tap =>
|
||||
@config.init() # Ensures uuid, deviceApiKey, apiSecret
|
||||
@ -65,13 +71,13 @@ module.exports = class Supervisor extends EventEmitter
|
||||
# We can't print to the dashboard until the logger has started up,
|
||||
# so we leave a trail of breadcrumbs in the logs in case runtime
|
||||
# fails to get to the first dashboard logs
|
||||
console.log('Starting event tracker')
|
||||
log.debug('Starting event tracker')
|
||||
@eventTracker.init(_.assign({}, conf, { @config }))
|
||||
.then =>
|
||||
console.log('Starting up api binder')
|
||||
log.debug('Starting up api binder')
|
||||
@apiBinder.initClient()
|
||||
.then =>
|
||||
console.log('Starting logging infrastructure')
|
||||
log.debug('Starting logging infrastructure')
|
||||
@logger.init({
|
||||
apiEndpoint: conf.apiEndpoint,
|
||||
uuid: conf.uuid,
|
||||
@ -84,13 +90,13 @@ module.exports = class Supervisor extends EventEmitter
|
||||
@logger.logSystemMessage('Supervisor starting', {}, 'Supervisor start')
|
||||
.then =>
|
||||
if conf.legacyAppsPresent
|
||||
console.log('Legacy app detected, running migration')
|
||||
log.info('Legacy app detected, running migration')
|
||||
@deviceState.normaliseLegacy(@apiBinder.balenaApi)
|
||||
.then =>
|
||||
@deviceState.init()
|
||||
.then =>
|
||||
# initialize API
|
||||
console.log('Starting API server')
|
||||
log.info('Starting API server')
|
||||
@api.listen(constants.allowedInterfaces, conf.listenPort, conf.apiTimeout)
|
||||
@deviceState.on('shutdown', => @api.stop())
|
||||
.then =>
|
||||
|
@ -20,6 +20,20 @@ const dockerode = require('dockerode');
|
||||
const chokidar = require('chokidar');
|
||||
const _ = require('lodash');
|
||||
|
||||
require('ts-node/register');
|
||||
const { ContainerLogs } = require('./src/logging/container');
|
||||
|
||||
const setupLogs = (containerId, docker) => {
|
||||
console.log('Setting up logs');
|
||||
const logs = new ContainerLogs(containerId, docker);
|
||||
logs.on('log', ({ message }) => {
|
||||
if (message.trim().length !== 0) {
|
||||
console.log(message);
|
||||
}
|
||||
});
|
||||
logs.attach(Date.now());
|
||||
};
|
||||
|
||||
const docker = new dockerode({
|
||||
host: ip,
|
||||
port: 2375,
|
||||
@ -53,10 +67,11 @@ function extractMessage(msgBuf) {
|
||||
let changedFiles = [];
|
||||
let deletedFiles = [];
|
||||
|
||||
const performLivepush = _.debounce(async livepush => {
|
||||
const performLivepush = _.debounce(async (livepush, containerId, docker) => {
|
||||
await livepush.performLivepush(changedFiles, deletedFiles);
|
||||
changedFiles = [];
|
||||
deletedFiles = [];
|
||||
setupLogs(containerId, docker);
|
||||
}, 1000);
|
||||
|
||||
(async () => {
|
||||
@ -85,15 +100,15 @@ const performLivepush = _.debounce(async livepush => {
|
||||
})
|
||||
.on('add', path => {
|
||||
changedFiles.push(path);
|
||||
performLivepush(livepush);
|
||||
performLivepush(livepush, containerId, docker);
|
||||
})
|
||||
.on('change', path => {
|
||||
changedFiles.push(path);
|
||||
performLivepush(livepush);
|
||||
performLivepush(livepush, containerId, docker);
|
||||
})
|
||||
.on('unlink', path => {
|
||||
deletedFiles.push(path);
|
||||
performLivepush(livepush);
|
||||
performLivepush(livepush, containerId, docker);
|
||||
});
|
||||
|
||||
livepush.on('commandExecute', ({ command }) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user