@@ -5,7 +5,8 @@ use futures::future::try_join_all;
5
5
use spin_common:: ui:: quoted_path;
6
6
use spin_manifest:: schema:: v2:: TargetEnvironmentRef2 ;
7
7
8
- const DEFAULT_REGISTRY : & str = "spinframework.dev" ;
8
+ const DEFAULT_ENV_DEF_REGISTRY : & str = "ghcr.io/itowlson/envs" ;
9
+ const DEFAULT_PACKAGE_REGISTRY : & str = "spinframework.dev" ;
9
10
10
11
/// Serialisation format for the lockfile: registry -> env|pkg -> { name -> digest }
11
12
#[ derive( Clone , Debug , Default , PartialEq , Eq , serde:: Serialize , serde:: Deserialize ) ]
@@ -126,7 +127,7 @@ async fn load_environment(
126
127
) -> anyhow:: Result < TargetEnvironment2 > {
127
128
match env_id {
128
129
TargetEnvironmentRef2 :: DefaultRegistry ( id) => {
129
- load_environment_from_registry ( DEFAULT_REGISTRY , id, cache, lockfile) . await
130
+ load_environment_from_registry ( DEFAULT_ENV_DEF_REGISTRY , id, cache, lockfile) . await
130
131
}
131
132
TargetEnvironmentRef2 :: Registry { registry, id } => {
132
133
load_environment_from_registry ( registry, id, cache, lockfile) . await
@@ -165,7 +166,34 @@ async fn load_env_def_toml_from_registry(
165
166
}
166
167
167
168
async fn download_env_def_file ( registry : & str , env_id : & str ) -> anyhow:: Result < ( Vec < u8 > , String ) > {
168
- todo ! ( )
169
+ // This implies env_id is in the format spin-up:3.2 which WHO KNOWS
170
+ let reference = format ! ( "{registry}/{env_id}" ) ;
171
+ let reference = oci_distribution:: Reference :: try_from ( reference) ?;
172
+
173
+ let config = oci_distribution:: client:: ClientConfig :: default ( ) ;
174
+ let client = oci_distribution:: client:: Client :: new ( config) ;
175
+ let auth = oci_distribution:: secrets:: RegistryAuth :: Anonymous ;
176
+
177
+ let ( manifest, digest) = client. pull_manifest ( & reference, & auth) . await ?;
178
+
179
+ let im = match manifest {
180
+ oci_distribution:: manifest:: OciManifest :: Image ( im) => im,
181
+ oci_distribution:: manifest:: OciManifest :: ImageIndex ( _ind) => {
182
+ anyhow:: bail!( "found image index instead of image manifest, get in the sea" )
183
+ }
184
+ } ;
185
+
186
+ let count = im. layers . len ( ) ;
187
+
188
+ if count != 1 {
189
+ anyhow:: bail!( "artifact {reference} should have had exactly one layer" ) ;
190
+ }
191
+
192
+ let the_layer = & im. layers [ 0 ] ;
193
+ let mut out = Vec :: with_capacity ( the_layer. size . try_into ( ) . unwrap_or_default ( ) ) ;
194
+ client. pull_blob ( & reference, the_layer, & mut out) . await ?;
195
+
196
+ Ok ( ( out, digest) )
169
197
}
170
198
171
199
/// Loads the given `TargetEnvironment` from the given registry, or
@@ -253,7 +281,7 @@ async fn load_world(
253
281
) -> anyhow:: Result < CompatibleWorld > {
254
282
match world_ref {
255
283
WorldRef :: DefaultRegistry ( world) => {
256
- load_world_from_registry ( DEFAULT_REGISTRY , world, cache, lockfile) . await
284
+ load_world_from_registry ( DEFAULT_PACKAGE_REGISTRY , world, cache, lockfile) . await
257
285
}
258
286
WorldRef :: Registry { registry, world } => {
259
287
load_world_from_registry ( registry, world, cache, lockfile) . await
@@ -282,7 +310,7 @@ async fn load_environment_from_toml(
282
310
cache : & spin_loader:: cache:: Cache ,
283
311
lockfile : & std:: sync:: Arc < tokio:: sync:: RwLock < TargetEnvironmentLockfile > > ,
284
312
) -> anyhow:: Result < TargetEnvironment2 > {
285
- let env: EnvironmentDefinition = toml:: from_str ( & toml_text) ?;
313
+ let env: EnvironmentDefinition = toml:: from_str ( toml_text) ?;
286
314
287
315
let mut trigger_worlds = HashMap :: new ( ) ;
288
316
@@ -416,7 +444,7 @@ async fn load_world_from_registry(
416
444
let version = world_name. package . version . as_ref ( ) . unwrap ( ) ; // TODO: surely we can cope with unversioned? surely?
417
445
418
446
let release = client
419
- . get_release ( & package, & version)
447
+ . get_release ( & package, version)
420
448
. await
421
449
. with_context ( || format ! ( "Failed to get {} release from registry" , world_name. package) ) ?;
422
450
let stm = client
@@ -436,36 +464,16 @@ async fn load_world_from_registry(
436
464
. await
437
465
. set_package_digest ( registry, & world_name. package , & digest) ;
438
466
439
- CompatibleWorld :: from_package_bytes ( & world_name, bytes)
467
+ CompatibleWorld :: from_package_bytes ( world_name, bytes)
440
468
}
441
469
442
- /// A parsed document representing a deployment environment, e.g. Spin 2.7,
470
+ /// A fully realised deployment environment, e.g. Spin 2.7,
443
471
/// SpinKube 3.1, Fermyon Cloud. The `TargetEnvironment` provides a mapping
444
472
/// from the Spin trigger types supported in the environment to the Component Model worlds
445
473
/// supported by that trigger type. (A trigger type may support more than one world,
446
474
/// for example when it supports multiple versions of the Spin or WASI interfaces.)
447
- ///
448
- /// In terms of implementation, internally the environment is represented by a
449
- /// WIT package that adheres to a specific naming convention - namely that the worlds for
450
- /// a given trigger type are exactly whose names begin with one of:
451
- ///
452
- /// * `trigger-xxx`
453
- /// * `xxx-trigger`
454
- /// * `spin-xxx` (a convention used by some plugins)
455
- ///
456
- /// where `xxx` is the Spin trigger type. This flexibility is intended to maximise
457
- /// reuse of existing WIT files rather than needing to create custom ones to
458
- /// define environments.
459
- // pub struct TargetEnvironment {
460
- // name: String,
461
- // decoded: wit_parser::decoding::DecodedWasm,
462
- // package: wit_parser::Package,
463
- // package_id: id_arena::Id<wit_parser::Package>,
464
- // package_bytes: Vec<u8>,
465
- // }
466
-
467
- // The realised format
468
-
475
+ /// The structure stores all worlds (that is, the packages containing them) as binaries:
476
+ /// no further download or resolution is required after this point.
469
477
pub struct TargetEnvironment2 {
470
478
name : String ,
471
479
trigger_worlds : HashMap < String , CompatibleWorlds > ,
@@ -525,7 +533,7 @@ impl<'a> IntoIterator for &'a CompatibleWorlds {
525
533
}
526
534
}
527
535
528
- const NO_COMPATIBLE_WORLDS : & ' static CompatibleWorlds = & CompatibleWorlds { worlds : vec ! [ ] } ;
536
+ const NO_COMPATIBLE_WORLDS : & CompatibleWorlds = & CompatibleWorlds { worlds : vec ! [ ] } ;
529
537
530
538
pub struct CompatibleWorld {
531
539
world : WorldName ,
0 commit comments