Skip to content

Commit

Permalink
feat: detect invalid binaries and show warning (#1124)
Browse files Browse the repository at this point in the history
* feat: detect invalid binaries and show warning

* fix: do not print warning in CLI mode

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
danez and kodiakhq[bot] committed Jul 4, 2022
1 parent 02f248f commit 77c835e
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 16 deletions.
22 changes: 11 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -53,13 +53,13 @@
},
"dependencies": {
"@babel/parser": "7.16.8",
"@netlify/binary-info": "^1.0.0",
"@netlify/esbuild": "0.14.25",
"@vercel/nft": "^0.20.0",
"archiver": "^5.3.0",
"common-path-prefix": "^3.0.0",
"cp-file": "^9.0.0",
"del": "^6.0.0",
"elf-cam": "^0.1.1",
"end-of-stream": "^1.4.4",
"es-module-lexer": "^0.10.0",
"execa": "^5.0.0",
Expand Down
6 changes: 6 additions & 0 deletions src/bin.ts
Expand Up @@ -7,13 +7,19 @@ import { hideBin } from 'yargs/helpers'
import type { ArchiveFormat } from './archive.js'
import { zipFunctions } from './main.js'

declare global {
// eslint-disable-next-line no-var
var ZISI_CLI: boolean
}

// CLI entry point
const runCli = async function () {
// @ts-expect-error TODO: `destFolder` and `srcFolder` are not being passed
// back from `parseArgs()`.
const { destFolder, srcFolder, ...options } = parseArgs()

try {
global.ZISI_CLI = true
// @ts-expect-error TODO: `options` is not getting the right types.
const zipped = await zipFunctions(srcFolder, destFolder, options)

Expand Down
28 changes: 24 additions & 4 deletions src/runtimes/detect_runtime.ts
@@ -1,11 +1,25 @@
import type { Buffer } from 'buffer'

import { detect, Runtime } from 'elf-cam'
import { detect, Runtime, Arch, Platform, BinaryInfo } from '@netlify/binary-info'

import { cachedReadFile, FsCache } from '../utils/fs.js'

import type { RuntimeName } from './runtime.js'

const isValidFunctionBinary = (info: BinaryInfo) => info.arch === Arch.Amd64 && info.platform === Platform.Linux

const warnIncompatibleBinary = function (path: string, binaryInfo: BinaryInfo): undefined {
if (!global.ZISI_CLI) {
console.warn(`
Found incompatible prebuilt function binary in ${path}.
The binary needs to be built for Linux/Amd64, but it was built for ${Platform[binaryInfo.platform]}/${
Arch[binaryInfo.arch]
}`)
}

return undefined
}

// Try to guess the runtime by inspecting the binary file.
export const detectBinaryRuntime = async function ({
fsCache,
Expand All @@ -20,15 +34,21 @@ export const detectBinaryRuntime = async function ({
// We're using the Type Assertion because the `cachedReadFile` abstraction
// loses part of the return type information. We can safely say it's a
// Buffer in this case because we're not specifying an encoding.
const binaryType = detect(buffer as Buffer)
const binaryInfo = detect(buffer as Buffer)

if (!isValidFunctionBinary(binaryInfo)) {
return warnIncompatibleBinary(path, binaryInfo)
}

switch (binaryType) {
switch (binaryInfo.runtime) {
case Runtime.Go:
return 'go'
case Runtime.Rust:
return 'rs'
default:
return undefined
}
} catch {}
} catch {
// Possible errors are: non binary files, arch/platforms not supported by binary-info, path is directory
}
}
Binary file not shown.
11 changes: 11 additions & 0 deletions tests/main.js
Expand Up @@ -2708,3 +2708,14 @@ test('listFunctionsFiles includes in-source config declarations', async (t) => {
t.is(func.schedule, '@daily')
})
})

test('listFunctionsFiles does not include wrong arch functions and warns', async (t) => {
sinon.spy(console, 'warn')
const functions = await listFunctionsFiles(join(FIXTURES_DIR, 'wrong-prebuilt-architecture'))

t.is(functions.length, 0)
t.is(console.warn.called, true)
t.is(console.warn.calledWith(sinon.match(/Darwin\/Arm64/)), true)

console.warn.restore()
})

1 comment on commit 77c835e

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⏱ Benchmark results

largeDepsEsbuild: 6.3s

largeDepsNft: 30s

largeDepsZisi: 45.4s

Please sign in to comment.