99 "charm.land/lipgloss/v2"
1010 composecli "github.com/compose-spec/compose-go/v2/cli"
1111 "github.com/docker/compose/v2/pkg/progress"
12+ "github.com/docker/docker/pkg/stringid"
1213 "github.com/psviderski/uncloud/internal/cli"
1314 "github.com/psviderski/uncloud/internal/cli/logs"
1415 "github.com/psviderski/uncloud/internal/cli/tui"
@@ -20,10 +21,6 @@ import (
2021 "github.com/spf13/cobra"
2122)
2223
23- // failedContainerLogsTail is the number of recent log lines to print from a failed container to give the user immediate
24- // context without requiring a follow-up 'uc logs' invocation.
25- const failedContainerLogsTail = 10
26-
2724type deployOptions struct {
2825 cli.BuildServicesOptions
2926
@@ -238,34 +235,46 @@ func runDeploy(ctx context.Context, uncli *cli.CLI, opts deployOptions) error {
238235 }, uncli .ProgressOut (), title )
239236 if err != nil {
240237 fmt .Println ()
238+
239+ tail := failedContainerLogsTail ()
241240 if hookErr , ok := errors.AsType [* operation.PreDeployHookError ](err ); ok {
242- printPreDeployHookLogs (ctx , clusterClient , hookErr )
241+ printFailedContainerLogs (ctx , clusterClient ,
242+ hookErr .ServiceName , hookErr .ContainerID , hookErr .MachineName , tail ,
243+ fmt .Sprintf ("Last %d log lines from failed pre-deploy hook:" , tail ))
244+ fmt .Println ()
245+ } else if startErr , ok := errors.AsType [* operation.ContainerHealthError ](err ); ok {
246+ printFailedContainerLogs (ctx , clusterClient ,
247+ startErr .ServiceName , startErr .ContainerID , startErr .MachineName , tail ,
248+ fmt .Sprintf ("Last %d log lines from failed container:" , tail ))
243249 fmt .Println ()
244250 }
251+
245252 return err
246253 }
247254 return nil
248255}
249256
250- // printPreDeployHookLogs fetches the last log lines from the failed pre-deploy hook container and prints them using
251- // the standard log formatter.
252- func printPreDeployHookLogs (ctx context.Context , cli * client.Client , hookErr * operation.PreDeployHookError ) {
253- _ , ch , err := cli .ServiceLogs (ctx , hookErr .ServiceName , api.ServiceLogsOptions {
254- Containers : []string {hookErr .ContainerID },
255- Machines : []string {hookErr .MachineName },
256- Tail : failedContainerLogsTail ,
257+ // printFailedContainerLogs fetches the last tail log lines from a container that failed during deployment and prints
258+ // them using the standard log formatter under the provided header.
259+ func printFailedContainerLogs (
260+ ctx context.Context , cli * client.Client , serviceName , containerID , machineName string , tail int , header string ,
261+ ) {
262+ _ , ch , err := cli .ServiceLogs (ctx , serviceName , api.ServiceLogsOptions {
263+ Containers : []string {containerID },
264+ Machines : []string {machineName },
265+ Tail : tail ,
257266 })
258267 if err != nil {
259- fmt .Fprintf (os .Stderr , "Failed to fetch pre-deploy hook logs: %v\n " , err )
260- fmt .Fprintf (os .Stderr , "You can try manually with: uc logs %s\n " , hookErr .ServiceName )
268+ shortCtrID := stringid .TruncateID (containerID )
269+ fmt .Fprintf (os .Stderr , "Failed to fetch container logs '%s/%s': %v\n " , serviceName , shortCtrID , err )
270+ fmt .Fprintf (os .Stderr , "You can try manually with: uc logs %s/%s\n " , serviceName , shortCtrID )
261271 return
262272 }
263273
264- header := fmt .Sprintf ("Last %d log lines from failed pre-deploy hook:" , failedContainerLogsTail )
265274 fmt .Println (tui .BoldRed .Render (header ))
266275
267276 logsEmpty := true
268- formatter := logs .NewFormatter ([]string {hookErr . MachineName }, []string {hookErr . ServiceName }, false )
277+ formatter := logs .NewFormatter ([]string {machineName }, []string {serviceName }, false )
269278 for entry := range ch {
270279 logsEmpty = false
271280 formatter .PrintEntry (entry )
@@ -275,3 +284,19 @@ func printPreDeployHookLogs(ctx context.Context, cli *client.Client, hookErr *op
275284 fmt .Println ("<no logs available>" )
276285 }
277286}
287+
288+ // defaultFailedContainerLogsTail is the default number of recent log lines to print from a failed container to give
289+ // the user immediate context without requiring a follow-up 'uc logs' invocation.
290+ // Overridable via UNCLOUD_FAILED_CONTAINER_LOGS_TAIL.
291+ const defaultFailedContainerLogsTail = 10
292+
293+ // failedContainerLogsTail returns the number of log lines to fetch from a failed container, honouring the
294+ // UNCLOUD_FAILED_CONTAINER_LOGS_TAIL environment variable override when set and valid.
295+ func failedContainerLogsTail () int {
296+ if v := os .Getenv ("UNCLOUD_FAILED_CONTAINER_LOGS_TAIL" ); v != "" {
297+ if tail , err := logs .Tail (v ); err == nil && (tail == - 1 || tail > 0 ) {
298+ return tail
299+ }
300+ }
301+ return defaultFailedContainerLogsTail
302+ }
0 commit comments