writeFileWithStatus() which shows 'Creating' for new, 'Updating' for changed and 'Unchanged' for files that won't change

This commit is contained in:
Pim van Pelt
2025-08-25 11:51:41 +02:00
parent c9c1e81619
commit 38fe915b37
5 changed files with 65 additions and 71 deletions

View File

@@ -2,7 +2,6 @@ package main
import (
"fmt"
"io"
"log"
"os"
"path/filepath"
@@ -25,11 +24,10 @@ func generateEnv(yamlFile string) {
// Create combined roots.pem file
rootsPemPath := filepath.Join(logEntry.LocalDirectory, "roots.pem")
err := createCombinedRootsPem(config.Roots, logEntry.ExtraRoots, rootsPemPath)
err := createCombinedRootsPemWithStatus(config.Roots, logEntry.ExtraRoots, rootsPemPath)
if err != nil {
log.Fatalf("Failed to create %s: %v", rootsPemPath, err)
}
fmt.Printf("Generated %s\n", rootsPemPath)
// Build TESSERACT_ARGS string
args := []string{
@@ -47,50 +45,32 @@ func generateEnv(yamlFile string) {
tesseractArgs := strings.Join(args, " ")
envContent := fmt.Sprintf("TESSERACT_ARGS=\"%s\"\nOTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318\n", tesseractArgs)
err = os.WriteFile(envPath, []byte(envContent), 0644)
err = writeFileWithStatus(envPath, []byte(envContent))
if err != nil {
log.Fatalf("Failed to write %s: %v", envPath, err)
}
fmt.Printf("Generated %s\n", envPath)
}
}
func createCombinedRootsPem(rootsFile, extraRootsFile, outputPath string) error {
// Create output file
outputFile, err := os.Create(outputPath)
if err != nil {
return fmt.Errorf("failed to create output file: %v", err)
}
defer outputFile.Close()
// Copy main roots file
func createCombinedRootsPemWithStatus(rootsFile, extraRootsFile, outputPath string) error {
// Read main roots file
var combinedContent []byte
if rootsFile != "" {
rootsData, err := os.Open(rootsFile)
rootsData, err := os.ReadFile(rootsFile)
if err != nil {
return fmt.Errorf("failed to open roots file %s: %v", rootsFile, err)
}
defer rootsData.Close()
_, err = io.Copy(outputFile, rootsData)
if err != nil {
return fmt.Errorf("failed to copy roots file: %v", err)
return fmt.Errorf("failed to read roots file %s: %v", rootsFile, err)
}
combinedContent = append(combinedContent, rootsData...)
}
// Append extra roots file if it exists
if extraRootsFile != "" {
extraRootsData, err := os.Open(extraRootsFile)
extraRootsData, err := os.ReadFile(extraRootsFile)
if err != nil {
return fmt.Errorf("failed to open extra roots file %s: %v", extraRootsFile, err)
}
defer extraRootsData.Close()
_, err = io.Copy(outputFile, extraRootsData)
if err != nil {
return fmt.Errorf("failed to copy extra roots file: %v", err)
return fmt.Errorf("failed to read extra roots file %s: %v", extraRootsFile, err)
}
combinedContent = append(combinedContent, extraRootsData...)
}
return nil
return writeFileWithStatus(outputPath, combinedContent)
}

View File

@@ -1,6 +1,7 @@
package main
import (
"bytes"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
@@ -136,27 +137,25 @@ func generateHTML(yamlFile string) {
for _, logEntry := range config.Logs {
indexPath := fmt.Sprintf("%s/index.html", logEntry.LocalDirectory)
file, err := os.Create(indexPath)
// Execute template to buffer
var buf bytes.Buffer
err := tmpl.Execute(&buf, config)
if err != nil {
log.Fatalf("Failed to create %s: %v", indexPath, err)
log.Fatalf("Failed to execute HTML template for %s: %v", indexPath, err)
}
err = tmpl.Execute(file, config)
// Write file with status
err = writeFileWithStatus(indexPath, buf.Bytes())
if err != nil {
file.Close()
log.Fatalf("Failed to write HTML to %s: %v", indexPath, err)
}
file.Close()
fmt.Printf("Generated %s\n", indexPath)
// Generate log.v3.json for this log
jsonPath := filepath.Join(logEntry.LocalDirectory, "log.v3.json")
err = generateLogJSON(logEntry, jsonPath)
err = generateLogJSONWithStatus(logEntry, jsonPath)
if err != nil {
log.Fatalf("Failed to generate %s: %v", jsonPath, err)
}
fmt.Printf("Generated %s\n", jsonPath)
}
}
@@ -210,7 +209,7 @@ func computeKeyInfo(logEntry *Log) error {
return nil
}
func generateLogJSON(logEntry Log, outputPath string) error {
func generateLogJSONWithStatus(logEntry Log, outputPath string) error {
logJSON := LogV3JSON{
Description: fmt.Sprintf("%s.log.ct.ipng.ch", logEntry.ShortName),
SubmissionURL: fmt.Sprintf("%s/", logEntry.SubmissionPrefix),
@@ -229,10 +228,5 @@ func generateLogJSON(logEntry Log, outputPath string) error {
return fmt.Errorf("failed to marshal JSON: %v", err)
}
err = os.WriteFile(outputPath, jsonData, 0644)
if err != nil {
return fmt.Errorf("failed to write JSON file: %v", err)
}
return nil
return writeFileWithStatus(outputPath, jsonData)
}

View File

@@ -97,6 +97,26 @@ func loadConfig(yamlFile string) Config {
return config
}
func writeFileWithStatus(filename string, content []byte) error {
existingContent, err := os.ReadFile(filename)
if os.IsNotExist(err) {
fmt.Printf("Creating %s\n", filename)
} else if err != nil {
return fmt.Errorf("failed to read existing file %s: %v", filename, err)
} else if string(existingContent) == string(content) {
fmt.Printf("Unchanged %s\n", filename)
return nil
} else {
fmt.Printf("Updating %s\n", filename)
}
err = os.WriteFile(filename, content, 0644)
if err != nil {
return fmt.Errorf("failed to write file %s: %v", filename, err)
}
return nil
}
func showHelp() {
fmt.Printf("Usage: %s [options] <command>\n\n", os.Args[0])
fmt.Printf("Options:\n")

View File

@@ -1,6 +1,7 @@
package main
import (
"bytes"
"fmt"
"net/url"
"os"
@@ -113,22 +114,20 @@ func generateNginx(yamlFile string) {
outputFilename := fmt.Sprintf("%s.conf", hostname)
outputPath := filepath.Join(log.LocalDirectory, outputFilename)
// Create output file
file, err := os.Create(outputPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to create nginx config file %s: %v\n", outputPath, err)
continue
}
defer file.Close()
// Execute template
err = tmpl.Execute(file, data)
// Execute template to buffer
var buf bytes.Buffer
err = tmpl.Execute(&buf, data)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to execute nginx template for %s: %v\n", outputPath, err)
continue
}
fmt.Printf("Generated nginx config: %s\n", outputPath)
// Write file with status
err = writeFileWithStatus(outputPath, buf.Bytes())
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to write nginx config file %s: %v\n", outputPath, err)
continue
}
}
}

View File

@@ -1,6 +1,7 @@
package main
import (
"bytes"
"crypto/x509"
"encoding/base64"
"encoding/json"
@@ -8,7 +9,6 @@ import (
"fmt"
"log"
"net/http"
"os"
"strings"
)
@@ -67,15 +67,10 @@ func generateRoots(args []string) {
log.Fatalf("Failed to parse JSON response: %v", err)
}
// Create output file
outFile, err := os.Create(outputFile)
if err != nil {
log.Fatalf("Failed to create output file %s: %v", outputFile, err)
}
defer outFile.Close()
// Write each certificate as PEM
// Collect all valid certificates in a buffer
var pemBuffer bytes.Buffer
validCertCount := 0
for _, certBase64 := range rootsResp.Certificates {
// Decode base64 certificate
certBytes, err := base64.StdEncoding.DecodeString(certBase64)
@@ -102,14 +97,20 @@ func generateRoots(args []string) {
Bytes: certBytes,
}
// Write PEM to file
err = pem.Encode(outFile, pemBlock)
// Write PEM to buffer
err = pem.Encode(&pemBuffer, pemBlock)
if err != nil {
log.Fatalf("Failed to write PEM certificate: %v", err)
log.Fatalf("Failed to encode PEM certificate: %v", err)
}
validCertCount++
}
// Write all certificates to file with status
err = writeFileWithStatus(outputFile, pemBuffer.Bytes())
if err != nil {
log.Fatalf("Failed to write output file %s: %v", outputFile, err)
}
fmt.Printf("Successfully wrote %d certificates to %s (out of %d total)\n", validCertCount, outputFile, len(rootsResp.Certificates))
}