Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add initial windows support #5

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ root = true
[*]
insert_final_newline = true
trim_trailing_whitespace = true
indent_size = 4

[*.{yml,yaml}]
indent_size = 2
43 changes: 35 additions & 8 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ jobs:
- os: macos
image: macos-latest
target: x86_64-apple-darwin
- os: windows
image: windows-latest
target: x86_64-pc-windows-msvc

steps:
- uses: actions/checkout@v2
Expand All @@ -42,17 +45,28 @@ jobs:
if: ${{ matrix.os == 'linux' }}
run: cross build --release --target=${{ matrix.target }} --verbose

- name: Build macos
if: ${{ matrix.os == 'macos' }}
- name: Build != linux
if: ${{ matrix.os != 'linux' }}
run: cargo build --release --target=${{ matrix.target }} --verbose

- name: Prepare
shell: bash
run: |
final_binary=${{ env.BINARY_NAME }}-${{ matrix.target }}
mv target/${{ matrix.target }}/release/${{ env.BINARY_NAME }} $final_binary
compress() {
if [[ "${{ matrix.os }}" = "windows" ]]; then
7z a $(echo $1 | sed 's/\.exe$//').zip $1
else
gzip -f9 $1
fi
}
if [[ "${{ matrix.os }}" = "windows" ]]; then
suffix=.exe
fi
final_binary=${{ env.BINARY_NAME }}-${{ matrix.target }}${suffix}
mv target/${{ matrix.target }}/release/${{ env.BINARY_NAME }}${suffix} $final_binary
ls
file $final_binary
gzip -f9 $final_binary
compress $final_binary

- name: Archive binary artifacts
uses: actions/upload-artifact@v2
Expand All @@ -61,6 +75,7 @@ jobs:
if-no-files-found: warn
path: |
*.gz
*.zip

create_release:
name: Create Release
Expand Down Expand Up @@ -90,8 +105,20 @@ jobs:
matrix:
include:
- target: x86_64-unknown-linux-musl
content_type: application/gzip
extension: gz
- target: aarch64-unknown-linux-musl
content_type: application/gzip
extension: gz
- target: x86_64-apple-darwin
content_type: application/gzip
extension: gz
- target: x86_64-apple-darwin
content_type: application/gzip
extension: gz
- target: x86_64-pc-windows-msvc
content_type: application/zip
extension: zip
steps:
- name: Download all workflow run artifacts
uses: actions/download-artifact@v2
Expand All @@ -103,6 +130,6 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
asset_path: ./binaries/${{ env.BINARY_NAME }}-${{ matrix.target }}.gz
asset_name: ${{ env.BINARY_NAME }}-${{ matrix.target }}.gz
asset_content_type: application/gzip
asset_path: ./binaries/${{ env.BINARY_NAME }}-${{ matrix.target }}.${{ matrix.extension }}
asset_name: ${{ env.BINARY_NAME }}-${{ matrix.target }}.${{ matrix.extension }}
asset_content_type: ${{ matrix.content_type }}
15 changes: 15 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ jobs:
image: ubuntu-latest
- os: macos
image: macos-latest
- os: windows
image: windows-latest

steps:
- uses: actions/checkout@v2
Expand All @@ -39,6 +41,19 @@ jobs:
set -ex
brew install gpg sops kustomize

# Chocolatey times out, so scoop it is
- name: Install windows
if: ${{ matrix.os == 'windows' }}
run: |
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
scoop install gnupg sops kustomize
echo "C:\Users\runneradmin\scoop\shims" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Check for kustomize
if: ${{ matrix.os == 'windows' }}
run: |
echo $env:PATH
get-command kustomize

- name: Build
run: cargo build --verbose
- name: Run tests
Expand Down
67 changes: 67 additions & 0 deletions src/installer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#[cfg(target_family = "unix")]
use std::os::unix::fs::symlink;
#[cfg(target_family = "windows")]
use std::os::windows::fs::symlink_file as symlink;

use std::path::MAIN_SEPARATOR;
use std::{
env::{args, var},
fs::{canonicalize, create_dir_all},
path::PathBuf,
};

use color_eyre::eyre::{eyre, WrapErr};
use dirs::home_dir;

use crate::types::Kind;
use crate::{API_VERSION, XDG_CONFIG_HOME};

pub fn install() -> color_eyre::Result<()> {
let home = home_dir().ok_or_else(|| eyre!("Failed to determine home director"))?;
let install_directory = get_install_directory(home);

let source = PathBuf::from(args().next().unwrap());
let source =
canonicalize(&source).wrap_err("failed to find the absolute path of the current binary")?;

let kinds = [
Kind::ConfigMapGenerator,
Kind::SecretGenerator,
Kind::SimpleDecrypt,
];

let binary_suffix = if cfg!(windows) { ".exe" } else { "" };

for kind in &kinds {
let kind = format!("{:?}", kind);
let destination_folder = install_directory.join(&kind.to_lowercase());
create_dir_all(&destination_folder).wrap_err_with(|| {
format!(
"failed to create directory {}",
&destination_folder.to_string_lossy()
)
})?;

let destination = destination_folder.join(format!("{}{}", &kind, &binary_suffix));
println!(
"Linking kustomize-sops-rs to {}",
&destination.to_string_lossy()
);
if destination.exists() {
std::fs::remove_file(&destination).wrap_err("failed to delete old file")?;
}
symlink(&source, destination).wrap_err("failed to create link")?;
}
Ok(())
}

fn get_install_directory(home: PathBuf) -> PathBuf {
let api_directory = API_VERSION.replace("/", &MAIN_SEPARATOR.to_string());
var(XDG_CONFIG_HOME)
.wrap_err("failed to get the install directory")
.map(|config| PathBuf::from(config))
.unwrap_or_else(|_| home.join(".config"))
.join("kustomize")
.join("plugin")
.join(api_directory)
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod cli;
pub mod decryption;
pub mod installer;
pub mod maps;
pub mod types;

Expand Down
64 changes: 8 additions & 56 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,18 @@
use std::{
env::{args, var},
fs::{canonicalize, create_dir_all, File},
fs::File,
io::{stdout, Write},
os::unix::fs::symlink,
path::PathBuf,
process::exit,
};

use clap::Clap;
use color_eyre::{
eyre::{eyre, Context},
Result,
};
use dirs::home_dir;
use color_eyre::Result;
use serde_yaml::{from_reader, to_string};

use kustomize_sops::{
cli::Arguments, cli::SubCommand, decryption::decrypt_file, maps::generate_data_field,
maps::generate_output_map, types::Input, types::Kind, API_VERSION, CONFIG_MAP_OUTPUT,
SECRET_OUTPUT, XDG_CONFIG_HOME,
cli::Arguments, cli::SubCommand, decryption::decrypt_file, installer,
maps::generate_data_field, maps::generate_output_map, types::Input, types::Kind,
CONFIG_MAP_OUTPUT, SECRET_OUTPUT,
};
use serde_yaml::{from_reader, to_string};

fn main() -> Result<()> {
color_eyre::install()?;
Expand All @@ -33,7 +27,7 @@ fn main() -> Result<()> {
};
}
match arguments.subcommand {
Some(SubCommand::Install) => return install(),
Some(SubCommand::Install) => return installer::install(),
None => {
eprintln!("The yaml file is required if no command is set");
exit(1);
Expand Down Expand Up @@ -61,45 +55,3 @@ fn process_simple_decrypt(input: &Input) -> Result<()> {

Ok(())
}

fn install() -> Result<()> {
let home = home_dir().ok_or_else(|| eyre!("Failed to determine home director"))?;
let install_directory = var(XDG_CONFIG_HOME)
.wrap_err("failed to get the install directory")
.map(|config| PathBuf::from(config))
.unwrap_or_else(|_| home.join(".config"))
.join("kustomize")
.join("plugin")
.join(API_VERSION);

let source = PathBuf::from(args().next().unwrap());
let source =
canonicalize(&source).wrap_err("failed to find the absolute path of the current binary")?;

let kinds = [
Kind::ConfigMapGenerator,
Kind::SecretGenerator,
Kind::SimpleDecrypt,
];

for kind in &kinds {
let kind = format!("{:?}", kind);
let destination_folder = install_directory.join(&kind.to_lowercase());
create_dir_all(&destination_folder).wrap_err_with(|| {
format!(
"failed to create directory {}",
&destination_folder.to_string_lossy()
)
})?;
let destination = destination_folder.join(&kind);
println!(
"Linking kustomize-sops-rs to {}",
&destination.to_string_lossy()
);
if !destination.exists() {
// XXX: To implement on windows this needs to change
symlink(&source, destination).wrap_err("failed to create link")?;
}
}
Ok(())
}
13 changes: 13 additions & 0 deletions tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ fn setup_tests() {
}

fn configure_gpg() -> Result<()> {
let output = Command::new("gpg")
.arg("--list-keys")
.stderr(Stdio::piped())
.stdout(Stdio::piped())
.output()
.wrap_err("failed to run gpg")?;

check_output_status(&output)?;
if String::from_utf8_lossy(&output.stdout).contains("EBC846D0169D43A96ABA1C31AD471BDF8E8A0484")
{
return Ok(());
}
let output = Command::new("gpg")
.args(&["--import", "tests/kustomization/private.key"])
.stderr(Stdio::piped())
Expand Down Expand Up @@ -59,6 +71,7 @@ fn run_with_kustomize() {
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.output()
.wrap_err("failed to execute kustomize")
.unwrap();

let stdout = String::from_utf8_lossy(&output.stdout);
Expand Down