package builder import ( "errors" "fmt" "os" "path/filepath" "strings" "github.com/dokku/dokku/plugins/common" ) // TriggerBuilderDetect outputs a manually selected builder for the app func TriggerBuilderDetect(appName string) error { if builder := common.PropertyGet("builder", appName, "selected"); builder != "" { fmt.Println(builder) return nil } if builder := common.PropertyGet("builder", "--global", "selected"); builder != "" { fmt.Println(builder) return nil } return nil } // TriggerBuilderGetProperty writes the builder key to stdout for a given app container func TriggerBuilderGetProperty(appName string, key string) error { if _, ok := DefaultProperties[key]; !ok { return errors.New("Invalid builder property specified") } fmt.Println(common.PropertyGet("builder", appName, key)) return nil } // TriggerBuilderSetProperty writes the builder key to stdout for a given app container func TriggerBuilderSetProperty(appName string, key string, value string) error { if _, ok := DefaultProperties[key]; !ok { return errors.New("Invalid builder property specified") } return common.PropertyWrite("builder", appName, key, value) } // TriggerBuilderImageIsCNB prints true if an image is cnb based, false otherwise func TriggerBuilderImageIsCNB(appName string, image string) error { if common.IsImageCnbBased(image) { fmt.Println("true") } else { fmt.Println("false") } return nil } // TriggerBuilderImageIsHerokuish prints true if an image is herokuish based, false otherwise func TriggerBuilderImageIsHerokuish(appName string, image string) error { if common.IsImageHerokuishBased(image, appName) { fmt.Println("true") } else { fmt.Println("false") } return nil } // TriggerCorePostExtract moves a configured build-dir to be in the app root dir func TriggerCorePostExtract(appName string, sourceWorkDir string) error { buildDir := strings.Trim(reportComputedBuildDir(appName), "/") if buildDir == "" { return nil } newSourceWorkDir := filepath.Join(sourceWorkDir, buildDir) if !common.DirectoryExists(newSourceWorkDir) { return fmt.Errorf("Specified build-dir not found in sourcecode working directory: %v", buildDir) } tmpWorkDir, err := os.MkdirTemp(os.TempDir(), fmt.Sprintf("dokku-%s-%s", common.MustGetEnv("DOKKU_PID"), "CorePostExtract")) if err != nil { return fmt.Errorf("Unable to create temporary working directory: %v", err.Error()) } if err := removeAllContents(tmpWorkDir); err != nil { return fmt.Errorf("Unable to clear out temporary working directory for rewrite: %v", err.Error()) } if err := common.Copy(newSourceWorkDir, tmpWorkDir); err != nil { return fmt.Errorf("Unable to move build-dir to temporary working directory: %v", err.Error()) } if err := removeAllContents(sourceWorkDir); err != nil { return fmt.Errorf("Unable to clear out sourcecode working directory for rewrite: %v", err.Error()) } if err := common.Copy(tmpWorkDir, sourceWorkDir); err != nil { return fmt.Errorf("Unable to move build-dir to sourcecode working directory: %v", err.Error()) } return nil } // TriggerInstall runs the install step for the builder plugin func TriggerInstall() error { if err := common.PropertySetup("builder"); err != nil { return fmt.Errorf("Unable to install the builder plugin: %s", err.Error()) } apps, err := common.UnfilteredDokkuApps() if err != nil && !errors.Is(err, common.NoAppsExist) { return nil } for _, appName := range apps { if common.PropertyExists("builder", appName, "detected") { continue } results, err := common.CallPlugnTrigger(common.PlugnTriggerInput{ Trigger: "config-get", Args: []string{appName, "DOKKU_APP_TYPE"}, }) if err != nil { return err } if results.StdoutContents() != "" { common.PropertyWrite("builder", appName, "detected", results.StdoutContents()) } } _, err = common.CallPlugnTrigger(common.PlugnTriggerInput{ Trigger: "install-builder-prune", }) return err } // TriggerPostAppCloneSetup creates new builder files func TriggerPostAppCloneSetup(oldAppName string, newAppName string) error { err := common.PropertyClone("builder", oldAppName, newAppName) if err != nil { return err } return nil } // TriggerPostAppRenameSetup renames builder files func TriggerPostAppRenameSetup(oldAppName string, newAppName string) error { if err := common.PropertyClone("builder", oldAppName, newAppName); err != nil { return err } if err := common.PropertyDestroy("builder", oldAppName); err != nil { return err } return nil } // TriggerPostDelete destroys the builder property for a given app container func TriggerPostDelete(appName string) error { if err := common.PropertyDestroy("builder", appName); err != nil { return err } imagesByAppLabel, err := common.DockerFilterImages([]string{ fmt.Sprintf("label=com.dokku.app-name=%s", appName), }) if err != nil { common.LogWarn(err.Error()) } imageRepo := common.GetAppImageRepo(appName) imagesByRepo, err := listImagesByImageRepo(imageRepo) if err != nil { common.LogWarn(err.Error()) } images := append(imagesByAppLabel, imagesByRepo...) common.RemoveImages(images) return nil } // TriggerPostReleaseBuilder deletes unused build images func TriggerPostReleaseBuilder(builderType string, appName string) error { images, _ := common.DockerFilterImages([]string{ "label=com.dokku.image-stage=build", fmt.Sprintf("label=com.dokku.app-name=%s", appName), }) if err := common.RemoveImages(images); err != nil { common.LogWarn(err.Error()) } return nil }