Skip to content

Commit cf51123

Browse files
committed
Merge commit 'fa32b6a37eca61a9eae08a8ac71ddd525b06d5b3' from main
2 parents 6e61338 + fa32b6a commit cf51123

File tree

16 files changed

+242
-100
lines changed

16 files changed

+242
-100
lines changed

ads/common/oci_logging.py

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ def _search_and_format(
533533
time_end: datetime.datetime = None,
534534
limit: int = LOG_RECORDS_LIMIT,
535535
sort_by: str = "datetime",
536-
sort_order: str = SortOrder.DESC,
536+
sort_order: str = SortOrder.ASC,
537537
log_filter: str = None,
538538
):
539539
"""Returns the formatted log records.
@@ -550,7 +550,7 @@ def _search_and_format(
550550
Maximum number of records to be returned.
551551
sort_by: (str, optional). Defaults to "datetime"
552552
The field for sorting the logs.
553-
sort_order: (str, optional). Defaults to "DESC".
553+
sort_order: (str, optional). Defaults to "ASC".
554554
The sort order for the log records. Can be "ASC" or "DESC".
555555
log_filter : (str, optional). Defaults to None.
556556
Expression for filtering the logs.
@@ -574,8 +574,8 @@ def _search_and_format(
574574
sort_order=sort_order,
575575
log_filter=log_filter,
576576
)
577-
logs = sorted((log.data for log in logs), key=lambda x: x.get("datetime"))
578-
logs = [log.get("logContent", {}) for log in logs]
577+
578+
logs = [log.data.get("logContent", {}) for log in logs]
579579
return [
580580
{
581581
"id": log.get("id"),
@@ -617,7 +617,7 @@ def tail(
617617
return self._search_and_format(
618618
source=source,
619619
limit=limit,
620-
sort_order=SortOrder.DESC,
620+
sort_order=SortOrder.ASC,
621621
time_start=time_start,
622622
log_filter=log_filter,
623623
)
@@ -808,7 +808,7 @@ def stream(
808808
logs = self._search_and_format(
809809
source=source,
810810
limit=None,
811-
sort_order=SortOrder.DESC,
811+
sort_order=SortOrder.ASC,
812812
time_start=time_start,
813813
log_filter=log_filter,
814814
)
@@ -858,7 +858,7 @@ def tail(
858858
self._search_and_format(
859859
source=source,
860860
limit=limit,
861-
sort_order=SortOrder.DESC,
861+
sort_order=SortOrder.ASC,
862862
time_start=time_start,
863863
log_filter=log_filter,
864864
)
@@ -927,7 +927,7 @@ def search(
927927
time_end: datetime.datetime = None,
928928
limit: int = None,
929929
sort_by: str = "datetime",
930-
sort_order: str = SortOrder.DESC,
930+
sort_order: str = SortOrder.ASC,
931931
log_filter: str = None,
932932
) -> List[oci.loggingsearch.models.SearchResult]:
933933
"""Searches raw logs.
@@ -951,7 +951,7 @@ def search(
951951
Defaults to "datetime"
952952
sort_order : str, optional.
953953
The sort order for the log records. Can be "ASC" or "DESC".
954-
Defaults to "DESC".
954+
Defaults to "ASC".
955955
log_filter : str, optional
956956
Expression for filtering the logs. This will be the WHERE clause of the query.
957957
Defaults to None.
@@ -979,7 +979,7 @@ def _search_and_format(
979979
time_end: datetime.datetime = None,
980980
limit: int = LOG_RECORDS_LIMIT,
981981
sort_by: str = "datetime",
982-
sort_order: str = SortOrder.DESC,
982+
sort_order: str = SortOrder.ASC,
983983
log_filter: str = None,
984984
need_format: bool = True,
985985
) -> List[Union[oci.loggingsearch.models.SearchResult, dict]]:
@@ -1005,7 +1005,7 @@ def _search_and_format(
10051005
Defaults to "datetime"
10061006
sort_order : str, optional.
10071007
The sort order for the log records. Can be "ASC" or "DESC".
1008-
Defaults to "DESC".
1008+
Defaults to "ASC".
10091009
log_filter : str, optional
10101010
Expression for filtering the logs. This will be the WHERE clause of the query.
10111011
Defaults to None.
@@ -1039,12 +1039,6 @@ def _search_and_format(
10391039
)
10401040
)
10411041

1042-
# _collect_logs returns a list of either dict or oci.loggingsearch.models.SearchResult
1043-
# objects based on `need_format` parameter, so below there are two cases for log sorting.
1044-
if need_format:
1045-
batch_logs.sort(key=lambda x: x.get("datetime"))
1046-
else:
1047-
batch_logs.sort(key=lambda x: x.data.get("datetime"))
10481042
if limit and len(batch_logs) > limit:
10491043
batch_logs = batch_logs[:limit]
10501044
return batch_logs
@@ -1057,7 +1051,7 @@ def _collect_logs(
10571051
time_end: datetime.datetime = None,
10581052
limit: int = LOG_RECORDS_LIMIT,
10591053
sort_by: str = "datetime",
1060-
sort_order: str = SortOrder.DESC,
1054+
sort_order: str = SortOrder.ASC,
10611055
log_filter: str = None,
10621056
need_format: bool = True,
10631057
) -> List[Union[oci.loggingsearch.models.SearchResult, dict]]:
@@ -1085,7 +1079,7 @@ def _collect_logs(
10851079
Defaults to "datetime"
10861080
sort_order : str, optional.
10871081
The sort order for the log records. Can be "ASC" or "DESC".
1088-
Defaults to "DESC".
1082+
Defaults to "ASC".
10891083
log_filter : str, optional
10901084
Expression for filtering the logs. This will be the WHERE clause of the query.
10911085
Defaults to None.

ads/common/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
MAX_DISPLAY_VALUES = 10
7272

7373
# par link of the index json file.
74-
PAR_LINK = "https://objectstorage.us-ashburn-1.oraclecloud.com/p/Ri7zFc_h91sxMdgnza9Qnqw3Ina8hf8wzDvEpAnUXMDOnUR1U1fpsaBUjUfgPgIq/n/ociodscdev/b/service-conda-packs/o/service_pack/index.json"
74+
PAR_LINK = "https://objectstorage.us-ashburn-1.oraclecloud.com/p/WyjtfVIG0uda-P3-2FmAfwaLlXYQZbvPZmfX1qg0-sbkwEQO6jpwabGr2hMDBmBp/n/ociodscdev/b/service-conda-packs/o/service_pack/index.json"
7575

7676
random_state = 42
7777
test_size = 0.3

ads/model/runtime/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def _get_index_json_through_bucket(
111111
bucketname: str
112112
The Object Storage bucketname.
113113
auth: (Dict, optional). Defaults to None.
114-
The default authetication is set using `ads.set_auth` API. If you need to override the
114+
The default authentication is set using `ads.set_auth` API. If you need to override the
115115
default, use the `ads.common.auth.api_keys` or `ads.common.auth.resource_principal` to create appropriate
116116
authentication signer and kwargs required to instantiate IdentityClient object.
117117
@@ -147,7 +147,7 @@ def get_service_packs(
147147
bucketname: str
148148
bucketname of the service pack.
149149
auth: (Dict, optional). Defaults to None.
150-
The default authetication is set using `ads.set_auth` API. If you need to override the
150+
The default authentication is set using `ads.set_auth` API. If you need to override the
151151
default, use the `ads.common.auth.api_keys` or `ads.common.auth.resource_principal` to create appropriate
152152
authentication signer and kwargs required to instantiate IdentityClient object.
153153

ads/opctl/conda/cmds.py

Lines changed: 68 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
from ads.opctl.config.base import ConfigProcessor
4747
from ads.opctl.config.merger import ConfigMerger
4848
from ads.opctl.conda.multipart_uploader import MultiPartUploader
49+
import tempfile
4950

5051

5152
def _fetch_manifest_template() -> Dict:
@@ -108,6 +109,7 @@ def _create(
108109
conda_pack_folder: str,
109110
gpu: bool,
110111
overwrite: bool,
112+
prepare_publish: bool = False,
111113
) -> str:
112114
"""Create a conda pack given an environment yaml file under conda pack folder specified.
113115
@@ -123,6 +125,8 @@ def _create(
123125
whether to build against GPU image
124126
overwrite : bool
125127
whether to overwrite existing pack of the same slug
128+
prepare_pubish : bool
129+
whether to create conda pack archive after conda pack is created
126130
127131
Raises
128132
------
@@ -180,6 +184,11 @@ def _create(
180184
manifest["manifest"]["manifest_version"] = "1.0"
181185

182186
logger.info(f"Creating conda environment {slug}")
187+
conda_dep = None
188+
with open(env_file) as mfile:
189+
conda_dep = yaml.safe_load(mfile.read())
190+
conda_dep["manifest"] = manifest["manifest"]
191+
183192
if is_in_notebook_session() or NO_CONTAINER:
184193
command = f"conda env create --prefix {pack_folder_path} --file {os.path.abspath(os.path.expanduser(env_file))}"
185194
run_command(command, shell=True)
@@ -191,35 +200,56 @@ def _create(
191200
)
192201

193202
create_command = f"conda env create --prefix {docker_pack_folder_path} --file {docker_env_file_path}"
194-
203+
195204
volumes = {
196205
pack_folder_path: {"bind": docker_pack_folder_path},
197206
os.path.abspath(os.path.expanduser(env_file)): {
198207
"bind": docker_env_file_path
199208
},
209+
200210
}
211+
201212
if gpu:
202213
image = ML_JOB_GPU_IMAGE
203214
else:
204215
image = ML_JOB_IMAGE
205216
try:
206-
run_container(
207-
image=image, bind_volumes=volumes, env_vars={}, command=create_command
208-
)
217+
if prepare_publish:
218+
tmp_file = tempfile.NamedTemporaryFile(suffix=".yaml")
219+
# Save the manifest in the temp file that can be mounted inside the container so that archiving will work
220+
with open(tmp_file.name, 'w') as f:
221+
yaml.safe_dump(conda_dep, f)
222+
223+
pack_script = os.path.join(os.path.dirname(os.path.abspath(__file__)), "pack.py")
224+
pack_command = f"python {os.path.join(DEFAULT_IMAGE_HOME_DIR, 'pack.py')} --conda-path {docker_pack_folder_path} --manifest-location {os.path.join(DEFAULT_IMAGE_HOME_DIR, 'manifest.yaml')}"
225+
226+
# add pack script and manifest file to the mount so that archive can be created in the same container run
227+
condapack_script = {
228+
pack_script: {"bind": os.path.join(DEFAULT_IMAGE_HOME_DIR, "pack.py")},
229+
tmp_file.name: {"bind": os.path.join(DEFAULT_IMAGE_HOME_DIR, "manifest.yaml")}
230+
}
231+
volumes = {**volumes, **condapack_script} # | not supported in python 3.8
232+
233+
run_container(
234+
image=image, bind_volumes=volumes, entrypoint="/bin/bash -c ", env_vars={}, command=f" '{create_command} && {pack_command}'"
235+
)
236+
else:
237+
run_container(
238+
image=image, bind_volumes=volumes, env_vars={}, command=create_command
239+
)
209240
except Exception:
210241
if os.path.exists(pack_folder_path):
211242
shutil.rmtree(pack_folder_path)
212243
raise RuntimeError(f"Could not create environment {slug}.")
213244

214-
conda_dep = None
215-
with open(env_file) as mfile:
216-
conda_dep = yaml.safe_load(mfile.read())
217-
conda_dep["manifest"] = manifest["manifest"]
218-
with open(f"{os.path.join(pack_folder_path, slug)}_manifest.yaml", "w") as mfile:
245+
# Save the manifest file inside the host machine, where the conda environment is saved.
246+
manifest_location = f"{os.path.join(pack_folder_path, slug)}_manifest.yaml"
247+
with open(manifest_location, "w") as mfile:
219248
yaml.safe_dump(conda_dep, mfile)
220249

221250
logger.info(f"Environment `{slug}` setup complete.")
222251
print(f"Pack {slug} created under {pack_folder_path}.")
252+
223253
return slug
224254

225255

@@ -467,6 +497,7 @@ def _install(
467497
def publish(**kwargs) -> None:
468498
p = ConfigProcessor().step(ConfigMerger, **kwargs)
469499
exec_config = p.config["execution"]
500+
skip_archive = False
470501
if exec_config.get("environment_file", None):
471502
name = _get_name(exec_config.get("name"), exec_config.get("environment_file"))
472503
slug = _create(
@@ -476,7 +507,9 @@ def publish(**kwargs) -> None:
476507
conda_pack_folder=exec_config["conda_pack_folder"],
477508
gpu=exec_config.get("gpu", False),
478509
overwrite=exec_config["overwrite"],
510+
prepare_publish=True
479511
)
512+
skip_archive = True # The conda pack archive is already created during create process.
480513
else:
481514
slug = exec_config.get("slug")
482515
if not slug:
@@ -493,9 +526,10 @@ def publish(**kwargs) -> None:
493526
oci_profile=exec_config.get("oci_profile"),
494527
overwrite=exec_config["overwrite"],
495528
auth_type=exec_config["auth"],
529+
skip_archive=skip_archive
496530
)
497531

498-
532+
499533
def _publish(
500534
conda_slug: str,
501535
conda_uri_prefix: str,
@@ -504,6 +538,7 @@ def _publish(
504538
oci_profile: str,
505539
overwrite: bool,
506540
auth_type: str,
541+
skip_archive: bool = False
507542
) -> None:
508543
"""Publish a local conda pack to object storage location
509544
@@ -579,29 +614,30 @@ def _publish(
579614
publish_slug = "_".join(ans.lower().split(" "))
580615

581616
pack_script = os.path.join(os.path.dirname(os.path.abspath(__file__)), "pack.py")
582-
if is_in_notebook_session() or NO_CONTAINER:
583-
command = f"python {pack_script} {pack_folder_path}"
584-
run_command(command, shell=True)
585-
else:
586-
volumes = {
587-
pack_folder_path: {
588-
"bind": os.path.join(DEFAULT_IMAGE_HOME_DIR, conda_slug)
589-
},
590-
pack_script: {"bind": os.path.join(DEFAULT_IMAGE_HOME_DIR, "pack.py")},
591-
}
592-
command = f"python {os.path.join(DEFAULT_IMAGE_HOME_DIR, 'pack.py')} {os.path.join(DEFAULT_IMAGE_HOME_DIR, conda_slug)}"
593-
gpu = env["manifest"]["arch_type"] == "GPU"
594-
_check_job_image_exists(gpu)
595-
if gpu:
596-
image = ML_JOB_GPU_IMAGE
617+
if not skip_archive:
618+
if is_in_notebook_session() or NO_CONTAINER:
619+
command = f"python {pack_script} --conda-path {pack_folder_path}"
620+
run_command(command, shell=True)
597621
else:
598-
image = ML_JOB_IMAGE
599-
try:
600-
run_container(
601-
image=image, bind_volumes=volumes, env_vars={}, command=command
602-
)
603-
except Exception:
604-
raise RuntimeError(f"Could not pack environment {conda_slug}.")
622+
volumes = {
623+
pack_folder_path: {
624+
"bind": os.path.join(DEFAULT_IMAGE_HOME_DIR, conda_slug)
625+
},
626+
pack_script: {"bind": os.path.join(DEFAULT_IMAGE_HOME_DIR, "pack.py")},
627+
}
628+
command = f"python {os.path.join(DEFAULT_IMAGE_HOME_DIR, 'pack.py')} --conda-path {os.path.join(DEFAULT_IMAGE_HOME_DIR, conda_slug)}"
629+
gpu = env["manifest"]["arch_type"] == "GPU"
630+
_check_job_image_exists(gpu)
631+
if gpu:
632+
image = ML_JOB_GPU_IMAGE
633+
else:
634+
image = ML_JOB_IMAGE
635+
try:
636+
run_container(
637+
image=image, bind_volumes=volumes, env_vars={}, command=command
638+
)
639+
except Exception:
640+
raise RuntimeError(f"Could not pack environment {conda_slug}.")
605641

606642
pack_file = os.path.join(pack_folder_path, f"{conda_slug}.tar.gz")
607643
if not os.path.exists(pack_file):

ads/opctl/conda/pack.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,14 @@
1616
import conda_pack
1717

1818
import yaml
19+
import argparse
1920

2021

21-
def main(pack_folder_path):
22+
def main(pack_folder_path, manifest_file=None):
2223
slug = os.path.basename(pack_folder_path)
23-
manifest_path = glob.glob(os.path.join(pack_folder_path, "*_manifest.yaml"))[0]
24+
manifest_path = (
25+
manifest_file or glob.glob(os.path.join(pack_folder_path, "*_manifest.yaml"))[0]
26+
)
2427
with open(manifest_path) as f:
2528
env = yaml.safe_load(f.read())
2629

@@ -59,8 +62,10 @@ def main(pack_folder_path):
5962
raise RuntimeError(
6063
"Error creating the pack file using `conda_pack.pack()`."
6164
)
65+
print(f"Copy {pack_file} to {pack_folder_path}")
6266
shutil.copy(pack_file, pack_folder_path)
6367
file_path = os.path.join(pack_folder_path, os.path.basename(pack_file))
68+
print(f"Pack built at {file_path}")
6469
print(
6570
f"changing permission for {file_path}",
6671
flush=True,
@@ -69,4 +74,14 @@ def main(pack_folder_path):
6974

7075

7176
if __name__ == "__main__":
72-
main(sys.argv[1])
77+
parser = argparse.ArgumentParser(
78+
prog="Prepare conda archive",
79+
description="Uses conda_pack library to pack the conda environment.",
80+
)
81+
parser.add_argument("--conda-path", type=str, help="Path to the conda environment")
82+
parser.add_argument(
83+
"--manifest-location", type=str, default=None, help="Path to manifest location"
84+
)
85+
args = parser.parse_args()
86+
87+
main(args.conda_path, args.manifest_location)

0 commit comments

Comments
 (0)