Skip to content

Commit

Permalink
Merge pull request #78 from Backblaze/windows-2019
Browse files Browse the repository at this point in the history
Add support for Windows amd64
  • Loading branch information
mlech-reef authored Aug 29, 2024
2 parents 3bd0602 + bf47ecc commit eceda1d
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 72 deletions.
20 changes: 17 additions & 3 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ on:
push:
tags: 'v*' # push events to matching v*, i.e. v1.0, v20.15.10

defaults:
run:
shell: bash

env:
PYTHON_DEFAULT_VERSION: '3.9'
GO_DEFAULT_VERSION: '1.20'
Expand All @@ -22,6 +26,7 @@ jobs:
# macos-13-xlarge instance are Apple silicon instances,
# only large and xlarge instances are available as of yet.
- { runner: macos-13-large, os: darwin, arch: arm64 }
- { runner: windows-2019, os: windows, arch: amd64 }
outputs:
version: ${{ steps.build.outputs.version }}
steps:
Expand All @@ -44,8 +49,8 @@ jobs:
--name builder \
python:${{ env.PYTHON_DEFAULT_VERSION }}-bullseye \
/bin/bash -c "sleep infinity"
- name: Set up Python ${{ env.PYTHON_DEFAULT_VERSION }} (darwin)
if: matrix.conf.os == 'darwin'
- name: Set up Python ${{ env.PYTHON_DEFAULT_VERSION }} (darwin, windows)
if: matrix.conf.os != 'linux'
uses: actions/setup-python@v2
with:
python-version: ${{ env.PYTHON_DEFAULT_VERSION }}
Expand All @@ -60,11 +65,19 @@ jobs:
- name: Define command wrapper (darwin)
if: matrix.conf.os == 'darwin'
run: |
# MacOS wraper just runs commands in python-bindings directory
# MacOS wrapper just runs commands in python-bindings directory
echo '#!/bin/bash' > run
echo 'pushd python-bindings; "$@"; popd' >> run
chmod +x run
sudo mv run /usr/local/bin/run
- name: Define command wrapper (windows)
if: matrix.conf.os == 'windows'
run: |
# Windows wrapper just runs commands in python-bindings directory
echo '#!/bin/bash' > run
echo 'pushd python-bindings; "$@"; popd' >> run
chmod +x run
mv run /usr/bin/run
- name: Install system dependencies (linux)
if: matrix.conf.os == 'linux'
run: |
Expand Down Expand Up @@ -116,6 +129,7 @@ jobs:
mv artifacts/py-terraform-provider-b2-linux-arm64/py-terraform-provider-b2 py-terraform-provider-b2-linux-arm64
mv artifacts/py-terraform-provider-b2-darwin-amd64/py-terraform-provider-b2 py-terraform-provider-b2-darwin-amd64
mv artifacts/py-terraform-provider-b2-darwin-arm64/py-terraform-provider-b2 py-terraform-provider-b2-darwin-arm64
mv artifacts/py-terraform-provider-b2-windows-amd64/py-terraform-provider-b2 py-terraform-provider-b2-windows-amd64
- name: Set release version output
id: version
run: |
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ on:
pull_request:
branches: [master]

defaults:
run:
shell: bash

env:
PYTHON_DEFAULT_VERSION: '3.9'
GO_DEFAULT_VERSION: '1.20'
Expand Down Expand Up @@ -52,6 +56,7 @@ jobs:
os:
- ubuntu-latest
- macos-12
- windows-2019
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ env.PYTHON_DEFAULT_VERSION }} (ubuntu-latest)
Expand Down Expand Up @@ -94,12 +99,15 @@ jobs:
os:
- ubuntu-latest
- macos-12
- windows-2019
terraform:
- '1.5.*'
- '1.4.*'
exclude:
- os: macos-12 # for macOS, the latest terraform is enough for ACC tests
terraform: '1.4.*'
- os: windows-2019 # for Windows, the latest terraform is enough for ACC tests
terraform: '1.4.*'
steps:
- uses: actions/checkout@v2
- name: Set up Go ${{ env.GO_DEFAULT_VERSION }}
Expand Down
4 changes: 4 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@ builds:
goos:
- linux
- darwin
- windows
goarch:
- amd64
- arm64
ignore:
- goos: windows
goarch: arm64
hooks:
pre:
- cp python-bindings/dist/py-terraform-provider-b2-{{ .Os }}-{{ .Arch }} python-bindings/dist/py-terraform-provider-b2
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Infrastructure
* Replace removed macOS 11 Big Sur in favour of macOS 12 Monterey in CI/CD
* Add support for Windows

## [0.8.12] - 2024-06-20

Expand Down
104 changes: 104 additions & 0 deletions b2/bindings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
//####################################################################
//
// File: b2/bindings.go
//
// Copyright 2024 Backblaze Inc. All Rights Reserved.
//
// License https://www.backblaze.com/using_b2_code.html
//
//####################################################################

package b2

import (
"bufio"
"github.com/markbates/pkger"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"runtime"
"sync"
)

var (
bindings *string
lock = &sync.Mutex{}
)

func GetBindings(sourcePath string, testing bool) (string, error) {
if bindings == nil {
lock.Lock()
defer lock.Unlock()
}
if bindings != nil {
return *bindings, nil
}

var sourceFile io.ReadCloser
if testing == true {
src, err := os.Open(sourcePath)
if err != nil {
return "", err
}
sourceFile = src
} else {
src, err := pkger.Open(sourcePath)
if err != nil {
return "", err
}
sourceFile = src
}
defer sourceFile.Close()

var tmpPattern string
if runtime.GOOS == "windows" {
tmpPattern = "py-terraform-provider*.exe"
} else {
tmpPattern = "py-terraform-provider*"
}

destinationFile, err := ioutil.TempFile("", tmpPattern)
if err != nil {
return "", err
}
defer destinationFile.Close()

destinationPath := filepath.ToSlash(destinationFile.Name())
reader := bufio.NewReader(sourceFile)
buf := make([]byte, 2048)

for {
_, err := reader.Read(buf)

if err != nil {
if err != io.EOF {
return destinationPath, err
}

_, err = destinationFile.Seek(0, 0)
if err != nil {
return destinationPath, err
}

break
}

_, err = destinationFile.Write(buf)
if err != nil {
return destinationPath, err
}
}

destinationFile.Close()

err = os.Chmod(destinationPath, 0770)
if err != nil {
return destinationPath, err
}

bindings = &destinationPath
log.Printf("[TRACE] Extracted pybindings: %s\n", *bindings)
return *bindings, nil
}
19 changes: 15 additions & 4 deletions b2/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,37 @@ package b2

import (
"io/ioutil"
"log"
"os"
"path/filepath"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

var testExec = filepath.FromSlash("../python-bindings/dist/py-terraform-provider-b2")
// Use external pybindings executable from git repo, not embedded one.
var pybindingsSource string = "../python-bindings/dist/py-terraform-provider-b2"

// providerFactories are used to instantiate a provider during acceptance testing.
// The factory function will be invoked for every Terraform CLI command executed
// to create a provider server to which the CLI can reattach.
var providerFactories = map[string]func() (*schema.Provider, error){
"b2": func() (*schema.Provider, error) {
return New("test", testExec)(), nil
pybindings, err := GetBindings(pybindingsSource, true)
if err != nil {
log.Fatal(err.Error())
return nil, err
}
return New("test", pybindings)(), nil
},
}

func TestProvider(t *testing.T) {
if err := New("test", testExec)().InternalValidate(); err != nil {
pybindings, err := GetBindings(pybindingsSource, true)
if err != nil {
t.Fatalf("err: %s", err)
}
if err := New("test", pybindings)().InternalValidate(); err != nil {
t.Fatalf("err: %s", err)
}
}
Expand Down Expand Up @@ -65,5 +76,5 @@ func createTempFile(t *testing.T, data string) string {
t.Fatal(err)
}

return filename
return filepath.ToSlash(filename)
}
70 changes: 7 additions & 63 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,89 +11,33 @@
package main

import (
"bufio"
"flag"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"

"github.com/Backblaze/terraform-provider-b2/b2"
"github.com/hashicorp/terraform-plugin-sdk/v2/plugin"
"github.com/markbates/pkger"
"log"
"os"
)

var (
// these will be set by the goreleaser configuration
// to appropriate values for the compiled binary
pkgerInput string = "/python-bindings/dist/py-terraform-provider-b2"
version string = "dev"
pybindingsSource string = "/python-bindings/dist/py-terraform-provider-b2"
version string = "dev"
)

func extractPybindings(sourcePath string) (string, error) {
sourceFile, err := pkger.Open(sourcePath)
if err != nil {
return "", err
}
defer sourceFile.Close()

destinationFile, err := ioutil.TempFile("", "py-terraform-provider")
if err != nil {
return "", err
}
defer destinationFile.Close()

destinationPath := destinationFile.Name()
reader := bufio.NewReader(sourceFile)
buf := make([]byte, 2048)

for {
_, err := reader.Read(buf)

if err != nil {
if err != io.EOF {
return destinationPath, err
}

_, err = destinationFile.Seek(0, 0)
if err != nil {
return destinationPath, err
}

break
}

_, err = destinationFile.Write(buf)
if err != nil {
return destinationPath, err
}
}

destinationFile.Close()

err = os.Chmod(destinationPath, 0770)
if err != nil {
return destinationPath, err
}

log.Printf("[TRACE] Extracted pybindings: %s\n", destinationPath)
return destinationPath, nil
}

func main() {
var debugMode bool

flag.BoolVar(&debugMode, "debug", false, "set to true to run the provider with support for debuggers like delve")
flag.Parse()

pkgerOutput, err := extractPybindings(filepath.FromSlash(pkgerInput))
pybindings, err := b2.GetBindings(pybindingsSource, false)
if err != nil {
log.Fatal(err.Error())
return
}
defer os.Remove(pkgerOutput)
defer os.Remove(pybindings)

opts := &plugin.ServeOpts{ProviderFunc: b2.New(version, pkgerOutput), Debug: debugMode}
opts := &plugin.ServeOpts{ProviderFunc: b2.New(version, pybindings), Debug: debugMode}
plugin.Serve(opts)
}
7 changes: 5 additions & 2 deletions python-bindings/GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ NAME=py-terraform-provider-b2
DIR=b2_terraform
EGG_INFO=${NAME}.egg-info
SPEC=${NAME}.spec
UNAME_=$(shell uname)
OS=$(shell python -c "import platform; print(platform.system())")

default: build

Expand All @@ -26,11 +26,14 @@ clean:

build:
@pyinstaller ${SPEC}
ifeq ($(UNAME_), Linux)
ifeq ($(OS), Linux)
@mv -f dist/py-terraform-provider-b2 dist/py-terraform-provider-b2-linked
@staticx --strip --loglevel INFO dist/py-terraform-provider-b2-linked dist/py-terraform-provider-b2
@rm -f dist/py-terraform-provider-b2-linked
endif
ifeq ($(OS), Windows)
@mv -f dist/py-terraform-provider-b2.exe dist/py-terraform-provider-b2
endif
ifneq ($(origin CI), undefined)
@echo "version=$(subst refs/tags/v,,${GITHUB_REF})" > "${GITHUB_OUTPUT}"
endif
Expand Down

0 comments on commit eceda1d

Please sign in to comment.