func()

in hgctl/pkg/plugin/build/build.go [485:645]


func (b *Builder) config(f ConfigFunc) (err error) {
	if err = f(b); err != nil {
		return err
	}

	// builder-go
	b.Builder.Go = strings.TrimSpace(b.Builder.Go)
	if b.Builder.Go == "" {
		b.Builder.Go = DefaultBuilderGo
	}

	// builder-tinygo
	b.Builder.TinyGo = strings.TrimSpace(b.Builder.TinyGo)
	if b.Builder.TinyGo == "" {
		b.Builder.TinyGo = DefaultBuilderTinyGo
	}

	// builder-oras
	b.Builder.Oras = strings.TrimSpace(b.Builder.Oras)
	if b.Builder.Oras == "" {
		b.Builder.Oras = DefaultBuilderOras
	}

	// input
	b.Input = strings.TrimSpace(b.Input)
	if b.Input == "" {
		b.Input = "./"
	}
	inp, err := utils.GetAbsolutePath(b.Input)
	if err != nil {
		return errors.Wrapf(err, "failed to parse input option %q", b.Input)
	}
	b.Input = inp

	// output-type
	b.Output.Type = strings.ToLower(strings.TrimSpace(b.Output.Type))
	if b.Output.Type == "" {
		b.Output.Type = "files"
	}
	if b.Output.Type != "files" && b.Output.Type != "image" {
		return errors.Errorf("invalid output type: %q, must be `files` or `image`", b.Output.Type)
	}

	// output-dest
	b.Output.Dest = strings.TrimSpace(b.Output.Dest)
	if b.Output.Dest == "" {
		b.Output.Dest = "./out"
	}
	out := b.Output.Dest
	if b.Output.Type == "files" {
		out, err = utils.GetAbsolutePath(b.Output.Dest)
		if err != nil {
			return errors.Wrapf(err, "failed to parse output destination %q", b.Output.Dest)
		}
		err = os.MkdirAll(b.Output.Dest, 0755)
		if err != nil && !os.IsExist(err) {
			return errors.Wrapf(err, "failed to create output destination %q", b.Output.Dest)
		}
	}
	b.Output.Dest = out

	// docker-auth
	b.DockerAuth = strings.TrimSpace(b.DockerAuth)
	if b.DockerAuth == "" {
		b.DockerAuth = "~/.docker/config.json"
	}
	auth, err := utils.GetAbsolutePath(b.DockerAuth)
	if err != nil {
		return errors.Wrapf(err, "failed to parse docker authentication %q", b.DockerAuth)
	}
	b.DockerAuth = auth

	// model-dir
	b.ModelDir = strings.TrimSpace(b.ModelDir)
	if b.ModelDir == "" {
		b.ModelDir = "./"
	}

	// option-file/username/password/model/debug: nothing to deal with

	// the unexported fields that users do not need to care about are as follows:
	b.repository = DefaultBuilderRepository

	b.tempDir, err = os.MkdirTemp("", HostTempDirPattern)
	if err != nil && !os.IsExist(err) {
		return errors.Wrap(err, "failed to create the host temporary dir")
	}

	dockerEp, err := os.CreateTemp("", HostDockerEntryPattern)
	if err != nil && !os.IsExist(err) {
		return errors.Wrap(err, "failed to create the docker entrypoint file")
	}
	err = dockerEp.Chmod(0777)
	if err != nil {
		return err
	}
	b.dockerEntrypoint = dockerEp.Name()
	dockerEp.Close()

	u, err := user.Current()
	if err != nil {
		return errors.Wrap(err, "failed to get the current user information")
	}
	b.uid, b.gid = u.Uid, u.Gid

	b.containerConf = types.ContainerCreateConfig{
		Name: "higress-wasm-go-builder",
		Config: &container.Config{
			Image: b.builderImageRef(),
			Env: []string{
				"GO111MODULE=on",
				"GOPROXY=https://goproxy.cn,direct",
			},
			WorkingDir: ContainerWorkDir,
			Entrypoint: []string{ContainerEntryFilePath},
		},
		HostConfig: &container.HostConfig{
			NetworkMode: "host",
			Mounts: []mount.Mount{
				{ // input dir that includes the wasm plugin source: main.go ...
					Type:   mount.TypeBind,
					Source: b.Input,
					Target: ContainerWorkDir,
				},
				{ // temp dir that includes the wasm plugin metadata: spec.yaml and README.md ...
					Type:   mount.TypeBind,
					Source: b.tempDir,
					Target: ContainerTempDir,
				},
				{ // entrypoint
					Type:   mount.TypeBind,
					Source: b.dockerEntrypoint,
					Target: ContainerEntryFilePath,
				},
			},
		},
	}

	if b.dockerCli == nil {
		b.dockerCli, err = client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
		if err != nil {
			return errors.Wrap(err, "failed to initialize the docker client")
		}
	}

	if b.w == nil {
		b.w = os.Stdout
	}

	signalNotify(b)

	if b.Debugger == nil {
		b.Debugger = utils.NewDefaultDebugger(b.Debug, b.w)
	}

	if b.YesOrNoPrinter == nil {
		b.YesOrNoPrinter = utils.NewPrinter(b.w, utils.DefaultIdent, utils.DefaultYes, utils.DefaultNo)
	}

	return nil
}