build

package
v0.11.3 Latest Latest
Warning

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

Go to latest
Published: Feb 28, 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,
			})

			if doVerify && doUpdate {
				cobra.CheckErr("only one of --verify and --update-manifest may be passed")
			}

			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)

			bnd := &bundle.Bundle{
				Manifest: &bundle.Manifest{
					Name: deployment.AppID,
					ID:   npa.ParaTime.Namespace(),
				},
			}
			bnd.Manifest.Version, err = version.FromString(manifest.Version)
			if err != nil {
				fmt.Printf("unsupported package version format: %s\n", err)
				return
			}

			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(npa, manifest, deployment, bnd)
			case buildRofl.TEETypeTDX:

				switch manifest.Kind {
				case buildRofl.AppKindRaw:
					err = tdxBuildRaw(tmpDir, npa, manifest, deployment, bnd)
				case buildRofl.AppKindContainer:
					err = tdxBuildContainer(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 := fmt.Sprintf("%s.%s.orc", manifest.Name, 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...")

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

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

			runScript(manifest, buildRofl.ScriptBundlePost)

			buildEnclaves := make(map[sgx.EnclaveIdentity]struct{})
			for _, eid := range eids {
				buildEnclaves[eid] = struct{}{}
			}

			manifestEnclaves := make(map[sgx.EnclaveIdentity]struct{})
			for _, eid := range deployment.Policy.Enclaves {
				manifestEnclaves[eid] = struct{}{}
			}

			if doVerify {
				showIdentityDiff := func(build, other map[sgx.EnclaveIdentity]struct{}, otherName string) {
					fmt.Println("Built enclave identities:")
					for enclaveID := range build {
						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, manifestEnclaves) {
					fmt.Println("Built enclave identities DIFFER from manifest enclave identities!")
					showIdentityDiff(buildEnclaves, manifestEnclaves, "Manifest")
					cobra.CheckErr(fmt.Errorf("enclave identity verification failed"))
				}

				fmt.Println("Built enclave identities MATCH manifest enclave identities.")

				if !offline {
					var conn connection.Connection
					ctx := context.Background()
					conn, err = connection.Connect(ctx, npa.Network)
					cobra.CheckErr(err)

					var appID rofl.AppID
					_ = appID.UnmarshalText([]byte(deployment.AppID))

					var appCfg *rofl.AppConfig
					appCfg, err = conn.Runtime(npa.ParaTime).ROFL.App(ctx, client.RoundLatest, appID)
					cobra.CheckErr(err)

					cfgEnclaves := make(map[sgx.EnclaveIdentity]struct{})
					for _, eid := range appCfg.Policy.Enclaves {
						cfgEnclaves[eid] = struct{}{}
					}

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

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

			if deployment.Policy == nil {
				doUpdate = false
			}

			switch doUpdate {
			case false:

				if maps.Equal(buildEnclaves, manifestEnclaves) {
					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 _, enclaveID := range eids {
					data, _ := enclaveID.MarshalText()
					fmt.Printf("        - \"%s\"\n", string(data))
				}
				fmt.Println()
				fmt.Println("Next time you can also use the --update-manifest flag to apply changes.")
			case true:

				deployment.Policy.Enclaves = eids

				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