No description
Find a file
Ilia Gogotchuri 491be2b7cc
Add nightly download method to downloader (#12)
Signed-off-by: Ilia Gogotchuri <ilia.gogotchuri0@gmail.com>
Co-authored-by: James Humphries <James@james-humphries.co.uk>
2025-10-27 14:52:54 +04:00
.github/workflows Added mockmirror for testing 2024-07-23 23:58:53 +02:00
branding Limit archive size to 1GB for 32bit arch 2024-09-23 13:34:47 +12:00
cli Adding caching 2024-07-18 10:03:25 +02:00
cmd/tofudl CLI implementation 2024-07-15 17:55:47 +02:00
internal Standalone mirror tests 2024-07-30 17:14:08 +02:00
mockmirror Standalone mirror tests 2024-07-30 17:14:08 +02:00
.gitignore Standalone mirror tests 2024-07-30 17:14:08 +02:00
.golangci.yml Initial import 2024-07-15 17:54:25 +02:00
api.schema.json Mirror specification (#7) 2025-06-12 14:57:43 +04:00
architecture.go Initial import 2024-07-15 17:54:25 +02:00
config.go Initial import 2024-07-15 17:54:25 +02:00
downloader.go Add nightly download method to downloader (#12) 2025-10-27 14:52:54 +04:00
downloader_download.go Add nightly download method to downloader (#12) 2025-10-27 14:52:54 +04:00
downloader_download_artifact.go Adding caching 2024-07-18 10:03:25 +02:00
downloader_download_nightly.go Add nightly download method to downloader (#12) 2025-10-27 14:52:54 +04:00
downloader_download_version.go Add nightly download method to downloader (#12) 2025-10-27 14:52:54 +04:00
downloader_list_versions.go Adding caching 2024-07-18 10:03:25 +02:00
downloader_nightly_test.go Add nightly download method to downloader (#12) 2025-10-27 14:52:54 +04:00
downloader_test.go Add nightly download method to downloader (#12) 2025-10-27 14:52:54 +04:00
downloader_verify_artifact.go Add nightly download method to downloader (#12) 2025-10-27 14:52:54 +04:00
errors.go Pluggable cache storage 2024-07-18 10:44:12 +02:00
generate.go Added mockmirror for testing 2024-07-23 23:58:53 +02:00
go.mod Bump golang.org/x/crypto from 0.25.0 to 0.31.0 2025-01-29 12:25:08 +00:00
go.sum Bump golang.org/x/crypto from 0.25.0 to 0.31.0 2025-01-29 12:25:08 +00:00
http.go Initial import 2024-07-15 17:54:25 +02:00
LICENSE License file 2024-07-15 17:49:39 +02:00
MIRROR-SPECIFICATION.md Mirror specification (#7) 2025-06-12 14:57:43 +04:00
mirror.go Linting 2024-07-30 17:15:33 +02:00
mirror_create_version.go Linting fixes 2024-07-24 10:25:44 +02:00
mirror_create_version_asset.go Linting fixes 2024-07-24 10:25:44 +02:00
mirror_download.go Fixes #3: Mirror tool 2024-07-24 10:12:40 +02:00
mirror_download_artifact.go Fixes #3: Mirror tool 2024-07-24 10:12:40 +02:00
mirror_download_nightly.go Add nightly download method to downloader (#12) 2025-10-27 14:52:54 +04:00
mirror_download_version.go Fixing bug with standalone mode 2024-07-30 16:58:22 +02:00
mirror_list_versions.go Fixes #3: Mirror tool 2024-07-24 10:12:40 +02:00
mirror_prewarm.go Fixes #3: Mirror tool 2024-07-24 10:12:40 +02:00
mirror_serve_http.go Linting fixes 2024-07-24 10:25:44 +02:00
mirror_storage.go Fixes #3: Mirror tool 2024-07-24 10:12:40 +02:00
mirror_storage_filesystem.go Fixes #3: Mirror tool 2024-07-24 10:12:40 +02:00
mirror_test.go Removed dead code 2024-07-30 18:15:47 +02:00
mirror_verify_artifact.go Fixing bug with standalone mode 2024-07-30 16:58:22 +02:00
nightly_id.go Add nightly download method to downloader (#12) 2025-10-27 14:52:54 +04:00
platform.go Initial import 2024-07-15 17:54:25 +02:00
README.md Add nightly download method to downloader (#12) 2025-10-27 14:52:54 +04:00
release_builder.go Readme and go generate 2024-07-24 10:18:23 +02:00
stability.go Initial import 2024-07-15 17:54:25 +02:00
version.go Initial import 2024-07-15 17:54:25 +02:00

TofuDL: OpenTofu downloader library for Go with minimal dependencies

This library provides an easy way to download, verify, and unpack OpenTofu binaries for local use in Go. It has a minimal set of dependencies and is easy to integrate.

Note: This is not a standalone tool to download OpenTofu, it is purely meant to be used as Go library in support of other tools that need to run tofu. Please check the installation instructions for supported ways to perform an OpenTofu installation.

Basic usage

The downloader will work without any extra configuration out of the box:

package main

import (
    "context"
    "os"
    "os/exec"
    "runtime"

    "github.com/opentofu/tofudl"
)

func main() {
    // Initialize the downloader:
    dl, err := tofudl.New()
    if err != nil {
        panic(err)
    }

    // Download the latest stable version
    // for the current architecture and platform:
    binary, err := dl.Download(context.TODO())
    if err != nil {
        panic(err)
    }

    // Write out the tofu binary to the disk:
    file := "tofu"
    if runtime.GOOS == "windows" {
        file += ".exe"
    }
    if err := os.WriteFile(file, binary, 0755); err != nil {
        panic(err)
    }

    // Run tofu:
    cmd := exec.Command("./"+file, "init")
    if err := cmd.Run(); err != nil {
        panic(err)
    }
}

Caching

This library also supports caching using the mirror tool:

package main

import (
    "context"
    "os"
    "os/exec"
    "runtime"
    "time"

    "github.com/opentofu/tofudl"
)

func main() {
    // Initialize the downloader:
    dl, err := tofudl.New()
    if err != nil {
        panic(err)
    }

    // Set up the caching layer:
    storage, err := tofudl.NewFilesystemStorage("/tmp")
    if err != nil {
        panic(err)
    }
    mirror, err := tofudl.NewMirror(
        tofudl.MirrorConfig{
            AllowStale: false,
            APICacheTimeout: time.Minute * 10,
            ArtifactCacheTimeout: time.Hour * 24,
        },
        storage,
        dl,
    )
    if err != nil {
        panic(err)
    }

    // Download the latest stable version
    // for the current architecture and platform:
    binary, err := mirror.Download(context.TODO())
    if err != nil {
        panic(err)
    }

    // Write out the tofu binary to the disk:
    file := "tofu"
    if runtime.GOOS == "windows" {
        file += ".exe"
    }
    if err := os.WriteFile(file, binary, 0755); err != nil {
        panic(err)
    }

    // Run tofu:
    cmd := exec.Command("./"+file, "init")
    if err := cmd.Run(); err != nil {
        panic(err)
    }
}

You can also use the mirror variable as an http.Handler. Additionally, you can also call PreWarm on the caching layer in order to pre-warm your local caches. (Be careful, this may take a long time!)

Standalone mirror

The example above showed a cache/mirror that acts as a pull-through cache to upstream. You can alternatively also use the mirror as a stand-alone mirror and publish your own binaries. The mirror has functions to facilitate uploading basic artifacts, but you can also use the ReleaseBuilder to make building releases easier. (Note: the ReleaseBuilder only builds artifacts needed for TofuDL, not all artifacts OpenTofu typically publishes.)

Advanced usage

Both New() and Download() accept a number of options. You can find the detailed documentation here.

Nightly Download

You can download the latest or a specified nightly build of OpenTofu using the new DownloadNightly method:

package main

import (
    "context"
    "os"
    "runtime"

    "github.com/opentofu/tofudl"
)

func main() {
    dl, err := tofudl.New()
    if err != nil {
        panic(err)
    }

    // Download the nightly build with ID 20251018-dc9bec611c for the current platform/architecture
    // You can pass platform and architecture options like usual. For the latest build, you can omit build ID.
    binary, err := dl.DownloadNightly(context.TODO(), dl.DownloadOptNightlyBuildID("20251018-dc9bec611c"))
    if err != nil {
        panic(err)
    }

    file := "tofu"
    if runtime.GOOS == "windows" {
        file += ".exe"
    }
    if err := os.WriteFile(file, binary, 0755); err != nil {
        panic(err)
    }
}

Note: Nightly downloads are not supported via the mirror/caching layer. You must use the downloader directly for nightly builds.