jac-scale 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jac_scale/__init__.py +0 -0
- jac_scale/abstractions/config/app_config.jac +30 -0
- jac_scale/abstractions/config/base_config.jac +26 -0
- jac_scale/abstractions/database_provider.jac +51 -0
- jac_scale/abstractions/deployment_target.jac +64 -0
- jac_scale/abstractions/image_registry.jac +54 -0
- jac_scale/abstractions/logger.jac +20 -0
- jac_scale/abstractions/models/deployment_result.jac +27 -0
- jac_scale/abstractions/models/resource_status.jac +38 -0
- jac_scale/config_loader.jac +31 -0
- jac_scale/context.jac +14 -0
- jac_scale/factories/database_factory.jac +43 -0
- jac_scale/factories/deployment_factory.jac +43 -0
- jac_scale/factories/registry_factory.jac +32 -0
- jac_scale/factories/utility_factory.jac +34 -0
- jac_scale/impl/config_loader.impl.jac +131 -0
- jac_scale/impl/context.impl.jac +24 -0
- jac_scale/impl/memory_hierarchy.main.impl.jac +63 -0
- jac_scale/impl/memory_hierarchy.mongo.impl.jac +239 -0
- jac_scale/impl/memory_hierarchy.redis.impl.jac +186 -0
- jac_scale/impl/serve.impl.jac +1785 -0
- jac_scale/jserver/__init__.py +0 -0
- jac_scale/jserver/impl/jfast_api.impl.jac +731 -0
- jac_scale/jserver/impl/jserver.impl.jac +79 -0
- jac_scale/jserver/jfast_api.jac +162 -0
- jac_scale/jserver/jserver.jac +101 -0
- jac_scale/memory_hierarchy.jac +138 -0
- jac_scale/plugin.jac +218 -0
- jac_scale/plugin_config.jac +175 -0
- jac_scale/providers/database/kubernetes_mongo.jac +137 -0
- jac_scale/providers/database/kubernetes_redis.jac +110 -0
- jac_scale/providers/registry/dockerhub.jac +64 -0
- jac_scale/serve.jac +118 -0
- jac_scale/targets/kubernetes/kubernetes_config.jac +215 -0
- jac_scale/targets/kubernetes/kubernetes_target.jac +841 -0
- jac_scale/targets/kubernetes/utils/kubernetes_utils.impl.jac +519 -0
- jac_scale/targets/kubernetes/utils/kubernetes_utils.jac +85 -0
- jac_scale/tests/__init__.py +0 -0
- jac_scale/tests/conftest.py +29 -0
- jac_scale/tests/fixtures/test_api.jac +159 -0
- jac_scale/tests/fixtures/todo_app.jac +68 -0
- jac_scale/tests/test_abstractions.py +88 -0
- jac_scale/tests/test_deploy_k8s.py +265 -0
- jac_scale/tests/test_examples.py +484 -0
- jac_scale/tests/test_factories.py +149 -0
- jac_scale/tests/test_file_upload.py +444 -0
- jac_scale/tests/test_k8s_utils.py +156 -0
- jac_scale/tests/test_memory_hierarchy.py +247 -0
- jac_scale/tests/test_serve.py +1835 -0
- jac_scale/tests/test_sso.py +711 -0
- jac_scale/utilities/loggers/standard_logger.jac +40 -0
- jac_scale/utils.jac +16 -0
- jac_scale-0.1.1.dist-info/METADATA +658 -0
- jac_scale-0.1.1.dist-info/RECORD +57 -0
- jac_scale-0.1.1.dist-info/WHEEL +5 -0
- jac_scale-0.1.1.dist-info/entry_points.txt +3 -0
- jac_scale-0.1.1.dist-info/top_level.txt +1 -0
jac_scale/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Application configuration model for deployments."""
|
|
2
|
+
import from pathlib { Path }
|
|
3
|
+
|
|
4
|
+
"""Configuration for an application deployment."""
|
|
5
|
+
class AppConfig {
|
|
6
|
+
has code_folder: str,
|
|
7
|
+
file_name: str = 'none',
|
|
8
|
+
build: bool = False,
|
|
9
|
+
app_name: (str | None) = None,
|
|
10
|
+
testing: bool = False;
|
|
11
|
+
|
|
12
|
+
def init(
|
|
13
|
+
self: AppConfig,
|
|
14
|
+
code_folder: str,
|
|
15
|
+
file_name: str = 'none',
|
|
16
|
+
build: bool = False,
|
|
17
|
+
app_name: (str | None) = None,
|
|
18
|
+
testing: bool = False
|
|
19
|
+
) -> None {
|
|
20
|
+
self.code_folder = code_folder;
|
|
21
|
+
self.file_name = file_name;
|
|
22
|
+
self.build = build;
|
|
23
|
+
self.app_name = app_name;
|
|
24
|
+
self.testing = testing;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
def get_code_path(self: AppConfig) -> Path {
|
|
28
|
+
return Path(self.code_folder);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Base configuration class for jac_scale."""
|
|
2
|
+
import from typing { Any }
|
|
3
|
+
|
|
4
|
+
"""Base configuration class that all target-specific configs should inherit from."""
|
|
5
|
+
class BaseConfig {
|
|
6
|
+
has app_name: str,
|
|
7
|
+
namespace: str = 'default';
|
|
8
|
+
|
|
9
|
+
def init(
|
|
10
|
+
self: BaseConfig, app_name: str = 'jaseci', namespace: str = 'default'
|
|
11
|
+
) -> None {
|
|
12
|
+
self.app_name = app_name;
|
|
13
|
+
self.namespace = namespace;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
def to_dict(self: BaseConfig) -> dict[str, Any] {
|
|
17
|
+
return {'app_name': self.app_name, 'namespace': self.namespace};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static def from_dict(cls: type, config: dict[str, Any]) -> BaseConfig {
|
|
21
|
+
return cls(
|
|
22
|
+
app_name=config.get('app_name', 'jaseci'),
|
|
23
|
+
namespace=config.get('namespace', 'default')
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""Base database provider abstraction for jac_scale.
|
|
2
|
+
|
|
3
|
+
All database provider implementations should inherit from this class.
|
|
4
|
+
"""
|
|
5
|
+
import from typing { Any }
|
|
6
|
+
|
|
7
|
+
"""Base class for all database provider implementations."""
|
|
8
|
+
class DatabaseProvider {
|
|
9
|
+
"""Deploy the database service.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
config: Database-specific configuration
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
Dictionary with deployment information (e.g., service name, connection details)
|
|
16
|
+
"""
|
|
17
|
+
def deploy(self: DatabaseProvider, config: dict[str, Any]) -> dict[str, Any];
|
|
18
|
+
|
|
19
|
+
"""Get the connection string for the database.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
Connection string/URI for the database
|
|
23
|
+
"""
|
|
24
|
+
def get_connection_string(self: DatabaseProvider) -> str;
|
|
25
|
+
|
|
26
|
+
"""Check if the database is available/ready.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
True if database is available, False otherwise
|
|
30
|
+
"""
|
|
31
|
+
def is_available(self: DatabaseProvider) -> bool;
|
|
32
|
+
|
|
33
|
+
"""Clean up database resources.
|
|
34
|
+
|
|
35
|
+
This should remove all resources created by deploy().
|
|
36
|
+
"""
|
|
37
|
+
def cleanup(self: DatabaseProvider) -> None;
|
|
38
|
+
|
|
39
|
+
"""Get the init container configuration for the database.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
app_name: Name of the application
|
|
43
|
+
wait_image: Docker image to use for the wait container
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
Dictionary representing the init container, or None if not applicable.
|
|
47
|
+
"""
|
|
48
|
+
def get_init_container(
|
|
49
|
+
self: DatabaseProvider, app_name: str, wait_image: str
|
|
50
|
+
) -> (dict[(str, Any)] | None);
|
|
51
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""Base deployment target abstraction for jac_scale.
|
|
2
|
+
|
|
3
|
+
All deployment target implementations should inherit from this class.
|
|
4
|
+
"""
|
|
5
|
+
import from jac_scale.abstractions.config.app_config { AppConfig }
|
|
6
|
+
import from jac_scale.abstractions.config.base_config { BaseConfig }
|
|
7
|
+
import from jac_scale.abstractions.models.deployment_result { DeploymentResult }
|
|
8
|
+
import from jac_scale.abstractions.models.resource_status { ResourceStatusInfo }
|
|
9
|
+
import from jac_scale.abstractions.database_provider { DatabaseProvider }
|
|
10
|
+
import from jac_scale.abstractions.image_registry { ImageRegistry }
|
|
11
|
+
import from jac_scale.abstractions.logger { Logger }
|
|
12
|
+
|
|
13
|
+
"""Base class for all deployment target implementations."""
|
|
14
|
+
class DeploymentTarget {
|
|
15
|
+
has config: BaseConfig,
|
|
16
|
+
logger: (Logger | None) = None,
|
|
17
|
+
database_providers: list[DatabaseProvider] = [],
|
|
18
|
+
image_registry: (ImageRegistry | None) = None;
|
|
19
|
+
|
|
20
|
+
"""Deploy an application.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
app_config: Application configuration
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
Deployment result with success status and service URL
|
|
27
|
+
"""
|
|
28
|
+
def deploy(self: DeploymentTarget, app_config: AppConfig) -> DeploymentResult;
|
|
29
|
+
|
|
30
|
+
"""Destroy/remove a deployed application.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
app_name: Name of the application to destroy
|
|
34
|
+
"""
|
|
35
|
+
def destroy(self: DeploymentTarget, app_name: str) -> None;
|
|
36
|
+
|
|
37
|
+
"""Get the status of a deployed application.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
app_name: Name of the application
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
Resource status information
|
|
44
|
+
"""
|
|
45
|
+
def get_status(self: DeploymentTarget, app_name: str) -> ResourceStatusInfo;
|
|
46
|
+
|
|
47
|
+
"""Scale an application to a specific number of replicas.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
app_name: Name of the application
|
|
51
|
+
replicas: Number of replicas desired
|
|
52
|
+
"""
|
|
53
|
+
def scale(self: DeploymentTarget, app_name: str, replicas: int) -> None;
|
|
54
|
+
|
|
55
|
+
"""Get the service URL for a deployed application.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
app_name: Name of the application
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
Service URL or None if not available
|
|
62
|
+
"""
|
|
63
|
+
def get_service_url(self: DeploymentTarget, app_name: str) -> (str | None);
|
|
64
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Base image registry abstraction for jac_scale.
|
|
2
|
+
|
|
3
|
+
All image registry implementations should inherit from this class.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
"""Base class for all image registry implementations."""
|
|
7
|
+
class ImageRegistry {
|
|
8
|
+
"""Build a Docker image from code folder.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
code_folder: Path to the code directory
|
|
12
|
+
image_name: Name for the image (optional)
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
Full image name/tag
|
|
16
|
+
"""
|
|
17
|
+
def build_image(
|
|
18
|
+
self: ImageRegistry, code_folder: str, image_name: (str | None) = None
|
|
19
|
+
) -> str;
|
|
20
|
+
|
|
21
|
+
"""Push an image to the registry.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
image_name: Full image name to push
|
|
25
|
+
"""
|
|
26
|
+
def push_image(self: ImageRegistry, image_name: str) -> None;
|
|
27
|
+
|
|
28
|
+
"""Get the full image URL for a given image name.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
image_name: Base image name
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
Full image URL including registry
|
|
35
|
+
"""
|
|
36
|
+
def get_image_url(self: ImageRegistry, image_name: str) -> str;
|
|
37
|
+
|
|
38
|
+
"""Build and push an image in one operation.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
code_folder: Path to the code directory
|
|
42
|
+
image_name: Name for the image (optional)
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
Full image URL
|
|
46
|
+
"""
|
|
47
|
+
def build_and_push(
|
|
48
|
+
self: ImageRegistry, code_folder: str, image_name: (str | None) = None
|
|
49
|
+
) -> str {
|
|
50
|
+
image = self.build_image(code_folder, image_name);
|
|
51
|
+
self.push_image(image);
|
|
52
|
+
return self.get_image_url(image);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Base logger abstraction for jac_scale.
|
|
2
|
+
|
|
3
|
+
All logger implementations should inherit from this class.
|
|
4
|
+
"""
|
|
5
|
+
import from typing { Any }
|
|
6
|
+
|
|
7
|
+
"""Base class for all logger implementations."""
|
|
8
|
+
class Logger {
|
|
9
|
+
"""Log an info message."""
|
|
10
|
+
def info(self: Logger, message: str, context: dict[str, Any] = {}) -> None;
|
|
11
|
+
|
|
12
|
+
"""Log an error message."""
|
|
13
|
+
def error(self: Logger, message: str, context: dict[str, Any] = {}) -> None;
|
|
14
|
+
|
|
15
|
+
"""Log a warning message."""
|
|
16
|
+
def warn(self: Logger, message: str, context: dict[str, Any] = {}) -> None;
|
|
17
|
+
|
|
18
|
+
"""Log a debug message."""
|
|
19
|
+
def debug(self: Logger, message: str, context: dict[str, Any] = {}) -> None;
|
|
20
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Deployment result model."""
|
|
2
|
+
import from typing { Any }
|
|
3
|
+
|
|
4
|
+
"""Result of a deployment operation."""
|
|
5
|
+
class DeploymentResult {
|
|
6
|
+
has success: bool,
|
|
7
|
+
service_url: (str | None) = None,
|
|
8
|
+
message: (str | None) = None,
|
|
9
|
+
details: dict[str, Any] = {};
|
|
10
|
+
|
|
11
|
+
def init(
|
|
12
|
+
self: DeploymentResult,
|
|
13
|
+
success: bool,
|
|
14
|
+
service_url: (str | None) = None,
|
|
15
|
+
message: (str | None) = None,
|
|
16
|
+
details: dict[str, Any] = {}
|
|
17
|
+
) -> None {
|
|
18
|
+
self.success = success;
|
|
19
|
+
self.service_url = service_url;
|
|
20
|
+
self.message = message;
|
|
21
|
+
self.details = details;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
def is_successful(self: DeploymentResult) -> bool {
|
|
25
|
+
return self.success;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Resource status model."""
|
|
2
|
+
import from enum { Enum }
|
|
3
|
+
|
|
4
|
+
"""Status of a deployed resource."""
|
|
5
|
+
class ResourceStatus(Enum) {
|
|
6
|
+
has UNKNOWN: str = 'unknown',
|
|
7
|
+
PENDING: str = 'pending',
|
|
8
|
+
RUNNING: str = 'running',
|
|
9
|
+
FAILED: str = 'failed',
|
|
10
|
+
STOPPED: str = 'stopped';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
"""Detailed resource status information."""
|
|
14
|
+
class ResourceStatusInfo {
|
|
15
|
+
has status: ResourceStatus,
|
|
16
|
+
replicas: int = 0,
|
|
17
|
+
ready_replicas: int = 0,
|
|
18
|
+
message: (str | None) = None;
|
|
19
|
+
|
|
20
|
+
def init(
|
|
21
|
+
self: ResourceStatusInfo,
|
|
22
|
+
status: ResourceStatus,
|
|
23
|
+
replicas: int = 0,
|
|
24
|
+
ready_replicas: int = 0,
|
|
25
|
+
message: (str | None) = None
|
|
26
|
+
) -> None {
|
|
27
|
+
self.status = status;
|
|
28
|
+
self.replicas = replicas;
|
|
29
|
+
self.ready_replicas = ready_replicas;
|
|
30
|
+
self.message = message;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
def is_ready(self: ResourceStatusInfo) -> bool {
|
|
34
|
+
return self.status == ResourceStatus.RUNNING
|
|
35
|
+
and self.replicas > 0
|
|
36
|
+
and self.ready_replicas == self.replicas;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Configuration loader for Jac Scale.
|
|
2
|
+
|
|
3
|
+
This module provides configuration access for the scale plugin.
|
|
4
|
+
Configuration is loaded from jac.toml under [plugins.scale] section.
|
|
5
|
+
|
|
6
|
+
Inherits from PluginConfigBase to eliminate boilerplate code.
|
|
7
|
+
"""
|
|
8
|
+
import from pathlib { Path }
|
|
9
|
+
import from typing { Any }
|
|
10
|
+
import from jaclang.project.plugin_config { PluginConfigBase }
|
|
11
|
+
import os;
|
|
12
|
+
|
|
13
|
+
"""Scale-specific configuration loader.
|
|
14
|
+
|
|
15
|
+
Provides access to jwt, sso, database, kubernetes, and server configuration
|
|
16
|
+
from the [plugins.scale] section of jac.toml.
|
|
17
|
+
"""
|
|
18
|
+
class JacScaleConfig(PluginConfigBase) {
|
|
19
|
+
override def get_plugin_name(self: JacScaleConfig) -> str;
|
|
20
|
+
override def get_default_config(self: JacScaleConfig) -> dict[str, Any];
|
|
21
|
+
def get_jwt_config(self: JacScaleConfig) -> dict[str, Any];
|
|
22
|
+
def get_sso_config(self: JacScaleConfig) -> dict[str, Any];
|
|
23
|
+
def get_database_config(self: JacScaleConfig) -> dict[str, Any];
|
|
24
|
+
def get_kubernetes_config(self: JacScaleConfig) -> dict[str, Any];
|
|
25
|
+
def get_server_config(self: JacScaleConfig) -> dict[str, Any];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
glob _scale_config_instance: JacScaleConfig | None = None;
|
|
29
|
+
|
|
30
|
+
def get_scale_config(project_dir: Path | None = None) -> JacScaleConfig;
|
|
31
|
+
def reset_scale_config -> None;
|
jac_scale/context.jac
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import from dataclasses { MISSING }
|
|
2
|
+
import from typing { Any }
|
|
3
|
+
import from uuid { UUID }
|
|
4
|
+
import from jaclang.pycore.constant { Constants as Con }
|
|
5
|
+
import from jaclang.runtimelib.context { ExecutionContext }
|
|
6
|
+
|
|
7
|
+
"""Jac Scale Execution Context with custom memory backend.
|
|
8
|
+
|
|
9
|
+
Storage backend is configured via environment variables (e.g., MONGODB_URI),
|
|
10
|
+
not per-context parameters.
|
|
11
|
+
"""
|
|
12
|
+
class JScaleExecutionContext(ExecutionContext) {
|
|
13
|
+
def init(self: JScaleExecutionContext) -> None;
|
|
14
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Factory for creating database providers."""
|
|
2
|
+
import from typing { Any }
|
|
3
|
+
import from jac_scale.abstractions.database_provider { DatabaseProvider }
|
|
4
|
+
import from jac_scale.abstractions.deployment_target { DeploymentTarget }
|
|
5
|
+
|
|
6
|
+
"""Factory for creating database provider instances."""
|
|
7
|
+
class DatabaseProviderFactory {
|
|
8
|
+
"""Create a database provider based on type.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
provider_type: Type of database provider ('kubernetes_mongo', 'kubernetes_redis', etc.)
|
|
12
|
+
target: Deployment target instance (for target-specific providers)
|
|
13
|
+
config: Optional provider-specific configuration
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
DatabaseProvider instance
|
|
17
|
+
|
|
18
|
+
Raises:
|
|
19
|
+
ValueError: If provider_type is not supported
|
|
20
|
+
NotImplementedError: If provider is not yet implemented
|
|
21
|
+
"""
|
|
22
|
+
static def create(
|
|
23
|
+
provider_type: str,
|
|
24
|
+
target: (DeploymentTarget | None) = None,
|
|
25
|
+
config: (dict[str, Any] | None) = None
|
|
26
|
+
) -> DatabaseProvider {
|
|
27
|
+
if provider_type == 'kubernetes_mongo' {
|
|
28
|
+
import from jac_scale.providers.database.kubernetes_mongo {
|
|
29
|
+
KubernetesMongoProvider
|
|
30
|
+
}
|
|
31
|
+
return KubernetesMongoProvider(target=target, config=config or {});
|
|
32
|
+
} elif provider_type == 'kubernetes_redis' {
|
|
33
|
+
import from jac_scale.providers.database.kubernetes_redis {
|
|
34
|
+
KubernetesRedisProvider
|
|
35
|
+
}
|
|
36
|
+
return KubernetesRedisProvider(target=target, config=config or {});
|
|
37
|
+
} elif provider_type == 'aws_documentdb' {
|
|
38
|
+
raise NotImplementedError("AWS DocumentDB provider not yet implemented") ;
|
|
39
|
+
} else {
|
|
40
|
+
raise ValueError(f"Unsupported database provider type: {provider_type}") ;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Factory for creating deployment targets."""
|
|
2
|
+
import from typing { Any }
|
|
3
|
+
import from jac_scale.abstractions.deployment_target { DeploymentTarget }
|
|
4
|
+
import from jac_scale.abstractions.config.base_config { BaseConfig }
|
|
5
|
+
import from jac_scale.abstractions.logger { Logger }
|
|
6
|
+
|
|
7
|
+
"""Factory for creating deployment target instances."""
|
|
8
|
+
class DeploymentTargetFactory {
|
|
9
|
+
"""Create a deployment target based on type.
|
|
10
|
+
|
|
11
|
+
Args:
|
|
12
|
+
target_type: Type of deployment target ('kubernetes', 'aws', 'gcp', etc.)
|
|
13
|
+
config: Configuration dictionary
|
|
14
|
+
logger: Optional logger instance
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
DeploymentTarget instance
|
|
18
|
+
|
|
19
|
+
Raises:
|
|
20
|
+
ValueError: If target_type is not supported
|
|
21
|
+
NotImplementedError: If target is not yet implemented
|
|
22
|
+
"""
|
|
23
|
+
static def create(
|
|
24
|
+
target_type: str, config: dict[str, Any], logger: (Logger | None) = None
|
|
25
|
+
) -> DeploymentTarget {
|
|
26
|
+
if target_type == 'kubernetes' {
|
|
27
|
+
import from jac_scale.targets.kubernetes.kubernetes_target {
|
|
28
|
+
KubernetesTarget
|
|
29
|
+
}
|
|
30
|
+
import from jac_scale.targets.kubernetes.kubernetes_config {
|
|
31
|
+
KubernetesConfig
|
|
32
|
+
}
|
|
33
|
+
k8s_config = KubernetesConfig.from_dict(KubernetesConfig, config);
|
|
34
|
+
return KubernetesTarget(config=k8s_config, logger=logger);
|
|
35
|
+
} elif target_type == 'aws' {
|
|
36
|
+
raise NotImplementedError("AWS target not yet implemented") ;
|
|
37
|
+
} elif target_type == 'gcp' {
|
|
38
|
+
raise NotImplementedError("GCP target not yet implemented") ;
|
|
39
|
+
} else {
|
|
40
|
+
raise ValueError(f"Unsupported deployment target type: {target_type}") ;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Factory for creating image registries."""
|
|
2
|
+
import from typing { Any }
|
|
3
|
+
import from jac_scale.abstractions.image_registry { ImageRegistry }
|
|
4
|
+
|
|
5
|
+
"""Factory for creating image registry instances."""
|
|
6
|
+
class ImageRegistryFactory {
|
|
7
|
+
"""Create an image registry based on type.
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
registry_type: Type of image registry ('dockerhub', 'ecr', 'gcr', etc.)
|
|
11
|
+
config: Configuration dictionary
|
|
12
|
+
|
|
13
|
+
Returns:
|
|
14
|
+
ImageRegistry instance
|
|
15
|
+
|
|
16
|
+
Raises:
|
|
17
|
+
ValueError: If registry_type is not supported
|
|
18
|
+
NotImplementedError: If registry is not yet implemented
|
|
19
|
+
"""
|
|
20
|
+
static def create(registry_type: str, config: dict[str, Any]) -> ImageRegistry {
|
|
21
|
+
if registry_type == 'dockerhub' {
|
|
22
|
+
import from jac_scale.providers.registry.dockerhub { DockerHubRegistry }
|
|
23
|
+
return DockerHubRegistry(config=config);
|
|
24
|
+
} elif registry_type == 'ecr' {
|
|
25
|
+
raise NotImplementedError("AWS ECR registry not yet implemented") ;
|
|
26
|
+
} elif registry_type == 'gcr' {
|
|
27
|
+
raise NotImplementedError("GCP GCR registry not yet implemented") ;
|
|
28
|
+
} else {
|
|
29
|
+
raise ValueError(f"Unsupported image registry type: {registry_type}") ;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Factory for creating utility instances (loggers, monitoring, etc.)."""
|
|
2
|
+
import from typing { Any }
|
|
3
|
+
import from jac_scale.abstractions.logger { Logger }
|
|
4
|
+
|
|
5
|
+
"""Factory for creating utility instances."""
|
|
6
|
+
class UtilityFactory {
|
|
7
|
+
"""Create a logger based on type.
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
logger_type: Type of logger ('standard', 'cloudwatch', 'elasticsearch', etc.)
|
|
11
|
+
config: Optional logger-specific configuration
|
|
12
|
+
|
|
13
|
+
Returns:
|
|
14
|
+
Logger instance
|
|
15
|
+
|
|
16
|
+
Raises:
|
|
17
|
+
ValueError: If logger_type is not supported
|
|
18
|
+
NotImplementedError: If logger is not yet implemented
|
|
19
|
+
"""
|
|
20
|
+
static def create_logger(
|
|
21
|
+
logger_type: str = 'standard', config: (dict[str, Any] | None) = None
|
|
22
|
+
) -> Logger {
|
|
23
|
+
if logger_type == 'standard' {
|
|
24
|
+
import from jac_scale.utilities.loggers.standard_logger { StandardLogger }
|
|
25
|
+
return StandardLogger(config=config or {});
|
|
26
|
+
} elif logger_type == 'cloudwatch' {
|
|
27
|
+
raise NotImplementedError("CloudWatch logger not yet implemented") ;
|
|
28
|
+
} elif logger_type == 'elasticsearch' {
|
|
29
|
+
raise NotImplementedError("Elasticsearch logger not yet implemented") ;
|
|
30
|
+
} else {
|
|
31
|
+
raise ValueError(f"Unsupported logger type: {logger_type}") ;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"""Implementation of Jac Scale configuration loader.
|
|
2
|
+
|
|
3
|
+
This module provides the implementation for JacScaleConfig, which inherits
|
|
4
|
+
from PluginConfigBase for common configuration loading functionality.
|
|
5
|
+
|
|
6
|
+
The base class handles: init, load, get_jac_config, deep_merge, get_section.
|
|
7
|
+
This file only implements plugin-specific methods.
|
|
8
|
+
"""
|
|
9
|
+
import from pathlib { Path }
|
|
10
|
+
import from typing { Any }
|
|
11
|
+
import os;
|
|
12
|
+
|
|
13
|
+
"""Get the plugin section name for scale."""
|
|
14
|
+
impl JacScaleConfig.get_plugin_name(self: JacScaleConfig) -> str {
|
|
15
|
+
return "scale";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
"""Get default configuration structure for scale."""
|
|
19
|
+
impl JacScaleConfig.get_default_config(self: JacScaleConfig) -> dict[str, Any] {
|
|
20
|
+
return {
|
|
21
|
+
'jwt': {'secret': 'supersecretkey', 'algorithm': 'HS256', 'exp_delta_days': 7},
|
|
22
|
+
'sso': {
|
|
23
|
+
'host': 'http://localhost:8000/sso',
|
|
24
|
+
'google': {'client_id': '', 'client_secret': ''}
|
|
25
|
+
},
|
|
26
|
+
'database': {
|
|
27
|
+
'mongodb_uri': None,
|
|
28
|
+
'redis_url': None,
|
|
29
|
+
'shelf_db_path': '.jac/data/anchor_store.db'
|
|
30
|
+
},
|
|
31
|
+
'kubernetes': {
|
|
32
|
+
'app_name': 'jaseci',
|
|
33
|
+
'docker_image_name': '',
|
|
34
|
+
'docker_username': '',
|
|
35
|
+
'docker_password': '',
|
|
36
|
+
'namespace': 'default',
|
|
37
|
+
'container_port': 8000,
|
|
38
|
+
'node_port': 30001,
|
|
39
|
+
'mongodb_enabled': True,
|
|
40
|
+
'redis_enabled': True,
|
|
41
|
+
# Resource requests/limits
|
|
42
|
+
'cpu_request': None,
|
|
43
|
+
'cpu_limit': None,
|
|
44
|
+
'memory_request': None,
|
|
45
|
+
'memory_limit': None,
|
|
46
|
+
# Probe timings
|
|
47
|
+
'readiness_initial_delay': 10,
|
|
48
|
+
'readiness_period': 20,
|
|
49
|
+
'liveness_initial_delay': 10,
|
|
50
|
+
'liveness_period': 20,
|
|
51
|
+
'liveness_failure_threshold': 80
|
|
52
|
+
},
|
|
53
|
+
'server': {'port': 8000, 'host': '0.0.0.0'}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
"""Get JWT configuration from jac.toml."""
|
|
58
|
+
impl JacScaleConfig.get_jwt_config(self: JacScaleConfig) -> dict[str, Any] {
|
|
59
|
+
config = self.load();
|
|
60
|
+
jwt_config = config.get('jwt', {});
|
|
61
|
+
return {
|
|
62
|
+
'secret': jwt_config.get('secret', 'supersecretkey'),
|
|
63
|
+
'algorithm': jwt_config.get('algorithm', 'HS256'),
|
|
64
|
+
'exp_delta_days': int(jwt_config.get('exp_delta_days', 7))
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
"""Get SSO configuration from jac.toml."""
|
|
69
|
+
impl JacScaleConfig.get_sso_config(self: JacScaleConfig) -> dict[str, Any] {
|
|
70
|
+
config = self.load();
|
|
71
|
+
sso_config = config.get('sso', {});
|
|
72
|
+
google_config = sso_config.get('google', {});
|
|
73
|
+
return {
|
|
74
|
+
'host': sso_config.get('host', 'http://localhost:8000/sso'),
|
|
75
|
+
'google': {
|
|
76
|
+
'client_id': google_config.get('client_id', ''),
|
|
77
|
+
'client_secret': google_config.get('client_secret', '')
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
"""Get database configuration from jac.toml."""
|
|
83
|
+
impl JacScaleConfig.get_database_config(self: JacScaleConfig) -> dict[str, Any] {
|
|
84
|
+
config = self.load();
|
|
85
|
+
db_config = config.get('database', {});
|
|
86
|
+
return {
|
|
87
|
+
'mongodb_uri': os.environ.get('MONGODB_URI') or db_config.get('mongodb_uri'),
|
|
88
|
+
'redis_url': os.environ.get('REDIS_URL') or db_config.get('redis_url'),
|
|
89
|
+
'shelf_db_path': db_config.get('shelf_db_path', '.jac/data/anchor_store.db')
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
"""Get Kubernetes configuration from jac.toml."""
|
|
94
|
+
impl JacScaleConfig.get_kubernetes_config(self: JacScaleConfig) -> dict[str, Any] {
|
|
95
|
+
config = self.load();
|
|
96
|
+
k8s_config = config.get('kubernetes', {});
|
|
97
|
+
# Handle docker_image_name default (needs app_name)
|
|
98
|
+
if not k8s_config.get('docker_image_name') {
|
|
99
|
+
app_name = k8s_config.get('app_name', 'jaseci');
|
|
100
|
+
k8s_config['docker_image_name'] = f"{app_name}:latest";
|
|
101
|
+
}
|
|
102
|
+
# Convert to dict using KubernetesConfig.from_dict() which handles all defaults
|
|
103
|
+
import from jac_scale.targets.kubernetes.kubernetes_config { KubernetesConfig }
|
|
104
|
+
k8s_config_obj = KubernetesConfig.from_dict(KubernetesConfig, k8s_config);
|
|
105
|
+
return k8s_config_obj.to_dict();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
"""Get server configuration from jac.toml."""
|
|
109
|
+
impl JacScaleConfig.get_server_config(self: JacScaleConfig) -> dict[str, Any] {
|
|
110
|
+
config = self.load();
|
|
111
|
+
server_config = config.get('server', {});
|
|
112
|
+
return {
|
|
113
|
+
'port': int(server_config.get('port', 8000)),
|
|
114
|
+
'host': server_config.get('host', '0.0.0.0')
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
"""Get or create the global JacScaleConfig instance."""
|
|
119
|
+
impl get_scale_config(project_dir: Path | None = None) -> JacScaleConfig {
|
|
120
|
+
global _scale_config_instance;
|
|
121
|
+
if _scale_config_instance is None {
|
|
122
|
+
_scale_config_instance = JacScaleConfig(project_dir);
|
|
123
|
+
}
|
|
124
|
+
return _scale_config_instance;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
"""Reset the global config instance (useful for testing)."""
|
|
128
|
+
impl reset_scale_config -> None {
|
|
129
|
+
global _scale_config_instance;
|
|
130
|
+
_scale_config_instance = None;
|
|
131
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Initialize JScaleExecutionContext.
|
|
2
|
+
|
|
3
|
+
Storage backend is configured via environment variables (e.g., MONGODB_URI),
|
|
4
|
+
not per-context parameters.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
impl JScaleExecutionContext.init(self: JScaleExecutionContext) -> None {
|
|
8
|
+
import from jac_scale.memory_hierarchy { ScaleTieredMemory }
|
|
9
|
+
import from jaclang.pycore.constructs { Anchor, NodeAnchor, Root }
|
|
10
|
+
# ScaleTieredMemory gets storage config from environment variables
|
|
11
|
+
self.mem = ScaleTieredMemory();
|
|
12
|
+
self.reports: list[Any] = [];
|
|
13
|
+
self.custom: Any = MISSING;
|
|
14
|
+
system_root_anchor: (Anchor | None) = self.mem.get(UUID(Con.SUPER_ROOT_UUID));
|
|
15
|
+
if not isinstance(system_root_anchor, NodeAnchor) {
|
|
16
|
+
system_root_anchor = Root().__jac__;
|
|
17
|
+
system_root_anchor.id = UUID(Con.SUPER_ROOT_UUID);
|
|
18
|
+
self.mem.put(system_root_anchor);
|
|
19
|
+
}
|
|
20
|
+
self.system_root = system_root_anchor;
|
|
21
|
+
# Default user_root and entry_node to system_root
|
|
22
|
+
self.user_root = self.system_root;
|
|
23
|
+
self.entry_node = self.system_root;
|
|
24
|
+
}
|