WIP: [helmile] Adding support for git subtree #2
@ -4,21 +4,22 @@
|
|||||||
name: zot
|
name: zot
|
||||||
repository: zot-git
|
repository: zot-git
|
||||||
extensions:
|
extensions:
|
||||||
- name: Add VPA
|
#- name: Add VPA
|
||||||
source_dir: ../extensions/vpa
|
# source_dir: ../extensions/vpa
|
||||||
target_dir: templates/gs-vpa
|
# target_dir: templates/gs-vpa
|
||||||
- name: Add values for CI
|
#- name: Add values for CI
|
||||||
source_dir: ../extensions/ci-values
|
# source_dir: ../extensions/ci-values
|
||||||
target_dir: ci
|
# target_dir: ci
|
||||||
variables:
|
variables:
|
||||||
target_repo: zot-app
|
target_repo: zot-app
|
||||||
patches:
|
patches:
|
||||||
- name: team annotation
|
#- name: team annotation
|
||||||
- name: set home
|
#- name: set home
|
||||||
- name: set engine
|
#- name: set engine
|
||||||
- name: yamlfmt
|
#- name: yamlfmt
|
||||||
- name: Git patch
|
- name: Git patch
|
||||||
git:
|
git:
|
||||||
path: ../patches/git/zot.patch
|
path: ../patches/git/zot.patch
|
||||||
|
ref: d43aaea7bc0e21edb5cc391d4eb47866a5a94aba
|
||||||
mirrors:
|
mirrors:
|
||||||
- apps-git
|
- apps-git
|
||||||
|
@ -8,6 +8,7 @@ include:
|
|||||||
path: ./charts/gitops-server.yaml
|
path: ./charts/gitops-server.yaml
|
||||||
- kind: Charts
|
- kind: Charts
|
||||||
path: ./charts/external-secrets-operator.yaml
|
path: ./charts/external-secrets-operator.yaml
|
||||||
|
|
||||||
patches:
|
patches:
|
||||||
- name: yamlfmt
|
- name: yamlfmt
|
||||||
custom_command:
|
custom_command:
|
||||||
@ -40,6 +41,7 @@ repositories:
|
|||||||
url: https://github.com/project-zot/helm-charts.git
|
url: https://github.com/project-zot/helm-charts.git
|
||||||
git_ref: zot-0.1.42
|
git_ref: zot-0.1.42
|
||||||
path: charts
|
path: charts
|
||||||
|
subtree: true
|
||||||
- name: weave
|
- name: weave
|
||||||
helm:
|
helm:
|
||||||
url: https://helm.gitops.weave.works
|
url: https://helm.gitops.weave.works
|
||||||
@ -50,7 +52,7 @@ mirrors:
|
|||||||
- name: apps-git
|
- name: apps-git
|
||||||
git:
|
git:
|
||||||
url: git@git.badhouseplants.net:allanger/{{ variables.target_repo }}.git
|
url: git@git.badhouseplants.net:allanger/{{ variables.target_repo }}.git
|
||||||
git_dir: app-{{ name }}-git
|
git_dir: app-{{ name }}
|
||||||
branch: upgrade-{{ name }}-to-{{ version }}
|
branch: upgrade-{{ name }}-to-{{ version }}
|
||||||
path: helm/{{ name }}
|
path: helm/{{ name }}
|
||||||
commit: |-
|
commit: |-
|
||||||
|
@ -109,13 +109,10 @@ index ac7f0f0..9730e9c 100644
|
|||||||
replicaCount: 1
|
replicaCount: 1
|
||||||
image:
|
image:
|
||||||
- repository: ghcr.io/project-zot/zot-linux-amd64
|
- repository: ghcr.io/project-zot/zot-linux-amd64
|
||||||
- pullPolicy: IfNotPresent
|
+ repository: ghcr.io/project-zot/zot-linux-amd64-bla
|
||||||
- # Overrides the image tag whose default is the chart appVersion.
|
pullPolicy: IfNotPresent
|
||||||
- tag: "v2.0.0"
|
# Overrides the image tag whose default is the chart appVersion.
|
||||||
+ registry: gsoci.azurecr.io
|
tag: "v2.0.0"
|
||||||
+ image: dummy/zot-linux
|
|
||||||
+ pullPolicy: Always
|
|
||||||
+ tag: ""
|
|
||||||
serviceAccount:
|
serviceAccount:
|
||||||
# Specifies whether a service account should be created
|
# Specifies whether a service account should be created
|
||||||
create: true
|
create: true
|
||||||
|
@ -47,7 +47,7 @@ struct Args {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn exec(args: Args) -> Result<(), Box<dyn Error>> {
|
fn exec(args: Args) -> Result<(), Box<dyn Error>> {
|
||||||
let prerequisites = vec![args.helm_bin, args.git_bin, args.yq_bin];
|
let prerequisites = vec![args.helm_bin, args.git_bin.clone(), args.yq_bin];
|
||||||
check_prerequisites(prerequisites)?;
|
check_prerequisites(prerequisites)?;
|
||||||
let workdir_path = helmzoo_lib::workdir::setup_workdir(args.workdir)?;
|
let workdir_path = helmzoo_lib::workdir::setup_workdir(args.workdir)?;
|
||||||
let mut config: Config = read_config(args.config.clone())?;
|
let mut config: Config = read_config(args.config.clone())?;
|
||||||
@ -72,7 +72,7 @@ fn exec(args: Args) -> Result<(), Box<dyn Error>> {
|
|||||||
patches
|
patches
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.try_for_each(|patch| -> Result<(), Box<dyn Error>> {
|
.try_for_each(|patch| -> Result<(), Box<dyn Error>> {
|
||||||
patch.apply(chart_path.clone(), config.patches.clone())
|
patch.apply(chart_path.clone(), config.patches.clone(), workdir_path.clone(), args.git_bin.clone())
|
||||||
})?
|
})?
|
||||||
}
|
}
|
||||||
config
|
config
|
||||||
|
@ -46,6 +46,7 @@ impl Target for GitMirror {
|
|||||||
Some(dir) => template::render(dir.clone(), &chart_local)?,
|
Some(dir) => template::render(dir.clone(), &chart_local)?,
|
||||||
None => general_purpose::STANDARD_NO_PAD.encode(self.url.clone()),
|
None => general_purpose::STANDARD_NO_PAD.encode(self.url.clone()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let git_instance = Git {
|
let git_instance = Git {
|
||||||
url: template::render(self.url.clone(), &chart_local)?,
|
url: template::render(self.url.clone(), &chart_local)?,
|
||||||
repo_path: repo_path.clone(),
|
repo_path: repo_path.clone(),
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
use std::{
|
use std::{
|
||||||
fs::{self, read_dir, remove_dir_all, File, OpenOptions},
|
fs::{self, read_dir, remove_dir_all, File, OpenOptions},
|
||||||
io::Write,
|
io::Write,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf}, process::exit,
|
||||||
};
|
};
|
||||||
|
|
||||||
use helmzoo_lib::{
|
use helmzoo_lib::{
|
||||||
cli::{cli_exec, cli_exec_from_dir},
|
cli::{cli_exec, cli_exec_from_dir}, git::{CheckoutOptions, Git, GitOptions}, output::message_info, workdir
|
||||||
output::message_info,
|
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@ -26,6 +25,12 @@ pub(crate) struct RegexpPatch {
|
|||||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
||||||
pub(crate) struct GitPatch {
|
pub(crate) struct GitPatch {
|
||||||
path: String,
|
path: String,
|
||||||
|
#[serde(alias = "ref")]
|
||||||
|
git_ref: Option<String>,
|
||||||
|
#[serde(skip)]
|
||||||
|
workdir: String,
|
||||||
|
#[serde(skip)]
|
||||||
|
git_bin: String
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
||||||
@ -62,18 +67,20 @@ impl Patch {
|
|||||||
&self,
|
&self,
|
||||||
chart_local_path: String,
|
chart_local_path: String,
|
||||||
global_patches: Option<Vec<Patch>>,
|
global_patches: Option<Vec<Patch>>,
|
||||||
|
workdir: String,
|
||||||
|
git_bin: String,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let patch_action: Box<dyn PatchInterface>;
|
let patch_action: Box<dyn PatchInterface>;
|
||||||
if self.is_ref() {
|
if self.is_ref() {
|
||||||
let patch_ref = self.get_ref(global_patches)?;
|
let patch_ref = self.get_ref(global_patches)?;
|
||||||
patch_action = Box::from(patch_action_from_definition(patch_ref)?);
|
patch_action = Box::from(patch_action_from_definition(patch_ref, workdir.clone(), git_bin.clone())?);
|
||||||
} else {
|
} else {
|
||||||
patch_action = Box::from(patch_action_from_definition(self.clone())?);
|
patch_action = Box::from(patch_action_from_definition(self.clone(), workdir.clone(), git_bin.clone())?);
|
||||||
}
|
}
|
||||||
patch_action.apply(chart_local_path)
|
patch_action.apply(chart_local_path)
|
||||||
}
|
}
|
||||||
pub(crate) fn get_path(&self) -> String {
|
pub(crate) fn get_path(&self) -> String {
|
||||||
match patch_action_from_definition(self.clone()) {
|
match patch_action_from_definition(self.clone(), String::new(), String::new()) {
|
||||||
Ok(patch) => patch.get_path(),
|
Ok(patch) => patch.get_path(),
|
||||||
Err(_) => "".to_string(),
|
Err(_) => "".to_string(),
|
||||||
}
|
}
|
||||||
@ -235,12 +242,34 @@ impl PatchInterface for RegexpPatch {
|
|||||||
|
|
||||||
impl PatchInterface for GitPatch {
|
impl PatchInterface for GitPatch {
|
||||||
fn apply(&self, chart_local_path: String) -> Result<(), Box<dyn std::error::Error>> {
|
fn apply(&self, chart_local_path: String) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
if !is_git_repo(chart_local_path.clone()) {
|
let git_instance = Git {
|
||||||
|
url: chart_local_path.clone(),
|
||||||
|
repo_path: chart_local_path.clone(),
|
||||||
|
};
|
||||||
|
let path = format!("{}", chart_local_path);
|
||||||
|
let is_git_repo = is_git_repo(path.clone());
|
||||||
|
if !is_git_repo {
|
||||||
init_git_repo(chart_local_path.clone())?;
|
init_git_repo(chart_local_path.clone())?;
|
||||||
};
|
};
|
||||||
|
let cmd = "git rev-parse --abbrev-ref HEAD".to_string();
|
||||||
|
let current_ref = cli_exec_from_dir(cmd, path)?;
|
||||||
|
let git_opts = GitOptions::new(self.git_bin.clone(), None);
|
||||||
|
if let Some(git_ref) = self.git_ref.clone() {
|
||||||
|
let checkout_options = CheckoutOptions {
|
||||||
|
create: false,
|
||||||
|
git_ref: git_ref.clone(),
|
||||||
|
};
|
||||||
|
git_instance.checkout(git_opts, checkout_options)?;
|
||||||
|
}
|
||||||
let cmd = format!("git -C {} apply {}", chart_local_path, self.path);
|
let cmd = format!("git -C {} apply {}", chart_local_path, self.path);
|
||||||
cli_exec(cmd)?;
|
cli_exec(cmd)?;
|
||||||
|
|
||||||
|
if let Some(git_ref) = self.git_ref.clone() {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if !is_git_repo{
|
||||||
remove_dir_all(chart_local_path + "/.git")?;
|
remove_dir_all(chart_local_path + "/.git")?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,6 +302,8 @@ impl PatchInterface for CustomCommandPatch {
|
|||||||
|
|
||||||
fn patch_action_from_definition(
|
fn patch_action_from_definition(
|
||||||
patch: Patch,
|
patch: Patch,
|
||||||
|
workdir: String,
|
||||||
|
git_bin: String,
|
||||||
) -> Result<Box<dyn PatchInterface>, Box<dyn std::error::Error>> {
|
) -> Result<Box<dyn PatchInterface>, Box<dyn std::error::Error>> {
|
||||||
if let Some(regexp) = patch.regexp {
|
if let Some(regexp) = patch.regexp {
|
||||||
Ok(Box::new(RegexpPatch { path: regexp.path }))
|
Ok(Box::new(RegexpPatch { path: regexp.path }))
|
||||||
@ -285,6 +316,9 @@ fn patch_action_from_definition(
|
|||||||
None => git.path.clone(),
|
None => git.path.clone(),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
git_ref: git.git_ref.clone(),
|
||||||
|
workdir: workdir.clone(),
|
||||||
|
git_bin: git_bin.clone(),
|
||||||
}));
|
}));
|
||||||
} else if let Some(custom_command) = patch.custom_command {
|
} else if let Some(custom_command) = patch.custom_command {
|
||||||
return Ok(Box::new(CustomCommandPatch {
|
return Ok(Box::new(CustomCommandPatch {
|
||||||
@ -301,7 +335,7 @@ fn patch_action_from_definition(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_git_repo(path: String) -> bool {
|
fn is_git_repo(path: String) -> bool {
|
||||||
let dot_git_path = path + ".git";
|
let dot_git_path = path + "/.git";
|
||||||
Path::new(dot_git_path.as_str()).exists()
|
Path::new(dot_git_path.as_str()).exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use std::error::Error;
|
use std::{error::Error, fmt::format};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::cli::{cli_exec, cli_exec_from_dir};
|
use crate::cli::{cli_exec, cli_exec_from_dir, is_path_relative};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
||||||
pub struct GitOptions {
|
pub struct GitOptions {
|
||||||
@ -46,6 +46,10 @@ pub struct Git {
|
|||||||
|
|
||||||
impl Git {
|
impl Git {
|
||||||
pub fn new(url: String, repo_path: String) -> Self {
|
pub fn new(url: String, repo_path: String) -> Self {
|
||||||
|
let repo_path = match is_path_relative(repo_path.clone()) {
|
||||||
|
true => format!("./{}", repo_path),
|
||||||
|
false => todo!(),
|
||||||
|
};
|
||||||
Self { url, repo_path }
|
Self { url, repo_path }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,8 +94,9 @@ impl Git {
|
|||||||
let _ = self.exec(cmd, git_opts.workdir.clone())?;
|
let _ = self.exec(cmd, git_opts.workdir.clone())?;
|
||||||
}
|
}
|
||||||
let cmd = format!(
|
let cmd = format!(
|
||||||
"{} diff --staged --quiet || {} -C {} commit -m \"{}\"",
|
"{} -C {} diff --staged --quiet || {} -C {} commit -m \"{}\"",
|
||||||
git_opts.bin, git_opts.bin, self.repo_path, opts.message
|
git_opts.bin, self.repo_path,
|
||||||
|
git_opts.bin, self.repo_path, opts.message
|
||||||
);
|
);
|
||||||
match self.exec(cmd, git_opts.workdir.clone()) {
|
match self.exec(cmd, git_opts.workdir.clone()) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
|
@ -4,6 +4,7 @@ use crate::git::GitOptions;
|
|||||||
use crate::{cli::cli_exec, helm::repository::Version};
|
use crate::{cli::cli_exec, helm::repository::Version};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fs::{self, rename};
|
use std::fs::{self, rename};
|
||||||
|
use std::process::exit;
|
||||||
|
|
||||||
use base64::{engine::general_purpose, Engine};
|
use base64::{engine::general_purpose, Engine};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
@ -19,6 +20,7 @@ pub struct GitRepo {
|
|||||||
#[serde(alias = "ref")]
|
#[serde(alias = "ref")]
|
||||||
pub git_ref: String,
|
pub git_ref: String,
|
||||||
pub path: String,
|
pub path: String,
|
||||||
|
pub subtree: bool,
|
||||||
#[serde(default = "default_git_bin")]
|
#[serde(default = "default_git_bin")]
|
||||||
pub(crate) git_bin: String,
|
pub(crate) git_bin: String,
|
||||||
}
|
}
|
||||||
@ -40,7 +42,7 @@ impl RepositoryImpl for GitRepo {
|
|||||||
git_ref: self.git_ref.clone(),
|
git_ref: self.git_ref.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
git_instance.checkout(git_opts, checkout_opts)?;
|
git_instance.checkout(git_opts.clone(), checkout_opts)?;
|
||||||
|
|
||||||
let old_dir_name = format!(
|
let old_dir_name = format!(
|
||||||
"{}/{}/{}/{}",
|
"{}/{}/{}/{}",
|
||||||
@ -56,13 +58,29 @@ impl RepositoryImpl for GitRepo {
|
|||||||
match serde_yaml::from_str::<Version>(&helm_stdout) {
|
match serde_yaml::from_str::<Version>(&helm_stdout) {
|
||||||
Ok(res) => {
|
Ok(res) => {
|
||||||
new_dir_name = format!("{}/{}-{}", workdir_path, chart.name.clone(), res.version);
|
new_dir_name = format!("{}/{}-{}", workdir_path, chart.name.clone(), res.version);
|
||||||
|
match self.subtree {
|
||||||
|
true => {
|
||||||
|
let cmd = format!("git subtree split --prefix {}/{} -b helmule-subtree-split", self.path, chart.name.clone());
|
||||||
|
cli_exec_from_dir(cmd, format!("{}/{}", workdir_path.clone(), repo_name))?;
|
||||||
|
let checkout_opts = CheckoutOptions{
|
||||||
|
create: false,
|
||||||
|
git_ref: "helmule-subtree-split".to_string(),
|
||||||
|
};
|
||||||
|
git_instance.checkout(git_opts.clone(), checkout_opts)?;
|
||||||
|
let old_dir_name = format!("{}/{}", workdir_path.clone(), repo_name);
|
||||||
rename(old_dir_name, new_dir_name.clone())?;
|
rename(old_dir_name, new_dir_name.clone())?;
|
||||||
|
},
|
||||||
|
false => {
|
||||||
|
rename(old_dir_name, new_dir_name.clone())?;
|
||||||
|
// Cleaning up
|
||||||
|
fs::remove_dir_all(format!("{}/{}", workdir_path, repo_name))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
}
|
}
|
||||||
Err(err) => return Err(Box::from(err)),
|
Err(err) => return Err(Box::from(err)),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Cleaning up
|
|
||||||
fs::remove_dir_all(format!("{}/{}", workdir_path, repo_name))?;
|
|
||||||
|
|
||||||
// Get the version
|
// Get the version
|
||||||
let cmd = "helm show chart . | yq '.version'".to_string();
|
let cmd = "helm show chart . | yq '.version'".to_string();
|
||||||
|
Loading…
Reference in New Issue
Block a user