Skip to content

Commit 817416b

Browse files
authored
Enable adoption and versioned model package (#90)
Description of changes: 1. Re-enables versioned model-package as using updated runtime and deploying to canary did not see test failure for versioned model package. Updated runtime fixes issue of multiple reconciliation loops which appears to have caused multiple creations of model-package. 2. Latest runtime/codegen can now correctly adopt and retrieve status for versioned model-package, thus adoption is now enabled for model-package. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent 3b0d907 commit 817416b

File tree

13 files changed

+501
-200
lines changed

13 files changed

+501
-200
lines changed

apis/v1alpha1/generator.yaml

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ operations:
1313
RetainAllVariantProperties: true
1414
DescribeModelPackage:
1515
custom_check_required_fields_missing_method: customCheckRequiredFieldsMissingMethod
16+
primary_identifier_field_name: ARN
1617
StopHyperParameterTuningJob:
1718
operation_type: Delete
1819
resource_name: HyperParameterTuningJob
@@ -460,9 +461,6 @@ resources:
460461
- InvalidParameterValue
461462
- MissingParameter
462463
- ConflictException
463-
# Custom error to disable support for Versioned
464-
# Model Package
465-
- VersionedModelPackageNotSupported
466464
hooks:
467465
delta_pre_compare:
468466
code: customSetDefaults(a, b)
@@ -478,8 +476,6 @@ resources:
478476
template_path: model_package/set_resource_name_as_arn.go.tpl
479477
sdk_update_pre_build_request:
480478
template_path: common/sdk_update_pre_build_request.go.tpl
481-
sdk_create_post_build_request:
482-
template_path: model_package/sdk_create_post_build_request.go.tpl
483479
fields:
484480
ModelPackageStatus:
485481
is_read_only: true
@@ -515,11 +511,6 @@ resources:
515511
Tags:
516512
compare:
517513
is_ignored: true
518-
# TODO: Can adopt unversioned Model Packages however versioned ModelPackages
519-
# cannot be adopted properly. Their spec will show in describe
520-
# kubecetl describe modelpackages however it cannot be deleted or updated
521-
# Since this is not expected behavior adoption is disabled
522-
is_adoptable: false
523514
FeatureGroup:
524515
update_conditions_custom_method_name: CustomUpdateConditions
525516
exceptions:

generator.yaml

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ operations:
1313
RetainAllVariantProperties: true
1414
DescribeModelPackage:
1515
custom_check_required_fields_missing_method: customCheckRequiredFieldsMissingMethod
16+
primary_identifier_field_name: ARN
1617
StopHyperParameterTuningJob:
1718
operation_type: Delete
1819
resource_name: HyperParameterTuningJob
@@ -460,9 +461,6 @@ resources:
460461
- InvalidParameterValue
461462
- MissingParameter
462463
- ConflictException
463-
# Custom error to disable support for Versioned
464-
# Model Package
465-
- VersionedModelPackageNotSupported
466464
hooks:
467465
delta_pre_compare:
468466
code: customSetDefaults(a, b)
@@ -478,8 +476,6 @@ resources:
478476
template_path: model_package/set_resource_name_as_arn.go.tpl
479477
sdk_update_pre_build_request:
480478
template_path: common/sdk_update_pre_build_request.go.tpl
481-
sdk_create_post_build_request:
482-
template_path: model_package/sdk_create_post_build_request.go.tpl
483479
fields:
484480
ModelPackageStatus:
485481
is_read_only: true
@@ -515,11 +511,6 @@ resources:
515511
Tags:
516512
compare:
517513
is_ignored: true
518-
# TODO: Can adopt unversioned Model Packages however versioned ModelPackages
519-
# cannot be adopted properly. Their spec will show in describe
520-
# kubecetl describe modelpackages however it cannot be deleted or updated
521-
# Since this is not expected behavior adoption is disabled
522-
is_adoptable: false
523514
FeatureGroup:
524515
update_conditions_custom_method_name: CustomUpdateConditions
525516
exceptions:

pkg/resource/model_package/hooks.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919

2020
ackrequeue "github.com/aws-controllers-k8s/runtime/pkg/requeue"
2121
svccommon "github.com/aws-controllers-k8s/sagemaker-controller/pkg/common"
22-
"github.com/aws/aws-sdk-go/aws/awserr"
2322
svcsdk "github.com/aws/aws-sdk-go/service/sagemaker"
2423
)
2524

@@ -34,9 +33,6 @@ var (
3433
errors.New(resourceName+" is deleting."),
3534
ackrequeue.DefaultRequeueAfterDuration,
3635
)
37-
38-
VersionedModelPackageNotSupported = awserr.New("VersionedModelPackageNotSupported",
39-
"unable to create modelpackage, versioned model package not supported", nil)
4036
)
4137

4238
// customSetOutput sets ConditionTypeResourceSynced condition to True or False
@@ -66,6 +62,5 @@ func (rm *resourceManager) requeueUntilCanModify(
6662
func (rm *resourceManager) customCheckRequiredFieldsMissingMethod(
6763
r *resource,
6864
) bool {
69-
return r.ko.Spec.ModelPackageName == nil && r.ko.Spec.ModelPackageGroupName == nil
70-
65+
return r.ko.Spec.ModelPackageName == nil && r.ko.Spec.ModelPackageGroupName == nil && r.ko.Status.ACKResourceMetadata.ARN == nil
7166
}

pkg/resource/model_package/manager_factory.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/resource/model_package/resource.go

Lines changed: 8 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/resource/model_package/sdk.go

Lines changed: 1 addition & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

templates/model_package/sdk_create_post_build_request.go.tpl

Lines changed: 0 additions & 5 deletions
This file was deleted.

test/e2e/__init__.py

Lines changed: 97 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import pytest
1515
import logging
16+
import botocore
1617
import time
1718
import boto3
1819
from pathlib import Path
@@ -70,7 +71,9 @@ def create_sagemaker_resource(
7071
return reference, spec, resource
7172

7273

73-
def create_adopted_resource(replacements, namespace="default"):
74+
def create_adopted_resource(
75+
replacements, namespace="default", spec_file="adopted_resource_base"
76+
):
7477
"""
7578
Wrapper around k8s.load_and_create_resource to create a Adopoted resource
7679
"""
@@ -81,7 +84,7 @@ def create_adopted_resource(replacements, namespace="default"):
8184
CRD_VERSION,
8285
"adoptedresources",
8386
replacements["ADOPTED_RESOURCE_NAME"],
84-
"adopted_resource_base",
87+
spec_file,
8588
replacements,
8689
namespace,
8790
)
@@ -159,6 +162,82 @@ def assert_endpoint_status_in_sync(endpoint_name, reference, expected_status):
159162
)
160163

161164

165+
def get_model_package_sagemaker_status(model_package_arn):
166+
response = sagemaker_client().describe_model_package(
167+
ModelPackageName=model_package_arn
168+
)
169+
return response["ModelPackageStatus"]
170+
171+
172+
def get_model_package_resource_status(reference: k8s.CustomResourceReference):
173+
resource = k8s.get_resource(reference)
174+
assert "modelPackageStatus" in resource["status"]
175+
return resource["status"]["modelPackageStatus"]
176+
177+
178+
def wait_sagemaker_model_package_status(
179+
model_package_arn,
180+
expected_status: str,
181+
wait_periods: int = 60,
182+
period_length: int = 30,
183+
):
184+
return wait_for_status(
185+
expected_status,
186+
wait_periods,
187+
period_length,
188+
get_model_package_sagemaker_status,
189+
model_package_arn,
190+
)
191+
192+
193+
def wait_resource_model_package_status(
194+
reference: k8s.CustomResourceReference,
195+
expected_status: str,
196+
wait_periods: int = 30,
197+
period_length: int = 30,
198+
):
199+
return wait_for_status(
200+
expected_status,
201+
wait_periods,
202+
period_length,
203+
get_model_package_resource_status,
204+
reference,
205+
)
206+
207+
208+
def assert_model_package_status_in_sync(model_package_arn, reference, expected_status):
209+
assert (
210+
wait_sagemaker_model_package_status(model_package_arn, expected_status)
211+
== wait_resource_model_package_status(reference, expected_status, 2)
212+
== expected_status
213+
)
214+
215+
216+
def get_sagemaker_model_package_group(model_package_group_name: str):
217+
try:
218+
return sagemaker_client().describe_model_package_group(
219+
ModelPackageGroupName=model_package_group_name
220+
)
221+
except botocore.exceptions.ClientError as error:
222+
logging.error(
223+
f"SageMaker could not find a model package group with the name {model_package_group_name}. Error {error}"
224+
)
225+
return None
226+
227+
228+
def get_sagemaker_model_package(model_package_name: str):
229+
try:
230+
model_package = sagemaker_client().describe_model_package(
231+
ModelPackageName=model_package_name
232+
)
233+
return model_package
234+
except botocore.exceptions.ClientError as error:
235+
logging.error(
236+
f"SageMaker could not find a model package with the name {model_package_name}. Error {error}"
237+
)
238+
return None
239+
240+
162241
def assert_tags_in_sync(resource_arn, resource_tags):
163242
response = sagemaker_client().list_tags(ResourceArn=resource_arn)
164243
response_tags = response["Tags"]
@@ -199,18 +278,19 @@ def get_training_resource_status(reference: k8s.CustomResourceReference):
199278

200279

201280
def wait_resource_training_status(
202-
reference: k8s.CustomResourceReference,
203-
expected_status: str,
204-
wait_periods: int = 30,
205-
period_length: int = 30,
206-
):
207-
return wait_for_status(
208-
expected_status,
209-
wait_periods,
210-
period_length,
211-
get_training_resource_status,
212-
reference,
213-
)
281+
reference: k8s.CustomResourceReference,
282+
expected_status: str,
283+
wait_periods: int = 30,
284+
period_length: int = 30,
285+
):
286+
return wait_for_status(
287+
expected_status,
288+
wait_periods,
289+
period_length,
290+
get_training_resource_status,
291+
reference,
292+
)
293+
214294

215295
def wait_sagemaker_training_status(
216296
training_job_name,
@@ -226,11 +306,10 @@ def wait_sagemaker_training_status(
226306
training_job_name,
227307
)
228308

229-
def assert_training_status_in_sync(
230-
training_job_name, reference, expected_status
231-
):
309+
310+
def assert_training_status_in_sync(training_job_name, reference, expected_status):
232311
assert (
233312
wait_sagemaker_training_status(training_job_name, expected_status)
234313
== wait_resource_training_status(reference, expected_status)
235314
== expected_status
236-
)
315+
)

test/e2e/common/config.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
ENDPOINT_RESOURCE_PLURAL = "endpoints"
1919
DATA_QUALITY_JOB_DEFINITION_RESOURCE_PLURAL = "dataqualityjobdefinitions"
2020
MODEL_PACKAGE_GROUP_RESOURCE_PLURAL = "modelpackagegroups"
21+
MODEL_PACKAGE_RESOURCE_PLURAL = "modelpackages"
2122

2223
# Job Type Resource Statuses
2324
LIST_JOB_STATUS_STOPPED = ("Stopped", "Stopping", "Completed")
@@ -33,4 +34,4 @@
3334
DELETE_WAIT_LENGTH = 30
3435

3536
JOB_DELETE_WAIT_PERIODS = 8
36-
JOB_DELETE_WAIT_LENGTH = 30
37+
JOB_DELETE_WAIT_LENGTH = 30
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
apiVersion: services.k8s.aws/v1alpha1
2+
kind: AdoptedResource
3+
metadata:
4+
name: $ADOPTED_RESOURCE_NAME
5+
spec:
6+
aws:
7+
arn: $TARGET_RESOURCE_AWS
8+
kubernetes:
9+
group: sagemaker.services.k8s.aws
10+
kind: $RESOURCE_KIND
11+
metadata:
12+
name: $TARGET_RESOURCE_K8S

0 commit comments

Comments
 (0)