func (self *Handler) imageAction(res http.ResponseWriter, req *http.Request, logres *LogResponder) { query := req.URL.Query() // Close body defer req.Body.Close() uuid := query.Get(":uuid") action := query.Get("action") var manifest *image.Manifest var err errors.Error switch action { case "activate": manifest, err = self.images.Activate(uuid) case "enable": manifest, err = self.images.SetDisabled(uuid, false) case "disable": manifest, err = self.images.SetDisabled(uuid, true) case "": err = errors.InvalidParameter(nil) default: err = errors.InvalidParameter(nil) } if err != nil { logres.Error(err) return } logres.JSON(manifest) }
func (self *Handler) addImageFile(res http.ResponseWriter, req *http.Request, logres *LogResponder) { query := req.URL.Query() // Close body independent of the outcome defer req.Body.Close() // Grab uuid uuid := query.Get(":uuid") // Grab compression type compression := query.Get("compression") if compression == "" { logres.Error(errors.InvalidParameter(nil)) return } manifest, err := self.images.AddFile(uuid, compression, req.Body) if err != nil { logres.Error(err) return } logres.JSON(manifest) }
func (self *Pool) AddFile(uuid, compression string, reader io.Reader) (*Manifest, errors.Error) { // Find manifest with matching uuid manifest, ok := self.findManifest(uuid) if !ok { return nil, errors.ResourceNotFound(nil) } // Make sure the manifest has the correct state if manifest.State != StateUnactivated { return nil, errors.ImageAlreadyActivated(nil) } // Resolve file extension for the given compression type ext, ok := FileExtensions[compression] if !ok { return nil, errors.InvalidParameter(nil) } // Find absolute path for image and md5file imageFpath := filepath.Join(self.imageDir, fmt.Sprintf("%s.%s", uuid, ext)) md5Fpath := filepath.Join(self.imageDir, uuid+".md5") // Create destination directory if it does not exist err := os.MkdirAll(self.imageDir, 0775) if err != nil { return nil, errors.InternalError(err) } // Open image file f, err := os.Create(imageFpath) if err != nil { return nil, errors.InternalError(err) } // Remember to close files defer f.Close() // Calcluate sha1 and md5 sum while writing image to disk // Sha1 is a required field in the manifest shaHash := sha1.New() sha1Reader := io.TeeReader(reader, shaHash) // Md5 is needed by imgadm client which expects the // content-md5 header to be present md5Hash := md5.New() md5Reader := io.TeeReader(sha1Reader, md5Hash) // Write image to disk nBytes, err := io.Copy(f, md5Reader) if err != nil { return nil, errors.Upload(err) } // Write md5sum to file md5sum := md5Hash.Sum(nil) if err := ioutil.WriteFile(md5Fpath, md5sum, 0660); err != nil { return nil, errors.InternalError(err) } // Add image file to manifest imageFile := &ImageFile{ Sha1: fmt.Sprintf("%x", shaHash.Sum(nil)), Compression: compression, Size: nBytes, } // Update manifest self.lock() defer self.unlock() manifest.Files = []*ImageFile{imageFile} // Save manifests to disk if err := saveManifests(self.manifests); err != nil { return nil, errors.InternalError(err) } return manifest, nil }