-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cache images slightly differently #165
Merged
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
ff3ebe8
Move files to impl
MarcoPolo dfe74be
Add gitignore to impl/js
MarcoPolo 61361c7
Add VSCode formatter settings
MarcoPolo 2798235
Add cache helper
MarcoPolo 0c9106b
Have CI use and push the image cache
MarcoPolo e6c6ad8
Cleanup
MarcoPolo 75679b5
Fix imports
MarcoPolo b50e472
Don't push if already cached
MarcoPolo 0324877
Base browser images from same base as node
MarcoPolo 21ca43f
Try skipping some make work
MarcoPolo ba2980b
Always tag the node image so you can use it in a build arg
MarcoPolo cfb42f3
Trigger CI
MarcoPolo 8770b7d
Cleanup cache.ts
MarcoPolo 3863584
Remove vscode settings for now
MarcoPolo edf1938
Add to gitignore
MarcoPolo 91fc5fd
Fix path import
MarcoPolo 5bcf7e4
Add section about caching to README
MarcoPolo cfcc8e9
Use createFilter
MarcoPolo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,4 +42,7 @@ __pycache__/ | |
|
||
### NodeJS | ||
|
||
node_modules | ||
node_modules | ||
|
||
# ignore system files | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
const AWS_BUCKET = process.env.AWS_BUCKET || 'libp2p-by-tf-aws-bootstrap'; | ||
const scriptDir = __dirname; | ||
|
||
import * as crypto from 'crypto'; | ||
import * as fs from 'fs'; | ||
import * as path from 'path'; | ||
import * as child_process from 'child_process'; | ||
import ignore, { Ignore } from 'ignore' | ||
|
||
const multidimInteropDir = path.join(scriptDir, '..') | ||
const arch = child_process.execSync('docker info -f "{{.Architecture}}"').toString().trim(); | ||
|
||
enum Mode { | ||
LoadCache = 1, | ||
PushCache, | ||
} | ||
const modeStr = process.argv[2]; | ||
let mode: Mode | ||
switch (modeStr) { | ||
case "push": | ||
mode = Mode.PushCache | ||
break | ||
case "load": | ||
mode = Mode.LoadCache | ||
break | ||
default: | ||
throw new Error(`Unknown mode: ${modeStr}`) | ||
} | ||
|
||
(async () => { | ||
for (const implFamily of fs.readdirSync(path.join(multidimInteropDir, 'impl'))) { | ||
const ig = ignore() | ||
|
||
addGitignoreIfPresent(ig, path.join(multidimInteropDir, ".gitignore")) | ||
addGitignoreIfPresent(ig, path.join(multidimInteropDir, "..", ".gitignore")) | ||
|
||
const implFamilyDir = path.join(multidimInteropDir, 'impl', implFamily) | ||
addGitignoreIfPresent(ig, path.join(implFamilyDir, ".gitignore")) | ||
|
||
for (const impl of fs.readdirSync(implFamilyDir)) { | ||
const implFolder = fs.realpathSync(path.join(implFamilyDir, impl)); | ||
if (!fs.statSync(implFolder).isDirectory()) { | ||
continue | ||
} | ||
|
||
addGitignoreIfPresent(ig, path.join(implFolder, ".gitignore")) | ||
|
||
// Get all the files in the implFolder: | ||
let files = walkDir(implFolder) | ||
// Turn them into relative paths: | ||
files = files.map(f => f.replace(implFolder + "/", "")) | ||
// Ignore files that are in the .gitignore: | ||
files = files.filter(ig.createFilter()) | ||
// Sort them to be deterministic | ||
files = files.sort() | ||
|
||
console.log(implFolder) | ||
console.log("Files:", files) | ||
|
||
// Turn them back into absolute paths: | ||
files = files.map(f => path.join(implFolder, f)) | ||
const cacheKey = await hashFiles(files) | ||
console.log("Cache key:", cacheKey) | ||
|
||
if (mode == Mode.PushCache) { | ||
console.log("Pushing cache") | ||
try { | ||
const res = await fetch(`https://s3.amazonaws.com/${AWS_BUCKET}/imageCache/${cacheKey}-${arch}.tar.gz`, { method: "HEAD" }) | ||
if (res.ok) { | ||
console.log("Cache already exists") | ||
} else { | ||
// Read image id from image.json | ||
const imageID = JSON.parse(fs.readFileSync(path.join(implFolder, 'image.json')).toString()).imageID; | ||
console.log(`Pushing cache for ${impl}: ${imageID}`) | ||
child_process.execSync(`docker image save ${imageID} | gzip | aws s3 cp - s3://${AWS_BUCKET}/imageCache/${cacheKey}-${arch}.tar.gz`); | ||
} | ||
} catch (e) { | ||
console.log("Failed to push image cache:", e) | ||
} | ||
} else if (mode == Mode.LoadCache) { | ||
if (fs.existsSync(path.join(implFolder, 'image.json'))) { | ||
console.log("Already built") | ||
continue | ||
} | ||
console.log("Loading cache") | ||
let cacheHit = false | ||
try { | ||
// Check if the cache exists | ||
const res = await fetch(`https://s3.amazonaws.com/${AWS_BUCKET}/imageCache/${cacheKey}-${arch}.tar.gz`, { method: "HEAD" }) | ||
if (res.ok) { | ||
const dockerLoadedMsg = child_process.execSync(`curl https://s3.amazonaws.com/${AWS_BUCKET}/imageCache/${cacheKey}-${arch}.tar.gz | docker image load`).toString(); | ||
const loadedImageId = dockerLoadedMsg.match(/Loaded image( ID)?: (.*)/)[2]; | ||
if (loadedImageId) { | ||
console.log(`Cache hit for ${loadedImageId}`); | ||
fs.writeFileSync(path.join(implFolder, 'image.json'), JSON.stringify({ imageID: loadedImageId }) + "\n"); | ||
cacheHit = true | ||
} | ||
} else { | ||
console.log("Cache not found") | ||
} | ||
} catch (e) { | ||
console.log("Cache not found:", e) | ||
} | ||
|
||
if (cacheHit) { | ||
console.log("Building any remaining things from image.json") | ||
// We're building using -o image.json. This tells make to | ||
// not bother building image.json or anything it depends on. | ||
child_process.execSync(`make -o image.json`, { cwd: implFolder }) | ||
} else { | ||
console.log("No cache, building from scratch") | ||
child_process.execSync(`make`, { cwd: implFolder }) | ||
} | ||
} | ||
} | ||
} | ||
})() | ||
|
||
function walkDir(dir: string) { | ||
let results = []; | ||
fs.readdirSync(dir).forEach(f => { | ||
let dirPath = path.join(dir, f); | ||
let isDirectory = fs.statSync(dirPath).isDirectory(); | ||
results = isDirectory ? results.concat(walkDir(dirPath)) : results.concat(path.join(dir, f)); | ||
}); | ||
return results; | ||
}; | ||
|
||
async function hashFiles(files: string[]): Promise<string> { | ||
const fileHashes = await Promise.all( | ||
files.map(async (file) => { | ||
const data = await fs.promises.readFile(file); | ||
return crypto.createHash('sha256').update(data).digest('hex'); | ||
}) | ||
); | ||
return crypto.createHash('sha256').update(fileHashes.join('')).digest('hex'); | ||
} | ||
|
||
function addGitignoreIfPresent(ig: Ignore, pathStr: string): boolean { | ||
try { | ||
if (fs.statSync(pathStr).isFile()) { | ||
ig.add(fs.readFileSync(pathStr).toString()) | ||
} | ||
return true | ||
} catch { | ||
return false | ||
} | ||
} |
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions
4
multidim-interop/go/v0.22/Makefile → multidim-interop/impl/go/v0.22/Makefile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
image_name := go-v0.22 | ||
|
||
image.json: Dockerfile main.go go.mod go.sum | ||
IMAGE_NAME=${image_name} ../../dockerBuildWrapper.sh . | ||
IMAGE_NAME=${image_name} ../../../dockerBuildWrapper.sh . | ||
docker image inspect ${image_name} -f "{{.Id}}" | \ | ||
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@ | ||
|
||
.PHONY: clean | ||
|
||
clean: | ||
rm image.json | ||
rm image.json |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions
4
multidim-interop/go/v0.23/Makefile → multidim-interop/impl/go/v0.23/Makefile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
image_name := go-v0.23 | ||
|
||
image.json: Dockerfile main.go go.mod go.sum | ||
IMAGE_NAME=${image_name} ../../dockerBuildWrapper.sh . | ||
IMAGE_NAME=${image_name} ../../../dockerBuildWrapper.sh . | ||
docker image inspect ${image_name} -f "{{.Id}}" | \ | ||
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@ | ||
|
||
.PHONY: clean | ||
|
||
clean: | ||
rm image.json | ||
rm image.json |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions
4
multidim-interop/go/v0.24/Makefile → multidim-interop/impl/go/v0.24/Makefile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
image_name := go-v0.24 | ||
|
||
image.json: Dockerfile main.go go.mod go.sum | ||
IMAGE_NAME=${image_name} ../../dockerBuildWrapper.sh . | ||
IMAGE_NAME=${image_name} ../../../dockerBuildWrapper.sh . | ||
docker image inspect ${image_name} -f "{{.Id}}" | \ | ||
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@ | ||
|
||
.PHONY: clean | ||
|
||
clean: | ||
rm image.json | ||
rm image.json |
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*image.json |
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# syntax=docker/dockerfile:1 | ||
|
||
ARG BASE_IMAGE | ||
FROM $BASE_IMAGE | ||
|
||
ENTRYPOINT [ "npm", "test", "--", "--build", "false", "--types", "false", "-t", "browser" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
image_name := js-v0.41 | ||
TEST_SOURCES := $(wildcard test/*.ts) | ||
|
||
all: chromium-image.json node-image.json | ||
|
||
chromium-image.json: node-image.json | ||
docker build -t chromium-${image_name} -f ChromiumDockerfile --build-arg="BASE_IMAGE=node-${image_name}" . | ||
docker image inspect chromium-${image_name} -f "{{.Id}}" | \ | ||
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@ | ||
|
||
node-image.json: image.json | ||
docker image tag $$(cat image.json | jq -r '.imageID') node-${image_name} | ||
cp image.json node-image.json | ||
|
||
image.json: Dockerfile $(TEST_SOURCES) package.json package-lock.json .aegir.js | ||
IMAGE_NAME=node-${image_name} ../../../dockerBuildWrapper.sh -f Dockerfile . | ||
docker image inspect node-${image_name} -f "{{.Id}}" | \ | ||
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@ | ||
|
||
.PHONY: clean | ||
|
||
clean: | ||
rm *image.json |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# syntax=docker/dockerfile:1 | ||
|
||
ARG BASE_IMAGE | ||
FROM $BASE_IMAGE | ||
|
||
ENTRYPOINT [ "npm", "test", "--", "--build", "false", "--types", "false", "-t", "browser" ] |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to extract
path.join(multidimInteropDir, ".gitignore")
and others constants as well?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's the same, but unless you feel strongly I'd rather just leave it.