1818
1919import com .iexec .common .lifecycle .purge .ExpiringTaskMapFactory ;
2020import com .iexec .common .lifecycle .purge .Purgeable ;
21+ import com .iexec .common .replicate .ReplicateStatusCause ;
2122import com .iexec .commons .containers .client .DockerClientInstance ;
22- import com .iexec .commons .poco .chain .IexecHubAbstractService ;
2323import com .iexec .commons .poco .task .TaskDescription ;
2424import com .iexec .commons .poco .tee .TeeEnclaveConfiguration ;
2525import com .iexec .commons .poco .tee .TeeFramework ;
2626import com .iexec .sms .api .SmsClient ;
2727import com .iexec .sms .api .config .TeeServicesProperties ;
28+ import com .iexec .worker .chain .IexecHubService ;
29+ import com .iexec .worker .config .WorkerConfigurationService ;
2830import com .iexec .worker .docker .DockerService ;
2931import com .iexec .worker .sms .SmsService ;
32+ import com .iexec .worker .workflow .WorkflowError ;
3033import jakarta .annotation .PreDestroy ;
3134import lombok .extern .slf4j .Slf4j ;
3235import org .springframework .stereotype .Service ;
36+ import org .springframework .util .unit .DataSize ;
3337
38+ import java .util .ArrayList ;
39+ import java .util .List ;
3440import java .util .Map ;
35- import java .util .Objects ;
3641
3742/**
3843 * Manages the {@link TeeServicesProperties}, providing an easy way to get properties for a task
4348public class TeeServicesPropertiesService implements Purgeable {
4449 private final SmsService smsService ;
4550 private final DockerService dockerService ;
46- private final IexecHubAbstractService iexecHubService ;
51+ private final IexecHubService iexecHubService ;
52+ private final WorkerConfigurationService workerConfigurationService ;
4753
4854 private final Map <String , TeeServicesProperties > propertiesForTask = ExpiringTaskMapFactory .getExpiringTaskMap ();
4955
50- public TeeServicesPropertiesService (SmsService smsService ,
51- DockerService dockerService ,
52- IexecHubAbstractService iexecHubService ) {
56+ public TeeServicesPropertiesService (final SmsService smsService ,
57+ final DockerService dockerService ,
58+ final IexecHubService iexecHubService ,
59+ final WorkerConfigurationService workerConfigurationService ) {
5360 this .smsService = smsService ;
5461 this .dockerService = dockerService ;
5562 this .iexecHubService = iexecHubService ;
63+ this .workerConfigurationService = workerConfigurationService ;
5664 }
5765
5866 public TeeServicesProperties getTeeServicesProperties (final String chainTaskId ) {
59- return propertiesForTask .computeIfAbsent (chainTaskId , this :: retrieveTeeServicesProperties );
67+ return propertiesForTask .get (chainTaskId );
6068 }
6169
62- < T extends TeeServicesProperties > T retrieveTeeServicesProperties (final String chainTaskId ) {
70+ public List < WorkflowError > retrieveTeeServicesProperties (final String chainTaskId ) {
6371 final TaskDescription taskDescription = iexecHubService .getTaskDescription (chainTaskId );
6472
73+ // TODO errors could be renamed for APP enclave checks
74+ final TeeEnclaveConfiguration teeEnclaveConfiguration = taskDescription .getAppEnclaveConfiguration ();
75+ if (teeEnclaveConfiguration == null ) {
76+ log .error ("No enclave configuration found for task [chainTaskId:{}]" , chainTaskId );
77+ return List .of (new WorkflowError (ReplicateStatusCause .PRE_COMPUTE_MISSING_ENCLAVE_CONFIGURATION ));
78+ }
79+ if (!teeEnclaveConfiguration .getValidator ().isValid ()) {
80+ log .error ("Invalid enclave configuration [chainTaskId:{}, violations:{}]" ,
81+ chainTaskId , teeEnclaveConfiguration .getValidator ().validate ().toString ());
82+ return List .of (new WorkflowError (ReplicateStatusCause .PRE_COMPUTE_INVALID_ENCLAVE_CONFIGURATION ));
83+ }
84+ long teeComputeMaxHeapSize = DataSize
85+ .ofGigabytes (workerConfigurationService .getTeeComputeMaxHeapSizeGb ())
86+ .toBytes ();
87+ if (teeEnclaveConfiguration .getHeapSize () > teeComputeMaxHeapSize ) {
88+ log .error ("Enclave configuration should define a proper heap size [chainTaskId:{}, heapSize:{}, maxHeapSize:{}]" ,
89+ chainTaskId , teeEnclaveConfiguration .getHeapSize (), teeComputeMaxHeapSize );
90+ return List .of (new WorkflowError (ReplicateStatusCause .PRE_COMPUTE_INVALID_ENCLAVE_HEAP_CONFIGURATION ));
91+ }
92+
6593 // SMS client should already have been created once before.
6694 // If it couldn't be created, then the task would have been aborted.
6795 // So the following won't throw an exception.
6896 final SmsClient smsClient = smsService .getSmsClient (chainTaskId );
6997 final TeeFramework teeFramework = taskDescription .getTeeFramework ();
7098 final TeeFramework smsTeeFramework = smsClient .getTeeFramework ();
7199 if (smsTeeFramework != teeFramework ) {
72- throw new TeeServicesPropertiesCreationException (
73- "SMS is configured for another TEE framework" +
74- " [chainTaskId:" + chainTaskId +
75- ", requiredFramework:" + teeFramework +
76- ", actualFramework:" + smsTeeFramework + "]" );
100+ return List .of (new WorkflowError (ReplicateStatusCause .GET_TEE_SERVICES_CONFIGURATION_FAILED ,
101+ String .format ("SMS is configured for another TEE framework [chainTaskId:%s, requiredFramework:%s, actualFramework:%s]" ,
102+ chainTaskId , teeFramework , smsTeeFramework )));
77103 }
78104
79- final TeeEnclaveConfiguration teeEnclaveConfiguration = taskDescription .getAppEnclaveConfiguration ();
80- Objects .requireNonNull (teeEnclaveConfiguration , "Missing TEE enclave configuration [chainTaskId:" + chainTaskId + "]" );
81-
82- final T properties = smsClient .getTeeServicesPropertiesVersion (teeFramework , teeEnclaveConfiguration .getVersion ());
83- log .info ("Received TEE services properties [properties:{}]" , properties );
105+ final TeeServicesProperties properties = smsClient .getTeeServicesPropertiesVersion (teeFramework , teeEnclaveConfiguration .getVersion ());
84106 if (properties == null ) {
85- throw new TeeServicesPropertiesCreationException (
86- "Missing TEE services properties [chainTaskId:" + chainTaskId + "]" );
107+ return List . of ( new WorkflowError ( ReplicateStatusCause . GET_TEE_SERVICES_CONFIGURATION_FAILED ,
108+ String . format ( "Missing TEE services properties [chainTaskId:%s]" , chainTaskId )) );
87109 }
110+ log .info ("TEE services properties received [chainTaskId:{}]" , chainTaskId );
88111
89112 final String preComputeImage = properties .getPreComputeProperties ().getImage ();
90113 final String postComputeImage = properties .getPostComputeProperties ().getImage ();
114+ final List <WorkflowError > errors = new ArrayList <>();
91115
92- checkImageIsPresentOrDownload (preComputeImage , chainTaskId , "preComputeImage" );
93- checkImageIsPresentOrDownload (postComputeImage , chainTaskId , "postComputeImage" );
116+ errors . addAll ( checkImageIsPresentOrDownload (preComputeImage , chainTaskId , "preComputeImage" ) );
117+ errors . addAll ( checkImageIsPresentOrDownload (postComputeImage , chainTaskId , "postComputeImage" ) );
94118
95- return properties ;
119+ if (errors .isEmpty ()) {
120+ propertiesForTask .put (chainTaskId , properties );
121+ log .info ("TEE services properties storage in cache [chainTaskId:{}, contains-key:{}]" ,
122+ chainTaskId , propertiesForTask .containsKey (chainTaskId ));
123+ }
124+ return List .copyOf (errors );
96125 }
97126
98- private void checkImageIsPresentOrDownload (final String image , final String chainTaskId , final String imageType ) {
127+ private List < WorkflowError > checkImageIsPresentOrDownload (final String image , final String chainTaskId , final String imageType ) {
99128 final DockerClientInstance client = dockerService .getClient (image );
100- if (!client .isImagePresent (image )
101- && !client .pullImage (image )) {
102- throw new TeeServicesPropertiesCreationException (
103- "Failed to download image " +
104- "[chainTaskId:" + chainTaskId + ", " + imageType + ":" + image + "]" );
129+ if (!client .isImagePresent (image ) && !client .pullImage (image )) {
130+ return List .of (new WorkflowError (ReplicateStatusCause .GET_TEE_SERVICES_CONFIGURATION_FAILED ,
131+ String .format ("Failed to download image [chainTaskId:%s, %s:%s]" , chainTaskId , imageType , image )));
105132 }
133+ return List .of ();
106134 }
107135
108136 /**
@@ -114,8 +142,9 @@ private void checkImageIsPresentOrDownload(final String image, final String chai
114142 */
115143 @ Override
116144 public boolean purgeTask (final String chainTaskId ) {
117- log .debug ("purgeTask [chainTaskId:{}]" , chainTaskId );
118145 propertiesForTask .remove (chainTaskId );
146+ log .info ("TEE services properties removal from cache [chainTaskId:{}, contains-key:{}]" ,
147+ chainTaskId , propertiesForTask .containsKey (chainTaskId ));
119148 return !propertiesForTask .containsKey (chainTaskId );
120149 }
121150
0 commit comments