Skip to content

Commit

Permalink
Add RabbitMQ image pull functionality with user feedback spinner
Browse files Browse the repository at this point in the history
- Implemented a check for the existence of the RabbitMQ Docker image and added functionality to pull the image if it is not found.
- Introduced a spinner UI using the Bubble Tea library to provide visual feedback during the image pull process.
- Enhanced error handling to log failures during the image pull operation.
- Updated server.go to integrate the new image pull logic, improving the overall user experience when starting the RabbitMQ server.
  • Loading branch information
hskiba committed Jan 15, 2025
1 parent 6c74067 commit 1010c34
Showing 1 changed file with 80 additions and 0 deletions.
80 changes: 80 additions & 0 deletions cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/tls"
"errors"
"fmt"
"io"
"net/http"
"os"
"os/signal"
Expand All @@ -17,6 +18,7 @@ import (
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/client"
"github.com/docker/go-connections/nat"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -109,6 +111,31 @@ func startRabbitMQServer(certFile, keyFile string, amqpPort, mgmtPortTLS int) (s
}
defer cli.Close()

// Check if image exists
imageName := "rabbitmq:3-management"
_, _, err = cli.ImageInspectWithRaw(ctx, imageName)
if err != nil {
if !client.IsErrNotFound(err) {
return "", fmt.Errorf("failed to inspect image: %w", err)
}

// Image not found, pull it with spinner
s := spinner.New()
s.Spinner = spinner.Dot
s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("69"))

p := tea.NewProgram(pullSpinnerModel{
spinner: s,
client: cli,
ctx: ctx,
image: imageName,
})

if _, err := p.Run(); err != nil {
return "", fmt.Errorf("failed to pull RabbitMQ image: %w", err)
}
}

// Get absolute paths for mounting certificates
certPath, err := filepath.Abs(certFile)
if err != nil {
Expand Down Expand Up @@ -268,3 +295,56 @@ func (m cleanupSpinnerModel) View() string {
}
return fmt.Sprintf("\n %s Cleaning up RabbitMQ container...\n\n", m.spinner.View())
}

type pullSpinnerModel struct {
spinner spinner.Model
client *client.Client
ctx context.Context
image string
quitting bool
}

type pullMsg struct{ err error }

func (m pullSpinnerModel) Init() tea.Cmd {
return tea.Batch(
m.spinner.Tick,
func() tea.Msg {
reader, err := m.client.ImagePull(m.ctx, m.image, image.PullOptions{})
if err != nil {
return pullMsg{err}
}
defer reader.Close()
_, _ = io.Copy(io.Discard, reader)
return pullMsg{nil}
},
)
}

func (m pullSpinnerModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
if msg.String() == "q" {
m.quitting = true
return m, tea.Quit
}
case pullMsg:
if msg.err != nil {
logger.Error("Image pull failed", "error", msg.err)
}
m.quitting = true
return m, tea.Quit
case spinner.TickMsg:
var cmd tea.Cmd
m.spinner, cmd = m.spinner.Update(msg)
return m, cmd
}
return m, nil
}

func (m pullSpinnerModel) View() string {
if m.quitting {
return ""
}
return fmt.Sprintf("\n %s Pulling RabbitMQ image...\n\n", m.spinner.View())
}

0 comments on commit 1010c34

Please sign in to comment.