Create & Init Porject...
This commit is contained in:
commit
0be3e70228
32
.gitignore
vendored
Normal file
32
.gitignore
vendored
Normal 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
182
main.go
Normal 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])
|
||||
}
|
Loading…
Reference in New Issue
Block a user