P21
Some checks failed
CI / test-build (push) Failing after 2m14s

This commit is contained in:
2025-12-15 01:26:44 +07:00
parent abd8cef10a
commit ad0c4dfc24
4 changed files with 526 additions and 5 deletions

View File

@@ -214,3 +214,153 @@ func contains(slice []string, item string) bool {
}
return false
}
// ConnectionInstructions represents iSCSI connection instructions
type ConnectionInstructions struct {
IQN string `json:"iqn"`
Portal string `json:"portal"` // IP:port
PortalIP string `json:"portal_ip"` // IP address
PortalPort int `json:"portal_port"` // Port (default 3260)
LUNs []LUNInfo `json:"luns"`
Commands Commands `json:"commands"`
}
// LUNInfo represents LUN information for connection
type LUNInfo struct {
ID int `json:"id"`
ZVOL string `json:"zvol"`
Size uint64 `json:"size"`
}
// Commands contains OS-specific connection commands
type Commands struct {
Linux []string `json:"linux"`
Windows []string `json:"windows"`
MacOS []string `json:"macos"`
}
// GetConnectionInstructions generates connection instructions for an iSCSI target
func (s *ISCSIService) GetConnectionInstructions(target models.ISCSITarget, portalIP string, portalPort int) *ConnectionInstructions {
if portalPort == 0 {
portalPort = 3260 // Default iSCSI port
}
portal := fmt.Sprintf("%s:%d", portalIP, portalPort)
// Build LUN information
luns := make([]LUNInfo, len(target.LUNs))
for i, lun := range target.LUNs {
luns[i] = LUNInfo{
ID: lun.ID,
ZVOL: lun.ZVOL,
Size: lun.Size,
}
}
// Generate Linux commands
linuxCmds := []string{
fmt.Sprintf("# Discover target"),
fmt.Sprintf("iscsiadm -m discovery -t sendtargets -p %s", portal),
fmt.Sprintf(""),
fmt.Sprintf("# Login to target"),
fmt.Sprintf("iscsiadm -m node -T %s -p %s --login", target.IQN, portal),
fmt.Sprintf(""),
fmt.Sprintf("# Verify connection"),
fmt.Sprintf("iscsiadm -m session"),
fmt.Sprintf(""),
fmt.Sprintf("# Logout (when done)"),
fmt.Sprintf("iscsiadm -m node -T %s -p %s --logout", target.IQN, portal),
}
// Generate Windows commands
windowsCmds := []string{
fmt.Sprintf("# Open PowerShell as Administrator"),
fmt.Sprintf(""),
fmt.Sprintf("# Add iSCSI target portal"),
fmt.Sprintf("New-IscsiTargetPortal -TargetPortalAddress %s -TargetPortalPortNumber %d", portalIP, portalPort),
fmt.Sprintf(""),
fmt.Sprintf("# Connect to target"),
fmt.Sprintf("Connect-IscsiTarget -NodeAddress %s", target.IQN),
fmt.Sprintf(""),
fmt.Sprintf("# Verify connection"),
fmt.Sprintf("Get-IscsiSession"),
fmt.Sprintf(""),
fmt.Sprintf("# Disconnect (when done)"),
fmt.Sprintf("Disconnect-IscsiTarget -NodeAddress %s", target.IQN),
}
// Generate macOS commands
macosCmds := []string{
fmt.Sprintf("# macOS uses built-in iSCSI support"),
fmt.Sprintf("# Use System Preferences > Network > iSCSI"),
fmt.Sprintf(""),
fmt.Sprintf("# Or use command line (if iscsiutil is available)"),
fmt.Sprintf("iscsiutil -a -t %s -p %s", target.IQN, portal),
fmt.Sprintf(""),
fmt.Sprintf("# Portal: %s", portal),
fmt.Sprintf("# Target IQN: %s", target.IQN),
}
return &ConnectionInstructions{
IQN: target.IQN,
Portal: portal,
PortalIP: portalIP,
PortalPort: portalPort,
LUNs: luns,
Commands: Commands{
Linux: linuxCmds,
Windows: windowsCmds,
MacOS: macosCmds,
},
}
}
// GetPortalIP attempts to detect the portal IP address
func (s *ISCSIService) GetPortalIP() (string, error) {
// Try to get IP from targetcli
cmd := exec.Command(s.targetcliPath, "/iscsi", "ls")
output, err := cmd.Output()
if err != nil {
// Fallback: try to get system IP
return s.getSystemIP()
}
// Parse output to find portal IP
// This is a simplified version - real implementation would parse targetcli output properly
lines := strings.Split(string(output), "\n")
for _, line := range lines {
if strings.Contains(line, "ipv4") || strings.Contains(line, "ipv6") {
// Extract IP from line
parts := strings.Fields(line)
for _, part := range parts {
// Check if it looks like an IP address
if strings.Contains(part, ".") || strings.Contains(part, ":") {
// Remove port if present
if idx := strings.Index(part, ":"); idx > 0 {
return part[:idx], nil
}
return part, nil
}
}
}
}
// Fallback to system IP
return s.getSystemIP()
}
// getSystemIP gets a system IP address (simplified)
func (s *ISCSIService) getSystemIP() (string, error) {
// Try to get IP from hostname -I (Linux)
cmd := exec.Command("hostname", "-I")
output, err := cmd.Output()
if err == nil {
ips := strings.Fields(string(output))
if len(ips) > 0 {
return ips[0], nil
}
}
// Fallback: return localhost
return "127.0.0.1", nil
}