DiffReleases wrapper for executing helm diff on the releases It returns releases that had any changes, and errors if any. This function has responsibility to stabilize the order of writes to stdout from multiple concurrent helm-diff runs. It's required to use the stdout from helmfile-diff to detect
(helm helmexec.Interface, additionalValues []string, workerLimit int, detailedExitCode bool, includeTests bool, suppress []string, suppressSecrets, showSecrets, suppressDiff, triggerCleanupEvents bool, opt ...DiffOpt)
| 1828 | // `terraform`, by design, fails when helmfile-diff outputs were not equivalent. |
| 1829 | // Stabilized helmfile-diff output rescues that. |
| 1830 | func (st *HelmState) DiffReleases(helm helmexec.Interface, additionalValues []string, workerLimit int, detailedExitCode bool, includeTests bool, suppress []string, suppressSecrets, showSecrets, suppressDiff, triggerCleanupEvents bool, opt ...DiffOpt) ([]ReleaseSpec, []error) { |
| 1831 | opts := &DiffOpts{} |
| 1832 | for _, o := range opt { |
| 1833 | o.Apply(opts) |
| 1834 | } |
| 1835 | |
| 1836 | preps, prepErrs := st.prepareDiffReleases(helm, additionalValues, workerLimit, detailedExitCode, includeTests, suppress, suppressSecrets, showSecrets, opts) |
| 1837 | |
| 1838 | if !opts.SkipCleanup { |
| 1839 | defer func() { |
| 1840 | for _, p := range preps { |
| 1841 | st.removeFiles(p.files) |
| 1842 | } |
| 1843 | }() |
| 1844 | } |
| 1845 | |
| 1846 | if len(prepErrs) > 0 { |
| 1847 | return []ReleaseSpec{}, prepErrs |
| 1848 | } |
| 1849 | |
| 1850 | jobQueue := make(chan *diffPrepareResult, len(preps)) |
| 1851 | results := make(chan diffResult, len(preps)) |
| 1852 | |
| 1853 | rs := []ReleaseSpec{} |
| 1854 | outputs := map[string]*bytes.Buffer{} |
| 1855 | errs := []error{} |
| 1856 | |
| 1857 | // The exit code returned by helm-diff when it detected any changes |
| 1858 | HelmDiffExitCodeChanged := 2 |
| 1859 | |
| 1860 | st.scatterGather( |
| 1861 | workerLimit, |
| 1862 | len(preps), |
| 1863 | func() { |
| 1864 | for i := 0; i < len(preps); i++ { |
| 1865 | jobQueue <- &preps[i] |
| 1866 | } |
| 1867 | close(jobQueue) |
| 1868 | }, |
| 1869 | func(workerIndex int) { |
| 1870 | for prep := range jobQueue { |
| 1871 | flags := prep.flags |
| 1872 | release := prep.release |
| 1873 | buf := &bytes.Buffer{} |
| 1874 | if prep.upgradeDueToSkippedDiff { |
| 1875 | results <- diffResult{release, &ReleaseError{ReleaseSpec: release, err: nil, Code: HelmDiffExitCodeChanged}, buf} |
| 1876 | } else if err := helm.DiffRelease(st.createHelmContextWithWriter(release, buf), release.Name, normalizeChart(st.basePath, release.Chart), suppressDiff, flags...); err != nil { |
| 1877 | switch e := err.(type) { |
| 1878 | case helmexec.ExitError: |
| 1879 | // Propagate any non-zero exit status from the external command like `helm` that is failed under the hood |
| 1880 | results <- diffResult{release, &ReleaseError{release, err, e.ExitStatus()}, buf} |
| 1881 | default: |
| 1882 | results <- diffResult{release, &ReleaseError{release, err, 0}, buf} |
| 1883 | } |
| 1884 | } else { |
| 1885 | // diff succeeded, found no changes |
| 1886 | results <- diffResult{release, nil, buf} |
| 1887 | } |