Weitere ähnliche Inhalte Ähnlich wie A Self Replicating Serverless Function (20) Kürzlich hochgeladen (20) A Self Replicating Serverless Function3. A quine is a non-empty computer
program which takes no input and
produces a copy of its own source
code as its only output
12. Write once without quotes and once
with quotes
“Write once without quotes and once
with quotes”
😀
13. Write the stanza without quotes.
Write the stanza with quotes.
“Write the stanza without quotes.
Write the stanza with quotes.”
😀
14. Write the stanza without quotes.
Write the stanza with quotes.
The stanza is: “
Write the stanza without quotes.
Write the stanza with quotes.”
☹
15. The stanza is: “
Write the stanza with quotes.
Write the stanza without quotes.”
Write the stanza with quotes.
Write the stanza without quotes.
🙁
16. The stanza is: “
Write ‘The stanza is: ’
Write the stanza with quotes.
Write the stanza without quotes.”
Write ‘The stanza is: ’
Write the stanza with quotes.
Write the stanza without quotes.
😃
17. const stanza = `
const backtick = String.fromCharCode(96);
const quine = ‘const stanza = ’
+ backtick + stanza + backtick + ‘;’
+ stanza;
console.log(quine);`;
const backtick = String.fromCharCode(96);
const quine = ‘const stanza = ’
+ backtick + stanza + backtick + ‘;’
+ stanza;
console.log(quine); 😃
18. stanza = “““
marker = chr(34) * 3
quine = ‘stanza = ’
+ marker + stanza + marker
+ stanza
print(quine)”””
marker = chr(34) * 3
quine = ‘stanza = ’
+ marker + stanza + marker
+ stanza
print(quine) 😃
19. $ node quine.js | diff quine.js -
$ echo $?
0
$ node quine.py | diff quine.py -
$ echo $?
0
&
20. const stanza = `
exports.handler = (event, context, cb) => {
const backtick = String.fromCharCode(96);
const quine = ‘const stanza = ’
+ backtick + stanza + backtick + ‘;’
+ stanza;
const response = {
statusCode: 200,
body: quine,
};
cb(null, response);
};`;
... 😃
21. stanza = “““
def lambda_handler(event, context):
marker = chr(34) * 3
quine = ‘stanza = ’
+ marker + stanza + marker
+ stanza
return {‘statusCode’: ‘200’,
‘body’: quine}
”””
... 😃
22. $ curl -s “https://hn8pe4gd37.execute-api.eu-central-1.amazonaws.com/
dev/lambda_quine_js” | diff lambda_quine.js -
$ echo $?
0
$ curl -s “https://hn8pe4gd37.execute-api.eu-central-1.amazonaws.com/
dev/lambda_quine_py” | diff lambda_quine.py -
$ echo $?
0
&
23. exports.handler = (event, context, cb) => {
const backtick = String.fromCharCode(96);
const quine = ‘const stanza = ’
+ backtick + stanza + backtick + ‘;’
+ stanza;
hook(event, quine, () => {
const response = {
statusCode: 200,
body: quine,
};
cb(null, response);
};
};
25. How to generate the zipped file?
• Embed the file binary representation
• Embed zip source code
• Use a serverless zip function
26. const admZip = require(‘adm-zip’);
exports.handler = (event, context, callback) => {
// creating archives
const zip = new admZip();
// add files directly
Object.keys(event).forEach((key) => {
zip.addFile(key,
new Buffer(event[key]),
‘Just another file’,
0o777 << 16);
});
// return the zip as a buffer
callback(null, zip.toBuffer());
};
27. function hook(event, quine, cb) {
const Role = process.env.Role;
if (event.queryStringParameters) {
const FunctionName = event.queryStringParameters.FunctionName;
lambda.invoke({
FunctionName: 'zipper',
Payload: JSON.stringify({ 'index.js': quine }),
}, (error, data) => {
const ZipFile = new Buffer(JSON.parse(data.Payload));
const params = {
Code: { ZipFile },
FunctionName,
Handler: 'index.handler',
Role,
Runtime: 'nodejs6.10',
Description: ‘Generated by a quine’,
Environment: { Variables: { Role } },
};
lambda.createFunction(params, cb);
} else {
cb();
}
}
😃
28. $ curl -s “https://draei6bs56.execute-api.eu-central-1.amazonaws.com/
quine/replicator?FunctionName=replicated" | diff replicator.js -
$ echo $?
0
$ aws lambda invoke --function-name replicated aws_results
$ cat aws_results | jq -j .body | diff replicator.js -
$ echo $?
0
&
30. const javaScriptStanza = `
const quote = String.fromCharCode(34);
const newline = String.fromCharCode(10);
const marker = quote + quote + quote;
const ouroboros = ‘javaScriptStanza = ’
+ marker + javaScriptStanza + marker + newline
+ ‘pythonStanza = ’
+ marker + pythonStanza + marker
+ pythonStanza;
console.log(ouroboros);`;
const pythonStanza = `
backtick = chr(96)
newline = chr(10)
ouroboros = ‘const javaScriptStanza = ’
+ backtick + javaScriptStanza + backtick + ‘;’ + newline
+ ‘const pythonStanza = ’
+ backtick + pythonStanza + backtick + ‘;’
+ javaScriptStanza
print(ouroboros)`;
😃
31. javaScriptStanza = “““
const quote = String.fromCharCode(34);
const newline = String.fromCharCode(10);
const marker = quote + quote + quote;
const ouroboros = ‘javaScriptStanza = ’
+ marker + javaScriptStanza + marker + newline
+ ‘pythonStanza = ’
+ marker + pythonStanza + marker
+ pythonStanza;
console.log(ouroboros);”””
pythonStanza = “““
backtick = chr(96)
newline = chr(10)
ouroboros = ‘const javaScriptStanza = ’
+ backtick + javaScriptStanza + backtick + ‘;’ + newline
+ ‘const pythonStanza = ’
+ backtick + pythonStanza + backtick + ‘;’
+ javaScriptStanza
print(ouroboros)”””
😃😃
32. For those interested in replicating this code:
https://github.com/gobinaris/serverlessconf-austin-2017
@michael_adda