Create & Init Porject...
This commit is contained in:
		
							
								
								
									
										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])
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user