Пример #1
0
func (ctx *Context) GetImageLayerHandler(w http.ResponseWriter, r *http.Request) {
	imageId := mux.Vars(r)["imageId"]
	imageReader, err := ctx.storage.StreamRead(storage.ImageLayerPath(imageId))
	if err != nil {
		sendResponse(w, "image not found", 404, nil, false)
		return
	}
	defer imageReader.Close()

	io.Copy(w, imageReader)
}
Пример #2
0
func (ctx *Context) computeImageChecksum(algo string, imageId string, jsonData []byte) (string, error) {
	if algo != "sha256" {
		return "", fmt.Errorf("bad algorithm %s, only sha256 supported right now", algo)
	}

	hash := sha256.New()
	fmt.Fprintf(hash, "%s\n", jsonData)
	reader, err := ctx.storage.StreamRead(storage.ImageLayerPath(imageId))
	if err != nil {
		return "", fmt.Errorf("couldn't read image for checksumming", algo)
	}
	io.Copy(hash, reader)
	return fmt.Sprintf("%x", hash.Sum(nil)), nil
}
Пример #3
0
func (ctx *Context) PutImageLayerHandler(w http.ResponseWriter, r *http.Request) {
	imageId := mux.Vars(r)["imageId"]
	jsonData, err := ctx.storage.GetContent(storage.ImageJsonPath(imageId))
	if err != nil {
		sendResponse(w, "Image's JSON not found", 404, nil, false)
		return
	}

	checksum, err := ctx.storage.GetContent(storage.ImageChecksumPath(imageId))
	if err != nil {
		sendResponse(w, "Image's checksum not found", 404, nil, false)
		return
	}

	layerPath := storage.ImageLayerPath(imageId)
	markPath := storage.ImageMarkPath(imageId)

	if layerExists, err := ctx.storage.Exists(layerPath); layerExists == true && err == nil {
		if markExists, err := ctx.storage.Exists(markPath); markExists == false || err != nil {
			sendResponse(w, "Image already exists", 409, nil, false)
			return
		}
	}

	writer, err := ctx.storage.StreamWrite(layerPath)
	if err != nil {
		sendResponse(w, "Couldn't write to layer file", 500, nil, false)
		return
	}

	io.Copy(writer, r.Body)

	checksumParts := strings.Split(string(checksum), ":")
	computedChecksum, err := ctx.computeImageChecksum(checksumParts[0], imageId, jsonData)
	if err != nil || computedChecksum != strings.ToLower(checksumParts[1]) {
		sendResponse(w, "Checksum mismatch, ignoring the layer", 400, nil, false)
		return
	}

	ctx.storage.Remove(markPath)

	sendResponse(w, nil, http.StatusOK, nil, false)
}