AIPCC:15489: Add support for Gaudi accelerator in mapt's IBM Cloud module#834
AIPCC:15489: Add support for Gaudi accelerator in mapt's IBM Cloud module#834deekay2310 wants to merge 1 commit into
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughAdds IBM Gaudi3 provisioning and teardown through a new ChangesIBM Gaudi3 provisioning feature
Estimated code review effort: 4 (Complex) | ~60 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (2)
pkg/provider/ibmcloud/action/ibm-gaudi/cloud-config (1)
94-98: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winUnquoted user-controlled key/value in extra attrs.
{{$k}}and{{$v}}fromOtelExtraAttrs(user-supplied via--otel-extra-attrs) are interpolated into YAML unquoted/partially quoted. A key containing YAML-significant characters (:,#, newline) could corrupt the generated config or inject unintended fields.♻️ Proposed fix
{{- range $k, $v := .OtelExtraAttrs}} - - key: {{$k}} + - key: "{{$k}}" value: "{{$v}}" action: upsert {{- end}}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/provider/ibmcloud/action/ibm-gaudi/cloud-config` around lines 94 - 98, The OtelExtraAttrs entries in the cloud-config template are being interpolated into YAML without safely quoting the user-controlled key and value, which can break the generated config or allow injected fields. Update the template loop in the cloud-config rendering block so the OtelExtraAttrs key/value are emitted using YAML-safe quoting/escaping, preserving the existing upsert structure while preventing special characters from being interpreted as YAML syntax.pkg/provider/ibmcloud/action/ibm-gaudi/ibm-gaudi.go (1)
173-233: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftLarge duplication between
deployanddeployWithExistingSubnet.Instance-args assembly, OTEL user-data injection (188-194 / 285-291), floating-IP association (202-215 / 299-312), username/host exports, and the readiness
remote.NewCommandblock (217-231 / 314-328) are nearly identical. Extracting a shared helper (e.g. taking VPC/zone/subnet/floating-IP/security-group inputs) would reduce drift risk as this evolves.Also applies to: 273-330
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/provider/ibmcloud/action/ibm-gaudi/ibm-gaudi.go` around lines 173 - 233, There is significant duplication between the deploy paths, especially around instanceArgs setup, OTEL user-data injection in gaudiUserData handling, floating-IP association with ibmcloud.NewIsInstanceNetworkInterfaceFloatingIp, ctx.Export of username/host, and the remote.NewCommand readiness check. Extract the shared provisioning logic into a helper used by both deploy and deployWithExistingSubnet, parameterized by the varying inputs like VPC, zone, subnet, security group, and floating IP, so future changes only need to be made in one place.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/ibmcloud/ibm-gaudi.md`:
- Around line 60-64: Update the IBM Cloud Gaudi SSH documentation to use the
current default SSH user `cloud-user` instead of `root`. In the table entry for
`username` and in the SSH access example, replace the stale `root` references
with `cloud-user` so the docs match the current RHEL AI image behavior. Use the
existing SSH example section and the `host`/`username` table to locate and
update both places consistently.
In `@pkg/provider/ibmcloud/action/ibm-gaudi/cloud-config`:
- Around line 99-103: The otlphttp exporter in the IBM Gaudi cloud-config
disables TLS verification with insecure_skip_verify, which should be removed.
Update the exporter configuration to use proper certificate validation for the
OTEL endpoint in this cloud-config block, and if custom trust is needed, wire in
the appropriate CA/cert settings instead of bypassing verification.
- Around line 128-144: The otelcol-contrib cloud-init install flow in the runcmd
block has no failure stopping behavior, so a bad download or RPM install can be
ignored and the script keeps going. Add explicit error handling to this shell
fragment (for example, stop on failures and check the curl and rpm steps before
proceeding) so the install only continues after each command succeeds. Use the
runcmd shell block and the curl/rpm install sequence as the key points to
update.
In `@pkg/provider/ibmcloud/action/ibm-gaudi/ibm-gaudi.go`:
- Around line 188-194: The OTEL user-data gating in gaudi user data generation
is broader than the cloud-config template, so the collector install can be
skipped while config files are still written. Update the condition around
gaudiUserData/UserData assignment in the IBM Gaudi flow to match the template’s
requirements, including otelIndex, or adjust the template to match the intended
behavior. Check the gaudiUserData helper and the instance setup block to keep
the gating consistent in both places.
- Around line 382-388: Stop logging the generated private key in debug output;
the current ApplyT callback on pk.PrivateKeyPem in the ibm-gaudi flow prints
sensitive material. Update the debug branch to log a non-sensitive identifier
instead, such as the public key or a fingerprint, and apply the same fix in the
analogous ApplyT/debug logging blocks in ibm-power and ibm-z so no private key
values are emitted anywhere.
---
Nitpick comments:
In `@pkg/provider/ibmcloud/action/ibm-gaudi/cloud-config`:
- Around line 94-98: The OtelExtraAttrs entries in the cloud-config template are
being interpolated into YAML without safely quoting the user-controlled key and
value, which can break the generated config or allow injected fields. Update the
template loop in the cloud-config rendering block so the OtelExtraAttrs
key/value are emitted using YAML-safe quoting/escaping, preserving the existing
upsert structure while preventing special characters from being interpreted as
YAML syntax.
In `@pkg/provider/ibmcloud/action/ibm-gaudi/ibm-gaudi.go`:
- Around line 173-233: There is significant duplication between the deploy
paths, especially around instanceArgs setup, OTEL user-data injection in
gaudiUserData handling, floating-IP association with
ibmcloud.NewIsInstanceNetworkInterfaceFloatingIp, ctx.Export of username/host,
and the remote.NewCommand readiness check. Extract the shared provisioning logic
into a helper used by both deploy and deployWithExistingSubnet, parameterized by
the varying inputs like VPC, zone, subnet, security group, and floating IP, so
future changes only need to be made in one place.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Enterprise
Run ID: d85efaa9-9a57-456b-b2de-bdc9fbb4fc4f
📒 Files selected for processing (5)
cmd/mapt/cmd/ibmcloud/hosts/ibm-gaudi.gocmd/mapt/cmd/ibmcloud/ibmcloud.godocs/ibmcloud/ibm-gaudi.mdpkg/provider/ibmcloud/action/ibm-gaudi/cloud-configpkg/provider/ibmcloud/action/ibm-gaudi/ibm-gaudi.go
| runcmd: | ||
| - | | ||
| PROXY_URL="" | ||
| if ! curl -sf --connect-timeout 5 --head {{.OtelEndpoint}} > /dev/null 2>&1; then | ||
| PROXY_URL="http://squid.corp.redhat.com:3128" | ||
| fi | ||
| RPM_URL="https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{.OtelColVersion}}/otelcol-contrib_{{.OtelColVersion}}_linux_{{.OtelArch}}.rpm" | ||
| HTTPS_PROXY="$PROXY_URL" curl -fsSL -o /tmp/otelcol-contrib.rpm "$RPM_URL" | ||
| rpm -Uvh /tmp/otelcol-contrib.rpm | ||
| rm -f /tmp/otelcol-contrib.rpm | ||
| chown -R otelcol-contrib:otelcol-contrib /etc/otelcol-contrib | ||
| if [ -n "$PROXY_URL" ]; then | ||
| printf '[Service]\nEnvironment="HTTPS_PROXY=%s/"\nEnvironment="NO_PROXY=10.*,192.168.*,localhost,127.0.0.1"\n' "$PROXY_URL" \ | ||
| > /etc/systemd/system/otelcol-contrib.service.d/proxy.conf | ||
| fi | ||
| systemctl daemon-reload | ||
| systemctl enable --now otelcol-contrib |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
No error handling in runcmd install script.
Lack of set -e/explicit checks after curl and rpm -Uvh means a failed download silently proceeds to install a stale/missing RPM, potentially leaving the instance without a functioning otelcol-contrib service and no clear failure signal in cloud-init logs.
🛡️ Proposed fix
- |
+ set -e
PROXY_URL=""📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| runcmd: | |
| - | | |
| PROXY_URL="" | |
| if ! curl -sf --connect-timeout 5 --head {{.OtelEndpoint}} > /dev/null 2>&1; then | |
| PROXY_URL="http://squid.corp.redhat.com:3128" | |
| fi | |
| RPM_URL="https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{.OtelColVersion}}/otelcol-contrib_{{.OtelColVersion}}_linux_{{.OtelArch}}.rpm" | |
| HTTPS_PROXY="$PROXY_URL" curl -fsSL -o /tmp/otelcol-contrib.rpm "$RPM_URL" | |
| rpm -Uvh /tmp/otelcol-contrib.rpm | |
| rm -f /tmp/otelcol-contrib.rpm | |
| chown -R otelcol-contrib:otelcol-contrib /etc/otelcol-contrib | |
| if [ -n "$PROXY_URL" ]; then | |
| printf '[Service]\nEnvironment="HTTPS_PROXY=%s/"\nEnvironment="NO_PROXY=10.*,192.168.*,localhost,127.0.0.1"\n' "$PROXY_URL" \ | |
| > /etc/systemd/system/otelcol-contrib.service.d/proxy.conf | |
| fi | |
| systemctl daemon-reload | |
| systemctl enable --now otelcol-contrib | |
| runcmd: | |
| - | | |
| set -e | |
| PROXY_URL="" | |
| if ! curl -sf --connect-timeout 5 --head {{.OtelEndpoint}} > /dev/null 2>&1; then | |
| PROXY_URL="http://squid.corp.redhat.com:3128" | |
| fi | |
| RPM_URL="https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v{{.OtelColVersion}}/otelcol-contrib_{{.OtelColVersion}}_linux_{{.OtelArch}}.rpm" | |
| HTTPS_PROXY="$PROXY_URL" curl -fsSL -o /tmp/otelcol-contrib.rpm "$RPM_URL" | |
| rpm -Uvh /tmp/otelcol-contrib.rpm | |
| rm -f /tmp/otelcol-contrib.rpm | |
| chown -R otelcol-contrib:otelcol-contrib /etc/otelcol-contrib | |
| if [ -n "$PROXY_URL" ]; then | |
| printf '[Service]\nEnvironment="HTTPS_PROXY=%s/"\nEnvironment="NO_PROXY=10.*,192.168.*,localhost,127.0.0.1"\n' "$PROXY_URL" \ | |
| > /etc/systemd/system/otelcol-contrib.service.d/proxy.conf | |
| fi | |
| systemctl daemon-reload | |
| systemctl enable --now otelcol-contrib |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@pkg/provider/ibmcloud/action/ibm-gaudi/cloud-config` around lines 128 - 144,
The otelcol-contrib cloud-init install flow in the runcmd block has no failure
stopping behavior, so a bad download or RPM install can be ignored and the
script keeps going. Add explicit error handling to this shell fragment (for
example, stop on failures and check the curl and rpm steps before proceeding) so
the install only continues after each command succeeds. Use the runcmd shell
block and the curl/rpm install sequence as the key points to update.
| //go:embed cloud-config | ||
| var CloudConfig []byte | ||
|
|
||
| var otelColVersion = "0.151.0" |
There was a problem hiding this comment.
why is this here? Did you rebase the branch, now whole otel is managed through its own intetration package
There was a problem hiding this comment.
Rebased onto latest main and refactored to use pkg/integrations/otelcol. Removed inline otelColVersion, the OTEL-specific userDataValues fields, and the 140-line inline cloud-config. Now uses otelcol.GetSnippetAsCloudInitWritableFile() matching the pattern in ibm-power and ibm-z.
| outputUserPrivateKey = "icgUserPrivatekey" | ||
|
|
||
| defaultProfile = "gx3d-160x1792x8gaudi3" | ||
| defaultImage = "ibm-redhat-ai-intel" |
There was a problem hiding this comment.
This is the RHEL AI stock image for Intel/x86_64 VPC instances. It resolves via GetVPCImage which uses strings.Contains (substring match), so ibm-redhat-ai-intel matches the full image name:
$ ibmcloud is images --visibility public | grep -i "redhat-ai"
ibm-redhat-ai-intel-1-5-1-amd64-1 available public
ibm-redhat-ai-nvidia-1-5-2-amd64-1 available public
Added a comment in the code noting the substring match behavior and the resolved name.
c4577bb to
06994bd
Compare
…dule Add ibm-gaudi target for provisioning Intel Gaudi 3 accelerator instances on IBM Cloud VPC. Includes auto-provision with RHEL AI image, SSH readiness check with unlimited dial retries, cloud-user default SSH user, and shared otelcol integration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
33f1208 to
4372a2b
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
pkg/provider/ibmcloud/action/ibm-gaudi/ibm-gaudi.go (1)
131-327: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftSignificant duplication between
deploy()anddeployWithExistingSubnet().Both functions repeat the same ~90-line sequence: image lookup, instance construction, conditional
UserData, instance creation, username export, floating-IP association, host export, and readiness command. The only real differences are how VPC/subnet/zone/security-group/floating-IP and resource group are obtained. Extracting a shared helper (parameterized byvpc,subnet,zone,securityGroupID,floatingIP, optionalresourceGroup) would remove the duplication and prevent the two paths from drifting (e.g., profile/image updates, SG rules, readiness timeouts needing edits in two places).type gaudiInstanceInputs struct { vpc, subnet, zone pulumi.StringInput securityGroupID pulumi.StringInput floatingIP *ibmcloud.IsFloatingIp // or equivalent output resourceGroup *ibmcloud.ResourceGroup // nil for existing-subnet path pik *ibmcloud.IsSshKey pk *tls.PrivateKey } func (r *gaudiRequest) provisionInstance(ctx *pulumi.Context, in gaudiInstanceInputs) error { // shared image lookup, instance creation, UserData, exports, FIP assoc, readiness cmd }Happy to draft the full extraction if useful.
As per path instructions, focus on major issues impacting maintainability.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/provider/ibmcloud/action/ibm-gaudi/ibm-gaudi.go` around lines 131 - 327, Extract the duplicated instance-provisioning sequence from deploy and deployWithExistingSubnet into a shared gaudiRequest.provisionInstance helper. Parameterize it with the path-specific VPC, subnet, zone, security group, floating IP, SSH keys, and optional resource group, then have both deploy methods prepare those inputs and delegate image lookup, instance creation, UserData, exports, floating-IP association, and readiness-command setup to the helper.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@pkg/provider/ibmcloud/action/ibm-gaudi/ibm-gaudi.go`:
- Around line 131-327: Extract the duplicated instance-provisioning sequence
from deploy and deployWithExistingSubnet into a shared
gaudiRequest.provisionInstance helper. Parameterize it with the path-specific
VPC, subnet, zone, security group, floating IP, SSH keys, and optional resource
group, then have both deploy methods prepare those inputs and delegate image
lookup, instance creation, UserData, exports, floating-IP association, and
readiness-command setup to the helper.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Enterprise
Run ID: 888a5da9-1759-4eb3-8875-157e2ace22d8
📒 Files selected for processing (5)
cmd/mapt/cmd/ibmcloud/hosts/ibm-gaudi.gocmd/mapt/cmd/ibmcloud/ibmcloud.godocs/ibmcloud/ibm-gaudi.mdpkg/provider/ibmcloud/action/ibm-gaudi/cloud-configpkg/provider/ibmcloud/action/ibm-gaudi/ibm-gaudi.go
🚧 Files skipped from review as they are similar to previous changes (4)
- pkg/provider/ibmcloud/action/ibm-gaudi/cloud-config
- cmd/mapt/cmd/ibmcloud/hosts/ibm-gaudi.go
- docs/ibmcloud/ibm-gaudi.md
- cmd/mapt/cmd/ibmcloud/ibmcloud.go
Summary
Adds
ibmcloud ibm-gaudicreate/destroy commands for provisioning Intel Gaudi 3 accelerator instances on IBM Cloud VPC.ibm-gaudiwith auto-provisioning via RHEL AI image ongx3d-160x1792x8profile (us-south-2)cloud-useras default SSH user for the RHEL AI imageResolves: AIPCC-15489