@@ -16,6 +16,7 @@ import (
1616 "daml.com/x/assistant/pkg/assembler"
1717 "daml.com/x/assistant/pkg/assistantconfig"
1818 "daml.com/x/assistant/pkg/assistantconfig/assistantremote"
19+ "daml.com/x/assistant/pkg/licenseutils"
1920 ociconsts "daml.com/x/assistant/pkg/oci"
2021 "daml.com/x/assistant/pkg/ociindex"
2122 "daml.com/x/assistant/pkg/ocipuller/localpuller"
@@ -195,6 +196,7 @@ func createFromManifest(ctx context.Context, client *assistantremote.Remote, man
195196
196197 comps := lo .Values (manifest .Spec .Components )
197198 comps = append (comps , manifest .Spec .Assistant )
199+ licenses := make (map [string ]string )
198200 for _ , comp := range comps {
199201 repoName := ociconsts .ComponentRepoPrefix + comp .Name
200202 tag := assembler .ComputeTagOrDigest (comp )
@@ -204,12 +206,19 @@ func createFromManifest(ctx context.Context, client *assistantremote.Remote, man
204206 return "" , fmt .Errorf ("failed to pull component '%s:%s'. %w" , repoName , tag , err )
205207 }
206208
209+ imageManifestPath := filepath .Join (localRegistryPath , repoName , "blobs" , "sha256" , desc .Digest .Hex ())
210+
207211 // put a symlink to the assistant binary at known location in the bundle
208212 if comp == manifest .Spec .Assistant {
209- imageManifestPath := filepath .Join (localRegistryPath , repoName , "blobs" , "sha256" , desc .Digest .Hex ())
210- if err := linkAssistant (platformBundlePath , imageManifestPath ); err != nil {
213+ if err := linkAssistant (platform , platformBundlePath , imageManifestPath ); err != nil {
211214 return "" , err
212215 }
216+ } else {
217+ licenseBlob , _ , err := findFileInOciBlobs (imageManifestPath , licenseutils .ComponentLicenseFilename )
218+ if err != nil {
219+ return "" , fmt .Errorf ("couldn't find file named %q in component %q: %w" , licenseutils .ComponentLicenseFilename , comp .Name , err )
220+ }
221+ licenses [comp .Name ] = licenseBlob
213222 }
214223 }
215224
@@ -237,33 +246,59 @@ func createFromManifest(ctx context.Context, client *assistantremote.Remote, man
237246 return "" , err
238247 }
239248
249+ fmt .Printf ("Writing LICENSES file for platform %q\n " , platform .String ())
250+ if err := licenseutils .WriteLicensesFile (licenses , filepath .Join (platformBundlePath )); err != nil {
251+ return "" , err
252+ }
253+
240254 fmt .Printf ("Bundle for %s created at %q.\n " , platform .String (), platformBundlePath )
241255 return platformBundlePath , nil
242256}
243257
244- func linkAssistant (dir , imageManifestPath string ) error {
258+ // findFileInOciBlobs returns the path to the blob (which has hashy name) of the desired file
259+ func findFileInOciBlobs (imageManifestPath , filename string ) (string , * v1.Descriptor , error ) {
245260 bytes , err := os .ReadFile (imageManifestPath )
246261 if err != nil {
247- return err
262+ return "" , nil , err
248263 }
249264 manifest := v1.Manifest {}
250265 if err := json .Unmarshal (bytes , & manifest ); err != nil {
251- return err
266+ return "" , nil , err
252267 }
253268
254- dpmBinLayer , ok := lo .Find (manifest .Layers , func (l v1.Descriptor ) bool {
255- filename , ok := l .Annotations [fileinfo .FileNameAnnotation ]
269+ layer , ok := lo .Find (manifest .Layers , func (l v1.Descriptor ) bool {
270+ fname , ok := l .Annotations [fileinfo .FileNameAnnotation ]
256271 if ! ok {
257272 slog .Warn ("layer missing annotation" , "annotation" , fileinfo .FileNameAnnotation )
258273 return false
259274 }
260- return filename == assembler . AssistantBinNameWindows || filename == assembler . AssistantBinNameUnix
275+ return fname == filename
261276 })
262277
263278 if ! ok {
264- return fmt .Errorf ("could not determine assistant binary's layer" )
279+ return "" , nil , fmt .Errorf ("could not determine file's OCI layer for filename %q" , filename )
280+ }
281+ return filepath .Join (filepath .Dir (imageManifestPath ), layer .Digest .Hex ()), & layer , nil
282+ }
283+
284+ func linkAssistant (platform * simpleplatform.NonGeneric , dir , imageManifestPath string ) error {
285+ bytes , err := os .ReadFile (imageManifestPath )
286+ if err != nil {
287+ return err
288+ }
289+ manifest := v1.Manifest {}
290+ if err := json .Unmarshal (bytes , & manifest ); err != nil {
291+ return err
292+ }
293+
294+ binFileName := assembler .AssistantBinNameUnix
295+ if platform .OS == "windows" {
296+ binFileName = assembler .AssistantBinNameWindows
297+ }
298+ binBlobPath , dpmBinLayer , err := findFileInOciBlobs (imageManifestPath , binFileName )
299+ if err != nil {
300+ return fmt .Errorf ("could not determine assistant binary's layer and file: %w" , err )
265301 }
266- binBlobPath := filepath .Join (filepath .Dir (imageManifestPath ), dpmBinLayer .Digest .Hex ())
267302
268303 // TODO figure out why running linked blob fails on windows, instead of this.
269304 // (seems windows isn't happy with the blob filename not having a .exe)
0 commit comments