-
-
Notifications
You must be signed in to change notification settings - Fork 1
feat: support dependency containers and a shared network for wip up #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,6 +29,7 @@ def run(arguments, settings: {}, interactive: true) | |
| def up(detach: false) | ||
| values = @config.defaults | ||
| command = [@wslc, 'run', '--name', required(values, 'container')] | ||
| command.push('--network', @config.network) if @config.network | ||
| command << '-d' if detach | ||
| command << '-it' if !detach && tty?(true) | ||
| command.concat(options(values)).push(required(values, 'image')) | ||
|
|
@@ -55,6 +56,40 @@ def remove | |
| [@wslc, 'remove', '-f', required(@config.defaults, 'container')] | ||
| end | ||
|
|
||
| def network_create | ||
| [@wslc, 'network', 'create', required_network] | ||
| end | ||
|
|
||
| def network_list | ||
| [@wslc, 'network', 'list', '--format', 'json'] | ||
| end | ||
|
|
||
| def dependency_up(name, detach: true) | ||
| values = dependency_values(name) | ||
| command = [@wslc, 'run', '--name', name.to_s] | ||
| command.push('--network', @config.network) if @config.network | ||
| command << '-d' if detach | ||
| command.concat(options(values)).push(required(values, 'image')) | ||
| command.concat(Shellwords.split(values['command'].to_s)) unless values['command'].to_s.empty? | ||
| command | ||
| end | ||
|
|
||
| def dependency_start(name) | ||
| [@wslc, 'start', name.to_s] | ||
| end | ||
|
Comment on lines
+77
to
+79
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
rg -n -C 4 --glob '*.rb' \
'\b(network\s+(connect|disconnect)|dependency_start|ensure_dependency|ensure_container|start\s*\()' \
lib specRepository: slidict/wip Length of output: 7251 🌐 Web query:
💡 Result: The Citations:
🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '--- command_builder.rb relevant ---\n'
sed -n '1,140p' lib/wip/command_builder.rb
printf '\n--- cli.rb ensure dependency/container/network ---\n'
sed -n '1,240p' lib/wip/cli.rb
printf '\n--- tests around existing containers and network ordering ---\n'
sed -n '30,120p' spec/wip/cli_spec.rbRepository: slidict/wip Length of output: 240 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '--- command_builder.rb relevant ---'
sed -n '1,140p' lib/wip/command_builder.rb
echo
echo '--- cli.rb ensure dependency/container/network ---'
sed -n '1,240p' lib/wip/cli.rb
echo
echo '--- tests around existing containers and network ordering ---'
sed -n '30,120p' spec/wip/cli_spec.rbRepository: slidict/wip Length of output: 14269 既存コンテナを network に接続してください。
🤖 Prompt for AI Agents |
||
|
|
||
| def dependency_find(name) | ||
| [@wslc, 'list', '--all', '--filter', "name=#{name}", '--format', 'json'] | ||
| end | ||
|
|
||
| def dependency_down(name) | ||
| [@wslc, 'stop', name.to_s] | ||
| end | ||
|
|
||
| def dependency_remove(name) | ||
| [@wslc, 'remove', '-f', name.to_s] | ||
| end | ||
|
|
||
| def build(settings:, extra: []) | ||
| values = @config.defaults.merge(settings) | ||
| context = values['context'] || '.' | ||
|
|
@@ -95,5 +130,16 @@ def required(values, key) | |
|
|
||
| value | ||
| end | ||
|
|
||
| def required_network | ||
| network = @config.network | ||
| raise ConfigError, 'Configured network must not be empty' if network.to_s.empty? | ||
|
|
||
| network | ||
| end | ||
|
|
||
| def dependency_values(name) | ||
| @config.dependency(name) || raise(ConfigError, "Unknown dependency: #{name}") | ||
| end | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -18,6 +18,8 @@ def wslc_command = @raw.dig('wslc', 'command') || 'auto' | |||||||||||||||||||||||||||||
| def commands = @raw['commands'] || {} | ||||||||||||||||||||||||||||||
| def defaults = DEFAULTS.merge(@raw['defaults'] || {}) | ||||||||||||||||||||||||||||||
| def up_command = @raw.dig('up', 'command') | ||||||||||||||||||||||||||||||
| def dependencies = @raw['dependencies'] || {} | ||||||||||||||||||||||||||||||
| def network = defaults['network'] | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| def command(name) | ||||||||||||||||||||||||||||||
| entry = commands[name.to_s] | ||||||||||||||||||||||||||||||
|
|
@@ -26,9 +28,16 @@ def command(name) | |||||||||||||||||||||||||||||
| defaults.merge('type' => 'exec').merge(entry) | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| def dependency(name) | ||||||||||||||||||||||||||||||
| entry = dependencies[name.to_s] | ||||||||||||||||||||||||||||||
| return unless entry | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| { 'workdir' => nil, 'env' => {}, 'ports' => [], 'volumes' => [] }.merge(entry) | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| def to_h(redact: true) | ||||||||||||||||||||||||||||||
| value = { 'version' => 1, 'wslc' => { 'command' => wslc_command }, 'defaults' => defaults, | ||||||||||||||||||||||||||||||
| 'up' => { 'command' => up_command }, | ||||||||||||||||||||||||||||||
| 'up' => { 'command' => up_command }, 'dependencies' => dependencies, | ||||||||||||||||||||||||||||||
| 'commands' => commands.transform_values { |entry| defaults.merge('type' => 'exec').merge(entry) } } | ||||||||||||||||||||||||||||||
| redact ? redact_secrets(value) : value | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
@@ -37,12 +46,24 @@ def to_h(redact: true) | |||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| def validate! | ||||||||||||||||||||||||||||||
| raise ConfigError, "Unsupported configuration version: #{@raw['version']}" unless (@raw['version'] || 1) == 1 | ||||||||||||||||||||||||||||||
| raise ConfigError, 'commands must be a mapping' unless commands.is_a?(Hash) | ||||||||||||||||||||||||||||||
| raise ConfigError, 'up must be a mapping' if @raw.key?('up') && !@raw['up'].is_a?(Hash) | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| validate_commands! | ||||||||||||||||||||||||||||||
| validate_dependencies! | ||||||||||||||||||||||||||||||
|
Comment on lines
+51
to
+52
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
修正案 def validate!
raise ConfigError, "Unsupported configuration version: #{`@raw`['version']}" unless (`@raw`['version'] || 1) == 1
raise ConfigError, 'up must be a mapping' if `@raw.key`?('up') && !`@raw`['up'].is_a?(Hash)
validate_commands!
validate_dependencies!
+ validate_network!
end
+
+def validate_network!
+ network = `@raw.dig`('defaults', 'network')
+ return if network.nil?
+
+ unless network.is_a?(String) && !network.strip.empty?
+ raise ConfigError, 'defaults.network must be a non-empty string'
+ end
+end
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| def validate_commands! | ||||||||||||||||||||||||||||||
| raise ConfigError, 'commands must be a mapping' unless commands.is_a?(Hash) | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| commands.each { |name, entry| validate_command!(name, entry) } | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| def validate_dependencies! | ||||||||||||||||||||||||||||||
| raise ConfigError, 'dependencies must be a mapping' unless dependencies.is_a?(Hash) | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| dependencies.each { |name, entry| validate_dependency!(name, entry) } | ||||||||||||||||||||||||||||||
|
Comment on lines
+61
to
+64
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win 依存コンテナ名と 依存名が main container 名と同じ場合、 修正案 def validate_dependencies!
raise ConfigError, 'dependencies must be a mapping' unless dependencies.is_a?(Hash)
- dependencies.each { |name, entry| validate_dependency!(name, entry) }
+ dependencies.each do |name, entry|
+ if name == defaults['container'].to_s
+ raise ConfigError, "dependencies.#{name} must not match defaults.container"
+ end
+
+ validate_dependency!(name, entry)
+ end
end
📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| def validate_command!(name, entry) | ||||||||||||||||||||||||||||||
| raise ConfigError, "commands.#{name} must be a mapping" unless entry.is_a?(Hash) | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
|
@@ -52,6 +73,13 @@ def validate_command!(name, entry) | |||||||||||||||||||||||||||||
| entry['env']&.transform_values!(&:to_s) | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| def validate_dependency!(name, entry) | ||||||||||||||||||||||||||||||
| raise ConfigError, "dependencies.#{name} must be a mapping" unless entry.is_a?(Hash) | ||||||||||||||||||||||||||||||
| raise ConfigError, "dependencies.#{name} must set image" if entry['image'].to_s.empty? | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| entry['env']&.transform_values!(&:to_s) | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| def stringify(object) | ||||||||||||||||||||||||||||||
| case object | ||||||||||||||||||||||||||||||
| when Hash then object.to_h { |key, value| [key.to_s, stringify(value)] } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| module Wip | ||
| VERSION = '0.3.1' | ||
| VERSION = '0.4.0' | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
Repository: slidict/wip
Length of output: 3899
🏁 Script executed:
Repository: slidict/wip
Length of output: 13733
🏁 Script executed:
Repository: slidict/wip
Length of output: 25675
🌐 Web query:
wslc net container inspect networks JSON💡 Result:
In the WSL container feature (WSL Containers), the command to inspect a container's networking configuration is: wslc container inspect <container_id_or_name> The
wslcCLI (available in Windows Subsystem for Linux public preview as of July 2026) outputs container information in JSON format [1]. When you run theinspectcommand, the output includes aNetworkSettingsobject within the container's inspection data [2]. TheInspectContainerschema, which dictates the structure of this JSON output, is defined in the WSL codebase [2]. TheNetworkSettingssection contains details about the networks the container is connected to, specifically mapping network names to endpoint settings (represented as anInspectEndpointSettingsobject) [2]. Becausewslccommands likecontainer inspectare designed to output structured JSON directly to the console [1], you can pipe or redirect this output as needed for parsing or further processing. [1].Citations:
🌐 Web query:
Microsoft WSL wslc container inspect NetworkSettings endpoints configuration💡 Result:
In the Microsoft Windows Subsystem for Linux (WSL) container feature, the
wslcCLI tool uses an inspection mechanism to retrieve detailed information about containers, which includes their network configurations [1][2]. ### Inspecting Network Settings To view the network configuration of a container, you use thewslc container inspectcommand (or theInspectmethod in the WSL container API) [1][2]. The output is a JSON-formatted structure that maps to an internal schema [2]. TheNetworkSettingsconfiguration within this inspection data is defined by anInspectNetworkSettingsobject [3]. This object primarily contains a map ofInspectEndpointSettingskeyed by the network name [3]: - InspectNetworkSettings: Contains a collection (std::map) of network endpoints associated with the container [3]. - InspectEndpointSettings: Represents the configuration for a specific network endpoint, which may include settings such as IP addresses, network aliases, links, and driver-specific options [3][4][5]. ### Context and Usage - CLI Interaction: Thewslcbinary allows you to manage containers with a familiar interface, supporting commands likewslc container inspect <container_id>[6][7]. This command triggers the backendInspectlogic, which gathers the container state, configuration, and network settings, then outputs the result as JSON [1][2]. - API Layer: For developers using the WSL container API (available via NuGet), theContainerobject provides anInspectmethod that returns anInspectContainerstructure [8][7]. This structure includes theNetworkSettingsfield, allowing programmatic access to the container's network topology, including endpoints created viawslc container runorwslc network connect[1][4]. - Network Capabilities: Recent updates have extended the endpoint configuration to support Docker-style settings such as--network-alias,--ip,--link,--link-local-ip, and--driver-opt[4][5]. These endpoint configurations are persisted and surfaced through the inspection flow, enabling the retrieval of detailed network state [4][5]. For further details on the exact schema structure, you can refer to thewslc_schema.hfile in the official Microsoft WSL repository [3].Citations:
既存コンテナの共有ネットワーク接続を保証してください。
upは配置ネットワークを作成/存在確認するだけで、既存の依存コンテナ・メインコンテナがそのネットワークに接続済みであるとは限りません。lib/wip/cli.rbのensure_dependencyとensure_containerは、既存リソースに対してstartだけを実行します。start前にwslc container inspectでNetworkSettingsにそのネットワークのエンターポイントがあるか確認し、未接続ならnetwork connectするか再作成してください。spec/wip/cli_spec.rbにも既存かつ未接続の依存コンテナ・メインコンテナのケースを追加し、接続または再作成が最初に実行されることを検証してください。📍 Affects 2 files
lib/wip/cli.rb#L154-L157(this comment)lib/wip/cli.rb#L164-L169spec/wip/cli_spec.rb#L63-L110🤖 Prompt for AI Agents