Example #1
0
// EnsureCode makes sure the code is in the ProjectDir.
// NOTE(termie): When launched by kiddie-pool the ProjectPath will be
// set to the location where grappler checked out the code and the copy
// will be a little superfluous, but in the case where this is being
// run in Single Player Mode this copy is necessary to avoid screwing
// with the local dir.
func (p *Runner) EnsureCode() (string, error) {
	projectDir := p.ProjectDir()
	if p.options.DirectMount {
		return projectDir, nil
	}

	// If the target is a tarball feetch and build that
	if p.options.ProjectURL != "" {
		resp, err := util.FetchTarball(p.options.ProjectURL)
		if err != nil {
			return projectDir, err
		}
		err = util.Untargzip(projectDir, resp.Body)
		if err != nil {
			return projectDir, err
		}
	} else {
		// We were pointed at a path with ProjectPath, copy it to projectDir

		ignoreFiles := []string{
			p.options.BuildPath(),
			p.options.ProjectDownloadPath(),
			p.options.StepPath(),
			p.options.ContainerPath(),
			p.options.CachePath(),
		}

		var err error

		// Make sure we don't accidentally recurse or copy extra files
		ignoreFunc := func(src string, files []os.FileInfo) []string {
			ignores := []string{}
			for _, file := range files {
				abspath, err := filepath.Abs(filepath.Join(src, file.Name()))
				if err != nil {
					// Something went sufficiently wrong
					panic(err)
				}
				if util.ContainsString(ignoreFiles, abspath) {
					ignores = append(ignores, file.Name())
				}
			}
			return ignores
		}
		copyOpts := &shutil.CopyTreeOptions{Ignore: ignoreFunc, CopyFunction: shutil.Copy}
		os.Rename(projectDir, fmt.Sprintf("%s-%s", projectDir, uuid.NewRandom().String()))
		err = shutil.CopyTree(p.options.ProjectPath, projectDir, copyOpts)
		if err != nil {
			return projectDir, err
		}
	}
	return projectDir, nil
}
Example #2
0
// Fetch grabs the Step content (or calls FetchScript for script steps).
func (s *ExternalStep) Fetch() (string, error) {
	// NOTE(termie): polymorphism based on kind, we could probably do something
	//               with interfaces here, but this is okay for now
	if s.IsScript() {
		return s.FetchScript()
	}

	stepPath := filepath.Join(s.options.StepPath(), s.CachedName())
	stepExists, err := util.Exists(stepPath)
	if err != nil {
		return "", err
	}

	if !stepExists {
		// If we don't have a url already
		if s.url == "" {
			// Grab the info about the step from the api

			// TODO(termie): probably don't need these in global options?
			apiOptions := api.APIOptions{
				BaseURL:   s.options.GlobalOptions.BaseURL,
				AuthToken: s.options.GlobalOptions.AuthToken,
			}
			client := api.NewAPIClient(&apiOptions)
			stepInfo, err := client.GetStepVersion(s.Owner(), s.Name(), s.Version())
			if err != nil {
				if apiErr, ok := err.(*api.APIError); ok && apiErr.StatusCode == 404 {
					return "", fmt.Errorf("The step \"%s\" was not found", s.ID())
				}
				return "", err
			}

			s.url = stepInfo.TarballURL
		}

		// If we have a file uri let's just copytree it.
		if strings.HasPrefix(s.url, "file:///") {
			if s.options.EnableDevSteps {
				localPath := s.url[len("file://"):]
				err = shutil.CopyTree(localPath, stepPath, nil)
				if err != nil {
					return "", err
				}
			} else {
				return "", fmt.Errorf("Dev mode is not enabled so refusing to copy local file urls: %s", s.url)
			}
		} else {
			// Grab the tarball and util.Untargzip it
			resp, err := util.FetchTarball(s.url)
			if err != nil {
				return "", err
			}

			// Assuming we have a gzip'd tarball at this point
			err = util.Untargzip(stepPath, resp.Body)
			if err != nil {
				return "", err
			}
		}
	}

	hostStepPath := s.HostPath()

	err = shutil.CopyTree(stepPath, hostStepPath, nil)
	if err != nil {
		return "", nil
	}

	// Now that we have the code, load any step config we might find
	desc, err := ReadStepDesc(s.HostPath("wercker-step.yml"))
	if err != nil && !os.IsNotExist(err) {
		// TODO(termie): Log an error instead of printing
		s.logger.Println("ERROR: Reading wercker-step.yml:", err)
	}
	if err == nil {
		s.stepDesc = desc
	}
	return hostStepPath, nil
}
Example #3
0
// EnsureCode makes sure the code is in the ProjectDir.
// NOTE(termie): When launched by kiddie-pool the ProjectPath will be
// set to the location where grappler checked out the code and the copy
// will be a little superfluous, but in the case where this is being
// run in Single Player Mode this copy is necessary to avoid screwing
// with the local dir.
func (p *Runner) EnsureCode() (string, error) {
	projectDir := p.ProjectDir()
	if p.options.DirectMount {
		return projectDir, nil
	}

	// If the target is a tarball feetch and build that
	if p.options.ProjectURL != "" {
		resp, err := util.FetchTarball(p.options.ProjectURL)
		if err != nil {
			return projectDir, err
		}
		err = util.Untargzip(projectDir, resp.Body)
		if err != nil {
			return projectDir, err
		}
	} else {
		// We were pointed at a path with ProjectPath, copy it to projectDir

		ignoreFiles := []string{
			p.options.WorkingDir,
		}

		oldbuilds, _ := filepath.Abs("./_builds")
		oldprojects, _ := filepath.Abs("./_projects")
		oldsteps, _ := filepath.Abs("./_steps")
		oldcache, _ := filepath.Abs("./_cache")
		oldcontainers, _ := filepath.Abs("./_containers")
		deprecatedPaths := []string{
			oldbuilds,
			oldprojects,
			oldsteps,
			oldcache,
			oldcontainers,
		}

		var err error

		// Make sure we don't accidentally recurse or copy extra files
		ignoreFunc := func(src string, files []os.FileInfo) []string {
			ignores := []string{}
			for _, file := range files {
				abspath, err := filepath.Abs(filepath.Join(src, file.Name()))
				if err != nil {
					// Something went sufficiently wrong
					panic(err)
				}
				if util.ContainsString(ignoreFiles, abspath) {
					ignores = append(ignores, file.Name())
				}

				// TODO(termie): remove this warning after a while
				if util.ContainsString(deprecatedPaths, abspath) {
					p.logger.Warnln(fmt.Sprintf("Not ignoring deprecated runtime path, %s. You probably want to delete it so it doesn't get copied into your container. Runtime files are now stored under '.wercker' by default. This message will go away in a future update.", file.Name()))
				}
			}
			return ignores
		}
		copyOpts := &shutil.CopyTreeOptions{Ignore: ignoreFunc, CopyFunction: shutil.Copy}
		os.Rename(projectDir, fmt.Sprintf("%s-%s", projectDir, uuid.NewRandom().String()))
		err = shutil.CopyTree(p.options.ProjectPath, projectDir, copyOpts)
		if err != nil {
			return projectDir, err
		}
	}
	return projectDir, nil
}