1
0

Create & Init Porject...

This commit is contained in:
502647092 2018-10-29 18:36:37 +08:00
commit 0be3e70228
2 changed files with 214 additions and 0 deletions

32
.gitignore vendored Normal file
View File

@ -0,0 +1,32 @@
# ---> Go
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof
/vendor
debug
*.exe
docker-image-sync
*.log
*.tgz

182
main.go Normal file
View File

@ -0,0 +1,182 @@
package main
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"net/http"
"os/exec"
"strconv"
"strings"
)
var (
cache = map[string]string{}
target string
client = &http.Client{}
)
const (
docker = "docker"
)
func main() {
b := flag.String("b", ":8080", "Server Listen Port")
t := flag.String("t", "registry.cn-hangzhou.aliyuncs.com/miaowoo", "Target Repo")
u := flag.String("u", "", "Target Repo UserName")
p := flag.String("p", "", "Target Repo Password")
flag.Parse()
target = *t
if _, err := exec.LookPath(docker); err != nil {
fmt.Printf("Error Can't Find %s Client...", docker)
return
}
loginResult, err := exec.Command(docker, "login", *t, "-u", *u, "-p", *p).Output()
if err != nil {
fmt.Printf("Error Can't Login To %s Username %s Password %s ...\nError: %s", *t, *u, *p, err.Error())
return
}
fmt.Printf(string(loginResult))
startServer(*b)
}
func startServer(b string) {
http.HandleFunc("/", func(resp http.ResponseWriter, req *http.Request) {
if strings.HasPrefix(req.RequestURI, "/api") {
handleAPI(resp, req)
return
}
handleNormal(resp, req)
})
fmt.Println("Start Server Listen On: " + b)
http.ListenAndServe(b, nil)
}
func handleAPI(w http.ResponseWriter, r *http.Request) {
fmt.Println("[A] " + r.RequestURI)
}
func getToken(image string) string {
resp, _ := http.Get("https://dockerauth.cn-hangzhou.aliyuncs.com/auth?service=registry.aliyuncs.com:cn-hangzhou:26842&scope=repository:miaowoo/" + image + ":pull")
var result []byte
result, _ = ioutil.ReadAll(resp.Body)
var auth map[string]string
json.Unmarshal(result, &auth)
return auth["token"]
}
func checkMirror(image string) bool {
i := image
v := "latest"
if strings.Contains(image, ":") {
arr := strings.Split(image, ":")
i = arr[0]
v = arr[1]
}
url := fmt.Sprintf("https://registry.cn-hangzhou.aliyuncs.com/v2/miaowoo/%s/manifests/%s", i, v)
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "Bearer "+getToken(i))
resp, _ := client.Do(req)
fmt.Println("[C] " + strconv.Itoa(resp.StatusCode))
return resp.StatusCode == 200
}
func handleNormal(resp http.ResponseWriter, req *http.Request) {
fmt.Println("[N] " + req.RequestURI)
if strings.Contains(req.RequestURI, ".ico") || strings.Contains(req.RequestURI, ".txt") {
resp.Write([]byte("Noop..."))
return
}
origin := subString(req.RequestURI, 1, len(req.RequestURI))
if strings.Contains(origin, target) {
resp.Write([]byte("Image " + origin + " Is Self Can't Sync..."))
return
}
if _, ok := cache[origin]; ok {
resp.Write([]byte("Image " + origin + " Is Syncing... \nProcess " + string(cache[origin]) + "... \nPlease Wait..."))
return
}
name := strings.Replace(origin, "/", "_", -1)
image := target + "/" + name
out := `<html><body>`
out += `<h3>Image ` + origin + ` Is Tag to ` + image + ` And Push Success</h3>`
if checkMirror(name) {
out += "Alread Transfer"
} else {
cache[origin] = "0"
out += `<h4>Transfer Log</h4>
<pre>
` + transferImage(origin, image) + `
</pre>`
delete(cache, origin)
}
out += `<h3>You Can Use below Command To Pull...</h3>
<pre>
docker pull ` + image + `
docker tag ` + image + ` ` + origin + `
docker rmi ` + image + `
</pre>`
out += "</body></html>"
resp.Write([]byte(out))
}
func transferImage(origin string, image string) string {
out := ""
cache[origin] = "10"
out += runCommand(docker, "pull", origin)
cache[origin] = "30"
out += runCommand(docker, "tag", origin, image)
cache[origin] = "50"
out += runCommand(docker, "push", image)
cache[origin] = "70"
out += runCommand(docker, "rmi", origin)
cache[origin] = "90"
out += runCommand(docker, "rmi", image)
cache[origin] = "100"
return out
}
func runCommand(command string, args ...string) string {
result, err := exec.Command(command, args...).Output()
out := string(result)
if err != nil {
out = out + err.Error()
}
return out
}
func subString(str string, begin, length int) (substr string) {
// 将字符串的转换成[]rune
rs := []rune(str)
lth := len(rs)
// 简单的越界判断
if begin < 0 {
begin = 0
}
if begin >= lth {
begin = lth
}
end := begin + length
if end > lth {
end = lth
}
// 返回子串
return string(rs[begin:end])
}