summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorXiang Gao2017-12-26 22:12:45 -0500
committerXiang Gao2017-12-27 01:21:24 -0500
commit9626dfc0aea269c4f1c2891ba40d177485209078 (patch)
tree9fe1e67eb97ee3b312dfcfd99878480b7c8df206
parente9cf253911664b2937af7b235cc762f628a19fd5 (diff)
downloadaur-9626dfc0aea269c4f1c2891ba40d177485209078.tar.gz
use golang to get cache-id
-rw-r--r--.SRCINFO14
-rw-r--r--PKGBUILD21
-rw-r--r--etc_docker-btrfs.json4
-rw-r--r--etc_docker-btrfs.sh2
-rw-r--r--get-docker-cache-id.go149
-rwxr-xr-xhooks_docker-btrfs7
-rwxr-xr-xinstall_docker-btrfs4
7 files changed, 178 insertions, 23 deletions
diff --git a/.SRCINFO b/.SRCINFO
index cdc75a36056b..f4a9e8eff2f0 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,6 +1,6 @@
pkgbase = mkinitcpio-docker-hooks
pkgdesc = mkinitcpio hooks that provides support for using docker image as root
- pkgver = 1.0
+ pkgver = 1.1
pkgrel = 1
url = https://github.com/zasdfgbnm/mkinitcpio-docker-hooks
arch = any
@@ -8,13 +8,15 @@ pkgbase = mkinitcpio-docker-hooks
license = GPL
depends = mkinitcpio
depends = jq
- backup = etc/docker-btrfs.sh
+ backup = etc/docker-btrfs.json
source = install_docker-btrfs
source = hooks_docker-btrfs
- source = etc_docker-btrfs.sh
- md5sums = 0da33ef9ff132737a09173fdd45cddd6
- md5sums = e1d51dd467412b48361c648226e6b57e
- md5sums = a1243d4a874f69ef696f5c6ac58424cb
+ source = etc_docker-btrfs.json
+ source = get-docker-cache-id.go
+ md5sums = 5ce9a3498b0af7e9fbbe830893da83e3
+ md5sums = b44c59a25ef2ff74e60d20aaabe683fd
+ md5sums = 4df2fd7306aef1e3d94ffc6b05056728
+ md5sums = bcae1950b172498e34c1aa4cb55ecad0
pkgname = mkinitcpio-docker-hooks
diff --git a/PKGBUILD b/PKGBUILD
index c400a964914a..adbd2ed89295 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -1,6 +1,7 @@
# Maintainer: Xiang Gao <qasdfgtyuiop at gmail dot com>
+
pkgname=mkinitcpio-docker-hooks
-pkgver=1.0
+pkgver=1.1
pkgrel=1
pkgdesc="mkinitcpio hooks that provides support for using docker image as root"
arch=(any)
@@ -8,14 +9,20 @@ url="https://github.com/zasdfgbnm/mkinitcpio-docker-hooks"
license=('GPL')
groups=('base')
depends=('mkinitcpio' 'jq')
-backup=(etc/docker-btrfs.sh)
-source=('install_docker-btrfs' 'hooks_docker-btrfs' 'etc_docker-btrfs.sh')
-md5sums=('0da33ef9ff132737a09173fdd45cddd6'
- 'e1d51dd467412b48361c648226e6b57e'
- 'a1243d4a874f69ef696f5c6ac58424cb')
+backup=(etc/docker-btrfs.json)
+source=('install_docker-btrfs' 'hooks_docker-btrfs' 'etc_docker-btrfs.json' 'get-docker-cache-id.go')
+md5sums=('5ce9a3498b0af7e9fbbe830893da83e3'
+ 'b44c59a25ef2ff74e60d20aaabe683fd'
+ '4df2fd7306aef1e3d94ffc6b05056728'
+ 'bcae1950b172498e34c1aa4cb55ecad0')
+
+build() {
+ go build get-docker-cache-id.go
+}
package() {
+ install -Dm755 get-docker-cache-id "${pkgdir}/usr/bin/get-docker-cache-id"
install -Dm644 install_docker-btrfs "${pkgdir}/usr/lib/initcpio/install/docker-btrfs"
install -Dm644 hooks_docker-btrfs "${pkgdir}/usr/lib/initcpio/hooks/docker-btrfs"
- install -Dm644 etc_docker-btrfs.sh "${pkgdir}/etc/docker-btrfs.sh"
+ install -Dm644 etc_docker-btrfs.json "${pkgdir}/etc/docker-btrfs.json"
}
diff --git a/etc_docker-btrfs.json b/etc_docker-btrfs.json
new file mode 100644
index 000000000000..7c5f8a2f6750
--- /dev/null
+++ b/etc_docker-btrfs.json
@@ -0,0 +1,4 @@
+{
+ "docker_image": "archlinux/base",
+ "docker_tag": "latest"
+}
diff --git a/etc_docker-btrfs.sh b/etc_docker-btrfs.sh
deleted file mode 100644
index 1843e6c864aa..000000000000
--- a/etc_docker-btrfs.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-docker_image=archlinux/base
-docker_tag=latest
diff --git a/get-docker-cache-id.go b/get-docker-cache-id.go
new file mode 100644
index 000000000000..cbaf367cda6a
--- /dev/null
+++ b/get-docker-cache-id.go
@@ -0,0 +1,149 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "os"
+ "strings"
+ "io/ioutil"
+)
+
+const DOCKER_DB_DIR = "/var/lib/docker/image/btrfs"
+const REPO_FILE = DOCKER_DB_DIR + "/repositories.json"
+const CFG_FILE = "/etc/docker-btrfs.json"
+
+func getImageTag() (string, string) {
+ buf, err := ioutil.ReadFile(CFG_FILE)
+ if err != nil {
+ panic(err)
+ }
+ var dat map[string]interface{}
+ err = json.Unmarshal(buf, &dat)
+ if err != nil {
+ panic(err)
+ }
+ return dat["docker_image"].(string), dat["docker_tag"].(string)
+}
+
+func getImageId(image string, tag string) string {
+ buf, err := ioutil.ReadFile(REPO_FILE)
+ if err != nil {
+ panic(err)
+ }
+ var dat map[string]interface{}
+ err = json.Unmarshal(buf, &dat)
+ if err != nil {
+ panic(err)
+ }
+ repositories := dat["Repositories"].(map[string]interface{})
+ imageTags := repositories[image].(map[string]interface{})
+ return imageTags[image+":"+tag].(string)
+}
+
+func getDiffIds(imgId string) []string {
+ imgPath := strings.Replace(imgId, ":", "/", 1)
+ buf, err := ioutil.ReadFile(DOCKER_DB_DIR + "/imagedb/content/" + imgPath)
+ if err != nil {
+ panic(err)
+ }
+ var dat map[string]interface{}
+ err = json.Unmarshal(buf, &dat)
+ if err != nil {
+ panic(err)
+ }
+ rootfs := dat["rootfs"].(map[string]interface{})
+ diffIdsInterface := rootfs["diff_ids"].([]interface{})
+ diffIdsStr := make([]string, len(diffIdsInterface))
+ for i, v := range diffIdsInterface {
+ diffIdsStr[i] = strings.Replace(v.(string), "sha256:", "", 1)
+ }
+ return diffIdsStr
+}
+
+type Node struct {
+ parent string
+ id string
+ diff string
+ cache string
+}
+
+func getNode(id string) Node {
+ var node Node
+
+ node.id = id
+
+ buf, err := ioutil.ReadFile(DOCKER_DB_DIR + "/layerdb/sha256/" + id + "/cache-id")
+ if err != nil {
+ panic(err)
+ }
+ node.cache = strings.Replace(string(buf), "sha256:", "", 1)
+
+ buf, err = ioutil.ReadFile(DOCKER_DB_DIR + "/layerdb/sha256/" + id + "/diff")
+ if err != nil {
+ panic(err)
+ }
+ node.diff = strings.Replace(string(buf), "sha256:", "", 1)
+
+ buf, err = ioutil.ReadFile(DOCKER_DB_DIR + "/layerdb/sha256/" + id + "/parent")
+ if os.IsNotExist(err) {
+ node.parent = ""
+ } else if err != nil {
+ panic(err)
+ } else {
+ node.parent = strings.Replace(string(buf), "sha256:", "", 1)
+ }
+ return node
+}
+
+func readLayerInfo() map[string]Node {
+ files, err := ioutil.ReadDir(DOCKER_DB_DIR + "/layerdb/sha256/")
+ if err != nil {
+ panic(err)
+ }
+ nodes := make(map[string]Node)
+ for i, _ := range files {
+ id := files[i].Name()
+ nodes[id] = getNode(id)
+ }
+ return nodes
+}
+
+func searchForCacheId(diffIds []string, layers map[string]Node) string {
+ candidates := make([]string, 0, len(layers))
+ last := diffIds[len(diffIds)-1]
+ for i, v := range layers {
+ if v.diff == last {
+ sz := len(candidates)
+ candidates = candidates[:sz+1]
+ candidates[sz] = i
+ }
+ }
+ candidatesCurrent := make([]string, len(candidates))
+ for i, v := range candidates {
+ candidatesCurrent[i] = layers[v].parent
+ }
+ for i := len(diffIds)-2; i>=0; i-- {
+ for j := 0; j < len(candidates); {
+ if layers[candidatesCurrent[j]].diff == diffIds[i] {
+ candidatesCurrent[j] = layers[candidatesCurrent[j]].parent
+ j++;
+ } else {
+ oldLen := len(candidates)
+ candidates[j] = candidates[oldLen-1]
+ candidatesCurrent[j] = candidatesCurrent[oldLen-1]
+ candidates = candidates[:oldLen-1]
+ candidatesCurrent = candidatesCurrent[:oldLen - 1]
+ }
+ }
+ }
+ return candidates[0]
+}
+
+func main() {
+ image, tag := getImageTag()
+ imgId := getImageId(image, tag)
+ diffIds := getDiffIds(imgId)
+ layers := readLayerInfo()
+ cacheId := searchForCacheId(diffIds, layers)
+ fmt.Print(cacheId)
+}
diff --git a/hooks_docker-btrfs b/hooks_docker-btrfs
index 31efedf9ebc9..3f764e95d7d8 100755
--- a/hooks_docker-btrfs
+++ b/hooks_docker-btrfs
@@ -1,7 +1,6 @@
#!/usr/bin/bash
run_hook() {
- . /etc/docker-btrfs.sh
docker_rwlayer=$(echo $rootflags | grep -o "subvol=[^,]*" | grep -o "[^=]*\$")
mkdir -p /docker_root
@@ -25,11 +24,7 @@ run_hook() {
fi
msg ":: getting docker cache subvolume"
- cd /var/lib/docker/image/btrfs
- image_id=$(jq ".Repositories.\"$docker_image\".\"$docker_image:$docker_tag\"" repositories.json | sed 's/:/\//g;s/"//g')
- last_layer_id=$(jq '.rootfs.diff_ids[]' imagedb/content/$image_id | sed 's/"//g' | tail -n 1)
- cache_id_file=$(grep $last_layer_id -rl layerdb | sed 's/diff/cache-id/g')
- cache_id=$(cat $cache_id_file)
+ cache_id=$(get-docker-cache-id)
msg ":: creating rwlayer"
[ -d /docker_root/"$docker_rwlayer" ] && btrfs subvolume delete /docker_root/"$docker_rwlayer"
diff --git a/install_docker-btrfs b/install_docker-btrfs
index 272329d55451..a0550a22b164 100755
--- a/install_docker-btrfs
+++ b/install_docker-btrfs
@@ -4,8 +4,8 @@ build() {
add_module btrfs
add_binary btrfs
add_binary btrfsck
- add_binary jq
- add_file /etc/docker-btrfs.sh
+ add_binary get-docker-cache-id
+ add_file /etc/docker-btrfs.json
add_runscript
}