Example #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
}
Example #2
0
//PutRepositoryImagesV1Handler
func PutRepositoryImagesV1Handler(ctx *macaron.Context) (int, []byte) {
	//TODO: If standalone == true, Dockyard will check HEADER Authorization; if standalone == false, Dockyard will check HEADER TOEKN.

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

	r := new(models.DockerV1)
	if err := r.Unlocked(namespace, repository); err != nil {
		log.Errorf("[%s] unlock repository error: %s", ctx.Req.RequestURI, err.Error())

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

	result, _ := json.Marshal(map[string]string{})
	return http.StatusNoContent, result
}
Example #3
0
//GetTagV1Handler is
func GetTagV1Handler(ctx *macaron.Context) (int, []byte) {
	//TODO: If standalone == true, Dockyard will check HEADER Authorization; if standalone == false, Dockyard will check HEADER TOEKN.
	namespace := ctx.Params(":namespace")
	repository := ctx.Params(":repository")

	r := new(models.DockerV1)
	if tags, err := r.GetTags(namespace, repository); err != nil {
		log.Errorf("[%s] get repository tags data error: %s", ctx.Req.RequestURI, err.Error())

		result, _ := json.Marshal(map[string]string{"Error": "Get Repository Tags Error"})
		return http.StatusBadRequest, result
	} else {
		result, _ := json.Marshal(tags)
		ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(result)))

		return http.StatusOK, result
	}
}
Example #4
0
//GetRepositoryImagesV1Handler will return images json data.
func GetRepositoryImagesV1Handler(ctx *macaron.Context) (int, []byte) {
	var username 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
	}

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

	r := new(models.DockerV1)
	if v1, err := r.Get(namespace, repository); err != nil {
		log.Errorf("[%s] get repository images data error: %s", ctx.Req.RequestURI, err.Error())

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

		//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, "read")

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

		ctx.Resp.Header().Set("Content-Length", fmt.Sprint(len(v1.JSON)))

		return http.StatusOK, []byte(v1.JSON)
	}

}