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