func (repo CloudControllerBuildpackBitsRepository) downloadBuildpack(url string, cb func(*os.File, error)) { fileutils.TempFile("buildpack-download", func(tempfile *os.File, err error) { if err != nil { cb(nil, err) return } var certPool *x509.CertPool if len(repo.TrustedCerts) > 0 { certPool = x509.NewCertPool() for _, tlsCert := range repo.TrustedCerts { cert, _ := x509.ParseCertificate(tlsCert.Certificate[0]) certPool.AddCert(cert) } } client := &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{RootCAs: certPool}, Proxy: http.ProxyFromEnvironment, }, } response, err := client.Get(url) if err != nil { cb(nil, err) return } io.Copy(tempfile, response.Body) tempfile.Seek(0, 0) cb(tempfile, nil) }) }
func (repo CloudControllerApplicationBitsRepository) UploadApp(appGuid string, appDir string, cb func(path string, zipSize, fileCount uint64)) (apiErr error) { fileutils.TempDir("apps", func(uploadDir string, err error) { if err != nil { apiErr = err return } var presentFiles []resources.AppFileResource repo.sourceDir(appDir, func(sourceDir string, sourceErr error) { if sourceErr != nil { err = sourceErr return } presentFiles, err = repo.copyUploadableFiles(sourceDir, uploadDir) }) if err != nil { apiErr = err return } fileutils.TempFile("uploads", func(zipFile *os.File, err error) { if err != nil { apiErr = err return } zipFileSize := uint64(0) zipFileCount := uint64(0) err = repo.zipper.Zip(uploadDir, zipFile) switch err := err.(type) { case nil: stat, err := zipFile.Stat() if err != nil { apiErr = errors.NewWithError("Error zipping application", err) return } zipFileSize = uint64(stat.Size()) zipFileCount = app_files.CountFiles(uploadDir) case *errors.EmptyDirError: zipFile = nil default: apiErr = errors.NewWithError("Error zipping application", err) return } cb(appDir, zipFileSize, zipFileCount) apiErr = repo.uploadBits(appGuid, zipFile, presentFiles) if apiErr != nil { return } }) }) return }
func (repo CloudControllerBuildpackBitsRepository) UploadBuildpack(buildpack models.Buildpack, buildpackLocation string) (apiErr error) { fileutils.TempFile("buildpack-upload", func(zipFileToUpload *os.File, err error) { if err != nil { apiErr = errors.NewWithError(T("Couldn't create temp file for upload"), err) return } var buildpackFileName string if isWebURL(buildpackLocation) { buildpackFileName = path.Base(buildpackLocation) repo.downloadBuildpack(buildpackLocation, func(downloadFile *os.File, downloadErr error) { if downloadErr != nil { err = downloadErr return } err = normalizeBuildpackArchive(downloadFile, zipFileToUpload) }) } else { buildpackFileName = filepath.Base(buildpackLocation) stats, statError := os.Stat(buildpackLocation) if statError != nil { apiErr = errors.NewWithError(T("Error opening buildpack file"), statError) err = statError return } if stats.IsDir() { buildpackFileName += ".zip" // FIXME: remove once #71167394 is fixed err = repo.zipper.Zip(buildpackLocation, zipFileToUpload) } else { specifiedFile, openError := os.Open(buildpackLocation) if openError != nil { apiErr = errors.NewWithError(T("Couldn't open buildpack file"), openError) err = openError return } err = normalizeBuildpackArchive(specifiedFile, zipFileToUpload) } } if err != nil { apiErr = errors.NewWithError(T("Couldn't write zip file"), err) return } apiErr = repo.uploadBits(buildpack, zipFileToUpload, buildpackFileName) }) return }
func (repo CloudControllerBuildpackBitsRepository) performMultiPartUpload(url string, fieldName string, fileName string, body io.Reader) error { var capturedErr error fileutils.TempFile("requests", func(requestFile *os.File, err error) { if err != nil { capturedErr = err return } writer := multipart.NewWriter(requestFile) part, err := writer.CreateFormFile(fieldName, fileName) if err != nil { _ = writer.Close() capturedErr = err return } _, err = io.Copy(part, body) if err != nil { capturedErr = fmt.Errorf("%s: %s", T("Error creating upload"), err.Error()) return } err = writer.Close() if err != nil { capturedErr = err return } var request *net.Request request, err = repo.gateway.NewRequestForFile("PUT", url, repo.config.AccessToken(), requestFile) if err != nil { capturedErr = err return } contentType := fmt.Sprintf("multipart/form-data; boundary=%s", writer.Boundary()) request.HTTPReq.Header.Set("Content-Type", contentType) _, err = repo.gateway.PerformRequest(request) if err != nil { capturedErr = err } }) return capturedErr }
func (repo CloudControllerApplicationBitsRepository) UploadBits(appGuid string, zipFile *os.File, presentFiles []resources.AppFileResource) (apiErr error) { url := fmt.Sprintf("%s/v2/apps/%s/bits", repo.config.ApiEndpoint(), appGuid) fileutils.TempFile("requests", func(requestFile *os.File, err error) { if err != nil { apiErr = errors.NewWithError(T("Error creating tmp file: {{.Err}}", map[string]interface{}{"Err": err}), err) return } // json.Marshal represents a nil value as "null" instead of an empty slice "[]" if presentFiles == nil { presentFiles = []resources.AppFileResource{} } presentFilesJSON, err := json.Marshal(presentFiles) if err != nil { apiErr = errors.NewWithError(T("Error marshaling JSON"), err) return } boundary, err := repo.writeUploadBody(zipFile, requestFile, presentFilesJSON) if err != nil { apiErr = errors.NewWithError(T("Error writing to tmp file: {{.Err}}", map[string]interface{}{"Err": err}), err) return } var request *net.Request request, apiErr = repo.gateway.NewRequest("PUT", url, repo.config.AccessToken(), requestFile) if apiErr != nil { return } contentType := fmt.Sprintf("multipart/form-data; boundary=%s", boundary) request.HttpReq.Header.Set("Content-Type", contentType) response := &resources.Resource{} _, apiErr = repo.gateway.PerformPollingRequestForJSONResponse(request, response, DefaultAppUploadBitsTimeout) if apiErr != nil { return } }) return }
func (repo CloudControllerApplicationBitsRepository) uploadBits(appGuid string, zipFile *os.File, presentFiles []resources.AppFileResource) (apiErr error) { url := fmt.Sprintf("%s/v2/apps/%s/bits", repo.config.ApiEndpoint(), appGuid) fileutils.TempFile("requests", func(requestFile *os.File, err error) { if err != nil { apiErr = errors.NewWithError("Error creating tmp file: %s", err) return } presentFilesJSON, err := json.Marshal(presentFiles) if err != nil { apiErr = errors.NewWithError("Error marshaling JSON", err) return } boundary, err := repo.writeUploadBody(zipFile, requestFile, presentFilesJSON) if err != nil { apiErr = errors.NewWithError("Error writing to tmp file: %s", err) return } var request *net.Request request, apiErr = repo.gateway.NewRequest("PUT", url, repo.config.AccessToken(), requestFile) if apiErr != nil { return } contentType := fmt.Sprintf("multipart/form-data; boundary=%s", boundary) request.HttpReq.Header.Set("Content-Type", contentType) response := &resources.Resource{} _, apiErr = repo.gateway.PerformPollingRequestForJSONResponse(request, response, 5*time.Minute) if apiErr != nil { return } }) return }
func (repo CloudControllerBuildpackBitsRepository) performMultiPartUpload(url string, fieldName string, fileName string, body io.Reader) (apiErr error) { fileutils.TempFile("requests", func(requestFile *os.File, err error) { if err != nil { apiErr = err return } writer := multipart.NewWriter(requestFile) part, err := writer.CreateFormFile(fieldName, fileName) if err != nil { writer.Close() return } _, err = io.Copy(part, body) writer.Close() if err != nil { apiErr = errors.NewWithError("Error creating upload", err) return } var request *net.Request request, apiErr = repo.gateway.NewRequest("PUT", url, repo.config.AccessToken(), requestFile) contentType := fmt.Sprintf("multipart/form-data; boundary=%s", writer.Boundary()) request.HttpReq.Header.Set("Content-Type", contentType) if apiErr != nil { return } _, apiErr = repo.gateway.PerformRequest(request) }) return }
fileutils.TempFile("zip_test", func(zipFile *os.File, err error) { workingDir, err := os.Getwd() Expect(err).NotTo(HaveOccurred()) dir := filepath.Join(workingDir, "../../fixtures/zip/") err = os.Chmod(filepath.Join(dir, "subDir/bar.txt"), 0666) Expect(err).NotTo(HaveOccurred()) zipper := ApplicationZipper{} err = zipper.Zip(dir, zipFile) Expect(err).NotTo(HaveOccurred()) fileStat, err := zipFile.Stat() Expect(err).NotTo(HaveOccurred()) reader, err := zip.NewReader(zipFile, fileStat.Size()) Expect(err).NotTo(HaveOccurred()) filenames := []string{} for _, file := range reader.File { filenames = append(filenames, file.Name) } Expect(filenames).To(Equal(filesInZip)) readFileInZip := func(index int) (string, string) { buf := &bytes.Buffer{} file := reader.File[index] fReader, err := file.Open() _, err = io.Copy(buf, fReader) Expect(err).NotTo(HaveOccurred()) return file.Name, string(buf.Bytes()) } Expect(err).NotTo(HaveOccurred()) name, contents := readFileInZip(0) Expect(name).To(Equal("foo.txt")) Expect(contents).To(Equal("This is a simple text file.")) name, contents = readFileInZip(5) Expect(name).To(Equal("subDir/bar.txt")) Expect(contents).To(Equal("I am in a subdirectory.")) Expect(reader.File[5].FileInfo().Mode()).To(Equal(os.FileMode(0666))) })
Expect(deps.curlRepo.Method).To(Equal("GET")) Expect(deps.curlRepo.Path).To(Equal("/foo")) Expect(deps.ui.Outputs).To(ContainSubstrings([]string{"response for get"})) Expect(deps.ui.Outputs).ToNot(ContainSubstrings( []string{"FAILED"}, []string{"Content-Size:1024"}, )) }) Context("when the --output flag is provided", func() { It("saves the body of the response to the given filepath if it exists", func() { fileutils.TempFile("poor-mans-pipe", func(tempFile *os.File, err error) { Expect(err).ToNot(HaveOccurred()) deps.curlRepo.ResponseBody = "hai" runCurlWithInputs(deps, []string{"--output", tempFile.Name(), "/foo"}) contents, err := ioutil.ReadAll(tempFile) Expect(err).ToNot(HaveOccurred()) Expect(string(contents)).To(Equal("hai")) }) }) It("saves the body of the response to the given filepath if it doesn't exists", func() { fileutils.TempDir("poor-mans-dir", func(tmpDir string, err error) { Expect(err).ToNot(HaveOccurred()) deps.curlRepo.ResponseBody = "hai" filePath := filepath.Join(tmpDir, "subdir1", "banana.txt") runCurlWithInputs(deps, []string{"--output", filePath, "/foo"}) file, err := os.Open(filePath)
}) It("TestTraceSetToFile", func() { stdOut := bytes.NewBuffer([]byte{}) trace.SetStdout(stdOut) fileutils.TempFile("trace_test", func(file *os.File, err error) { Expect(err).NotTo(HaveOccurred()) file.Write([]byte("pre-existing content")) os.Setenv(trace.CF_TRACE, file.Name()) logger := trace.NewLogger() logger.Print("hello world") file.Seek(0, os.SEEK_SET) result, err := ioutil.ReadAll(file) Expect(err).NotTo(HaveOccurred()) byteString := string(result) Expect(byteString).To(ContainSubstring("pre-existing content")) Expect(byteString).To(ContainSubstring("hello world")) result, _ = ioutil.ReadAll(stdOut) Expect(string(result)).To(Equal("")) }) }) It("TestTraceSetToInvalidFile", func() { if runtime.GOOS != "windows" { stdOut := bytes.NewBuffer([]byte{}) trace.SetStdout(stdOut)
result, err := ioutil.ReadAll(stdout) Expect(err).ToNot(HaveOccurred()) Expect(result).To(BeEmpty()) }) It("prints to a file when given a string", func() { fileutils.TempFile("trace_test", func(file *os.File, err error) { Expect(err).NotTo(HaveOccurred()) file.Write([]byte("pre-existing content")) logger := NewLogger(file.Name()) logger.Print("hello world") file.Seek(0, os.SEEK_SET) result, err := ioutil.ReadAll(file) Expect(err).NotTo(HaveOccurred()) byteString := string(result) Expect(byteString).To(ContainSubstring("pre-existing content")) Expect(byteString).To(ContainSubstring("hello world")) result, _ = ioutil.ReadAll(stdout) Expect(string(result)).To(BeEmpty()) }) }) Context("when CF_TRACE is set to a file path that cannot be opened", func() { It("defaults to printing to its out pipe", func() { if runtime.GOOS != "windows" { stdOut := bytes.NewBuffer([]byte{}) SetStdout(stdOut)
logger := NewLogger(buffer, true, "", "false") logger.Print("Hello World") Expect(buffer).To(gbytes.Say("Hello World")) _, err := os.Open("false") Expect(err).To(HaveOccurred()) }) It("returns a logger that writes to STDOUT and a file when verbose is set and CF_TRACE is a path", func() { fileutils.TempFile("trace_test", func(file *os.File, err error) { logger := NewLogger(buffer, true, file.Name(), "") logger.Print("Hello World") Expect(buffer).To(gbytes.Say("Hello World")) fileContents, _ := ioutil.ReadAll(file) Expect(fileContents).To(ContainSubstring("Hello World")) }) }) It("returns a logger that writes to STDOUT and a file when verbose is set and config.trace is a path", func() { fileutils.TempFile("trace_test", func(file *os.File, err error) { logger := NewLogger(buffer, true, "", file.Name()) logger.Print("Hello World") Expect(buffer).To(gbytes.Say("Hello World")) fileContents, _ := ioutil.ReadAll(file)
. "github.com/onsi/gomega" ) var _ = Describe("Flag Content Helpers", func() { Describe("GetContentsFromOptionalFlagValue", func() { It("returns an empty byte slice when given an empty string", func() { bs, err := util.GetContentsFromOptionalFlagValue("") Expect(err).NotTo(HaveOccurred()) Expect(bs).To(Equal([]byte{})) }) It("returns bytes when given a file name prefixed with @", func() { fileutils.TempFile("get-data-test", func(tmpFile *os.File, err error) { fileData := `{"foo": "bar"}` tmpFile.WriteString(fileData) bs, err := util.GetContentsFromOptionalFlagValue("@" + tmpFile.Name()) Expect(err).NotTo(HaveOccurred()) Expect(bs).To(Equal([]byte(fileData))) }) }) It("returns bytes when given a file name not prefixed with @", func() { fileutils.TempFile("get-data-test", func(tmpFile *os.File, err error) { fileData := `{"foo": "bar"}` tmpFile.WriteString(fileData) bs, err := util.GetContentsFromOptionalFlagValue(tmpFile.Name()) Expect(err).NotTo(HaveOccurred()) Expect(bs).To(Equal([]byte(fileData))) }) })