Skip to content

Commit

Permalink
Support app deploy with build service (Azure#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
smile37773 authored May 21, 2021
1 parent 266d2ab commit c5c79ed
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 34 deletions.
10 changes: 7 additions & 3 deletions src/spring-cloud/azext_spring_cloud/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,14 @@

helps['spring-cloud tanzu app deploy'] = """
type: command
short-summary: Deploy local artifact to Azure Spring Cloud Tanzu app's deployment.
short-summary: Deploy source code, Jar or War to Azure Spring Cloud Tanzu app's deployment.
examples:
- name: Deploy a Tanzu app's deployment with Jar file
text: az spring-cloud tanzu app deploy -g myresourcegroup -s myservice -n myapp --artifact-path <my-Jar>
- name: Deploy a Tanzu app's deployment with Jar or War file
text: az spring-cloud tanzu app deploy -g myresourcegroup -s myservice -n myapp --artifact-path <my-JarOrWar>
- name: Deploy a Tanzu app's deployment with source code
text: az spring-cloud tanzu app deploy -g myresourcegroup -s myservice -n myapp
- name: Deploy a Tanzu app's deployment with source code of target module
text: az spring-cloud tanzu app deploy -g myresourcegroup -s myservice -n myapp --target-module myModule
"""

helps['spring-cloud tanzu application-configuration-service'] = """
Expand Down
4 changes: 3 additions & 1 deletion src/spring-cloud/azext_spring_cloud/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ def load_arguments(self, _):
c.argument('patterns', type=str, help='Collection of patterns separate with \',\'', validator=validate_tanzu_configuration_service_patterns)

with self.argument_context('spring-cloud tanzu app deploy') as c:
c.argument('artifact-path', help='artifact path to deploy to this deployment.')
c.argument('artifact-path', help='artifact path to deploy to this deployment')
c.argument(
'target_module', help='Child module to be deployed, required for multiple jar packages built from source code.')

with self.argument_context('spring-cloud tanzu application-configuration-service') as c:
c.argument('service', service_name_type)
Expand Down
4 changes: 4 additions & 0 deletions src/spring-cloud/azext_spring_cloud/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@

logger = get_logger(__name__)

def _get_tanzu_upload_local_file():
file_path = os.path.join(tempfile.gettempdir(), 'build_archive_{}.tar.gz'.format(uuid.uuid4().hex))
_pack_source_code(os.getcwd(), file_path)
return file_path

def _get_upload_local_file(runtime_version, artifact_path=None):
file_path = artifact_path
Expand Down
54 changes: 50 additions & 4 deletions src/spring-cloud/azext_spring_cloud/tanzu.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
from knack.log import get_logger
from msrestazure.azure_exceptions import CloudError
from .vendored_sdks.appplatform.v2021_03_01_preview import models
from ._utils import _get_tanzu_upload_local_file, get_azure_files_info
from .azure_storage_file import FileService
from msrestazure.tools import parse_resource_id

logger = get_logger(__name__)
DEFAULT_DEPLOYMENT_NAME = "default"
Expand Down Expand Up @@ -162,8 +165,7 @@ def tanzu_app_stop(cmd, client, resource_group, service, name, no_wait=None):
deployment_name = _assert_deployment_exist_and_retrieve_name(cmd, client, resource_group, service, name)
return client.deployments.stop(resource_group, service, name, deployment_name)


def tanzu_app_deploy(cmd, client, resource_group, service, name, artifact_path, no_wait=None):
def tanzu_app_deploy(cmd, client, resource_group, service, name, artifact_path=None, target_module=None, no_wait=None):
'''tanzu_app_deploy
Deploy artifact to deployment under the existing app.
Throw exception if app or deployment not found.
Expand All @@ -175,8 +177,52 @@ def tanzu_app_deploy(cmd, client, resource_group, service, name, artifact_path,
5. Send build result id to deployment
'''
deployment_name = _assert_deployment_exist_and_retrieve_name(cmd, client, resource_group, service, name)
# todo (qingyi)
build_result_id = ''
# get upload url
upload_url = None
relative_path = None
logger.warning("[1/5] Requesting for upload URL")
try:
response = client.build_service.get_upload_url(resource_group, service)
upload_url = response.upload_url
relative_path = response.relative_path
except (AttributeError, CloudError) as e:
raise CLIError("Failed to get a SAS URL to upload context. Error: {}".format(e.message))
# upload file
if not upload_url:
raise CLIError("Failed to get a SAS URL to upload context.")
account_name, endpoint_suffix, share_name, relative_name, sas_token = get_azure_files_info(upload_url)
logger.warning("[2/5] Uploading package to blob")
path = None
if artifact_path:
path = artifact_path
else:
path = _get_tanzu_upload_local_file()
file_service = FileService(account_name, sas_token=sas_token, endpoint_suffix=endpoint_suffix)
file_service.create_file_from_path(share_name, None, relative_name, path)
properties = models.BuildProperties(
builder="default-tanzu-builder",
name=name,
relative_path=relative_path,
env={"BP_JVM_VERSION": "8.*", "BP_MAVEN_BUILT_MODULE": target_module} if target_module else None)
# create or update build
logger.warning("[3/5] Creating or Updating build '{}' (this operation can take a while to complete)".format(name))
build_result_id = None
try:
response = client.build_service.create_or_update_build(resource_group, service, name, properties)
build_result_id = response.properties.triggered_build_result.id
build_result_name = parse_resource_id(build_result_id)["resource_name"]
except (AttributeError, CloudError) as e:
raise CLIError("Failed to create or update a build. Error: {}".format(e.message))
# get build result
logger.warning("[4/5] Waiting build finish")
result = client.build_service.get_build_result(resource_group, service, name, build_result_name)
while result.properties.status == "Building" or result.properties.status == "Queuing":
sleep(5)
result = client.build_service.get_build_result(resource_group, service, name, build_result_name)
if result.properties.status != "Succeeded":
raise CLIError("Failed to get a successful build result.")

logger.warning("[5/5] Deploying build result to deployment {} under app {}".format(deployment_name, name))
return client.deployments.deploy(resource_group, service, name, deployment_name, build_result_id=build_result_id)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,10 @@ class BuildContainerImageReference(Model):
"""

_attribute_map = {
'acr_name': {'key': 'AcrName', 'type': 'str'},
'image_name': {'key': 'ImageName', 'type': 'str'},
'digest': {'key': 'Digest', 'type': 'str'},
'tag': {'key': 'Tag', 'type': 'str'},
'acr_name': {'key': 'acrName', 'type': 'str'},
'image_name': {'key': 'imageName', 'type': 'str'},
'digest': {'key': 'digest', 'type': 'str'},
'tag': {'key': 'tag', 'type': 'str'},
}

def __init__(self, **kwargs):
Expand Down Expand Up @@ -251,11 +251,11 @@ class BuildProperties(Model):
"""

_attribute_map = {
'builder': {'key': 'Builder', 'type': 'str'},
'name': {'key': 'Name', 'type': 'str'},
'relative_path': {'key': 'RelativePath', 'type': 'str'},
'env': {'key': 'Env', 'type': '{str}'},
'triggered_build_result': {'key': 'TriggeredBuildResult', 'type': 'TriggeredBuildResult'},
'builder': {'key': 'builder', 'type': 'str'},
'name': {'key': 'name', 'type': 'str'},
'relative_path': {'key': 'relativePath', 'type': 'str'},
'env': {'key': 'env', 'type': '{str}'},
'triggered_build_result': {'key': 'triggeredBuildResult', 'type': 'TriggeredBuildResult'},
}

def __init__(self, **kwargs):
Expand Down Expand Up @@ -325,9 +325,9 @@ class BuildResultProperties(Model):
}

_attribute_map = {
'name': {'key': 'Name', 'type': 'str'},
'status': {'key': 'Status', 'type': 'str'},
'container_image_reference': {'key': 'ContainerImageReference', 'type': 'BuildContainerImageReference'},
'name': {'key': 'name', 'type': 'str'},
'status': {'key': 'status', 'type': 'str'},
'container_image_reference': {'key': 'containerImageReference', 'type': 'BuildContainerImageReference'},
}

def __init__(self, **kwargs):
Expand Down Expand Up @@ -934,7 +934,7 @@ class TriggeredBuildResult(Model):
"""

_attribute_map = {
'id': {'key': 'Id', 'type': 'str'},
'id': {'key': 'id', 'type': 'str'},
}

def __init__(self, **kwargs):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,10 @@ class BuildContainerImageReference(Model):
"""

_attribute_map = {
'acr_name': {'key': 'AcrName', 'type': 'str'},
'image_name': {'key': 'ImageName', 'type': 'str'},
'digest': {'key': 'Digest', 'type': 'str'},
'tag': {'key': 'Tag', 'type': 'str'},
'acr_name': {'key': 'acrName', 'type': 'str'},
'image_name': {'key': 'imageName', 'type': 'str'},
'digest': {'key': 'digest', 'type': 'str'},
'tag': {'key': 'tag', 'type': 'str'},
}

def __init__(self, *, acr_name: str=None, image_name: str=None, digest: str=None, tag: str=None, **kwargs) -> None:
Expand Down Expand Up @@ -251,11 +251,11 @@ class BuildProperties(Model):
"""

_attribute_map = {
'builder': {'key': 'Builder', 'type': 'str'},
'name': {'key': 'Name', 'type': 'str'},
'relative_path': {'key': 'RelativePath', 'type': 'str'},
'env': {'key': 'Env', 'type': '{str}'},
'triggered_build_result': {'key': 'TriggeredBuildResult', 'type': 'TriggeredBuildResult'},
'builder': {'key': 'builder', 'type': 'str'},
'name': {'key': 'name', 'type': 'str'},
'relative_path': {'key': 'relativePath', 'type': 'str'},
'env': {'key': 'env', 'type': '{str}'},
'triggered_build_result': {'key': 'triggeredBuildResult', 'type': 'TriggeredBuildResult'},
}

def __init__(self, *, builder: str=None, name: str=None, relative_path: str=None, env=None, triggered_build_result=None, **kwargs) -> None:
Expand Down Expand Up @@ -325,9 +325,9 @@ class BuildResultProperties(Model):
}

_attribute_map = {
'name': {'key': 'Name', 'type': 'str'},
'status': {'key': 'Status', 'type': 'str'},
'container_image_reference': {'key': 'ContainerImageReference', 'type': 'BuildContainerImageReference'},
'name': {'key': 'name', 'type': 'str'},
'status': {'key': 'status', 'type': 'str'},
'container_image_reference': {'key': 'containerImageReference', 'type': 'BuildContainerImageReference'},
}

def __init__(self, *, name: str=None, container_image_reference=None, **kwargs) -> None:
Expand Down Expand Up @@ -934,7 +934,7 @@ class TriggeredBuildResult(Model):
"""

_attribute_map = {
'id': {'key': 'Id', 'type': 'str'},
'id': {'key': 'id', 'type': 'str'},
}

def __init__(self, *, id: str=None, **kwargs) -> None:
Expand Down

0 comments on commit c5c79ed

Please sign in to comment.