build

package
v0.13.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 6, 2025 License: Apache-2.0 Imports: 42 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	Cmd = &cobra.Command{
		Use:   "build",
		Short: "Build a ROFL application",
		Args:  cobra.NoArgs,
		Run: func(_ *cobra.Command, _ []string) {
			cfg := cliConfig.Global()
			npa := common.GetNPASelection(cfg)
			manifest, deployment := roflCommon.LoadManifestAndSetNPA(cfg, npa, deploymentName, &roflCommon.ManifestOptions{
				NeedAppID: true,
				NeedAdmin: false,
			})

			fmt.Println("Building a ROFL application...")
			fmt.Printf("Deployment: %s\n", deploymentName)
			fmt.Printf("Network:    %s\n", deployment.Network)
			fmt.Printf("ParaTime:   %s\n", deployment.ParaTime)
			fmt.Printf("Debug:      %v\n", deployment.Debug)
			fmt.Printf("App ID:     %s\n", deployment.AppID)
			fmt.Printf("Name:       %s\n", manifest.Name)
			fmt.Printf("Version:    %s\n", manifest.Version)
			fmt.Printf("TEE:        %s\n", manifest.TEE)
			fmt.Printf("Kind:       %s\n", manifest.Kind)

			switch deployment.Debug {
			case true:
				buildMode = buildModeUnsafe
			case false:
				buildMode = buildModeProduction
			}

			tmpDir, err := os.MkdirTemp("", "oasis-build")
			if err != nil {
				cobra.CheckErr(fmt.Errorf("failed to create temporary build directory: %w", err))
			}
			defer os.RemoveAll(tmpDir)

			var buildEnv env.ExecEnv
			switch {
			case manifest.Artifacts.Builder == "" || noDocker:
				buildEnv = env.NewNativeEnv()
			default:
				var baseDir string
				baseDir, err = env.GetBasedir()
				if err != nil {
					cobra.CheckErr(fmt.Sprintf("failed to determine base directory: %s", err))
				}

				dockerEnv := env.NewDockerEnv(
					manifest.Artifacts.Builder,
					baseDir,
					"/src",
				)
				dockerEnv.AddDirectory(tmpDir)
				buildEnv = dockerEnv
			}

			if !buildEnv.IsAvailable() {
				cobra.CheckErr(fmt.Sprintf("Build environment '%s' is not available. Make sure it is installed.", buildEnv))
			}

			bnd := &bundle.Bundle{
				Manifest: &bundle.Manifest{
					Name: deployment.AppID,
					ID:   npa.ParaTime.Namespace(),
				},
			}

			os.Setenv("ROFL_MANIFEST", manifest.SourceFileName())
			os.Setenv("ROFL_DEPLOYMENT_NAME", deploymentName)
			os.Setenv("ROFL_DEPLOYMENT_NETWORK", deployment.Network)
			os.Setenv("ROFL_DEPLOYMENT_PARATIME", deployment.ParaTime)
			os.Setenv("ROFL_TMPDIR", tmpDir)

			runScript(manifest, buildRofl.ScriptBuildPre)

			switch manifest.TEE {
			case buildRofl.TEETypeSGX:

				if manifest.Kind != buildRofl.AppKindRaw {
					fmt.Printf("unsupported app kind for SGX TEE: %s\n", manifest.Kind)
					return
				}

				sgxBuild(buildEnv, npa, manifest, deployment, bnd)
			case buildRofl.TEETypeTDX:

				switch manifest.Kind {
				case buildRofl.AppKindRaw:
					err = tdxBuildRaw(buildEnv, tmpDir, npa, manifest, deployment, bnd)
				case buildRofl.AppKindContainer:
					err = tdxBuildContainer(buildEnv, tmpDir, npa, manifest, deployment, bnd)
				}
			default:
				fmt.Printf("unsupported TEE kind: %s\n", manifest.TEE)
				return
			}
			if err != nil {
				fmt.Printf("%s\n", err)
				return
			}

			runScript(manifest, buildRofl.ScriptBuildPost)

			outFn := roflCommon.GetOrcFilename(manifest, deploymentName)
			if outputFn != "" {
				outFn = outputFn
			}
			if err = bnd.Write(outFn); err != nil {
				fmt.Printf("failed to write output bundle: %s\n", err)
				return
			}

			fmt.Printf("ROFL app built and bundle written to '%s'.\n", outFn)

			fmt.Println("Computing enclave identity...")

			ids, err := roflCommon.ComputeEnclaveIdentity(bnd, "")
			if err != nil {
				fmt.Printf("%s\n", err)
				return
			}

			os.Setenv("ROFL_BUNDLE", outFn)
			for idx, id := range ids {
				data, _ := id.Enclave.MarshalText()
				os.Setenv(fmt.Sprintf("ROFL_ENCLAVE_ID_%d", idx), string(data))
			}

			runScript(manifest, buildRofl.ScriptBundlePost)

			buildEnclaves := make(map[sgx.EnclaveIdentity]struct{})
			for _, id := range ids {
				buildEnclaves[id.Enclave] = struct{}{}
			}

			allManifestEnclaves := make(map[sgx.EnclaveIdentity]struct{})
			latestManifestEnclaves := make(map[sgx.EnclaveIdentity]struct{})
			for _, eid := range deployment.Policy.Enclaves {
				if eid.IsLatest() {
					latestManifestEnclaves[eid.ID] = struct{}{}
				}
				allManifestEnclaves[eid.ID] = struct{}{}
			}

			if doVerify {
				showIdentityDiff := func(this, other map[sgx.EnclaveIdentity]struct{}, thisName, otherName string) {
					fmt.Printf("%s enclave identities:\n", thisName)
					for enclaveID := range this {
						data, _ := enclaveID.MarshalText()
						fmt.Printf("  - %s\n", string(data))
					}

					fmt.Printf("%s enclave identities:\n", otherName)
					for enclaveID := range other {
						data, _ := enclaveID.MarshalText()
						fmt.Printf("  - %s\n", string(data))
					}
				}

				if !maps.Equal(buildEnclaves, latestManifestEnclaves) {
					fmt.Println("Built enclave identities DIFFER from latest manifest enclave identities!")
					showIdentityDiff(buildEnclaves, latestManifestEnclaves, "Built", "Manifest")
					cobra.CheckErr(fmt.Errorf("enclave identity verification failed"))
				}

				fmt.Println("Built enclave identities MATCH latest manifest enclave identities.")
				if len(latestManifestEnclaves) != len(allManifestEnclaves) {
					fmt.Println("NOTE: Non-latest enclave identities present in manifest!")
				}

				if !offline {
					ctx := context.Background()
					var cfgEnclaves map[sgx.EnclaveIdentity]struct{}
					cfgEnclaves, err = roflCommon.GetRegisteredEnclaves(ctx, deployment.AppID, npa)
					cobra.CheckErr(err)

					if !maps.Equal(allManifestEnclaves, cfgEnclaves) {
						fmt.Println("Manifest enclave identities DIFFER from on-chain enclave identities!")
						showIdentityDiff(allManifestEnclaves, cfgEnclaves, "Manifest", "On-chain")
						cobra.CheckErr(fmt.Errorf("enclave identity verification failed"))
					}

					fmt.Println("Manifest enclave identities MATCH on-chain enclave identities.")
				}
				return
			}

			if deployment.Policy == nil {
				noUpdate = true
			}

			switch noUpdate {
			case true:

				if maps.Equal(buildEnclaves, latestManifestEnclaves) {
					fmt.Println("Built enclave identities already match manifest enclave identities.")
					break
				}

				fmt.Println("Update the manifest with the following identities to use the new app:")
				fmt.Println()
				fmt.Printf("deployments:\n")
				fmt.Printf("  %s:\n", deploymentName)
				fmt.Printf("    policy:\n")
				fmt.Printf("      enclaves:\n")
				for _, id := range ids {
					data, _ := id.Enclave.MarshalText()
					fmt.Printf("        - \"%s\"\n", string(data))
				}
			case false:

				deployment.Policy.Enclaves = slices.DeleteFunc(deployment.Policy.Enclaves, func(ei *buildRofl.EnclaveIdentity) bool {
					return ei.IsLatest()
				})
				for _, id := range ids {
					deployment.Policy.Enclaves = append(deployment.Policy.Enclaves, &buildRofl.EnclaveIdentity{
						ID: id.Enclave,
					})
				}

				if err = manifest.Save(); err != nil {
					cobra.CheckErr(fmt.Errorf("failed to update manifest: %w", err))
				}

				fmt.Printf("Run `oasis rofl update` to update your ROFL app's on-chain configuration.\n")
			}
		},
	}
)

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL