From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2395D21B9C1 for ; Sun, 31 Aug 2025 04:00:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.133 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756612809; cv=none; b=UWcT4uNaTAipJ5RKFJirxdMfOVPTULX41rWkzzcSdOtCA0v7wRk54kFOyyimES75iZgVHEjCsK/iG1v51BalvX/NWK3JNU+v8YEFhoXPqeSEzLn/5Wc+V9J4uXtB/p3Sc9b7O1XbjgBSxoIFH2I8MP6tLf++uNKGLGoYSZOmri4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1756612809; c=relaxed/simple; bh=YqPlbFWoAj+5jdxktkasZukXHbF5xGFbymQzu/FdHnM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=LvRyEL6dDxZZMM43tnXcWlfyBCgubXmLXPA6EV7/YgryjlnwVgh+QCgGERY3K0TL0uhb3iFfIkK02zDmzBJ8ZthVjcmXz5WUtil/2bCpW5sAoKpfvNyPjQGPSl+mWPJmd2BF+fHYHB/dVZGXJmTob0iaXop/TBqKk9oCWQwCXqI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=kernel.org; spf=none smtp.mailfrom=infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=lvQijKnt; arc=none smtp.client-ip=198.137.202.133 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=kernel.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="lvQijKnt" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc: To:From:Reply-To:Content-ID:Content-Description; bh=k/5C57wB4NfC0iRJ6+einhFTjXo6Dz6Ek0zGjssZ5cA=; b=lvQijKntl+k1BgDOgrPzgUPB+B aK2gtbXl/Ce0C9Zze/PqaI7ZLBWOft2ZcgN7itPqDpc+mU2Rg7MS3Csl0KYlLMFClJOexHnQfMaJo FXYyqHbQooOUKvWn7sL6JuKD9doC6ukZNMpMojFD7IrsF0Tb3K6qdVeO5rONEn4whPzUH3RodWTNK E7NrdVtgHe3EmkNEQM18hsTtcnQzgnIT158p1k0yK5iv7uxcHlQ98bWdrCfwyGQyVOKpZ1Mxli5Kh CBkHA4xTEilO8O36OFu8OcfhxWqb9dH9ybUDwoERlrzMT3zW6hUBcWWnMsupinI2DK2sFsrZriReD vHS0OpCA==; Received: from mcgrof by bombadil.infradead.org with local (Exim 4.98.2 #2 (Red Hat Linux)) id 1usZEb-000000093s8-3G9g; Sun, 31 Aug 2025 04:00:05 +0000 From: Luis Chamberlain To: Chuck Lever , Daniel Gomez , kdevops@lists.linux.dev Cc: Luis Chamberlain , Your Name Subject: [PATCH v3 06/10] kconfig: add dynamic cloud provider configuration infrastructure Date: Sat, 30 Aug 2025 21:00:00 -0700 Message-ID: <20250831040004.2159779-7-mcgrof@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250831040004.2159779-1-mcgrof@kernel.org> References: <20250831040004.2159779-1-mcgrof@kernel.org> Precedence: bulk X-Mailing-List: kdevops@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: Luis Chamberlain Add framework for dynamic cloud configuration generation: - dynamic-cloud-kconfig.Makefile: Build system integration - generate_cloud_configs.py: Multi-provider config coordinator - lambdalabs_smart_inference.py: Intelligent region/instance selection - lambdalabs_infer_region.py: Region inference for instance types - Documentation for dynamic configuration system Features: - Real-time API-based configuration generation - Smart instance and region selection algorithms - Cheapest instance finder with proximity optimization - Extensible framework for multiple cloud providers This infrastructure enables kdevops to provide up-to-date cloud configuration options based on real availability and pricing. Generated-by: Claude AI Signed-off-by: Your Name --- docs/dynamic-cloud-kconfig.md | 461 +++++++++++++++++++++++++ scripts/dynamic-cloud-kconfig.Makefile | 44 +++ scripts/generate_cloud_configs.py | 113 ++++++ scripts/lambdalabs_infer_region.py | 61 ++++ scripts/lambdalabs_smart_inference.py | 62 ++++ 5 files changed, 741 insertions(+) create mode 100644 docs/dynamic-cloud-kconfig.md create mode 100644 scripts/dynamic-cloud-kconfig.Makefile create mode 100755 scripts/generate_cloud_configs.py create mode 100755 scripts/lambdalabs_infer_region.py create mode 100755 scripts/lambdalabs_smart_inference.py diff --git a/docs/dynamic-cloud-kconfig.md b/docs/dynamic-cloud-kconfig.md new file mode 100644 index 0000000..3c43f95 --- /dev/null +++ b/docs/dynamic-cloud-kconfig.md @@ -0,0 +1,461 @@ +# Dynamic Cloud Kconfig Generation + +This document describes how kdevops implements dynamic configuration generation for cloud providers, using Lambda Labs as the reference implementation. This approach can be adapted for other cloud providers. + +## Table of Contents + +1. [Overview](#overview) +2. [Architecture](#architecture) +3. [Lambda Labs Implementation](#lambda-labs-implementation) +4. [Creating a New Cloud Provider](#creating-a-new-cloud-provider) +5. [API Reference](#api-reference) + +## Overview + +Dynamic cloud Kconfig generation allows kdevops to query cloud provider APIs at configuration time to present users with: +- Currently available instance types +- Regions with capacity +- Real-time pricing information +- Smart selection of optimal configurations + +This eliminates hardcoded lists that become outdated and helps users make informed decisions based on current availability. + +## Architecture + +### Core Components + +``` +┌─────────────────────────────────────────────────────┐ +│ User Interface │ +│ (make menuconfig) │ +└─────────────────────┬───────────────────────────────┘ + │ +┌─────────────────────▼───────────────────────────────┐ +│ Kconfig System │ +│ │ +│ ┌──────────────────────────────────────────────┐ │ +│ │ Static Kconfig Files │ │ +│ │ - Kconfig.location │ │ +│ │ - Kconfig.compute │ │ +│ │ - Kconfig.smart │ │ +│ └────────────┬─────────────────────────────────┘ │ +│ │ sources │ +│ ┌────────────▼─────────────────────────────────┐ │ +│ │ Generated Kconfig Files │ │ +│ │ - Kconfig.location.generated │ │ +│ │ - Kconfig.compute.generated │ │ +│ └────────────▲─────────────────────────────────┘ │ +└───────────────┼─────────────────────────────────────┘ + │ generates +┌───────────────┼─────────────────────────────────────┐ +│ │ Dynamic Generation Layer │ +│ ┌────────────┴─────────────────────────────────┐ │ +│ │ Makefile Rules (dynamic-cloud-kconfig.mk) │ │ +│ └────────────┬─────────────────────────────────┘ │ +│ │ calls │ +│ ┌────────────▼─────────────────────────────────┐ │ +│ │ CLI Tool (lambda-cli) │ │ +│ └────────────┬─────────────────────────────────┘ │ +└───────────────┼─────────────────────────────────────┘ + │ uses +┌───────────────▼─────────────────────────────────────┐ +│ API Library Layer │ +│ ┌──────────────────────────────────────────────┐ │ +│ │ lambdalabs_api.py │ │ +│ │ - API communication │ │ +│ │ - Data transformation │ │ +│ │ - Kconfig generation │ │ +│ └────────────┬─────────────────────────────────┘ │ +└───────────────┼─────────────────────────────────────┘ + │ queries +┌───────────────▼─────────────────────────────────────┐ +│ Cloud Provider API │ +│ (Lambda Labs REST API) │ +└─────────────────────────────────────────────────────┘ +``` + +### Data Flow + +1. **Configuration Time** (`make menuconfig`): + - Makefile detects cloud provider selection + - Triggers dynamic Kconfig generation + - CLI tool queries cloud API + - Generates `.generated` files + - Kconfig includes generated files + +2. **Runtime** (Terraform/Ansible): + - Uses values from `extra_vars.yaml` + - No API calls needed + - Configuration already resolved + +## Lambda Labs Implementation + +### 1. CLI Tool (scripts/lambda-cli) + +The `lambda-cli` tool provides a unified interface for all Lambda Labs operations: + +```bash +# Generate Kconfig files +lambda-cli generate-kconfig + +# Query available instances +lambda-cli --output json instance-types list + +# Smart selection +lambda-cli --output json smart-select --mode cheapest +``` + +**Key Features:** +- Structured command interface (mimics AWS CLI) +- JSON and human-readable output formats +- Error handling with fallbacks +- Caching for performance + +### 2. API Library (scripts/lambdalabs_api.py) + +Core API functionality: + +```python +def get_instance_types_with_capacity(api_key: str) -> Tuple[Dict, Dict[str, List[str]]]: + """ + Get instance types and their regional availability. + Returns: (instances_dict, capacity_map) + """ + response = make_api_request("/instance-types", api_key) + # Process and return structured data +``` + +### 3. Kconfig Integration + +#### Static Kconfig (terraform/lambdalabs/kconfigs/Kconfig.location) + +```kconfig +choice + prompt "Lambda Labs region selection method" + default TERRAFORM_LAMBDALABS_REGION_SMART_CHEAPEST + +config TERRAFORM_LAMBDALABS_REGION_SMART_CHEAPEST + bool "Smart selection - automatically select cheapest" + help + Uses lambda-cli to find the cheapest instance globally + +config TERRAFORM_LAMBDALABS_REGION_MANUAL + bool "Manual region selection" + help + Manually select from available regions + +endchoice + +# Include dynamically generated regions when manual selection +if TERRAFORM_LAMBDALABS_REGION_MANUAL +source "terraform/lambdalabs/kconfigs/Kconfig.location.generated" +endif + +# Smart inference using lambda-cli +config TERRAFORM_LAMBDALABS_REGION + string + output yaml + default $(shell, python3 scripts/lambdalabs_smart_inference.py region) if TERRAFORM_LAMBDALABS_REGION_SMART_CHEAPEST +``` + +#### Generated Kconfig (Kconfig.location.generated) + +```kconfig +# Dynamically generated from Lambda Labs API +# Generated at: 2025-08-27 12:00:00 + +choice + prompt "Lambda Labs region" + default TERRAFORM_LAMBDALABS_REGION_US_WEST_1 + +config TERRAFORM_LAMBDALABS_REGION_US_WEST_1 + bool "us-west-1 - US West (California)" + depends on TERRAFORM_LAMBDALABS_REGION_MANUAL + +config TERRAFORM_LAMBDALABS_REGION_US_EAST_1 + bool "us-east-1 - US East (Virginia)" + depends on TERRAFORM_LAMBDALABS_REGION_MANUAL + +# ... more regions +endchoice +``` + +### 4. Makefile Integration + +The `dynamic-cloud-kconfig.Makefile` handles generation: + +```makefile +# Lambda Labs dynamic Kconfig generation +terraform/lambdalabs/kconfigs/Kconfig.compute.generated: .config + @echo "Generating Lambda Labs compute Kconfig..." + @python3 scripts/lambda-cli --output json generate-kconfig \ + --output-dir terraform/lambdalabs/kconfigs + +terraform/lambdalabs/kconfigs/Kconfig.location.generated: .config + @echo "Generating Lambda Labs location Kconfig..." + @python3 scripts/lambda-cli --output json generate-kconfig \ + --output-dir terraform/lambdalabs/kconfigs + +# Include generated files as dependencies +KCONFIG_DEPS += terraform/lambdalabs/kconfigs/Kconfig.compute.generated +KCONFIG_DEPS += terraform/lambdalabs/kconfigs/Kconfig.location.generated +``` + +### 5. Smart Inference + +The system provides intelligent defaults through shell command execution in Kconfig: + +```kconfig +config TERRAFORM_LAMBDALABS_INSTANCE_TYPE + string + output yaml + default $(shell, python3 scripts/lambdalabs_smart_inference.py instance) +``` + +The `lambdalabs_smart_inference.py` wrapper calls lambda-cli: + +```python +def get_smart_selection(): + """Get smart selection from lambda-cli""" + result = subprocess.run( + ['scripts/lambda-cli', '--output', 'json', + 'smart-select', '--mode', 'cheapest'], + capture_output=True + ) + return json.loads(result.stdout) +``` + +## Creating a New Cloud Provider + +To add dynamic Kconfig support for a new cloud provider, follow this pattern: + +### Step 1: Create the CLI Tool + +Create `scripts/provider-cli`: + +```python +#!/usr/bin/env python3 +"""CLI tool for Provider cloud management.""" + +import argparse +import json +from provider_api import get_instances, get_regions + +class ProviderCLI: + def list_instance_types(self): + # Query API and return structured data + pass + + def generate_kconfig(self, output_dir): + # Generate Kconfig files + pass + +def main(): + parser = argparse.ArgumentParser() + # Add commands and options + # Handle commands +``` + +### Step 2: Create API Library + +Create `scripts/provider_api.py`: + +```python +def get_instance_types(): + """Get available instance types from provider.""" + # API communication + # Data transformation + return instances + +def generate_instance_kconfig(instances): + """Generate Kconfig choices for instances.""" + kconfig = "choice\n" + kconfig += ' prompt "Instance type"\n' + for instance in instances: + kconfig += f"config PROVIDER_INSTANCE_{instance['id']}\n" + kconfig += f' bool "{instance["name"]}"\n' + kconfig += "endchoice\n" + return kconfig +``` + +### Step 3: Create Kconfig Structure + +``` +terraform/provider/kconfigs/ +├── Kconfig.compute # Static configuration +├── Kconfig.location # Static configuration +└── Kconfig.smart # Smart defaults +``` + +### Step 4: Add Makefile Rules + +In `scripts/dynamic-cloud-kconfig.Makefile`: + +```makefile +ifdef CONFIG_TERRAFORM_PROVIDER +terraform/provider/kconfigs/Kconfig.%.generated: + @python3 scripts/provider-cli generate-kconfig +endif +``` + +### Step 5: Integration Points + +1. **Credentials Management**: Create `provider_credentials.py` +2. **Smart Inference**: Create wrapper scripts for Kconfig shell commands +3. **Terraform Integration**: Add provider configuration +4. **Ansible Integration**: Add provisioning support + +## API Reference + +### lambda-cli Commands + +#### generate-kconfig +Generate dynamic Kconfig files from API data. + +```bash +lambda-cli generate-kconfig [--output-dir DIR] +``` + +**Output**: Creates `.generated` files with current API data + +#### instance-types list +List available instance types. + +```bash +lambda-cli --output json instance-types list [--available-only] [--region REGION] +``` + +**Output JSON Structure**: +```json +[ + { + "name": "gpu_1x_a10", + "price_per_hour": "$0.75", + "specs": "1x NVIDIA A10 (24GB)", + "available_regions": 3 + } +] +``` + +#### smart-select +Intelligently select instance and region. + +```bash +lambda-cli --output json smart-select --mode cheapest +``` + +**Output JSON Structure**: +```json +{ + "instance_type": "gpu_1x_a10", + "region": "us-west-1", + "price_per_hour": "$0.75", + "selection_mode": "cheapest_global" +} +``` + +### Key Design Principles + +1. **Fallback Values**: Always provide sensible defaults when API is unavailable +2. **Caching**: Cache API responses to avoid rate limits +3. **Error Handling**: Graceful degradation when API fails +4. **Separation of Concerns**: + - CLI tool for interface + - API library for communication + - Kconfig for configuration + - Makefile for orchestration + +### Testing Dynamic Generation + +```bash +# Test API access +scripts/lambda-cli --output json regions list + +# Test Kconfig generation +make clean +make menuconfig # Select Lambda Labs provider +# Check generated files +ls terraform/lambdalabs/kconfigs/*.generated + +# Test smart inference +python3 scripts/lambdalabs_smart_inference.py instance +python3 scripts/lambdalabs_smart_inference.py region +``` + +## Best Practices + +1. **API Key Management** + - Store in `~/.provider/credentials` + - Support environment variables + - Never commit keys to repository + +2. **Performance** + - Generate files only when provider is selected + - Cache API responses (15-minute TTL) + - Minimize API calls during configuration + +3. **User Experience** + - Provide clear status messages + - Show availability information + - Offer smart defaults + - Graceful fallbacks + +4. **Maintainability** + - Single CLI tool for all operations + - Consistent command structure + - Comprehensive error messages + - Well-documented API + +## Troubleshooting + +### Generated files not appearing +```bash +# Check if provider is enabled +grep CONFIG_TERRAFORM_PROVIDER .config + +# Manually trigger generation +make terraform/provider/kconfigs/Kconfig.compute.generated + +# Check for API errors +scripts/provider-cli --output json instance-types list +``` + +### API authentication failures +```bash +# Check credentials +scripts/provider_credentials.py check + +# Set credentials +scripts/provider_credentials.py set YOUR_API_KEY +``` + +### Stale data in menus +```bash +# Force regeneration +rm terraform/provider/kconfigs/*.generated +make menuconfig +``` + +## Future Enhancements + +1. **Multi-Region Optimization**: Select instances across regions for best price/performance +2. **Spot Instance Support**: Include spot pricing in smart selection +3. **Resource Prediction**: Estimate resource needs based on workload +4. **Cost Tracking**: Integration with cloud billing APIs +5. **Availability Monitoring**: Real-time capacity updates + +## Contributing + +When adding a new cloud provider: +1. Follow the Lambda Labs pattern +2. Implement all required commands in CLI tool +3. Provide comprehensive fallbacks +4. Document API endpoints and data structures +5. Add integration tests +6. Update this documentation + +## References + +- [Lambda Labs Implementation](../terraform/lambdalabs/README.md) +- [Kconfig Documentation](https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html) +- [kdevops Cloud Providers](https://github.com/linux-kdevops/kdevops) \ No newline at end of file diff --git a/scripts/dynamic-cloud-kconfig.Makefile b/scripts/dynamic-cloud-kconfig.Makefile new file mode 100644 index 0000000..cc0a6b8 --- /dev/null +++ b/scripts/dynamic-cloud-kconfig.Makefile @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: copyleft-next-0.3.1 +# Dynamic cloud provider Kconfig generation + +DYNAMIC_CLOUD_KCONFIG := +DYNAMIC_CLOUD_KCONFIG_ARGS := + +# Lambda Labs dynamic configuration +LAMBDALABS_KCONFIG_DIR := terraform/lambdalabs/kconfigs +LAMBDALABS_KCONFIG_COMPUTE := $(LAMBDALABS_KCONFIG_DIR)/Kconfig.compute.generated +LAMBDALABS_KCONFIG_LOCATION := $(LAMBDALABS_KCONFIG_DIR)/Kconfig.location.generated +LAMBDALABS_KCONFIG_IMAGES := $(LAMBDALABS_KCONFIG_DIR)/Kconfig.images.generated + +LAMBDALABS_KCONFIGS := $(LAMBDALABS_KCONFIG_COMPUTE) $(LAMBDALABS_KCONFIG_LOCATION) $(LAMBDALABS_KCONFIG_IMAGES) + +# Individual Lambda Labs targets are now handled by generate_cloud_configs.py +cloud-config-lambdalabs: + $(Q)python3 scripts/generate_cloud_configs.py + +# Clean Lambda Labs generated files +clean-cloud-config-lambdalabs: + $(Q)rm -f $(LAMBDALABS_KCONFIGS) + +DYNAMIC_CLOUD_KCONFIG += cloud-config-lambdalabs + +cloud-config-help: + @echo "Cloud-specific dynamic kconfig targets:" + @echo "cloud-config - generates all cloud provider dynamic kconfig content" + @echo "cloud-config-lambdalabs - generates Lambda Labs dynamic kconfig content" + @echo "clean-cloud-config - removes all generated cloud kconfig files" + @echo "cloud-list-all - list all cloud instances for configured provider" + +HELP_TARGETS += cloud-config-help + +cloud-config: + $(Q)python3 scripts/generate_cloud_configs.py + +clean-cloud-config: clean-cloud-config-lambdalabs + $(Q)echo "Cleaned all cloud provider dynamic Kconfig files." + +cloud-list-all: + $(Q)chmod +x scripts/cloud_list_all.sh + $(Q)scripts/cloud_list_all.sh + +PHONY += cloud-config cloud-config-lambdalabs clean-cloud-config clean-cloud-config-lambdalabs cloud-config-help cloud-list-all diff --git a/scripts/generate_cloud_configs.py b/scripts/generate_cloud_configs.py new file mode 100755 index 0000000..110987b --- /dev/null +++ b/scripts/generate_cloud_configs.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: copyleft-next-0.3.1 + +""" +Generate dynamic cloud configurations for all supported providers. +Provides a summary of available options and pricing. +""" + +import os +import sys +import subprocess +import json + + +def get_lambdalabs_summary() -> tuple[bool, str]: + """ + Get a summary of Lambda Labs configurations using lambda-cli. + Returns (success, summary_string) + """ + script_dir = os.path.dirname(os.path.abspath(__file__)) + cli_path = os.path.join(script_dir, 'lambda-cli') + + try: + # Get instance availability + result = subprocess.run( + [cli_path, '--output', 'json', 'instance-types', 'list'], + capture_output=True, + text=True, + check=False + ) + + if result.returncode != 0: + return False, "Lambda Labs: API key not set - using defaults" + + instances = json.loads(result.stdout) + + # Count available instances + available = [i for i in instances if i.get('available_regions', 0) > 0] + total_count = len(instances) + available_count = len(available) + + # Get price range + prices = [] + regions = set() + for instance in available: + price_str = instance.get('price_per_hour', '$0.00') + price = float(price_str.replace('$', '')) + if price > 0: + prices.append(price) + # Note: available_regions is a count, not a list + + # Get regions separately + regions_result = subprocess.run( + [cli_path, '--output', 'json', 'regions', 'list'], + capture_output=True, + text=True, + check=False + ) + + if regions_result.returncode == 0: + regions_data = json.loads(regions_result.stdout) + region_count = len(regions_data) + else: + region_count = 0 + + # Format summary + if prices: + min_price = min(prices) + max_price = max(prices) + price_range = f"${min_price:.2f}-${max_price:.2f}/hr" + else: + price_range = "pricing varies" + + return ( + True, + f"Lambda Labs: {available_count}/{total_count} instances available, " + f"{region_count} regions, {price_range}" + ) + + except (subprocess.SubprocessError, json.JSONDecodeError, KeyError): + return False, "Lambda Labs: Error querying API - using defaults" + + +def main(): + """Main function to generate cloud configurations.""" + print("Cloud Provider Configuration Summary") + print("=" * 60) + print() + + # Lambda Labs + success, summary = get_lambdalabs_summary() + if success: + print(f"✓ {summary}") + else: + print(f"⚠ {summary}") + print() + + # AWS (placeholder - not implemented) + print("⚠ AWS: Dynamic configuration not yet implemented") + + # Azure (placeholder - not implemented) + print("⚠ Azure: Dynamic configuration not yet implemented") + + # GCE (placeholder - not implemented) + print("⚠ GCE: Dynamic configuration not yet implemented") + + print() + print("Note: Dynamic configurations query real-time availability") + print("Run 'make menuconfig' to configure your cloud provider") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/scripts/lambdalabs_infer_region.py b/scripts/lambdalabs_infer_region.py new file mode 100755 index 0000000..e6a069f --- /dev/null +++ b/scripts/lambdalabs_infer_region.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: copyleft-next-0.3.1 +""" +Smart region inference for Lambda Labs. + +This is a thin wrapper around lambda-cli for backward compatibility +with existing Kconfig shell commands. +""" + +import sys +import subprocess +import json +import os + +def get_best_region_for_instance(instance_type): + """Get best region for a specific instance type using lambda-cli""" + script_dir = os.path.dirname(os.path.abspath(__file__)) + cli_path = os.path.join(script_dir, 'lambda-cli') + + try: + # First try to get regions where this instance is available + result = subprocess.run( + [cli_path, '--output', 'json', 'instance-types', 'list'], + capture_output=True, + text=True, + check=False + ) + + if result.returncode == 0: + instances = json.loads(result.stdout) + for instance in instances: + if instance.get('name') == instance_type: + # This instance exists, try smart selection + smart_result = subprocess.run( + [cli_path, '--output', 'json', 'smart-select', '--mode', 'cheapest'], + capture_output=True, + text=True, + check=False + ) + if smart_result.returncode == 0: + data = json.loads(smart_result.stdout) + if 'error' not in data: + return data.get('region', 'us-west-1') + except (subprocess.SubprocessError, json.JSONDecodeError): + pass + + # Return default if lambda-cli fails + return 'us-west-1' + +def main(): + """Main function for command-line usage.""" + if len(sys.argv) != 2: + print("us-west-1") # Default + sys.exit(0) + + instance_type = sys.argv[1] + region = get_best_region_for_instance(instance_type) + print(region) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/scripts/lambdalabs_smart_inference.py b/scripts/lambdalabs_smart_inference.py new file mode 100755 index 0000000..8bf9a00 --- /dev/null +++ b/scripts/lambdalabs_smart_inference.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: copyleft-next-0.3.1 +""" +Lambda Labs smart inference for Kconfig. + +This is a thin wrapper around lambda-cli for backward compatibility +with existing Kconfig shell commands. +""" + +import sys +import subprocess +import json +import os + +def get_smart_selection(): + """Get smart selection from lambda-cli""" + script_dir = os.path.dirname(os.path.abspath(__file__)) + cli_path = os.path.join(script_dir, 'lambda-cli') + + try: + result = subprocess.run( + [cli_path, '--output', 'json', 'smart-select', '--mode', 'cheapest'], + capture_output=True, + text=True, + check=False + ) + + if result.returncode == 0: + data = json.loads(result.stdout) + if 'error' not in data: + return data + except (subprocess.SubprocessError, json.JSONDecodeError): + pass + + # Return defaults if lambda-cli fails + return { + 'instance_type': 'gpu_1x_a10', + 'region': 'us-west-1', + 'price_per_hour': '$0.75' + } + +def main(): + """Main entry point for Kconfig shell commands""" + if len(sys.argv) < 2: + print("Usage: lambdalabs_smart_inference.py [instance|region|price]") + sys.exit(1) + + query_type = sys.argv[1] + selection = get_smart_selection() + + if query_type == 'instance': + print(selection.get('instance_type', 'gpu_1x_a10')) + elif query_type == 'region': + print(selection.get('region', 'us-west-1')) + elif query_type == 'price': + print(selection.get('price_per_hour', '$0.75')) + else: + print(f"Unknown query type: {query_type}", file=sys.stderr) + sys.exit(1) + +if __name__ == '__main__': + main() \ No newline at end of file -- 2.50.1