Пример #1
0
//PutRepositoryV1Handler will create or update the repository, it's first step of Docker push.
//TODO: @1 When someone create or update the repository, it will be locked to forbidden others action include pull action.
//TODO: @2 Add a config option for allow/forbidden Docker client pull action when a repository is locked.
//TODO: @3 Intergated with [Crew](https://github.com/containerops/crew).
//TODO: @4 Token will be store in Redis, and link the push action with username@repository.
func PutRepositoryV1Handler(ctx *macaron.Context) (int, []byte) {
	var username, body string
	//var passwd string
	var err error

	if username, _, err = utils.DecodeBasicAuth(ctx.Req.Header.Get("Authorization")); err != nil {
		log.Errorf("[%s] decode Authorization error: %s", ctx.Req.RequestURI, err.Error())

		result, _ := json.Marshal(map[string]string{"Error": "Decode Authorization Error"})
		return http.StatusUnauthorized, result
	}

	//When integrated with crew, like this:
	//@1: username, passwd, _ := utils.DecodeBasicAuth(ctx.Req.Header.Get("Authorization"))
	//@2: username, passwd authorizated in Crew.

	namespace := ctx.Params(":namespace")
	repository := ctx.Params(":repository")

	//When integrated the Crew, should be check the privilage.
	if username != namespace {

	}

	//In Docker Registry V1, the repository json data in the body of `PUT /v1/:namespace/:repository`
	if body, err = ctx.Req.Body().String(); err != nil {
		log.Errorf("[%s] get repository json from http body error: %s", ctx.Req.RequestURI, err.Error())

		result, _ := json.Marshal(map[string]string{"Error": "Get Repository JSON Error"})
		return http.StatusBadRequest, result
	}

	//Create or update the repository.
	r := new(models.DockerV1)
	if e := r.Put(namespace, repository, body, ctx.Req.Header.Get("User-Agent")); e != nil {
		log.Errorf("[%s] put repository error: %s", ctx.Req.RequestURI, e.Error())

		result, _ := json.Marshal(map[string]string{"Error": "PUT Repository Error"})
		return http.StatusBadRequest, result
	}

	//If the Docker client use "X-Docker-Token", will return a randon token value.
	if ctx.Req.Header.Get("X-Docker-Token") == "true" {
		token := fmt.Sprintf("Token signature=%v,repository=\"%v/%v\",access=%v",
			utils.MD5(username), namespace, repository, "write")

		ctx.Resp.Header().Set("X-Docker-Token", token)
		ctx.Resp.Header().Set("WWW-Authenticate", token)
	}

	//TODO: When deploy multi instances of dockyard, the endpoints will schedule comply all instances stauts and arithmetic.
	ctx.Resp.Header().Set("X-Docker-Endpoints", setting.Domains)

	result, _ := json.Marshal(map[string]string{})
	return http.StatusOK, result
}