| 690 | } |
| 691 | |
| 692 | func parseTerraformLogLine(line []byte) *terraformProvisionLog { |
| 693 | var log terraformProvisionLog |
| 694 | err := json.Unmarshal(line, &log) |
| 695 | if err != nil { |
| 696 | // Sometimes terraform doesn't log JSON, even though we asked it to. |
| 697 | // The terraform maintainers have said on the issue tracker that |
| 698 | // they don't guarantee that non-JSON lines won't get printed. |
| 699 | // https://github.com/hashicorp/terraform/issues/29252#issuecomment-887710001 |
| 700 | // |
| 701 | // > I think as a practical matter it isn't possible for us to |
| 702 | // > promise that the output will always be entirely JSON, because |
| 703 | // > there's plenty of code that runs before command line arguments |
| 704 | // > are parsed and thus before we even know we're in JSON mode. |
| 705 | // > Given that, I'd suggest writing code that consumes streaming |
| 706 | // > JSON output from Terraform in such a way that it can tolerate |
| 707 | // > the output not having JSON in it at all. |
| 708 | // |
| 709 | // Log lines such as: |
| 710 | // - Acquiring state lock. This may take a few moments... |
| 711 | // - Releasing state lock. This may take a few moments... |
| 712 | if len(bytes.TrimSpace(line)) == 0 { |
| 713 | return nil |
| 714 | } |
| 715 | log.Level = "info" |
| 716 | log.Message = string(line) |
| 717 | } |
| 718 | return &log |
| 719 | } |
| 720 | |
| 721 | func extractTimingSpan(log *terraformProvisionLog) (time.Time, *timingSpan, error) { |
| 722 | // Input is not well-formed, bail out. |